ref #10222 add agentlink to taxonNodeAgentRelDto
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / CommonServiceImpl.java
index 6b047fedd2d8c2d9e6bb64ec9517b5c4d8cf14f6..ba0527d59b4762ced30fc096479d7993aef4da89 100644 (file)
-/**\r
- * Copyright (C) 2007 EDIT\r
- * European Distributed Institute of Taxonomy\r
- * http://www.e-taxonomy.eu\r
- *\r
- * The contents of this file are subject to the Mozilla Public License Version 1.1\r
- * See LICENSE.TXT at the top of this package for the full license terms.\r
- */\r
-\r
-package eu.etaxonomy.cdm.api.service;\r
-\r
-import java.util.Collection;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-import java.util.UUID;\r
-\r
-import org.apache.log4j.Logger;\r
-import org.springframework.beans.factory.annotation.Autowired;\r
-import org.springframework.stereotype.Service;\r
-import org.springframework.transaction.annotation.Transactional;\r
-\r
-import eu.etaxonomy.cdm.model.common.CdmBase;\r
-import eu.etaxonomy.cdm.model.common.ISourceable;\r
-import eu.etaxonomy.cdm.model.common.IdentifiableEntity;\r
-import eu.etaxonomy.cdm.model.metadata.CdmMetaData;\r
-import eu.etaxonomy.cdm.model.metadata.CdmMetaDataPropertyName;\r
-import eu.etaxonomy.cdm.persistence.dao.common.ICdmGenericDao;\r
-import eu.etaxonomy.cdm.persistence.dao.common.IOriginalSourceDao;\r
-import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
-import eu.etaxonomy.cdm.strategy.match.DefaultMatchStrategy;\r
-import eu.etaxonomy.cdm.strategy.match.IMatchStrategyEqual;\r
-import eu.etaxonomy.cdm.strategy.match.IMatchable;\r
-import eu.etaxonomy.cdm.strategy.match.MatchException;\r
-import eu.etaxonomy.cdm.strategy.match.MatchStrategyConfigurator;\r
-import eu.etaxonomy.cdm.strategy.match.MatchStrategyConfigurator.MatchStrategy;\r
-import eu.etaxonomy.cdm.strategy.merge.DefaultMergeStrategy;\r
-import eu.etaxonomy.cdm.strategy.merge.IMergable;\r
-import eu.etaxonomy.cdm.strategy.merge.IMergeStrategy;\r
-import eu.etaxonomy.cdm.strategy.merge.MergeException;\r
-\r
-\r
-@Service\r
-@Transactional(readOnly = true)\r
-public class CommonServiceImpl /*extends ServiceBase<OriginalSourceBase,IOriginalSourceDao>*/ implements ICommonService {\r
-    @SuppressWarnings("unused")\r
-    private static final Logger logger = Logger.getLogger(CommonServiceImpl.class);\r
-\r
-\r
-    @Autowired\r
-    private IOriginalSourceDao originalSourceDao;\r
-\r
-\r
-    @Autowired\r
-    private ICdmGenericDao genericDao;\r
-\r
-\r
-    @Override\r
-    public <T extends CdmBase> T findWithUpdate(Class<T> clazz, int id){\r
-        return genericDao.find(clazz, id);\r
-    }\r
-\r
-    @Override\r
-    public <T extends CdmBase> T find(Class<T> clazz, int id){\r
-        return genericDao.find(clazz, id);\r
-    }\r
-\r
-    @Override\r
-    public <T extends CdmBase> T find(Class<T> clazz, int id, List<String> propertyPaths){\r
-        return  genericDao.find(clazz, id, propertyPaths);\r
-    }\r
-\r
-    @Override\r
-    public <T extends CdmBase> T find(Class<T> clazz, UUID uuid) {\r
-        return uuid == null ? null : genericDao.find(clazz, uuid);\r
-    }\r
-\r
-    @Override\r
-    public <T extends CdmBase> T find(Class<T> clazz, UUID uuid, List<String> propertyPaths) {\r
-        return uuid == null ? null : genericDao.find(clazz, uuid, propertyPaths);\r
-    }\r
-\r
-    @Override\r
-    public Map<String, ? extends ISourceable> getSourcedObjectsByIdInSource(Class clazz, Set<String> idInSourceSet, String idNamespace) {\r
-        Map<String, ? extends ISourceable> list = originalSourceDao.findOriginalSourcesByIdInSource(clazz, idInSourceSet, idNamespace);\r
-        return list;\r
-    }\r
-\r
-    @Override\r
-    public ISourceable getSourcedObjectByIdInSource(Class clazz, String idInSource, String idNamespace) {\r
-        ISourceable<?> result = null;\r
-        List<IdentifiableEntity> list = originalSourceDao.findOriginalSourceByIdInSource(clazz, idInSource, idNamespace);\r
-        if (! list.isEmpty()){\r
-            result = list.get(0);\r
-        }return result;\r
-    }\r
-\r
-\r
-    @Override\r
-    public Set<CdmBase> getReferencingObjects(CdmBase referencedCdmBase){\r
-        return this.genericDao.getReferencingObjects(referencedCdmBase);\r
-    }\r
-\r
-    @Override\r
-    public long getReferencingObjectsCount(CdmBase referencedCdmBase){\r
-        return this.genericDao.getReferencingObjectsCount(referencedCdmBase);\r
-    }\r
-\r
-    @Override\r
-    public Set<CdmBase> getReferencingObjectsForDeletion(CdmBase referencedCdmBase){\r
-        return this.genericDao.getReferencingObjectsForDeletion(referencedCdmBase);\r
-    }\r
-    //         try {\r
-    //                 Set<Class<? extends CdmBase>> allCdmClasses = genericDao.getAllCdmClasses(false); //findAllCdmClasses();\r
-    //\r
-    //                 referencedCdmBase = (CdmBase)HibernateProxyHelper.deproxy(referencedCdmBase);\r
-    //                 Class referencedClass = referencedCdmBase.getClass();\r
-    //                 Set<CdmBase> result = new HashSet<>();\r
-    //                 logger.debug("Referenced Class: " + referencedClass.getName());\r
-    //\r
-    //                 for (Class<? extends CdmBase> cdmClass : allCdmClasses){\r
-    //                         Set<Field> fields = getFields(cdmClass);\r
-    //                         for (Field field: fields){\r
-    //                                 Class<?> type = field.getType();\r
-    //                                 //class\r
-    //                                 if (! type.isInterface()){\r
-    //                                         if (referencedClass.isAssignableFrom(type)||\r
-    //                                                         type.isAssignableFrom(referencedClass) && CdmBase.class.isAssignableFrom(type)){\r
-    //                                                 handleSingleClass(referencedClass, type, field, cdmClass, result, referencedCdmBase, false);\r
-    //                                         }\r
-    //                                 //interface\r
-    //                                 }else if (type.isAssignableFrom(referencedClass)){\r
-    //                                                 handleSingleClass(referencedClass, type, field, cdmClass, result, referencedCdmBase, false);\r
-    //                                 }else if (Collection.class.isAssignableFrom(type)){\r
-    //\r
-    //                                         if (checkIsSetOfType(field, referencedClass, type) == true){\r
-    //                                                 handleSingleClass(referencedClass, type, field, cdmClass, result, referencedCdmBase, true);\r
-    //                                         }\r
-    //                                 }\r
-    ////                               Class[] interfaces = referencedClass.getInterfaces();\r
-    ////                               for (Class interfaze: interfaces){\r
-    ////                                       if (interfaze == type){\r
-    //////                                     if(interfaze.isAssignableFrom(returnType)){\r
-    ////                                               handleSingleClass(interfaze, type, field, cdmClass, result, referencedCdmBase);\r
-    ////                                       }\r
-    ////                               }\r
-    //                         }\r
-    //                 }\r
-    //                 return result;\r
-    //         } catch (Exception e) {\r
-    //                 e.printStackTrace();\r
-    //                 throw new RuntimeException(e);\r
-    //         }\r
-    //\r
-    // }\r
-    //\r
-    // private boolean checkIsSetOfType(Field field, Class referencedClass, Class<?> type){\r
-    //         Type genericType = (ParameterizedTypeImpl)field.getGenericType();\r
-    //         if (genericType instanceof ParameterizedTypeImpl){\r
-    //                 ParameterizedTypeImpl paraType = (ParameterizedTypeImpl)genericType;\r
-    //                 paraType.getRawType();\r
-    //                 Type[] arguments = paraType.getActualTypeArguments();\r
-    //                 //logger.debug(arguments.length);\r
-    //                 if (arguments.length == 1){\r
-    //                         Class collectionClass;\r
-    //                         try {\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
-    //                                         GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration();\r
-    //                                         collectionClass = (Class)genericDeclaration;\r
-    //                                 }else{\r
-    //                                         logger.warn("Unknown Type");\r
-    //                                         return false;\r
-    //                                 }\r
-    //                                 if (CdmBase.class.isAssignableFrom(collectionClass) && collectionClass.isAssignableFrom(referencedClass)  ){\r
-    //                                         return true;\r
-    //                                 }\r
-    //                         } catch (Exception e) {\r
-    //                                 logger.warn(e.getMessage());\r
-    //                         }\r
-    //                 }else{\r
-    //                         logger.warn("Length of arguments <> 1");\r
-    //                 }\r
-    //         }else{\r
-    //                 logger.warn("Not a generic type of type ParameterizedTypeImpl");\r
-    //         }\r
-    //         return false;\r
-    // }\r
-    //\r
-    //\r
-    //\r
-    //\r
-    // private boolean handleSingleClass(Class itemClass, Class type, Field field, Class cdmClass, Set<CdmBase> result,CdmBase value, boolean isCollection){\r
-    //         if (! Modifier.isStatic(field.getModifiers())){\r
-    //                 String methodName = StringUtils.rightPad(field.getName(), 30);\r
-    //                 String className = StringUtils.rightPad(cdmClass.getSimpleName(), 30);\r
-    //                 String returnTypeName = StringUtils.rightPad(type.getSimpleName(), 30);\r
-    //\r
-    //                 logger.debug(methodName +   "\t\t" + className + "\t\t" + returnTypeName);\r
-    ////                       result_old.add(method);\r
-    //                 result.addAll(getCdmBasesByFieldAndClass(field, itemClass, cdmClass, value, isCollection));\r
-    //         }\r
-    //         return true;\r
-    // }\r
-    //\r
-    // private Set<Field> getFields(Class clazz){\r
-    //         Set<Field> result = new HashSet<>();\r
-    //         for (Field field: clazz.getDeclaredFields()){\r
-    //                 if (!Modifier.isStatic(field.getModifiers())){\r
-    //                         result.add(field);\r
-    //                 }\r
-    //         }\r
-    //         Class superclass = clazz.getSuperclass();\r
-    //         if (CdmBase.class.isAssignableFrom(superclass)){\r
-    //                 result.addAll(getFields(superclass));\r
-    //         }\r
-    //         return result;\r
-    // }\r
-    //\r
-    // private Set<CdmBase> getCdmBasesByFieldAndClass(Field field, Class itemClass, Class otherClazz, CdmBase item, boolean isCollection){\r
-    //         Set<CdmBase> result = new HashSet<>();\r
-    //         if (isCollection){\r
-    //                 result.addAll(genericDao.getCdmBasesWithItemInCollection(itemClass, otherClazz, field.getName(), item));\r
-    //         }else{\r
-    //                 result.addAll(genericDao.getCdmBasesByFieldAndClass(otherClazz, field.getName(), item));\r
-    //         }\r
-    //         return result;\r
-    // }\r
-\r
-    @Override\r
-    public List getHqlResult(String hqlQuery){\r
-        return genericDao.getHqlResult(hqlQuery);\r
-    }\r
-\r
-    @Override\r
-    public <T extends IMergable> void merge(T mergeFirst, T mergeSecond, IMergeStrategy mergeStrategy) throws MergeException {\r
-        if (mergeStrategy == null){\r
-            mergeStrategy = DefaultMergeStrategy.NewInstance(((CdmBase)mergeFirst).getClass());\r
-        }\r
-        genericDao.merge((CdmBase)mergeFirst, (CdmBase)mergeSecond, mergeStrategy);\r
-    }\r
-\r
-    @Override\r
-    public <T extends IMergable> void merge(T mergeFirst, T mergeSecond, Class<? extends CdmBase> clazz) throws MergeException {\r
-        IMergeStrategy mergeStrategy;\r
-        if (clazz == null){\r
-            mergeStrategy = DefaultMergeStrategy.NewInstance(((CdmBase)mergeFirst).getClass());\r
-        } else {\r
-            mergeStrategy = DefaultMergeStrategy.NewInstance(clazz);\r
-        }\r
-        merge(mergeFirst, mergeSecond, mergeStrategy);\r
-    }\r
-\r
-    @Override\r
-    @Transactional(readOnly = false)\r
-    @Deprecated\r
-    public <T extends IMergable> void merge(int mergeFirstId, int mergeSecondId, Class<? extends CdmBase> clazz) throws MergeException {\r
-        IMergeStrategy mergeStrategy;\r
-        T mergeFirst = (T) genericDao.find(clazz, mergeFirstId);\r
-        T mergeSecond = (T) genericDao.find(clazz, mergeSecondId);\r
-        mergeStrategy = DefaultMergeStrategy.NewInstance(clazz);\r
-        merge(mergeFirst, mergeSecond, mergeStrategy);\r
-    }\r
-\r
-    @Override\r
-    @Transactional(readOnly = false)\r
-    public <T extends IMergable> void merge(UUID mergeFirstUuid, UUID mergeSecondUuid, Class<? extends CdmBase> clazz) throws MergeException {\r
-        IMergeStrategy mergeStrategy;\r
-        T mergeFirst = (T) genericDao.find(clazz, mergeFirstUuid);\r
-        T mergeSecond = (T) genericDao.find(clazz, mergeSecondUuid);\r
-        if (mergeFirst == null){\r
-            throw new MergeException("The merge target is not available anymore.");\r
-        }\r
-        if (mergeSecond == null){\r
-            throw new MergeException("The merge candidate is not available anymore.");\r
-        }\r
-        mergeStrategy = DefaultMergeStrategy.NewInstance(clazz);\r
-        merge(mergeFirst, mergeSecond, mergeStrategy);\r
-    }\r
-\r
-    @Override\r
-    public <T extends IMergable> void merge(T mergeFirst, T mergeSecond) throws MergeException {\r
-        IMergeStrategy mergeStrategy = DefaultMergeStrategy.NewInstance(((CdmBase)mergeFirst).getClass());\r
-        merge(mergeFirst, mergeSecond, mergeStrategy);\r
-    }\r
-\r
-\r
-    @Override\r
-    public <T extends IMatchable> List<T> findMatching(T objectToMatch, IMatchStrategyEqual matchStrategy) throws MatchException {\r
-        if (matchStrategy == null){\r
-            matchStrategy = DefaultMatchStrategy.NewInstance(((objectToMatch).getClass()));\r
-        }\r
-        return genericDao.findMatching(objectToMatch, matchStrategy);\r
-    }\r
-\r
-\r
-\r
-    /* (non-Javadoc)\r
-     * @see eu.etaxonomy.cdm.api.service.ICommonService#findMatching(eu.etaxonomy.cdm.strategy.match.IMatchable, eu.etaxonomy.cdm.strategy.match.MatchStrategyConfigurator.MatchStrategy)\r
-     */\r
-    @Override\r
-    public <T extends IMatchable> List<T> findMatching(T objectToMatch, MatchStrategy strategy) throws MatchException {\r
-        return findMatching(objectToMatch, MatchStrategyConfigurator.getMatchStrategy(strategy));\r
-    }\r
-\r
-    // /* (non-Javadoc)\r
-    //  * @see eu.etaxonomy.cdm.api.service.IService#list(java.lang.Class, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r
-    //  */\r
-    // @Override\r
-    // public <TYPE extends OriginalSourceBase> Pager<TYPE> list(Class<TYPE> type,\r
-    //                 Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,\r
-    //                 List<String> propertyPaths) {\r
-    //         logger.warn("Not yet implemented");\r
-    //         return null;\r
-    // }\r
-\r
-\r
-    @Transactional(readOnly = false)\r
-    @Override\r
-    public void saveAllMetaData(Collection<CdmMetaData> metaData) {\r
-        Iterator<CdmMetaData> iterator = metaData.iterator();\r
-        while(iterator.hasNext()){\r
-            CdmMetaData cdmMetaData = iterator.next();\r
-            genericDao.saveMetaData(cdmMetaData);\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public Map<CdmMetaDataPropertyName, CdmMetaData> getCdmMetaData() {\r
-        Map<CdmMetaDataPropertyName, CdmMetaData> result = new HashMap<>();\r
-        List<CdmMetaData> metaDataList = genericDao.getMetaData();\r
-        for (CdmMetaData metaData : metaDataList){\r
-            CdmMetaDataPropertyName propertyName = metaData.getPropertyName();\r
-            result.put(propertyName, metaData);\r
-        }\r
-        return result;\r
-    }\r
-\r
-    @Override\r
-    public Object initializeCollection(UUID ownerUuid, String fieldName) {\r
-        return genericDao.initializeCollection(ownerUuid, fieldName);\r
-\r
-    }\r
-\r
-    @Override\r
-    public Object initializeCollection(UUID ownerUuid, String fieldName, List<String> propertyPaths) {\r
-        return genericDao.initializeCollection(ownerUuid, fieldName, propertyPaths);\r
-\r
-    }\r
-\r
-    @Override\r
-    public boolean isEmpty(UUID ownerUuid, String fieldName) {\r
-        return genericDao.isEmpty(ownerUuid, fieldName);\r
-\r
-    }\r
-\r
-    @Override\r
-    public int size(UUID ownerUuid, String fieldName) {\r
-        return genericDao.size(ownerUuid, fieldName);\r
-    }\r
-\r
-\r
-    @Override\r
-    public Object get(UUID ownerUuid, String fieldName, int index) {\r
-        return genericDao.get(ownerUuid, fieldName, index);\r
-    }\r
-\r
-    @Override\r
-    public boolean contains(UUID ownerUuid, String fieldName, Object element) {\r
-        return genericDao.contains(ownerUuid, fieldName, element);\r
-    }\r
-\r
-    @Override\r
-    public boolean containsKey(UUID ownerUuid, String fieldName, Object key) {\r
-        return genericDao.containsKey(ownerUuid, fieldName, key);\r
-    }\r
-\r
-    @Override\r
-    public boolean containsValue(UUID ownerUuid, String fieldName, Object value) {\r
-        return genericDao.containsValue(ownerUuid, fieldName, value);\r
-    }\r
-\r
-    @Override\r
-    @Transactional(readOnly = false)\r
-    public void createFullSampleData() {\r
-        genericDao.createFullSampleData();\r
-    }\r
-\r
-\r
-\r
-    @Override\r
-    public <S extends CdmBase> List<S> list(Class<S> type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths){\r
-        return genericDao.list(type, limit, start, orderHints, propertyPaths);\r
-    }\r
-\r
-    @Override\r
-    public <S extends CdmBase> long count(Class<S> type) {\r
-        return genericDao.count(type);\r
-    }\r
-\r
-    @Override\r
-    @Transactional(readOnly = false)\r
-    public CdmBase save(CdmBase newInstance) {\r
-        return genericDao.save(newInstance);\r
-    }\r
-\r
-    @Override\r
-    @Transactional(readOnly = false)\r
-    public UUID delete(CdmBase instance) {\r
-        return genericDao.delete(instance);\r
-    }\r
-\r
-    @Override\r
-    @Transactional(readOnly = false)\r
-    public UUID saveOrUpdate(CdmBase newInstance) {\r
-        return genericDao.saveOrUpdate(newInstance);\r
-    }\r
-\r
-\r
-    @Override\r
-    @Transactional(readOnly = false)\r
-    public <T extends CdmBase> Map<UUID,T> save(Collection<T> newInstances) {\r
-        //this is very ugly, I know, but for now I do not want to copy the saveAll method from CdmEntityDaoBase to genericDao\r
-        //and generally the saveAll method should work for other CdmBase types with generics removed\r
-        return (Map<UUID, T>) originalSourceDao.saveAll((Collection)newInstances);\r
-    }\r
-\r
-    @Override\r
-    @Transactional(readOnly = false)\r
-    public <T extends CdmBase> Map<UUID,T> saveOrUpdate(Collection<T> newInstances) {\r
-        //this is very ugly, I know, but for now I do not want to copy the saveAll method from CdmEntityDaoBase to genericDao\r
-        //and generally the saveAll method should work for other CdmBase types with generics removed\r
-        return (Map<UUID, T>) originalSourceDao.saveOrUpdateAll((Collection)newInstances);\r
-    }\r
-\r
-\r
-    @Override\r
-    public <T extends CdmBase> boolean isMergeable(T cdmBase1, T cdmBase2, IMergeStrategy mergeStrategy) throws MergeException {\r
-        return genericDao.isMergeable(cdmBase1, cdmBase2, mergeStrategy);\r
-    }\r
-\r
-}\r
+/**
+ * Copyright (C) 2007 EDIT
+ * European Distributed Institute of Taxonomy
+ * http://www.e-taxonomy.eu
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * See LICENSE.TXT at the top of this package for the full license terms.
+ */
+package eu.etaxonomy.cdm.api.service;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import eu.etaxonomy.cdm.format.ReferencingObjectFormatter;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
+import eu.etaxonomy.cdm.model.common.IdentifiableSource;
+import eu.etaxonomy.cdm.model.common.Language;
+import eu.etaxonomy.cdm.model.common.SingleSourcedEntityBase;
+import eu.etaxonomy.cdm.model.description.DescriptionBase;
+import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
+import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
+import eu.etaxonomy.cdm.model.metadata.CdmMetaData;
+import eu.etaxonomy.cdm.model.metadata.CdmMetaDataPropertyName;
+import eu.etaxonomy.cdm.model.name.NomenclaturalSource;
+import eu.etaxonomy.cdm.model.reference.ISourceable;
+import eu.etaxonomy.cdm.model.reference.NamedSource;
+import eu.etaxonomy.cdm.model.taxon.SecundumSource;
+import eu.etaxonomy.cdm.persistence.dao.common.ICdmGenericDao;
+import eu.etaxonomy.cdm.persistence.dao.reference.IOriginalSourceDao;
+import eu.etaxonomy.cdm.persistence.dto.ReferencingObjectDto;
+import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
+import eu.etaxonomy.cdm.persistence.query.OrderHint;
+import eu.etaxonomy.cdm.strategy.match.DefaultMatchStrategy;
+import eu.etaxonomy.cdm.strategy.match.IMatchStrategy;
+import eu.etaxonomy.cdm.strategy.match.IMatchable;
+import eu.etaxonomy.cdm.strategy.match.MatchException;
+import eu.etaxonomy.cdm.strategy.match.MatchStrategyConfigurator;
+import eu.etaxonomy.cdm.strategy.match.MatchStrategyConfigurator.MatchStrategy;
+import eu.etaxonomy.cdm.strategy.merge.DefaultMergeStrategy;
+import eu.etaxonomy.cdm.strategy.merge.IMergable;
+import eu.etaxonomy.cdm.strategy.merge.IMergeStrategy;
+import eu.etaxonomy.cdm.strategy.merge.MergeException;
+
+@Service
+@Transactional(readOnly = true)
+public class CommonServiceImpl
+        /*extends ServiceBase<OriginalSourceBase,IOriginalSourceDao>*/
+        implements ICommonService {
+
+    @SuppressWarnings("unused")
+    private static final Logger logger = LogManager.getLogger();
+
+    @Autowired
+    private IOriginalSourceDao originalSourceDao;
+
+    @Autowired
+    private ICdmGenericDao genericDao;
+
+    @Override
+    public <T extends CdmBase> T findWithUpdate(Class<T> clazz, int id){
+        return genericDao.find(clazz, id);
+    }
+
+    @Override
+    public <T extends CdmBase> T find(Class<T> clazz, int id){
+        return genericDao.find(clazz, id);
+    }
+
+    @Override
+    public <T extends CdmBase> T find(Class<T> clazz, int id, List<String> propertyPaths){
+        return  genericDao.find(clazz, id, propertyPaths);
+    }
+
+    @Override
+    public <T extends CdmBase> T find(Class<T> clazz, UUID uuid) {
+        return uuid == null ? null : genericDao.find(clazz, uuid);
+    }
+
+    @Override
+    public <T extends CdmBase> T find(Class<T> clazz, UUID uuid, List<String> propertyPaths) {
+        return uuid == null ? null : genericDao.find(clazz, uuid, propertyPaths);
+    }
+
+    @Override
+    public <S extends ISourceable> Map<String, S> getSourcedObjectsByIdInSourceC(Class<S> clazz, Set<String> idInSourceSet, String idNamespace){
+        Map<String, S> list = originalSourceDao.findOriginalSourcesByIdInSource(clazz, idInSourceSet, idNamespace);
+        return list;
+    }
+
+    @Override
+    public <S extends ISourceable> S getSourcedObjectByIdInSource(Class<S> clazz, String idInSource, String idNamespace) {
+        S result = null;
+        List<S> list = originalSourceDao.findOriginalSourceByIdInSource(clazz, idInSource, idNamespace);
+        if (! list.isEmpty()){
+            result = list.get(0);
+        }return result;
+    }
+
+    @Override
+    public Set<ReferencingObjectDto> getReferencingObjectDtos(CdmBase referencedCdmBase){
+        return this.genericDao.getReferencingObjectsDto(referencedCdmBase);
+    }
+
+    @Override
+    public Set<CdmBase> getReferencingObjects(CdmBase referencedCdmBase){
+        return this.genericDao.getReferencingObjects(referencedCdmBase);
+    }
+
+    @Override
+    public long getReferencingObjectsCount(CdmBase referencedCdmBase){
+        return this.genericDao.getReferencingObjectsCount(referencedCdmBase);
+    }
+
+    @Override
+    public Set<CdmBase> getReferencingObjectsForDeletion(CdmBase referencedCdmBase){
+        return this.genericDao.getReferencingObjectsForDeletion(referencedCdmBase);
+    }
+
+
+    @Override
+    public Set<ReferencingObjectDto> initializeReferencingObjectDtos(Set<ReferencingObjectDto> dtos,
+            boolean doReferencingEntity, boolean doTargetEntity, boolean doDescription, Language language) {
+
+        for (ReferencingObjectDto dto : dtos){
+            //TODO or load()?
+            CdmBase entity = this.genericDao.find(dto.getType(), dto.getUuid());
+            entity = CdmBase.deproxy(entity); //TODO necessary here or should we only do this in called methods below
+            if (doReferencingEntity){
+                dto.setReferencedEntity(entity);
+            }
+            if (doTargetEntity){
+                UuidAndTitleCache<CdmBase> target = getReferencingObjectTarget(entity);
+                dto.setOpenInTarget(target);
+            }
+            if (doDescription){
+                String targetString = dto.getOpenInTarget() == null ? null : dto.getOpenInTarget().getTitleCache();
+                String description = getReferencingObjectDescription(entity, targetString, language);
+                dto.setTitleCache(description);
+            }
+        }
+        return dtos;
+    }
+
+    private UuidAndTitleCache<CdmBase> getReferencingObjectTarget(CdmBase entity) {
+        CdmBase targetEntity;
+        entity = CdmBase.deproxy(entity);
+        if (entity instanceof SecundumSource){
+            targetEntity = ((SecundumSource) entity).getSourcedTaxon();
+        }else if (entity instanceof NomenclaturalSource){
+            targetEntity = ((NomenclaturalSource) entity).getSourcedName();
+        }else if (entity instanceof DescriptionElementSource){
+            DescriptionElementBase element = ((DescriptionElementSource) entity).getSourcedElement();
+            targetEntity = getTarget(element);
+        }else if (entity instanceof DescriptionElementBase){
+           targetEntity = getTarget((DescriptionElementBase)entity);
+        }else if (entity instanceof IdentifiableSource){
+            IdentifiableSource source = (IdentifiableSource) entity;
+            targetEntity = originalSourceDao.findIdentifiableBySourceId(IdentifiableEntity.class, source.getId());
+        }else if (entity instanceof NamedSource){
+            NamedSource source = (NamedSource) entity;
+            SingleSourcedEntityBase singleSourced = originalSourceDao.findSingleSourceBySourceId(SingleSourcedEntityBase.class, source.getId());
+            if (singleSourced != null){
+                targetEntity = singleSourced;
+            }else{
+                //TODO
+                targetEntity = entity;
+            }
+        }else if (entity instanceof DescriptionBase){
+            targetEntity = getTarget((DescriptionBase<?>)entity);
+        }else{
+            targetEntity = entity;
+        }
+        targetEntity = CdmBase.deproxy(targetEntity);
+
+        if (targetEntity == null){
+            targetEntity = entity;
+        }
+        String targetLabel = targetEntity instanceof IdentifiableEntity ? ((IdentifiableEntity<?>)targetEntity).getTitleCache() : null;
+        UuidAndTitleCache<CdmBase> result = new UuidAndTitleCache<>(targetEntity.getClass(), targetEntity.getUuid(), targetEntity.getId(), targetLabel);
+        return result;
+    }
+
+    private CdmBase getTarget(DescriptionElementBase element) {
+        return element == null ? null :getTarget(element.getInDescription());
+    }
+
+    private CdmBase getTarget(DescriptionBase<?> db) {
+        return db.describedEntity() != null ? (CdmBase)db.describedEntity() : db;
+    }
+
+    private String getReferencingObjectDescription(CdmBase entity, String targetString, Language language) {
+        return ReferencingObjectFormatter.format(entity, targetString, language);
+    }
+
+    @Override
+    public <T> List<T> getHqlResult(String hqlQuery, Class<T> clazz){
+        return genericDao.getHqlResult(hqlQuery, new Object[0], clazz);
+    }
+
+    @Override
+    public <T> List<T> getHqlResult(String hqlQuery, Object[] params, Class<T> clazz){
+        return genericDao.getHqlResult(hqlQuery, params, clazz);
+    }
+
+    @Override
+    public <T extends IMergable> void merge(T mergeFirst, T mergeSecond, IMergeStrategy mergeStrategy) throws MergeException {
+        if (mergeStrategy == null){
+            mergeStrategy = DefaultMergeStrategy.NewInstance(((CdmBase)mergeFirst).getClass());
+        }
+        genericDao.merge((CdmBase)mergeFirst, (CdmBase)mergeSecond, mergeStrategy);
+    }
+
+    @Override
+    public <T extends IMergable> void merge(T mergeFirst, T mergeSecond, Class<? extends CdmBase> clazz) throws MergeException {
+        IMergeStrategy mergeStrategy;
+        if (clazz == null){
+            mergeStrategy = DefaultMergeStrategy.NewInstance(((CdmBase)mergeFirst).getClass());
+        } else {
+            mergeStrategy = DefaultMergeStrategy.NewInstance(clazz);
+        }
+        merge(mergeFirst, mergeSecond, mergeStrategy);
+    }
+
+    @Override
+    @Transactional(readOnly = false)
+    @Deprecated
+    public <T extends IMergable> void merge(int mergeFirstId, int mergeSecondId, Class<? extends CdmBase> clazz) throws MergeException {
+        IMergeStrategy mergeStrategy;
+        T mergeFirst = (T) genericDao.find(clazz, mergeFirstId);
+        T mergeSecond = (T) genericDao.find(clazz, mergeSecondId);
+        mergeStrategy = DefaultMergeStrategy.NewInstance(clazz);
+        merge(mergeFirst, mergeSecond, mergeStrategy);
+    }
+
+    @Override
+    @Transactional(readOnly = false)
+    public <T extends IMergable> void merge(UUID mergeFirstUuid, UUID mergeSecondUuid, Class<? extends CdmBase> clazz) throws MergeException {
+        IMergeStrategy mergeStrategy;
+        T mergeFirst = (T) genericDao.find(clazz, mergeFirstUuid);
+        T mergeSecond = (T) genericDao.find(clazz, mergeSecondUuid);
+        if (mergeFirst == null){
+            throw new MergeException("The merge target is not available anymore.");
+        }
+        if (mergeSecond == null){
+            throw new MergeException("The merge candidate is not available anymore.");
+        }
+        mergeStrategy = DefaultMergeStrategy.NewInstance(clazz);
+        merge(mergeFirst, mergeSecond, mergeStrategy);
+    }
+
+    @Override
+    public <T extends IMergable> void merge(T mergeFirst, T mergeSecond) throws MergeException {
+        IMergeStrategy mergeStrategy = DefaultMergeStrategy.NewInstance(((CdmBase)mergeFirst).getClass());
+        merge(mergeFirst, mergeSecond, mergeStrategy);
+    }
+
+    @Override
+    public <T extends IMatchable> List<T> findMatching(T objectToMatch, IMatchStrategy matchStrategy) throws MatchException {
+        if (matchStrategy == null){
+            matchStrategy = DefaultMatchStrategy.NewInstance(((objectToMatch).getClass()));
+        }
+        return genericDao.findMatching(objectToMatch, matchStrategy);
+    }
+
+    @Override
+    public <T extends IMatchable> List<T> findMatching(T objectToMatch, MatchStrategy strategy) throws MatchException {
+        return findMatching(objectToMatch, MatchStrategyConfigurator.getMatchStrategy(strategy));
+    }
+
+    @Transactional(readOnly = false)
+    @Override
+    public void saveAllMetaData(Collection<CdmMetaData> metaData) {
+        Iterator<CdmMetaData> iterator = metaData.iterator();
+        while(iterator.hasNext()){
+            CdmMetaData cdmMetaData = iterator.next();
+            genericDao.saveMetaData(cdmMetaData);
+        }
+    }
+
+    @Override
+    public Map<CdmMetaDataPropertyName, CdmMetaData> getCdmMetaData() {
+        Map<CdmMetaDataPropertyName, CdmMetaData> result = new HashMap<>();
+        List<CdmMetaData> metaDataList = genericDao.getMetaData();
+        for (CdmMetaData metaData : metaDataList){
+            CdmMetaDataPropertyName propertyName = metaData.getPropertyName();
+            result.put(propertyName, metaData);
+        }
+        return result;
+    }
+
+    @Override
+    public Object initializeCollection(UUID ownerUuid, String fieldName) {
+        return genericDao.initializeCollection(ownerUuid, fieldName);
+    }
+
+    @Override
+    public Object initializeCollection(UUID ownerUuid, String fieldName, List<String> propertyPaths) {
+        return genericDao.initializeCollection(ownerUuid, fieldName, propertyPaths);
+    }
+
+    @Override
+    public boolean isEmpty(UUID ownerUuid, String fieldName) {
+        return genericDao.isEmpty(ownerUuid, fieldName);
+    }
+
+    @Override
+    public int size(UUID ownerUuid, String fieldName) {
+        return genericDao.size(ownerUuid, fieldName);
+    }
+
+    @Override
+    public Object get(UUID ownerUuid, String fieldName, int index) {
+        return genericDao.get(ownerUuid, fieldName, index);
+    }
+
+    @Override
+    public boolean contains(UUID ownerUuid, String fieldName, Object element) {
+        return genericDao.contains(ownerUuid, fieldName, element);
+    }
+
+    @Override
+    public boolean containsKey(UUID ownerUuid, String fieldName, Object key) {
+        return genericDao.containsKey(ownerUuid, fieldName, key);
+    }
+
+    @Override
+    public boolean containsValue(UUID ownerUuid, String fieldName, Object value) {
+        return genericDao.containsValue(ownerUuid, fieldName, value);
+    }
+
+    @Override
+    @Transactional(readOnly = false)
+    public void createFullSampleData() {
+        genericDao.createFullSampleData();
+    }
+
+    @Override
+    public <S extends CdmBase> List<S> list(Class<S> type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths){
+        return genericDao.list(type, limit, start, orderHints, propertyPaths);
+    }
+
+    @Override
+    public <S extends CdmBase> long count(Class<S> type) {
+        return genericDao.count(type);
+    }
+
+    @Override
+    @Transactional(readOnly = false)
+    public CdmBase save(CdmBase newInstance) {
+        return genericDao.save(newInstance);
+    }
+
+    @Override
+    @Transactional(readOnly = false)
+    public UUID delete(CdmBase instance) {
+        return genericDao.delete(instance);
+    }
+
+    @Override
+    @Transactional(readOnly = false)
+    public UUID saveOrUpdate(CdmBase newInstance) {
+        return genericDao.saveOrUpdate(newInstance);
+    }
+
+    @Override
+    @Transactional(readOnly = false)
+    public <T extends CdmBase> Map<UUID,T> save(Collection<T> newInstances) {
+        //this is very ugly, I know, but for now I do not want to copy the saveAll method from CdmEntityDaoBase to genericDao
+        //and generally the saveAll method should work for other CdmBase types with generics removed
+        return originalSourceDao.saveAll((Collection)newInstances);
+    }
+
+    @Override
+    @Transactional(readOnly = false)
+    public <T extends CdmBase> Map<UUID,T> saveOrUpdate(Collection<T> newInstances) {
+        //this is very ugly, I know, but for now I do not want to copy the saveAll method from CdmEntityDaoBase to genericDao
+        //and generally the saveAll method should work for other CdmBase types with generics removed
+        return originalSourceDao.saveOrUpdateAll((Collection)newInstances);
+    }
+
+    @Override
+    public <T extends CdmBase> boolean isMergeable(T cdmBase1, T cdmBase2, IMergeStrategy mergeStrategy) throws MergeException {
+        return genericDao.isMergeable(cdmBase1, cdmBase2, mergeStrategy);
+    }
+
+    @Override
+    public List<UUID> listUuid(Class<? extends CdmBase> clazz) {
+        return genericDao.listUuid(clazz);
+    }
+
+    @Override
+    @Transactional(readOnly = true)
+    public UUID refresh(CdmBase persistentObject) {
+        return genericDao.refresh(persistentObject);
+    }
+
+}