/**
   * Create business object instances via API (not via process instances) and validate if they're
   * created and if a business object query for a given primary key returns the corresponding BO.
   */
  @Test
  public void CreateCustomersCheck() {
    DeployedModelDescription model =
        sf.getQueryService().getModels(DeployedModelQuery.findActiveForId(MODEL_NAME2)).get(0);
    for (int i = 1; i <= 3; i++) {
      createCustomer(model, i);
    }

    String businessObjectQualifiedId = new QName(model.getId(), "Customer").toString();
    BusinessObjectQuery query =
        BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    BusinessObjects bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    BusinessObject bo = bos.get(0);
    List<BusinessObject.Value> values = bo.getValues();
    Assert.assertEquals("Values", 3, values.size());

    query = BusinessObjectQuery.findWithPrimaryKey(businessObjectQualifiedId, 2);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "firstName", "Danny2");
  }
  /**
   * Create some instances for a given BO and validate if they can be queried:
   *
   * <ul>
   *   <li>where the qualified business object id is set
   *   <li>the primary key is passed to findForBusinessObject()
   *   <li>the qualified business object id is passed to findForBusinessObject and the primary key
   *       is set as a data filter
   *   <li>the qualified business object id is passed to findForBusinessObject and an attribute of
   *       the BO is set as a data filter
   * </ul>
   */
  @Test
  public void CheckFiltering() throws Exception {
    DeployedModelDescription model =
        sf.getQueryService().getModels(DeployedModelQuery.findActiveForId(MODEL_NAME3)).get(0);

    String businessObjectQualifiedId = new QName(model.getId(), "Fund").toString();
    for (int i = 1; i <= 9; i++) {
      final Map<String, Object> fund = CollectionUtils.newMap();
      fund.put("AccountNumber", "100100" + i);
      fund.put("AccountName", "Fund" + i);

      sf.getWorkflowService()
          .createBusinessObjectInstance(businessObjectQualifiedId, (Serializable) fund);
    }

    BusinessObjectQuery query =
        BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    BusinessObjects bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    BusinessObject bo = bos.get(0);
    List<BusinessObject.Value> values = bo.getValues();
    Assert.assertEquals("Values", 9, values.size());

    query = BusinessObjectQuery.findWithPrimaryKey(businessObjectQualifiedId, "1001003");
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "AccountNumber", "1001003");

    query = BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query.where(DataFilter.isEqual("Fund", "AccountNumber", "1001005"));
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "AccountNumber", "1001005");

    query = BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query.where(DataFilter.isEqual("Fund", "AccountName", "Fund7"));
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "AccountName", "Fund7");
  }
  /**
   * Test if the business object query returns all business object instances for a given business
   * object id. The BO instances was created by the OrderCreation process resp. EnterOrderData
   * activity in the setup() method.
   */
  @Test
  public void CheckOrders() {
    DeployedModelDescription model =
        sf.getQueryService().getModels(DeployedModelQuery.findActiveForId(MODEL_NAME2)).get(0);

    BusinessObjectQuery query =
        BusinessObjectQuery.findForBusinessObject(new QName(model.getId(), "Order").toString());
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));

    BusinessObjects bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    BusinessObject bo = bos.get(0);
    List<BusinessObject.Value> values = bo.getValues();
    Assert.assertTrue("Expected at least 5 values: " + values.size(), 5 <= values.size());
    checkValue(values, false, "customerId", 1, 2, 3, 4, 5);
  }
  private BusinessObject createOrder(DeployedModelDescription model, int customerId) {
    final Map<String, Object> order = CollectionUtils.newMap();
    order.put("date", new Date());
    order.put("customerId", customerId);

    return sf.getWorkflowService()
        .createBusinessObjectInstance(
            new QName(model.getId(), "Order").toString(), (Serializable) order);
  }
  private BusinessObject createCustomer(DeployedModelDescription model, int customerId) {
    final Map<String, Object> order = CollectionUtils.newMap();
    order.put("id", customerId);
    order.put("firstName", "Danny" + customerId);
    order.put("lastName", "North" + customerId);

    return sf.getWorkflowService()
        .createBusinessObjectInstance(
            new QName(model.getId(), "Customer").toString(), (Serializable) order);
  }
  /** Check if an already created BO instance can be deleted and created again later. */
  @Test
  public void DeleteOrdersCheck() {
    DeployedModelDescription model =
        sf.getQueryService().getModels(DeployedModelQuery.findActiveForId(MODEL_NAME2)).get(0);
    createOrder(model, 888);
    BusinessObjectQuery query =
        BusinessObjectQuery.findWithPrimaryKey(new QName(model.getId(), "Order").toString(), 888);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    BusinessObjects bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Values", 1, bos.getSize());

    sf.getWorkflowService()
        .deleteBusinessObjectInstance(new QName(model.getId(), "Order").toString(), 888);

    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Values", 0, bos.getSize());
    createOrder(model, 888);
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Values", 1, bos.getSize());
  }
 /** Test if a field, other than the primary key, of a BO instance can be modified. */
 @Test
 public void ModifyOrdersCheck() {
   DeployedModelDescription model =
       sf.getQueryService().getModels(DeployedModelQuery.findActiveForId(MODEL_NAME2)).get(0);
   BusinessObject bo = createOrder(model, 777);
   @SuppressWarnings("unchecked")
   final Map<String, Object> order = (Map<String, Object>) bo.getValues().get(0).getValue();
   Date date = (Date) order.get("date");
   order.put("date", new Date(date.getTime() + TIME_LAPSE));
   sf.getWorkflowService()
       .updateBusinessObjectInstance(
           new QName(model.getId(), "Order").toString(), (Serializable) order);
   BusinessObjectQuery query =
       BusinessObjectQuery.findWithPrimaryKey(new QName(model.getId(), "Order").toString(), 777);
   query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
   BusinessObjects bos = sf.getQueryService().getAllBusinessObjects(query);
   bo = bos.get(0);
   @SuppressWarnings("unchecked")
   Map<String, Object> updatedOrder = (Map<String, Object>) bo.getValues().get(0).getValue();
   Date updatedDate = (Date) updatedOrder.get("date");
   Assert.assertEquals("Time difference", TIME_LAPSE, updatedDate.getTime() - date.getTime());
 }
  /**
   * Validate if BO instances can be created once only with the same primary key and that they can
   * be queried either via findWithPrimaryKey() or with help of data filters.
   */
  @Test
  public void CreateOrdersCheck() {
    DeployedModelDescription model =
        sf.getQueryService().getModels(DeployedModelQuery.findActiveForId(MODEL_NAME2)).get(0);
    createOrder(model, 666);
    try {
      createOrder(model, 666);
      Assert.fail("Extected BPMRT03825 error message");
    } catch (ObjectExistsException ex) {
      Assert.assertEquals("Error code", "BPMRT03825", ex.getError().getId());
    }

    String businessObjectQualifiedId = new QName(model.getId(), "Order").toString();
    BusinessObjectQuery query =
        BusinessObjectQuery.findWithPrimaryKey(businessObjectQualifiedId, 666);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    BusinessObjects bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    BusinessObject bo = bos.get(0);
    List<Value> values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "customerId", 666);

    query = BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query
        .getFilter()
        .addOrTerm()
        .or(DataFilter.isEqual("Order", "customerId", 2))
        .or(DataFilter.isEqual("Order", "customerId", 4));
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 2, values.size());
    checkValue(values, true, "customerId", 2, 4);
  }
  /**
   * Create some instances for a given BO and validate if they can be queried where:
   *
   * <ul>
   *   <li>the qualified business object id is set
   *   <li>the primary key is passed to findForBusinessObject()
   *   <li>the qualified business object id is passed to findForBusinessObject and an attribute of
   *       the BO is set as a data filter
   *   <li>the qualified business object id is passed to findForBusinessObject and the query is
   *       restricted to the currently active model
   *   <li>the qualified business object id is passed to findForBusinessObject and across all
   *       deployed model versions
   *   <li>the qualified business object id is passed to findForBusinessObject and the query is
   *       restricted to a given modelOid
   * </ul>
   */
  @Test
  public void CheckFiltering2() throws Exception {
    DeployedModelDescription model =
        sf.getQueryService().getModels(DeployedModelQuery.findActiveForId(MODEL_NAME3)).get(0);

    String businessObjectQualifiedId = new QName(model.getId(), "Employee").toString();

    createEmployee(businessObjectQualifiedId, "1", "Florin");
    createEmployee(businessObjectQualifiedId, "Sid", "2");

    BusinessObjectQuery query =
        BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    BusinessObjects bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    BusinessObject bo = bos.get(0);
    List<BusinessObject.Value> values = bo.getValues();
    Assert.assertEquals("Values", 2, values.size());

    query = BusinessObjectQuery.findWithPrimaryKey(businessObjectQualifiedId, "1");
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "EmpID", "1");

    query = BusinessObjectQuery.findWithPrimaryKey(businessObjectQualifiedId, "Sid");
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "EmpID", "Sid");

    query = BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query.where(DataFilter.isEqual("Employee", "EmpName", "2"));
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "EmpName", "2");

    query = BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query.where(DataFilter.isEqual("Employee", "EmpName", "Florin"));
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "EmpName", "Florin");

    RtEnvHome.deployModel(sf.getAdministrationService(), null, MODEL_NAME3);
    createEmployee(businessObjectQualifiedId, "3", "Meyer");
    query =
        BusinessObjectQuery.findForBusinessObject(
            PredefinedConstants.ACTIVE_MODEL, businessObjectQualifiedId);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());

    query = BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 2, bos.getSize());
    Assert.assertEquals("Values", 3, getTotalSize(bos));

    query =
        BusinessObjectQuery.findForBusinessObject(model.getModelOID(), businessObjectQualifiedId);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 2, values.size());
  }