示例#1
0
  @Override
  @Transactional
  public <T> Records<T> getRelatedFieldValue(
      Long entityId, Long instanceId, String fieldName, QueryParams queryParams) {
    EntityDto entity = getEntity(entityId);
    validateCredentials(entity);
    String entityName = entity.getName();

    MotechDataService service = getServiceForEntity(entity);
    Object instance = service.findById(instanceId);

    if (instance == null) {
      throw new ObjectNotFoundException(entityName, instanceId);
    }

    try {
      Collection<T> relatedAsColl =
          TypeHelper.asCollection(PropertyUtil.getProperty(instance, fieldName));

      List<T> filtered = InMemoryQueryFilter.filter(relatedAsColl, queryParams);

      int recordCount = relatedAsColl.size();
      int rowCount = (int) Math.ceil(recordCount / (double) queryParams.getPageSize());

      return new Records<>(queryParams.getPage(), rowCount, recordCount, filtered);
    } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
      throw new ObjectReadException(entityName, e);
    }
  }
示例#2
0
  @Override
  public void revertInstanceFromTrash(Long entityId, Long instanceId) {
    EntityDto entity = getEntity(entityId);
    validateCredentials(entity);
    validateNonEditableProperty(entity);
    MotechDataService service = getServiceForEntity(entity);

    Object trash = service.findTrashInstanceById(instanceId, entityId);
    List<FieldRecord> fieldRecords = new LinkedList<>();

    try {
      for (FieldDto field : entityService.getEntityFields(entity.getId())) {
        if (ID_FIELD_NAME.equalsIgnoreCase(field.getBasic().getDisplayName())) {
          continue;
        }
        Field f =
            FieldUtils.getField(
                trash.getClass(), StringUtils.uncapitalize(field.getBasic().getName()), true);
        FieldRecord record = new FieldRecord(field);
        record.setValue(f.get(trash));
        fieldRecords.add(record);
      }

      Class<?> entityClass = getEntityClass(entity);

      Object newInstance = entityClass.newInstance();
      updateFields(newInstance, fieldRecords, service, null);

      service.revertFromTrash(newInstance, trash);
    } catch (Exception e) {
      throw new RevertFromTrashException(entity.getName(), instanceId, e);
    }
  }
示例#3
0
  @Override
  public long countRecords(Long entityId) {
    EntityDto entity = getEntity(entityId);
    validateCredentialsForReading(entity);
    MotechDataService service = getServiceForEntity(entity);

    return service.count();
  }
示例#4
0
  @Override
  public void deleteInstance(Long entityId, Long instanceId) {
    EntityDto entity = getEntity(entityId);
    validateCredentials(entity);
    validateNonEditableProperty(entity);
    MotechDataService service = getServiceForEntity(entity);

    service.delete(ID_FIELD_NAME, instanceId);
  }
示例#5
0
  @Test
  public void shouldCreateInstanceOfSubclassedEntityWithRelation() {
    mockEntity(SubclassSample.class, ENTITY_ID, entity);
    mockDataService(SubclassSample.class, motechDataService);
    when(motechDataService.retrieve("id", INSTANCE_ID)).thenReturn(new SubclassSample());
    when(entityService.getEntityFieldsForUI(ENTITY_ID))
        .thenReturn(
            asList(
                FieldTestHelper.fieldDto(
                    1L, "superclassInteger", Integer.class.getName(), "Superclass Integer", 7),
                FieldTestHelper.fieldDto(
                    2L, "subclassString", String.class.getName(), "Subclass String", "test"),
                FieldTestHelper.fieldDto(
                    3L,
                    "superclassRelation",
                    TypeDto.ONE_TO_ONE_RELATIONSHIP.getTypeClass(),
                    "Superclass Relationship",
                    null)));

    long relationEntityId = ANOTHER_ENTITY_ID;
    long relationInstanceId = INSTANCE_ID + 1;
    EntityDto relationEntity = mock(EntityDto.class);
    MotechDataService relationDataService = mock(MotechDataService.class);
    mockEntity(TestSample.class, relationEntityId, relationEntity);
    mockDataService(TestSample.class, relationDataService);
    TestSample relatedInstance = new TestSample("test sample", 42);
    when(relationDataService.retrieve("id", relationInstanceId)).thenReturn(relatedInstance);
    when(relationDataService.findById(relationInstanceId)).thenReturn(relatedInstance);

    RelationshipsUpdate relationshipsUpdate = new RelationshipsUpdate();
    relationshipsUpdate.getAddedIds().add(relationInstanceId);

    EntityRecord createRecord =
        new EntityRecord(
            null,
            ENTITY_ID,
            asList(
                FieldTestHelper.fieldRecord("superclassInteger", Integer.class.getName(), "", 77),
                FieldTestHelper.fieldRecord(
                    "subclassString", String.class.getName(), "", "test test"),
                FieldTestHelper.fieldRecord(
                    TypeDto.ONE_TO_ONE_RELATIONSHIP,
                    "superclassRelation",
                    "",
                    relationshipsUpdate)));

    ArgumentCaptor<SubclassSample> createCaptor = ArgumentCaptor.forClass(SubclassSample.class);
    instanceService.saveInstance(createRecord);
    verify(motechDataService).create(createCaptor.capture());

    SubclassSample instance = createCaptor.getValue();
    assertEquals(77, (int) instance.getSuperclassInteger());
    assertEquals("test test", instance.getSubclassString());
    assertNotNull(instance.getSuperclassRelation());
    assertEquals(relatedInstance.getStrField(), instance.getSuperclassRelation().getStrField());
    assertEquals(relatedInstance.getIntField(), instance.getSuperclassRelation().getIntField());
  }
示例#6
0
  @Override
  public long countHistoryRecords(Long entityId, Long instanceId) {
    EntityDto entity = getEntity(entityId);
    validateCredentialsForReading(entity);
    MotechDataService service = getServiceForEntity(entity);

    Object instance = service.retrieve(ID_FIELD_NAME, instanceId);

    return historyService.countHistoryRecords(instance);
  }
示例#7
0
  @Override
  public Object getInstanceField(Long entityId, Long instanceId, String fieldName) {
    EntityDto entity = getEntity(entityId);
    MotechDataService service = getServiceForEntity(entity);
    validateCredentialsForReading(entity);

    Object instance = service.retrieve(ID_FIELD_NAME, instanceId);

    return service.getDetachedField(instance, fieldName);
  }
示例#8
0
  @Override
  public List<EntityRecord> getEntityRecords(Long entityId, QueryParams queryParams) {
    EntityDto entity = getEntity(entityId);
    validateCredentialsForReading(entity);
    List<FieldDto> fields = entityService.getEntityFields(entityId);

    MotechDataService service = getServiceForEntity(entity);
    List instances = service.retrieveAll(queryParams);

    return instancesToRecords(instances, entity, fields, service);
  }
示例#9
0
  @Override
  public HistoryRecord getHistoryRecord(Long entityId, Long instanceId, Long historyId) {
    EntityDto entity = getEntity(entityId);
    validateCredentialsForReading(entity);
    MotechDataService service = getServiceForEntity(entity);

    Object instance = service.retrieve(ID_FIELD_NAME, instanceId);

    Object historyInstance = historyService.getSingleHistoryInstance(instance, historyId);

    return convertToHistoryRecord(historyInstance, entity, instanceId, service);
  }
示例#10
0
  @Override
  public EntityRecord getEntityInstance(Long entityId, Long instanceId) {
    EntityDto entity = getEntity(entityId);
    validateCredentialsForReading(entity);
    MotechDataService service = getServiceForEntity(entity);

    Object instance = service.retrieve(ID_FIELD_NAME, instanceId);
    if (instance == null) {
      throw new ObjectNotFoundException(entity.getName(), instanceId);
    }

    List<FieldDto> fields = entityService.getEntityFields(entityId);

    return instanceToRecord(instance, entity, fields, service);
  }
示例#11
0
  @Override
  public List<HistoryRecord> getInstanceHistory(
      Long entityId, Long instanceId, QueryParams queryParams) {
    EntityDto entity = getEntity(entityId);
    validateCredentialsForReading(entity);
    MotechDataService service = getServiceForEntity(entity);

    Object instance = service.retrieve(ID_FIELD_NAME, instanceId);

    List history = historyService.getHistoryForInstance(instance, queryParams);
    List<HistoryRecord> result = new ArrayList<>();
    for (Object o : history) {
      result.add(convertToHistoryRecord(o, entity, instanceId, service));
    }
    return result;
  }
示例#12
0
  private void testUpdateCreate(boolean edit) throws ClassNotFoundException {
    final DateTime dtValue = DateUtil.now();

    mockSampleFields();
    mockDataService();
    mockEntity();
    when(motechDataService.retrieve("id", INSTANCE_ID)).thenReturn(new TestSample());

    List<FieldRecord> fieldRecords =
        asList(
            FieldTestHelper.fieldRecord("strField", String.class.getName(), "", "this is a test"),
            FieldTestHelper.fieldRecord("intField", Integer.class.getName(), "", 16),
            FieldTestHelper.fieldRecord("timeField", Time.class.getName(), "", "10:17"),
            FieldTestHelper.fieldRecord("dtField", DateTime.class.getName(), "", dtValue));

    Long id = (edit) ? INSTANCE_ID : null;
    EntityRecord record = new EntityRecord(id, ENTITY_ID, fieldRecords);

    MDSClassLoader.getInstance().loadClass(TestSample.class.getName());
    instanceService.saveInstance(record);

    ArgumentCaptor<TestSample> captor = ArgumentCaptor.forClass(TestSample.class);
    if (edit) {
      verify(motechDataService).update(captor.capture());
    } else {
      verify(motechDataService).create(captor.capture());
    }

    TestSample sample = captor.getValue();
    assertEquals("this is a test", sample.getStrField());
    assertEquals(Integer.valueOf(16), sample.getIntField());
    assertEquals(new Time(10, 17), sample.getTimeField());
    assertEquals(dtValue, sample.getDtField());
  }
示例#13
0
  private Object getProperty(Object instance, FieldDto field, MotechDataService service)
      throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    String fieldName = StringUtils.uncapitalize(field.getBasic().getName());

    PropertyDescriptor propertyDescriptor = PropertyUtil.getPropertyDescriptor(instance, fieldName);
    Method readMethod = propertyDescriptor.getReadMethod();

    if (readMethod == null) {
      throw new NoSuchMethodException(String.format("No getter for field %s", fieldName));
    }

    if (TypeDto.BLOB.getTypeClass().equals(field.getType().getTypeClass())) {
      return ArrayUtils.EMPTY_BYTE_OBJECT_ARRAY;
    }

    try {
      return readMethod.invoke(instance);
    } catch (InvocationTargetException e) {
      LOGGER.debug(
          "Invocation target exception thrown when retrieving field {}. This may indicate a non loaded field",
          fieldName,
          e);
      // fallback to the service
      return service.getDetachedField(instance, fieldName);
    }
  }
示例#14
0
  @Override
  @Transactional
  public Object saveInstance(EntityRecord entityRecord, Long deleteValueFieldId) {
    EntityDto entity = getEntity(entityRecord.getEntitySchemaId());
    validateCredentials(entity);
    validateNonEditableProperty(entity);

    List<FieldDto> entityFields = getEntityFields(entityRecord.getEntitySchemaId());

    try {
      MotechDataService service = getServiceForEntity(entity);
      Class<?> entityClass = getEntityClass(entity);

      boolean newObject = entityRecord.getId() == null;

      Object instance;
      if (newObject) {
        instance = entityClass.newInstance();

        for (FieldDto entityField : entityFields) {
          if (entityField.getType().isMap() && entityField.getBasic().getDefaultValue() != null) {
            setInstanceFieldMap(instance, entityField);
          }
        }

      } else {
        instance = service.retrieve(ID_FIELD_NAME, entityRecord.getId());
        if (instance == null) {
          throw new ObjectNotFoundException(entity.getName(), entityRecord.getId());
        }
      }

      updateFields(instance, entityRecord.getFields(), service, deleteValueFieldId, !newObject);

      if (newObject) {
        return service.create(instance);
      } else {
        return service.update(instance);
      }
    } catch (Exception e) {
      if (entityRecord.getId() == null) {
        throw new ObjectCreateException(entity.getName(), e);
      } else {
        throw new ObjectUpdateException(entity.getName(), entityRecord.getId(), e);
      }
    }
  }
示例#15
0
  @Test
  public void shouldReturnRelatedInstances() {
    mockDataService();
    mockAnotherEntity();
    mockEntity();
    mockSampleFields();
    mockAnotherEntityFields();
    mockTestClassEntity();
    mockTestClassService();
    mockTestClassFields();
    when(serviceForAnotherSample.findById(INSTANCE_ID)).thenReturn(sampleForRelationshipTesting());

    QueryParams queryParams =
        new QueryParams(1, 2, new Order(Constants.Util.ID_FIELD_NAME, Order.Direction.ASC));
    Records<BasicEntityRecord> records =
        instanceService.getRelatedFieldValue(
            ANOTHER_ENTITY_ID, INSTANCE_ID, "testClasses", new RelationshipsUpdate(), queryParams);

    assertNotNull(records);
    assertEquals(Integer.valueOf(1), records.getPage()); // page 1
    assertEquals(Integer.valueOf(2), records.getTotal()); // 2 pages total
    assertEquals(Integer.valueOf(3), records.getRecords()); // 3 records total
    assertEquals(
        asList(1L, 2L),
        extract(records.getRows(), on(BasicEntityRecord.class).getFieldByName("id").getValue()));

    RelationshipsUpdate filter = new RelationshipsUpdate();
    filter.setRemovedIds(Arrays.asList(1L, 2L));
    filter.setAddedIds(Arrays.asList(50L));

    when(testClassMotechDataService.findByIds(filter.getAddedIds()))
        .thenReturn(Arrays.asList(new TestClass(50)));
    records =
        instanceService.getRelatedFieldValue(
            ANOTHER_ENTITY_ID, INSTANCE_ID, "testClasses", filter, queryParams);

    assertNotNull(records);
    assertEquals(Integer.valueOf(1), records.getPage()); // page 1
    assertEquals(Integer.valueOf(1), records.getTotal()); // 1 page total
    assertEquals(Integer.valueOf(2), records.getRecords()); // 2 records total
    // 1L and 2L removed, 50L added
    assertEquals(
        asList(3L, 50L),
        extract(records.getRows(), on(BasicEntityRecord.class).getFieldByName("id").getValue()));
  }
示例#16
0
  @Test
  public void shouldCountAllEntities() {
    mockSampleFields();
    mockDataService();
    mockEntity();

    when(motechDataService.count()).thenReturn(56L);

    assertEquals(56L, instanceService.countRecords(ENTITY_ID));
  }
示例#17
0
  @Override
  public FieldRecord getInstanceValueAsRelatedField(Long entityId, Long fieldId, Long instanceId) {
    validateCredentialsForReading(getEntity(entityId));
    try {
      FieldRecord fieldRecord;
      FieldDto field = entityService.getEntityFieldById(entityId, fieldId);
      MotechDataService service =
          DataServiceHelper.getDataService(
              bundleContext, field.getMetadata(RELATED_CLASS).getValue());

      Object instance = service.findById(instanceId);
      if (instance == null) {
        throw new ObjectNotFoundException(service.getClassType().getName(), instanceId);
      }
      fieldRecord = new FieldRecord(field);
      fieldRecord.setValue(
          parseValueForDisplay(instance, field.getMetadata(Constants.MetadataKeys.RELATED_FIELD)));
      fieldRecord.setDisplayValue(instance.toString());
      return fieldRecord;
    } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
      throw new ObjectReadException(entityId, e);
    }
  }
示例#18
0
  @Test
  public void shouldLoadBlobField() throws InstanceNotFoundException {
    EntityDto entityDto = new EntityDto();
    entityDto.setReadOnlySecurityMode(null);
    entityDto.setSecurityMode(null);
    entityDto.setClassName(TestSample.class.getName());

    when(entityService.getEntity(ENTITY_ID + 1)).thenReturn(entityDto);
    mockDataService();
    TestSample instance = Mockito.mock(TestSample.class);
    when(motechDataService.findById(ENTITY_ID + 1)).thenReturn(instance);

    instanceService.getInstanceField(12l, ENTITY_ID + 1, "blobField");
    verify(motechDataService).getDetachedField(instance, "blobField");
  }
示例#19
0
  @Test(expected = ObjectUpdateException.class)
  public void shouldThrowExceptionWhileUpdatingReadonlyField() throws ClassNotFoundException {
    mockDataService();
    mockEntity();
    when(motechDataService.retrieve("id", INSTANCE_ID)).thenReturn(new TestSample());

    List<FieldRecord> fieldRecords =
        asList(
            FieldTestHelper.fieldRecord("strField", String.class.getName(), "", "CannotEditThis"));
    fieldRecords.get(0).setNonEditable(true);

    EntityRecord record = new EntityRecord(INSTANCE_ID, ENTITY_ID, fieldRecords);

    instanceService.saveInstance(record);
  }
示例#20
0
  private Object parseBlobValue(
      FieldRecord fieldRecord,
      MotechDataService service,
      String fieldName,
      Long deleteValueFieldId,
      Object instance) {
    Object parsedValue;
    if ((ArrayUtils.EMPTY_BYTE_OBJECT_ARRAY.equals(fieldRecord.getValue())
            || ArrayUtils.EMPTY_BYTE_ARRAY.equals(fieldRecord.getValue()))
        && !fieldRecord.getId().equals(deleteValueFieldId)) {
      parsedValue = service.getDetachedField(instance, fieldName);
    } else {
      parsedValue = fieldRecord.getValue();
    }

    return verifyParsedValue(parsedValue);
  }
示例#21
0
  @Test
  public void shouldReturnEntityInstance() {
    mockDataService();
    mockSampleFields();
    mockEntity();
    when(motechDataService.retrieve("id", INSTANCE_ID))
        .thenReturn(new TestSample("Hello world", 99));

    EntityRecord record = instanceService.getEntityInstance(ENTITY_ID, INSTANCE_ID);

    assertNotNull(record);
    assertEquals(Long.valueOf(ENTITY_ID), record.getEntitySchemaId());
    assertEquals(Long.valueOf(INSTANCE_ID), record.getId());

    List<FieldRecord> fieldRecords = record.getFields();
    assertCommonFieldRecordFields(fieldRecords);
    assertEquals(
        asList("Hello world", 99, null, null, null),
        extract(fieldRecords, on(FieldRecord.class).getValue()));
  }
示例#22
0
  @Test
  public void shouldUpdateRelatedFields() {
    TestSample test1 = new TestSample("someString", 4);
    TestSample test2 = new TestSample("otherString", 5);
    TestSample test3 = new TestSample("sample", 6);

    RelationshipsUpdate oneToOneUpdate = new RelationshipsUpdate();
    oneToOneUpdate.getAddedIds().add(6L);
    RelationshipsUpdate oneToManyUpdate = buildRelationshipUpdate();

    List<FieldRecord> fieldRecords =
        asList(
            FieldTestHelper.fieldRecord("title", String.class.getName(), "String field", "Default"),
            FieldTestHelper.fieldRecord(
                TypeDto.ONE_TO_MANY_RELATIONSHIP, "testSamples", "Related field", oneToManyUpdate),
            FieldTestHelper.fieldRecord(
                TypeDto.ONE_TO_ONE_RELATIONSHIP,
                "testSample",
                "Other Related field",
                oneToOneUpdate));

    EntityRecord entityRecord = new EntityRecord(null, ANOTHER_ENTITY_ID, fieldRecords);

    mockSampleFields();
    mockDataService();
    mockEntity();

    EntityDto entityWithRelatedField = mock(EntityDto.class);
    when(entityService.getEntity(ANOTHER_ENTITY_ID)).thenReturn(entityWithRelatedField);
    when(entityWithRelatedField.getClassName()).thenReturn(AnotherSample.class.getName());
    when(entityWithRelatedField.getId()).thenReturn(ENTITY_ID + 1);

    ServiceReference serviceReferenceForClassWithRelatedField = mock(ServiceReference.class);
    MotechDataService serviceForClassWithRelatedField = mock(MotechDataService.class);
    when(bundleContext.getServiceReference(
            ClassName.getInterfaceName(AnotherSample.class.getName())))
        .thenReturn(serviceReferenceForClassWithRelatedField);
    when(bundleContext.getService(serviceReferenceForClassWithRelatedField))
        .thenReturn(serviceForClassWithRelatedField);
    when(motechDataService.findById(4L)).thenReturn(test1);
    when(motechDataService.findById(5L)).thenReturn(test2);
    when(motechDataService.findById(6L)).thenReturn(test3);
    when(motechDataService.findByIds(oneToManyUpdate.getAddedIds()))
        .thenReturn(Arrays.asList(test1, test2));

    when(entityService.getEntityFieldsForUI(ANOTHER_ENTITY_ID))
        .thenReturn(
            asList(
                FieldTestHelper.fieldDto(
                    5L, "title", String.class.getName(), "String field", "Default"),
                FieldTestHelper.fieldDto(
                    6L,
                    "testSamples",
                    TypeDto.ONE_TO_MANY_RELATIONSHIP.getTypeClass(),
                    "Related field",
                    null)));

    ArgumentCaptor<AnotherSample> captor = ArgumentCaptor.forClass(AnotherSample.class);
    instanceService.saveInstance(entityRecord, null);

    verify(serviceForClassWithRelatedField).create(captor.capture());
    AnotherSample capturedValue = captor.getValue();
    assertEquals(capturedValue.getTestSample(), test3);
    assertEquals(capturedValue.getTestSamples().size(), 3);
    assertEquals(capturedValue.getTitle(), "Default");
    assertTrue(capturedValue.getTestSamples().contains(test1));
    assertFalse(capturedValue.getTestSamples().contains(test3));
    assertTrue(capturedValue.getTestSamples().contains(test2));
  }
示例#23
0
 private Object findRelatedObjectById(Object id, MotechDataService service) {
   // We need parse id value to the long type
   return service.findById(TypeHelper.parseNumber(id, Long.class.getName()).longValue());
 }