use of org.motechproject.mds.util.MDSClassLoader in project motech by motech.
the class EntityInfrastructureBuilderTest method shouldCreateCodeForClassWithLookups.
@Test
public void shouldCreateCodeForClassWithLookups() throws Exception {
MDSClassLoader mdsClassLoaderImpl = MDSClassLoader.getStandaloneInstance(getClass().getClassLoader());
EntityDto entity = new EntityDto(SampleWithLookups.class.getName());
entity.setMaxFetchDepth(-1);
LookupDto lookup = new LookupDto();
lookup.setLookupName("testLookup");
lookup.setMethodName("testLookupMethod");
FieldDto testField = fieldDto("TestField", "testDispName", String.class);
FieldDto testField2 = fieldDto("TestField2", "DisplayName with space", String.class);
FieldDto dateField = fieldDto("dateField", "Display names should not affect methods", DateTime.class);
FieldDto timeField = fieldDto("timeField", Time.class);
when(schemaHolder.getFieldByName(SampleWithLookups.class.getName(), "TestField")).thenReturn(testField);
when(schemaHolder.getFieldByName(SampleWithLookups.class.getName(), "TestField2")).thenReturn(testField2);
when(schemaHolder.getFieldByName(SampleWithLookups.class.getName(), "dateField")).thenReturn(dateField);
when(schemaHolder.getFieldByName(SampleWithLookups.class.getName(), "timeField")).thenReturn(timeField);
lookup.setFieldsOrder(asList("TestField", "TestField2", "dateField", "timeField"));
lookup.setSingleObjectReturn(true);
when(schemaHolder.getLookups(entity)).thenReturn(singletonList(lookup));
List<LookupFieldDto> lookupFields = new ArrayList<>();
lookupFields.add(new LookupFieldDto("TestField", LookupFieldType.VALUE));
lookupFields.add(new LookupFieldDto("TestField2", LookupFieldType.VALUE));
lookupFields.add(new LookupFieldDto("dateField", LookupFieldType.RANGE));
lookupFields.add(new LookupFieldDto("timeField", LookupFieldType.SET));
lookup.setLookupFields(lookupFields);
List<ClassData> data = entityInfrastructureBuilder.buildInfrastructure(entity, schemaHolder);
for (ClassData classData : data) {
mdsClassLoaderImpl.safeDefineClass(classData.getClassName(), classData.getBytecode());
}
verifySingleLookup(mdsClassLoaderImpl.loadClass(SAMPLE_WITH_LOOKUPS_SERVICE));
verifySingleLookup(mdsClassLoaderImpl.loadClass(SAMPLE_WITH_LOOKUPS_INTERFACE));
verifyCountLookup(mdsClassLoaderImpl.loadClass(SAMPLE_WITH_LOOKUPS_SERVICE));
verifyCountLookup(mdsClassLoaderImpl.loadClass(SAMPLE_WITH_LOOKUPS_INTERFACE));
// lookup with multiple return
lookup.setSingleObjectReturn(false);
mdsClassLoaderImpl = MDSClassLoader.getStandaloneInstance(getClass().getClassLoader());
data = entityInfrastructureBuilder.buildInfrastructure(entity, schemaHolder);
for (ClassData classData : data) {
mdsClassLoaderImpl.safeDefineClass(classData.getClassName(), classData.getBytecode());
}
verifyMultiReturnLookup(mdsClassLoaderImpl.loadClass(SAMPLE_WITH_LOOKUPS_SERVICE));
verifyMultiReturnLookup(mdsClassLoaderImpl.loadClass(SAMPLE_WITH_LOOKUPS_INTERFACE));
verifyCountLookup(mdsClassLoaderImpl.loadClass(SAMPLE_WITH_LOOKUPS_SERVICE));
verifyCountLookup(mdsClassLoaderImpl.loadClass(SAMPLE_WITH_LOOKUPS_INTERFACE));
verifyFetchDepthInRepository(mdsClassLoaderImpl.loadClass(SAMPLE_WITH_LOOKUPS_REPOSITORY), -1);
}
use of org.motechproject.mds.util.MDSClassLoader in project motech by motech.
the class MDSConstructorImpl method constructEntities.
@Override
public synchronized boolean constructEntities(SchemaHolder schemaHolder) {
// To be able to register updated class, we need to reload class loader
// and therefore add all the classes again
MotechClassPool.clearEnhancedData();
MDSClassLoader.reloadClassLoader();
// we need an jdo enhancer and a temporary classLoader
// to define classes in before enhancement
MDSClassLoader tmpClassLoader = MDSClassLoader.getStandaloneInstance();
MdsJDOEnhancer enhancer = createEnhancer(tmpClassLoader);
JavassistLoader loader = new JavassistLoader(tmpClassLoader);
// process only entities that are not drafts
List<EntityDto> entities = schemaHolder.getAllEntities();
filterEntities(entities);
sortEntities(entities, schemaHolder);
// create enum for appropriate combobox fields
for (EntityDto entity : entities) {
buildEnum(loader, enhancer, entity, schemaHolder);
}
// load entities interfaces
for (EntityDto entity : entities) {
buildInterfaces(loader, enhancer, entity);
}
// generate jdo metadata from scratch for our entities
JDOMetadata jdoMetadata = metadataHolder.reloadMetadata();
// since we just fetch fields from existing definition
for (EntityDto entity : entities) {
if (entity.isRecordHistory()) {
entityBuilder.prepareHistoryClass(entity);
}
entityBuilder.prepareTrashClass(entity);
}
// Build classes
Map<String, ClassData> classDataMap = buildClasses(entities, schemaHolder);
List<Class> classes = new ArrayList<>();
// the temporary ClassLoader and enhancer
for (EntityDto entity : entities) {
String className = entity.getClassName();
Class<?> definition = addClassData(loader, enhancer, classDataMap.get(className));
if (entity.isRecordHistory()) {
addClassData(loader, enhancer, classDataMap.get(ClassName.getHistoryClassName(className)));
}
addClassData(loader, enhancer, classDataMap.get(ClassName.getTrashClassName(className)));
classes.add(definition);
LOGGER.debug("Generated classes for {}", entity.getClassName());
}
for (Class<?> definition : classes) {
loader.loadFieldsAndMethodsOfClass(definition);
}
// Prepare metadata
buildMetadata(entities, jdoMetadata, classDataMap, classes, schemaHolder);
// after the classes are defined, we register their metadata
enhancer.registerMetadata(jdoMetadata);
// then, we commence with enhancement
enhancer.enhance();
// we register the enhanced class bytes
// and build the infrastructure classes
registerEnhancedClassBytes(entities, enhancer, schemaHolder);
metadataBuilder.fixEnhancerIssuesInMetadata(jdoMetadata, schemaHolder);
return CollectionUtils.isNotEmpty(entities);
}
Aggregations