2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.cdm
.api
.service
;
12 import java
.util
.Collection
;
13 import java
.util
.HashMap
;
14 import java
.util
.Iterator
;
15 import java
.util
.List
;
18 import java
.util
.UUID
;
20 import org
.apache
.log4j
.Logger
;
21 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
22 import org
.springframework
.stereotype
.Service
;
23 import org
.springframework
.transaction
.annotation
.Transactional
;
25 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
26 import eu
.etaxonomy
.cdm
.model
.metadata
.CdmMetaData
;
27 import eu
.etaxonomy
.cdm
.model
.metadata
.CdmMetaDataPropertyName
;
28 import eu
.etaxonomy
.cdm
.model
.reference
.ISourceable
;
29 import eu
.etaxonomy
.cdm
.persistence
.dao
.common
.ICdmGenericDao
;
30 import eu
.etaxonomy
.cdm
.persistence
.dao
.reference
.IOriginalSourceDao
;
31 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
32 import eu
.etaxonomy
.cdm
.strategy
.match
.DefaultMatchStrategy
;
33 import eu
.etaxonomy
.cdm
.strategy
.match
.IMatchStrategyEqual
;
34 import eu
.etaxonomy
.cdm
.strategy
.match
.IMatchable
;
35 import eu
.etaxonomy
.cdm
.strategy
.match
.MatchException
;
36 import eu
.etaxonomy
.cdm
.strategy
.match
.MatchStrategyConfigurator
;
37 import eu
.etaxonomy
.cdm
.strategy
.match
.MatchStrategyConfigurator
.MatchStrategy
;
38 import eu
.etaxonomy
.cdm
.strategy
.merge
.DefaultMergeStrategy
;
39 import eu
.etaxonomy
.cdm
.strategy
.merge
.IMergable
;
40 import eu
.etaxonomy
.cdm
.strategy
.merge
.IMergeStrategy
;
41 import eu
.etaxonomy
.cdm
.strategy
.merge
.MergeException
;
45 @Transactional(readOnly
= true)
46 public class CommonServiceImpl
/*extends ServiceBase<OriginalSourceBase,IOriginalSourceDao>*/ implements ICommonService
{
47 @SuppressWarnings("unused")
48 private static final Logger logger
= Logger
.getLogger(CommonServiceImpl
.class);
52 private IOriginalSourceDao originalSourceDao
;
56 private ICdmGenericDao genericDao
;
60 public <T
extends CdmBase
> T
findWithUpdate(Class
<T
> clazz
, int id
){
61 return genericDao
.find(clazz
, id
);
65 public <T
extends CdmBase
> T
find(Class
<T
> clazz
, int id
){
66 return genericDao
.find(clazz
, id
);
70 public <T
extends CdmBase
> T
find(Class
<T
> clazz
, int id
, List
<String
> propertyPaths
){
71 return genericDao
.find(clazz
, id
, propertyPaths
);
75 public <T
extends CdmBase
> T
find(Class
<T
> clazz
, UUID uuid
) {
76 return uuid
== null ?
null : genericDao
.find(clazz
, uuid
);
80 public <T
extends CdmBase
> T
find(Class
<T
> clazz
, UUID uuid
, List
<String
> propertyPaths
) {
81 return uuid
== null ?
null : genericDao
.find(clazz
, uuid
, propertyPaths
);
85 public Map
<String
, ?
extends ISourceable
> getSourcedObjectsByIdInSource(Class clazz
, Set
<String
> idInSourceSet
, String idNamespace
) {
86 Map
<String
, ?
extends ISourceable
> list
= originalSourceDao
.findOriginalSourcesByIdInSource(clazz
, idInSourceSet
, idNamespace
);
91 public <S
extends ISourceable
> Map
<String
, S
> getSourcedObjectsByIdInSourceC(Class
<S
> clazz
, Set
<String
> idInSourceSet
, String idNamespace
){
92 Map
<String
, S
> list
= originalSourceDao
.findOriginalSourcesByIdInSource(clazz
, idInSourceSet
, idNamespace
);
98 public <S
extends ISourceable
> S
getSourcedObjectByIdInSource(Class
<S
> clazz
, String idInSource
, String idNamespace
) {
100 List
<S
> list
= originalSourceDao
.findOriginalSourceByIdInSource(clazz
, idInSource
, idNamespace
);
101 if (! list
.isEmpty()){
102 result
= list
.get(0);
108 public Set
<CdmBase
> getReferencingObjects(CdmBase referencedCdmBase
){
109 return this.genericDao
.getReferencingObjects(referencedCdmBase
);
113 public long getReferencingObjectsCount(CdmBase referencedCdmBase
){
114 return this.genericDao
.getReferencingObjectsCount(referencedCdmBase
);
118 public Set
<CdmBase
> getReferencingObjectsForDeletion(CdmBase referencedCdmBase
){
119 return this.genericDao
.getReferencingObjectsForDeletion(referencedCdmBase
);
122 // Set<Class<? extends CdmBase>> allCdmClasses = genericDao.getAllCdmClasses(false); //findAllCdmClasses();
124 // referencedCdmBase = (CdmBase)HibernateProxyHelper.deproxy(referencedCdmBase);
125 // Class referencedClass = referencedCdmBase.getClass();
126 // Set<CdmBase> result = new HashSet<>();
127 // logger.debug("Referenced Class: " + referencedClass.getName());
129 // for (Class<? extends CdmBase> cdmClass : allCdmClasses){
130 // Set<Field> fields = getFields(cdmClass);
131 // for (Field field: fields){
132 // Class<?> type = field.getType();
134 // if (! type.isInterface()){
135 // if (referencedClass.isAssignableFrom(type)||
136 // type.isAssignableFrom(referencedClass) && CdmBase.class.isAssignableFrom(type)){
137 // handleSingleClass(referencedClass, type, field, cdmClass, result, referencedCdmBase, false);
140 // }else if (type.isAssignableFrom(referencedClass)){
141 // handleSingleClass(referencedClass, type, field, cdmClass, result, referencedCdmBase, false);
142 // }else if (Collection.class.isAssignableFrom(type)){
144 // if (checkIsSetOfType(field, referencedClass, type) == true){
145 // handleSingleClass(referencedClass, type, field, cdmClass, result, referencedCdmBase, true);
148 //// Class[] interfaces = referencedClass.getInterfaces();
149 //// for (Class interfaze: interfaces){
150 //// if (interfaze == type){
151 ////// if(interfaze.isAssignableFrom(returnType)){
152 //// handleSingleClass(interfaze, type, field, cdmClass, result, referencedCdmBase);
158 // } catch (Exception e) {
159 // e.printStackTrace();
160 // throw new RuntimeException(e);
165 // private boolean checkIsSetOfType(Field field, Class referencedClass, Class<?> type){
166 // Type genericType = (ParameterizedTypeImpl)field.getGenericType();
167 // if (genericType instanceof ParameterizedTypeImpl){
168 // ParameterizedTypeImpl paraType = (ParameterizedTypeImpl)genericType;
169 // paraType.getRawType();
170 // Type[] arguments = paraType.getActualTypeArguments();
171 // //logger.debug(arguments.length);
172 // if (arguments.length == 1){
173 // Class collectionClass;
175 // if (arguments[0] instanceof Class){
176 // collectionClass = (Class)arguments[0];
177 // }else if(arguments[0] instanceof TypeVariableImpl){
178 // TypeVariableImpl typeVariable = (TypeVariableImpl)arguments[0];
179 // GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration();
180 // collectionClass = (Class)genericDeclaration;
182 // logger.warn("Unknown Type");
185 // if (CdmBase.class.isAssignableFrom(collectionClass) && collectionClass.isAssignableFrom(referencedClass) ){
188 // } catch (Exception e) {
189 // logger.warn(e.getMessage());
192 // logger.warn("Length of arguments <> 1");
195 // logger.warn("Not a generic type of type ParameterizedTypeImpl");
203 // private boolean handleSingleClass(Class itemClass, Class type, Field field, Class cdmClass, Set<CdmBase> result,CdmBase value, boolean isCollection){
204 // if (! Modifier.isStatic(field.getModifiers())){
205 // String methodName = StringUtils.rightPad(field.getName(), 30);
206 // String className = StringUtils.rightPad(cdmClass.getSimpleName(), 30);
207 // String returnTypeName = StringUtils.rightPad(type.getSimpleName(), 30);
209 // logger.debug(methodName + "\t\t" + className + "\t\t" + returnTypeName);
210 //// result_old.add(method);
211 // result.addAll(getCdmBasesByFieldAndClass(field, itemClass, cdmClass, value, isCollection));
216 // private Set<Field> getFields(Class clazz){
217 // Set<Field> result = new HashSet<>();
218 // for (Field field: clazz.getDeclaredFields()){
219 // if (!Modifier.isStatic(field.getModifiers())){
220 // result.add(field);
223 // Class superclass = clazz.getSuperclass();
224 // if (CdmBase.class.isAssignableFrom(superclass)){
225 // result.addAll(getFields(superclass));
230 // private Set<CdmBase> getCdmBasesByFieldAndClass(Field field, Class itemClass, Class otherClazz, CdmBase item, boolean isCollection){
231 // Set<CdmBase> result = new HashSet<>();
232 // if (isCollection){
233 // result.addAll(genericDao.getCdmBasesWithItemInCollection(itemClass, otherClazz, field.getName(), item));
235 // result.addAll(genericDao.getCdmBasesByFieldAndClass(otherClazz, field.getName(), item));
241 public List
getHqlResult(String hqlQuery
){
242 return genericDao
.getHqlResult(hqlQuery
);
246 public <T
extends IMergable
> void merge(T mergeFirst
, T mergeSecond
, IMergeStrategy mergeStrategy
) throws MergeException
{
247 if (mergeStrategy
== null){
248 mergeStrategy
= DefaultMergeStrategy
.NewInstance(((CdmBase
)mergeFirst
).getClass());
250 genericDao
.merge((CdmBase
)mergeFirst
, (CdmBase
)mergeSecond
, mergeStrategy
);
254 public <T
extends IMergable
> void merge(T mergeFirst
, T mergeSecond
, Class
<?
extends CdmBase
> clazz
) throws MergeException
{
255 IMergeStrategy mergeStrategy
;
257 mergeStrategy
= DefaultMergeStrategy
.NewInstance(((CdmBase
)mergeFirst
).getClass());
259 mergeStrategy
= DefaultMergeStrategy
.NewInstance(clazz
);
261 merge(mergeFirst
, mergeSecond
, mergeStrategy
);
265 @Transactional(readOnly
= false)
267 public <T
extends IMergable
> void merge(int mergeFirstId
, int mergeSecondId
, Class
<?
extends CdmBase
> clazz
) throws MergeException
{
268 IMergeStrategy mergeStrategy
;
269 T mergeFirst
= (T
) genericDao
.find(clazz
, mergeFirstId
);
270 T mergeSecond
= (T
) genericDao
.find(clazz
, mergeSecondId
);
271 mergeStrategy
= DefaultMergeStrategy
.NewInstance(clazz
);
272 merge(mergeFirst
, mergeSecond
, mergeStrategy
);
276 @Transactional(readOnly
= false)
277 public <T
extends IMergable
> void merge(UUID mergeFirstUuid
, UUID mergeSecondUuid
, Class
<?
extends CdmBase
> clazz
) throws MergeException
{
278 IMergeStrategy mergeStrategy
;
279 T mergeFirst
= (T
) genericDao
.find(clazz
, mergeFirstUuid
);
280 T mergeSecond
= (T
) genericDao
.find(clazz
, mergeSecondUuid
);
281 if (mergeFirst
== null){
282 throw new MergeException("The merge target is not available anymore.");
284 if (mergeSecond
== null){
285 throw new MergeException("The merge candidate is not available anymore.");
287 mergeStrategy
= DefaultMergeStrategy
.NewInstance(clazz
);
288 merge(mergeFirst
, mergeSecond
, mergeStrategy
);
292 public <T
extends IMergable
> void merge(T mergeFirst
, T mergeSecond
) throws MergeException
{
293 IMergeStrategy mergeStrategy
= DefaultMergeStrategy
.NewInstance(((CdmBase
)mergeFirst
).getClass());
294 merge(mergeFirst
, mergeSecond
, mergeStrategy
);
299 public <T
extends IMatchable
> List
<T
> findMatching(T objectToMatch
, IMatchStrategyEqual matchStrategy
) throws MatchException
{
300 if (matchStrategy
== null){
301 matchStrategy
= DefaultMatchStrategy
.NewInstance(((objectToMatch
).getClass()));
303 return genericDao
.findMatching(objectToMatch
, matchStrategy
);
309 * @see eu.etaxonomy.cdm.api.service.ICommonService#findMatching(eu.etaxonomy.cdm.strategy.match.IMatchable, eu.etaxonomy.cdm.strategy.match.MatchStrategyConfigurator.MatchStrategy)
312 public <T
extends IMatchable
> List
<T
> findMatching(T objectToMatch
, MatchStrategy strategy
) throws MatchException
{
313 return findMatching(objectToMatch
, MatchStrategyConfigurator
.getMatchStrategy(strategy
));
317 // * @see eu.etaxonomy.cdm.api.service.IService#list(java.lang.Class, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
320 // public <TYPE extends OriginalSourceBase> Pager<TYPE> list(Class<TYPE> type,
321 // Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,
322 // List<String> propertyPaths) {
323 // logger.warn("Not yet implemented");
328 @Transactional(readOnly
= false)
330 public void saveAllMetaData(Collection
<CdmMetaData
> metaData
) {
331 Iterator
<CdmMetaData
> iterator
= metaData
.iterator();
332 while(iterator
.hasNext()){
333 CdmMetaData cdmMetaData
= iterator
.next();
334 genericDao
.saveMetaData(cdmMetaData
);
339 public Map
<CdmMetaDataPropertyName
, CdmMetaData
> getCdmMetaData() {
340 Map
<CdmMetaDataPropertyName
, CdmMetaData
> result
= new HashMap
<>();
341 List
<CdmMetaData
> metaDataList
= genericDao
.getMetaData();
342 for (CdmMetaData metaData
: metaDataList
){
343 CdmMetaDataPropertyName propertyName
= metaData
.getPropertyName();
344 result
.put(propertyName
, metaData
);
350 public Object
initializeCollection(UUID ownerUuid
, String fieldName
) {
351 return genericDao
.initializeCollection(ownerUuid
, fieldName
);
356 public Object
initializeCollection(UUID ownerUuid
, String fieldName
, List
<String
> propertyPaths
) {
357 return genericDao
.initializeCollection(ownerUuid
, fieldName
, propertyPaths
);
362 public boolean isEmpty(UUID ownerUuid
, String fieldName
) {
363 return genericDao
.isEmpty(ownerUuid
, fieldName
);
368 public int size(UUID ownerUuid
, String fieldName
) {
369 return genericDao
.size(ownerUuid
, fieldName
);
374 public Object
get(UUID ownerUuid
, String fieldName
, int index
) {
375 return genericDao
.get(ownerUuid
, fieldName
, index
);
379 public boolean contains(UUID ownerUuid
, String fieldName
, Object element
) {
380 return genericDao
.contains(ownerUuid
, fieldName
, element
);
384 public boolean containsKey(UUID ownerUuid
, String fieldName
, Object key
) {
385 return genericDao
.containsKey(ownerUuid
, fieldName
, key
);
389 public boolean containsValue(UUID ownerUuid
, String fieldName
, Object value
) {
390 return genericDao
.containsValue(ownerUuid
, fieldName
, value
);
394 @Transactional(readOnly
= false)
395 public void createFullSampleData() {
396 genericDao
.createFullSampleData();
402 public <S
extends CdmBase
> List
<S
> list(Class
<S
> type
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
){
403 return genericDao
.list(type
, limit
, start
, orderHints
, propertyPaths
);
407 public <S
extends CdmBase
> long count(Class
<S
> type
) {
408 return genericDao
.count(type
);
412 @Transactional(readOnly
= false)
413 public CdmBase
save(CdmBase newInstance
) {
414 return genericDao
.save(newInstance
);
418 @Transactional(readOnly
= false)
419 public UUID
delete(CdmBase instance
) {
420 return genericDao
.delete(instance
);
424 @Transactional(readOnly
= false)
425 public UUID
saveOrUpdate(CdmBase newInstance
) {
426 return genericDao
.saveOrUpdate(newInstance
);
431 @Transactional(readOnly
= false)
432 public <T
extends CdmBase
> Map
<UUID
,T
> save(Collection
<T
> newInstances
) {
433 //this is very ugly, I know, but for now I do not want to copy the saveAll method from CdmEntityDaoBase to genericDao
434 //and generally the saveAll method should work for other CdmBase types with generics removed
435 return (Map
<UUID
, T
>) originalSourceDao
.saveAll((Collection
)newInstances
);
439 @Transactional(readOnly
= false)
440 public <T
extends CdmBase
> Map
<UUID
,T
> saveOrUpdate(Collection
<T
> newInstances
) {
441 //this is very ugly, I know, but for now I do not want to copy the saveAll method from CdmEntityDaoBase to genericDao
442 //and generally the saveAll method should work for other CdmBase types with generics removed
443 return (Map
<UUID
, T
>) originalSourceDao
.saveOrUpdateAll((Collection
)newInstances
);
448 public <T
extends CdmBase
> boolean isMergeable(T cdmBase1
, T cdmBase2
, IMergeStrategy mergeStrategy
) throws MergeException
{
449 return genericDao
.isMergeable(cdmBase1
, cdmBase2
, mergeStrategy
);
453 public List
<UUID
> listUuid(Class
<?
extends CdmBase
> clazz
) {
454 return genericDao
.listUuid(clazz
);