package org.whole.lang.pojo.util; import static org.whole.lang.commons.factories.CommonsEntityAdapterFactory.createResolver; import static org.whole.lang.pojo.reflect.PojoEntityDescriptorEnum.AnnotationDeclaration_ord; import static org.whole.lang.pojo.reflect.PojoEntityDescriptorEnum.ArrayType_ord; import static org.whole.lang.pojo.reflect.PojoEntityDescriptorEnum.CollectionType_ord; import static org.whole.lang.pojo.reflect.PojoEntityDescriptorEnum.DataTypeDeclaration_ord; import static org.whole.lang.pojo.reflect.PojoEntityDescriptorEnum.EnumDeclaration_ord; import static org.whole.lang.pojo.reflect.PojoEntityDescriptorEnum.MapType_ord; import static org.whole.lang.pojo.reflect.PojoEntityDescriptorEnum.PojoDeclaration; import static org.whole.lang.pojo.reflect.PojoEntityDescriptorEnum.PojoDeclaration_ord; import static org.whole.lang.pojo.reflect.PojoEntityDescriptorEnum.PrimitiveType; import static org.whole.lang.pojo.reflect.PojoEntityDescriptorEnum.PrimitiveType_ord; import static org.whole.lang.pojo.reflect.PojoEntityDescriptorEnum.ReferenceType; import static org.whole.lang.pojo.reflect.PojoEntityDescriptorEnum.ReferenceType_ord; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import org.whole.lang.bindings.BindingManagerFactory; import org.whole.lang.bindings.IBindingManager; import org.whole.lang.factories.GenericEntityFactory; import org.whole.lang.factories.RegistryConfigurations; import org.whole.lang.iterators.IEntityIterator; import org.whole.lang.iterators.IteratorFactory; import org.whole.lang.matchers.Matcher; import org.whole.lang.model.EnumValue; import org.whole.lang.model.IEntity; import org.whole.lang.parsers.DefaultDataTypePersistenceParser; import org.whole.lang.pojo.factories.PojoEntityFactory; import org.whole.lang.pojo.model.ArrayType; import org.whole.lang.pojo.model.CollectionInterfaceEnum; import org.whole.lang.pojo.model.CollectionType; import org.whole.lang.pojo.model.Constructor; import org.whole.lang.pojo.model.Constructors; import org.whole.lang.pojo.model.DataTypeDeclaration; import org.whole.lang.pojo.model.EnumDeclaration; import org.whole.lang.pojo.model.Library; import org.whole.lang.pojo.model.MapType; import org.whole.lang.pojo.model.ModifierEnum; import org.whole.lang.pojo.model.Name; import org.whole.lang.pojo.model.Parameter; import org.whole.lang.pojo.model.PojoDeclaration; import org.whole.lang.pojo.model.PrimitiveType; import org.whole.lang.pojo.model.PrimitiveTypeEnum; import org.whole.lang.pojo.model.ProductDeclaration; import org.whole.lang.pojo.model.Property; import org.whole.lang.pojo.model.ReferenceType; import org.whole.lang.pojo.model.Type; import org.whole.lang.pojo.model.CollectionInterfaceEnum.Value; import org.whole.lang.pojo.reflect.PojoEntityDescriptorEnum; import org.whole.lang.pojo.templates.PojoTemplateManager; import org.whole.lang.queries.model.PathExpression; import org.whole.lang.reflect.EntityDescriptor; import org.whole.lang.reflect.FeatureDescriptor; import org.whole.lang.reflect.ILanguageKit; import org.whole.lang.reflect.ReflectionFactory; import org.whole.lang.util.BehaviorUtils; import org.whole.lang.util.DataTypeUtils; import org.whole.lang.util.EntityUtils; import org.whole.lang.util.StringUtils; public class PojoUtils { public static String calculateTypeName(Type type) { String typeName = null; switch (type.wGetEntityDescriptor().getOrdinal()) { case PrimitiveType_ord: typeName = StringUtils.toUpperCap(type.wStringValue())+"Data"; break; case ReferenceType_ord: typeName = StringUtils.toSimpleName(type.wStringValue()); break; case ArrayType_ord: ArrayType arrayType = (ArrayType) type; typeName = calculateTypeName(arrayType.getElementType())+"Array"; break; case CollectionType_ord: CollectionType collectionType = (CollectionType) type; String interfaceName = collectionType.getCollectionInterface().wEnumValue().toString(); typeName = calculateTypeName(collectionType.getElementType())+interfaceName; break; case MapType_ord: MapType mapType = (MapType) type; typeName = calculateTypeName(mapType.getKeyType())+"To"+calculateTypeName(mapType.getValueType())+"Map"; break; } return typeName; } public static void addDataTypeDeclaration(Type type, String name, Library entity) { entity.getDeclarations().wAdd(PojoEntityFactory.instance.createDataTypeDeclaration( createResolver(PojoEntityDescriptorEnum.Annotations), PojoEntityFactory.instance.createName(name), EntityUtils.clone(type) )); } public static ProductDeclaration findProductDeclaration(Type type, Library entity) { IBindingManager bindings = BindingManagerFactory.instance.createArguments(); bindings.wDef("name", type); return BehaviorUtils.<ProductDeclaration>evaluateFirstResult((PathExpression) PojoTemplateManager.instance().share("findProductDeclarationByName"), entity, bindings); } private static Map<PrimitiveTypeEnum.Value, Class<?>> primitiveTypesMap; private static Map<PrimitiveTypeEnum.Value, Class<?>> primitiveTypesMap() { if (primitiveTypesMap == null) { primitiveTypesMap = new HashMap<PrimitiveTypeEnum.Value, Class<?>>(); primitiveTypesMap.put(PrimitiveTypeEnum._boolean, boolean.class); primitiveTypesMap.put(PrimitiveTypeEnum._byte, byte.class); primitiveTypesMap.put(PrimitiveTypeEnum._char, char.class); primitiveTypesMap.put(PrimitiveTypeEnum._double, double.class); primitiveTypesMap.put(PrimitiveTypeEnum._float, float.class); primitiveTypesMap.put(PrimitiveTypeEnum._int, int.class); primitiveTypesMap.put(PrimitiveTypeEnum._long, long.class); primitiveTypesMap.put(PrimitiveTypeEnum._short, short.class); primitiveTypesMap.put(PrimitiveTypeEnum.String, String.class); } return primitiveTypesMap; } public static Class<?> getPrimitiveTypeClass(PrimitiveType primitiveType) { return primitiveTypesMap().get(primitiveType.getValue()); } @SuppressWarnings("unchecked") private static <E extends IEntity> EntityDescriptor<E> getEntityDescriptor(ProductDeclaration declaration, Library library) { String entityTypeName = declaration.getTemplate().wStringValue();; ILanguageKit languageKit = ReflectionFactory.getLanguageKit(library.getLanguageURI().wStringValue()); return (EntityDescriptor<E>) languageKit.getEntityDescriptorEnum().valueOf(entityTypeName); } public static IEntity toDataEntity(Object fromObject, PrimitiveType type, Library library) { String edName = StringUtils.toUpperCap(type.wStringValue())+"Data"; ILanguageKit languageKit = ReflectionFactory.getLanguageKit(library.getLanguageURI().wStringValue()); return GenericEntityFactory.instance(RegistryConfigurations.RESOLVER).create(languageKit.getEntityDescriptorEnum().valueOf(edName), fromObject); } public static ProductDeclaration findProductDeclarationByTemplateName(EntityDescriptor<?> ed, Library library) { PojoEntityFactory pef = PojoEntityFactory.instance; PathExpression findProductDeclarationByTemplateName = (PathExpression) PojoTemplateManager.instance().create("findProductDeclarationByTemplateName"); Name templateName = pef.createName(ed.getName()); IBindingManager bindings = BindingManagerFactory.instance.createArguments(); bindings.wDef("templateName", templateName); return BehaviorUtils.evaluateFirstResult(findProductDeclarationByTemplateName, library, bindings); } public static boolean isFieldOnly(Property property) { return property.getAnnotations().wContainsValue(ModifierEnum.FIELD_ONLY); } public static boolean isReadOnly(Property property) { return property.getAnnotations().wContainsValue(ModifierEnum.READ_ONLY); } public static boolean isAbstract(ProductDeclaration productDeclaration) { return productDeclaration.getAnnotations().wContainsValue(ModifierEnum.ABSTRACT); } public static Object getPropertyValue(Property property, Object fromObject) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { Class<?> fromClass = fromObject.getClass(); Object fieldValue; Name name = property.getName(); String filedName = name.wStringValue(); if (isFieldOnly(property)) { Field field = fromClass.getField(filedName); fieldValue = field.get(fromObject); } else { Type type = property.getType(); boolean isBoolean = type.wContainsValue(PrimitiveTypeEnum._boolean); String getterMethodName = (isBoolean ? "is" : "get")+StringUtils.toUpperCap(filedName); Method getterMethod = fromClass.getMethod(getterMethodName, new Class[0]); fieldValue = getterMethod.invoke(fromObject, new Object[0]); } return fieldValue; } public static void setPropertyValue(Property property, Object toObject, Object value) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException { Class<?> fromClass = toObject.getClass(); Name name = property.getName(); String fieldName = name.getValue(); if (isFieldOnly(property)) { Field field = fromClass.getField(fieldName); field.set(toObject, value); } else { String setterMethodName = "set"+StringUtils.toUpperCap(fieldName); for (Method method : fromClass.getMethods()) { Class<?>[] parameterTypes = method.getParameterTypes(); if (setterMethodName.equals(method.getName())&& parameterTypes.length == 1 && parameterTypes[0].isAssignableFrom(DataTypeUtils.unboxFilter(value.getClass()))){ method.invoke(toObject, new Object[] { value }); return; } } throw new IllegalArgumentException("missing setter method for property"); } } public static List<Type> findMappingTypes(Class<?> fromClass, Library library) { ReferenceType exactType = PojoEntityFactory.instance.createReferenceType(fromClass.getName()); if (findProductDeclaration(exactType, library) != null) return Collections.<Type>singletonList(exactType); List<Type> mappingTypes = new ArrayList<Type>(); for (Class<?> implInterface : fromClass.getInterfaces()) { ReferenceType implType = PojoEntityFactory.instance.createReferenceType(implInterface.getName()); if (findProductDeclaration(implType, library) != null) mappingTypes.add(implType); } Class<?> superclass = fromClass.getSuperclass(); ReferenceType superType = PojoEntityFactory.instance.createReferenceType(superclass.getName()); if (!fromClass.isInterface()) { if (findProductDeclaration(superType, library) != null) mappingTypes.add(superType); } if (!Object.class.equals(superclass) && mappingTypes.isEmpty()) mappingTypes.addAll(findMappingTypes(superclass, library)); return mappingTypes; } public static void translate(Object fromObject, IEntity toIEntity, PojoDeclaration pojoDeclaration, Library library) { // translate inherited properties IEntityIterator<ReferenceType> superPojosIterator = IteratorFactory.<ReferenceType>childIterator(); superPojosIterator.reset(pojoDeclaration.getTypes()); for (ReferenceType superType : superPojosIterator) { PojoDeclaration superDeclaration = (PojoDeclaration) findProductDeclaration(superType, library); translate(fromObject, toIEntity, superDeclaration, library); } // translate declared properties IEntityIterator<Property> iterator = IteratorFactory.<Property>childIterator(); iterator.reset(pojoDeclaration.getProperties()); EntityDescriptor<?> ed = toIEntity.wGetEntityDescriptor(); Property property = null; try { while (iterator.hasNext()) { property = iterator.next(); Type type = property.getType(); Name template = property.getTemplate(); FeatureDescriptor fd = ed.getFeatureDescriptorEnum().valueOf(template.wStringValue()); Object fieldValue = getPropertyValue(property, fromObject); if (fieldValue == null) continue; if (Matcher.match(PrimitiveType, type)) toIEntity.wSet(fd, toDataEntity(fieldValue, (PrimitiveType) type, library)); else if (Matcher.match(ReferenceType, type)) toIEntity.wSet(fd, create(fieldValue, library)); else toIEntity.wSet(fd, create(fieldValue, type, library)); } } catch (Exception e) { throw new IllegalStateException("Cannot translate property: "+property, e); } } public static void translate(IEntity fromEntity, Object toObject, PojoDeclaration pojoDeclaration, Library library) { // translate inherited properties IEntityIterator<ReferenceType> superPojosIterator = IteratorFactory.<ReferenceType>childIterator(); superPojosIterator.reset(pojoDeclaration.getTypes()); for (ReferenceType superType : superPojosIterator) { PojoDeclaration superDeclaration = (PojoDeclaration) findProductDeclaration(superType, library); translate(fromEntity, toObject, superDeclaration, library); } // translate declared properties IEntityIterator<Property> iterator = IteratorFactory.<Property>childIterator(); iterator.reset(pojoDeclaration.getProperties()); EntityDescriptor<?> ed = fromEntity.wGetEntityDescriptor(); Property property = null; try { while (iterator.hasNext()) { property = iterator.next(); if (isReadOnly(property)) continue; Type type = property.getType(); Name template = property.getTemplate(); FeatureDescriptor fd = ed.getFeatureDescriptorEnum().valueOf(template.wStringValue()); IEntity fieldEntity = fromEntity.wGet(fd); if (!EntityUtils.isNotResolver(fieldEntity)) continue; if (Matcher.match(PrimitiveType, type)) setPropertyValue(property, toObject, fieldEntity.wGetValue()); else setPropertyValue(property, toObject, create(fieldEntity, library)); } } catch (Exception e) { throw new IllegalStateException("Cannot translate property: "+property, e); } } public static void translate(Object fromObject, IEntity toIEntity, Library library) { Class<?> fromClass = fromObject.getClass(); ProductDeclaration productDeclaration = findProductDeclaration(PojoEntityFactory.instance.createReferenceType(fromClass.getName()), library); if (!Matcher.matchImpl(PojoDeclaration, productDeclaration)) throw new IllegalStateException("translate can be invoked only on pojo objects"); translate(fromObject, toIEntity, (PojoDeclaration) productDeclaration, library); } public static void translate(IEntity fromEntity, Object toObject, Library library) { Class<?> toClass = toObject.getClass(); ProductDeclaration productDeclaration = findProductDeclaration(PojoEntityFactory.instance.createReferenceType(toClass.getName()), library); if (!Matcher.matchImpl(PojoDeclaration, productDeclaration)) throw new IllegalStateException("translate can be invoked only on pojo objects"); translate(fromEntity, toObject, (PojoDeclaration) productDeclaration, library); } @SuppressWarnings("unchecked") public static <E extends IEntity> E create(Object fromObject, Type type, Library library) { // map product type ProductDeclaration productDeclaration = findProductDeclaration(type, library); E toIEntity = PojoUtils.<E>createEntity(productDeclaration, library); // translate contents as needed switch (productDeclaration.wGetEntityDescriptor().getOrdinal()) { case PojoDeclaration_ord: translate(fromObject, toIEntity, (PojoDeclaration) productDeclaration, library); break; case EnumDeclaration_ord: EnumValue enumValue = DefaultDataTypePersistenceParser.instance.parseEnumValue(toIEntity.wGetEntityDescriptor(), fromObject.toString()); toIEntity.wSetValue(enumValue); break; case AnnotationDeclaration_ord://TODO break; case DataTypeDeclaration_ord: Type elementType; switch (type.wGetEntityDescriptor().getOrdinal()) { case PrimitiveType_ord: case ReferenceType_ord: toIEntity.wSetValue(fromObject); break; case ArrayType_ord: ArrayType arrayType = (ArrayType) type; elementType = arrayType.getElementType(); for (int i = 0; i < Array.getLength(fromObject); i++) toIEntity.wAdd(create(Array.get(fromObject, i), elementType, library)); break; case CollectionType_ord: CollectionType collectionType = (CollectionType) type; Collection<Object> fromCollection = (Collection<Object>) fromObject; elementType = collectionType.getElementType(); for (Object element : fromCollection) toIEntity.wAdd(create(element, elementType, library)); break; case MapType_ord: MapType mapType = (MapType) type; Map<Object, Object> fromMap = (Map<Object, Object>) fromObject; Type keyType = mapType.getKeyType(); elementType = mapType.getValueType(); for (Entry<Object, Object> element : fromMap.entrySet()) toIEntity.wSet((IEntity) create(element.getKey(), keyType, library),//FIXME workaround for Java 8 compiler create(element.getValue(), elementType, library)); break; } break; } return toIEntity; } public static <E extends IEntity> E createEntity(ProductDeclaration productDeclaration, Library library) { EntityDescriptor<E> ed = getEntityDescriptor(productDeclaration, library); return GenericEntityFactory.instance(RegistryConfigurations.RESOLVER).create(ed); } /* * expects a normalized library */ public static <E extends IEntity> E create(Object fromObject, Library library) { // find product type Class<? extends Object> fromClass = fromObject.getClass(); List<Type> types = findMappingTypes(fromClass, library); if (types.size() == 0) throw new IllegalStateException("Cannot find type mapping for class: "+fromClass.getName()); else if (types.size() != 1) throw new IllegalStateException("Ambiguous type mapping for class: "+fromClass.getName()); return PojoUtils.<E>create(fromObject, types.get(0), library); } /* * expects a normalized library */ public static Object create(IEntity fromEntity, Library library) { // find product type EntityDescriptor<?> ed = fromEntity.wGetEntityDescriptor(); ProductDeclaration productDeclaration = findProductDeclarationByTemplateName(ed, library); if (productDeclaration == null) throw new IllegalStateException("Cannot find type mapping for entity: "+fromEntity); // translate contents as needed Object toObject = null; switch (productDeclaration.wGetEntityDescriptor().getOrdinal()) { case PojoDeclaration_ord: toObject = createInstance(fromEntity, (PojoDeclaration) productDeclaration, library); translate(fromEntity, toObject, (PojoDeclaration) productDeclaration, library); break; case EnumDeclaration_ord: String enumValue = DefaultDataTypePersistenceParser.instance.unparseEnumValue(fromEntity.wGetEntityDescriptor(), fromEntity.wEnumValue()); toObject = createEnumValue((EnumDeclaration) productDeclaration, enumValue); break; case AnnotationDeclaration_ord://TODO break; case DataTypeDeclaration_ord: Type type = ((DataTypeDeclaration) productDeclaration).getName(); switch (type.wGetEntityDescriptor().getOrdinal()) { case PrimitiveType_ord: case ReferenceType_ord: toObject = fromEntity.wGetValue(); break; case ArrayType_ord: toObject = Array.newInstance(getClass(((ArrayType) type).getElementType()), fromEntity.wSize()); for (int i=0; i<fromEntity.wSize(); i++) { IEntity element = fromEntity.wGet(i); Array.set(toObject, i, create(element, library)); } break; case CollectionType_ord: Collection<Object> toCollection = ((CollectionType) type).getCollectionInterface().getValue().equals(CollectionInterfaceEnum.Set) ? new HashSet<Object>() : new ArrayList<Object>(); IEntityIterator<IEntity> ci = IteratorFactory.childIterator(); ci.reset(fromEntity); for (IEntity feature : ci) toCollection.add(create(feature, library)); toObject = toCollection; break; case MapType_ord: Map<Object, Object> toMap = new HashMap<Object, Object>(); for (int i=0; i<fromEntity.wSize(); i++) { IEntity key = fromEntity.wGet(i); IEntity value = fromEntity.wGet(key); toMap.put(create(key, library), create(value, library)); } toObject = toMap; break; } break; } return toObject; } public static Class<?> getClass(Type type) { switch (type.wGetEntityDescriptor().getOrdinal()) { case PrimitiveType_ord: return getPrimitiveTypeClass((PrimitiveType) type); case ReferenceType_ord: try { return Class.forName(((ReferenceType) type).getValue()); } catch (ClassNotFoundException e) { throw new IllegalArgumentException("Cannot find class for reference type", e); } case ArrayType_ord: return Array.newInstance(getClass(((ArrayType) type).getElementType()), 0).getClass(); case CollectionType_ord: Value collectionInterface = ((CollectionType) type).getCollectionInterface().getValue(); return collectionInterface.equals(CollectionInterfaceEnum.Set) ? Set.class : List.class; case MapType_ord: return Map.class; } return null; } public static Object createEnumValue(EnumDeclaration enumDeclaration, String value) { ReferenceType referenceType = enumDeclaration.getName(); String toEnumName = referenceType.wStringValue(); try { Class<?> toEnum = Class.forName(toEnumName); Method valueOfMethod = toEnum.getMethod("valueOf", new Class[] { String.class }); return valueOfMethod.invoke(null, value); } catch (Exception e) { throw new IllegalStateException("Cannot istantiate enum from reference type: "+toEnumName+" using value:"+value, e); } } public static Set<Name> getReadOnlyFields(PojoDeclaration pojoDeclaration) { Set<Name> readOnlyFields = new HashSet<Name>(); IBindingManager bindings = BindingManagerFactory.instance.createArguments(); PathExpression findAllReadOnlyFields = (PathExpression) PojoTemplateManager.instance().create("findAllReadOnlyFields"); for (Name readOnlyField : BehaviorUtils.<Name>compileAndLazyEvaluate(findAllReadOnlyFields, pojoDeclaration, bindings)) readOnlyFields.add(readOnlyField); return readOnlyFields; } public static List<Constructor> getConstructors(PojoDeclaration pojoDeclaration) { Constructors constructors = pojoDeclaration.getConstructors(); List<Constructor> constructorsList = new ArrayList<Constructor>(constructors.wSize()); IEntityIterator<Constructor> i = IteratorFactory.<Constructor>childIterator(); i.reset(constructors); for (Constructor constructor : i) constructorsList.add(constructor); Collections.sort(constructorsList, new Comparator<Constructor>() { public int compare(Constructor c1, Constructor c2) { return c1.getParameters().wSize()-c2.getParameters().wSize(); } }); return constructorsList; } public static Constructor findConstructor(PojoDeclaration pojoDeclaration) { IBindingManager bindings = BindingManagerFactory.instance.createArguments(); PathExpression findParameterByTemplate = (PathExpression) PojoTemplateManager.instance().create("findParameterByTemplate"); List<Constructor> constructors = getConstructors(pojoDeclaration); int[] supportedFields = new int[constructors.size()]; PathExpression findAllReadOnlyFields = (PathExpression) PojoTemplateManager.instance().create("findAllReadOnlyFields"); IEntityIterator<Name> iterator = BehaviorUtils.<Name>compileAndLazyEvaluate(findAllReadOnlyFields, pojoDeclaration, bindings); int readOnlyFieldCount = 0; while (iterator.hasNext()) { iterator.next(); for (int i=0; i<supportedFields.length; i++) if (BehaviorUtils.evaluateFirstResult(findParameterByTemplate, constructors.get(i), bindings) != null) supportedFields[i]++; readOnlyFieldCount++; } for (int i=0; i<supportedFields.length; i++) if (supportedFields[i] >= readOnlyFieldCount) return constructors.get(i); return constructors.get(supportedFields.length-1); } public static Object createInstanceUsingConstructor(IEntity fromEntity, PojoDeclaration pojoDeclaration, Library library) throws Exception { ReferenceType referenceType = pojoDeclaration.getName(); Class<?> clazz = Class.forName(referenceType.getValue()); Constructor constructor = findConstructor(pojoDeclaration); int params = constructor.getParameters().wSize(); List<Class<?>> parameterTypes = new ArrayList<Class<?>>(params); List<Object> initargs = new ArrayList<Object>(params); IBindingManager bindings = BindingManagerFactory.instance.createArguments(); PathExpression findPropertyByTemplate = (PathExpression) PojoTemplateManager.instance().create("findPropertyByTemplate"); PathExpression findParameterByTemplate = (PathExpression) PojoTemplateManager.instance().create("findParameterByTemplate"); IEntityIterator<Parameter> iterator = BehaviorUtils.<Parameter>compileAndLazyEvaluate(findParameterByTemplate, constructor, bindings); while (iterator.hasNext()) { iterator.next(); Property property = BehaviorUtils.<Property>evaluateFirstResult(findPropertyByTemplate, pojoDeclaration, bindings); Type type = property.getType(); Name template = property.getTemplate(); FeatureDescriptor fd = fromEntity.wGetEntityDescriptor().getFeatureDescriptorEnum().valueOf(template.wStringValue()); IEntity fieldEntity = fromEntity.wGet(fd); parameterTypes.add(getClass(type)); initargs.add(Matcher.match(PrimitiveType, type) ? fieldEntity.wGetValue() : create(fieldEntity, library)); } return clazz.getConstructor(parameterTypes.toArray(new Class<?>[0])).newInstance(initargs.toArray()); } public static Object createInstance(IEntity fromEntity, PojoDeclaration pojoDeclaration, Library library) { try { //TODO add construction strategy using factories return createInstanceUsingConstructor(fromEntity, pojoDeclaration, library); } catch (Exception e) { throw new IllegalStateException("Cannot istantiate class from reference type: "+pojoDeclaration.getName(), e); } } }