import java.lang.reflect.Field;\r
import java.lang.reflect.GenericDeclaration;\r
import java.lang.reflect.Method;\r
-import java.lang.reflect.Modifier;\r
+import java.lang.reflect.ParameterizedType;\r
import java.lang.reflect.Type;\r
+import java.lang.reflect.TypeVariable;\r
import java.util.ArrayList;\r
import java.util.Collection;\r
import java.util.HashMap;\r
import java.util.Set;\r
import java.util.UUID;\r
\r
-import javax.persistence.Transient;\r
-\r
import org.apache.log4j.Logger;\r
-import org.joda.time.DateTime;\r
\r
-import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;\r
-import sun.reflect.generics.reflectiveObjects.TypeVariableImpl;\r
-import eu.etaxonomy.cdm.model.agent.Contact;\r
+import eu.etaxonomy.cdm.common.CdmUtils;\r
import eu.etaxonomy.cdm.model.common.CdmBase;\r
import eu.etaxonomy.cdm.model.common.ICdmBase;\r
import eu.etaxonomy.cdm.model.common.IRelated;\r
-import eu.etaxonomy.cdm.model.common.LSID;\r
import eu.etaxonomy.cdm.model.common.RelationshipBase;\r
-import eu.etaxonomy.cdm.model.common.TimePeriod;\r
import eu.etaxonomy.cdm.strategy.StrategyBase;\r
\r
/**\r
boolean includeStatic = false;\r
boolean includeTransient = false;\r
boolean makeAccessible = true;\r
- this.mergeFields = getAllNonStaticNonTransientFields(mergeClazz, includeStatic, includeTransient, makeAccessible);\r
+ this.mergeFields = CdmUtils.getAllFields(mergeClass, CdmBase.class, includeStatic, includeTransient, makeAccessible, true);\r
initMergeModeMap();\r
}\r
\r
throw new MergeException("Identifier must always have merge mode MergeMode.FIRST");\r
}\r
}\r
- \r
}\r
\r
public <T extends IMergable> Set<ICdmBase> invoke(T mergeFirst, T mergeSecond) throws MergeException {\r
mergeSingleCdmBaseField(mergeFirst, mergeSecond, field, deleteSet);\r
}else if(fieldType.isInterface()){\r
mergeInterfaceField(mergeFirst, mergeSecond, field, deleteSet);\r
+ }else if(fieldType.isEnum()){\r
+ mergeEnumField(mergeFirst, mergeSecond, field, deleteSet);\r
}else{\r
throw new RuntimeException("Unknown Object type for merging: " + fieldType);\r
}\r
if (mergeMode != MergeMode.FIRST){\r
mergeCdmBaseValue(mergeFirst, mergeSecond, field, deleteSet);\r
}\r
- System.out.println(propertyName + ": " + mergeMode + ", " + field.getType().getName());\r
+ logger.debug(propertyName + ": " + mergeMode + ", " + field.getType().getName());\r
+ \r
+ }\r
+\r
+ /**\r
+ * @throws Exception \r
+ * \r
+ */\r
+ private <T extends IMergable> void mergeEnumField(T mergeFirst, T mergeSecond, Field field, Set<ICdmBase> deleteSet) throws Exception {\r
+ String propertyName = field.getName();\r
+ MergeMode mergeMode = this.getMergeMode(propertyName);\r
+ if (mergeMode != MergeMode.FIRST){\r
+ mergeCdmBaseValue(mergeFirst, mergeSecond, field, deleteSet);\r
+ }\r
+ logger.debug(propertyName + ": " + mergeMode + ", " + field.getType().getName());\r
\r
}\r
- \r
\r
/**\r
* @throws Exception \r
if (mergeMode != MergeMode.FIRST){\r
mergeCdmBaseValue(mergeFirst, mergeSecond, field, deleteSet);\r
}\r
- System.out.println(propertyName + ": " + mergeMode + ", " + field.getType().getName());\r
+ logger.debug(propertyName + ": " + mergeMode + ", " + field.getType().getName());\r
\r
}\r
\r
Object value = getMergeValue(mergeFirst, mergeSecond, field);\r
field.set(mergeFirst, value);\r
}\r
- System.out.println(propertyName + ": " + mergeMode + ", " + fieldType.getName());\r
+ logger.debug(propertyName + ": " + mergeMode + ", " + fieldType.getName());\r
}\r
\r
/**\r
if (mergeMode != MergeMode.FIRST){\r
mergeCollectionFieldNoFirst(mergeFirst, mergeSecond, field, mergeMode, deleteSet, clonedObjects);\r
}\r
- System.out.println(propertyName + ": " + mergeMode + ", " + fieldType.getName());\r
+ logger.debug(propertyName + ": " + mergeMode + ", " + fieldType.getName());\r
\r
}\r
\r
if (Set.class.isAssignableFrom(fieldType) || List.class.isAssignableFrom(fieldType)){\r
Collection<ICdmBase> secondCollection = (Collection<ICdmBase>)field.get(mergeSecond);\r
List<ICdmBase> removeList = new ArrayList<ICdmBase>();\r
+ if(secondCollection != null) {\r
for (ICdmBase obj : secondCollection){\r
Object objectToAdd; \r
if (mergeMode == MergeMode.ADD){\r
addMethod.invoke(mergeFirst, objectToAdd);\r
removeList.add(obj);\r
}\r
+ }\r
for (ICdmBase removeObj : removeList ){\r
//removeMethod.invoke(mergeSecond, removeObj);\r
if ((removeObj instanceof CdmBase)&& mergeMode == MergeMode.ADD_CLONE) {\r
Object value = getMergeValue(mergeFirst, mergeSecond, field);\r
field.set(mergeFirst, value);\r
}\r
- System.out.println(propertyName + ": " + mergeMode + ", " + fieldType.getName());\r
+ logger.debug(propertyName + ": " + mergeMode + ", " + fieldType.getName());\r
\r
}\r
\r
Object value = getMergeValue(mergeFirst, mergeSecond, field);\r
field.set(mergeFirst, value);\r
}\r
- System.out.println(propertyName + ": " + mergeMode + ", " + fieldType.getName());\r
+ logger.debug(propertyName + ": " + mergeMode + ", " + fieldType.getName());\r
\r
}\r
\r
return false;\r
}\r
}\r
- \r
- /**\r
- * @param fieldType\r
- * @return\r
- */\r
- private boolean isPrimitive(Class<?> fieldType) {\r
- if (fieldType.isPrimitive()){\r
- return true;\r
- }else{\r
- return false;\r
- }\r
- }\r
-\r
- /**\r
- * @param fieldType\r
- * @return\r
- */\r
- private boolean isSingleCdmBaseObject(Class<?> fieldType) {\r
- if (CdmBase.class.isAssignableFrom(fieldType)){\r
- return true;\r
- }else{\r
- return false;\r
- }\r
- }\r
-\r
-\r
-\r
- /**\r
- * @param fieldType\r
- * @return\r
- */\r
- private boolean isCollection(Class<?> fieldType) {\r
- if (Collection.class.isAssignableFrom(fieldType) ){\r
- return true;\r
- }else{\r
- return false;\r
- }\r
- }\r
-\r
-\r
- /**\r
- * @param fieldType\r
- * @return\r
- */\r
- private boolean isUserType(Class<?> fieldType) {\r
- if ( fieldType == TimePeriod.class ||\r
- fieldType == DateTime.class ||\r
- fieldType == LSID.class ||\r
- fieldType == Contact.class\r
- ){\r
- return true;\r
- }else{\r
- return false;\r
- }\r
- }\r
\r
\r
/**\r
}\r
}\r
\r
- /**\r
- * Computes all fields recursively\r
- * @param clazz\r
- * @return\r
- */\r
- protected Map<String, Field> getAllNonStaticNonTransientFields(Class clazz, boolean includeStatic, boolean includeTransient, boolean makeAccessible) {\r
- Map<String, Field> result = new HashMap<String, Field>();\r
- //exclude static\r
- for (Field field: clazz.getDeclaredFields()){\r
- if (includeStatic || ! Modifier.isStatic(field.getModifiers())){\r
- if (includeTransient || ! isTransient(field)){\r
- field.setAccessible(makeAccessible);\r
- result.put(field.getName(), field);\r
- }\r
- }\r
- }\r
- \r
- //include superclass fields\r
- Class superclass = clazz.getSuperclass();\r
- if (CdmBase.class.isAssignableFrom(superclass)){\r
- result.putAll(getAllNonStaticNonTransientFields(superclass, includeStatic, includeTransient, makeAccessible));\r
- }\r
- return result;\r
- }\r
-\r
-\r
-\r
- /**\r
- * Returns true, if field has an annotation of type javax.persistence.Annotation\r
- * @param field\r
- * @return\r
- */\r
- private boolean isTransient(Field field) {\r
- for (Annotation annotation : field.getAnnotations()){\r
- //if (Transient.class.isAssignableFrom(annotation.annotationType())){\r
- if (annotation.annotationType() == Transient.class){\r
- return true;\r
- }\r
- }\r
- return false;\r
- }\r
-\r
\r
private static Class getCollectionType(Field field) throws MergeException{\r
- Type genericType = (ParameterizedTypeImpl)field.getGenericType();\r
- if (genericType instanceof ParameterizedTypeImpl){\r
- ParameterizedTypeImpl paraType = (ParameterizedTypeImpl)genericType;\r
- Class<?> rawType = paraType.getRawType();\r
+ Type genericType = (ParameterizedType)field.getGenericType();\r
+ if (genericType instanceof ParameterizedType/*Impl*/){\r
+ ParameterizedType paraType = (ParameterizedType)genericType;\r
+ Type rawType = paraType.getRawType();\r
Type[] arguments = paraType.getActualTypeArguments();\r
- //System.out.println(arguments.length);\r
+\r
if (arguments.length == 1){\r
Class collectionClass;\r
if (arguments[0] instanceof Class){\r
collectionClass = (Class)arguments[0];\r
- }else if(arguments[0] instanceof TypeVariableImpl){\r
- TypeVariableImpl typeVariable = (TypeVariableImpl)arguments[0];\r
+ }else if(arguments[0] instanceof TypeVariable/*Impl*/){\r
+ TypeVariable typeVariable = (TypeVariable)arguments[0];\r
GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration();\r
collectionClass = (Class)genericDeclaration;\r
}else{\r