add additional method for more specific return type of CommonService.getSourcedObject...
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / CommonServiceImpl.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
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.
8 */
9
10 package eu.etaxonomy.cdm.api.service;
11
12 import java.util.Collection;
13 import java.util.HashMap;
14 import java.util.Iterator;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Set;
18 import java.util.UUID;
19
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;
24
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;
42
43
44 @Service
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);
49
50
51 @Autowired
52 private IOriginalSourceDao originalSourceDao;
53
54
55 @Autowired
56 private ICdmGenericDao genericDao;
57
58
59 @Override
60 public <T extends CdmBase> T findWithUpdate(Class<T> clazz, int id){
61 return genericDao.find(clazz, id);
62 }
63
64 @Override
65 public <T extends CdmBase> T find(Class<T> clazz, int id){
66 return genericDao.find(clazz, id);
67 }
68
69 @Override
70 public <T extends CdmBase> T find(Class<T> clazz, int id, List<String> propertyPaths){
71 return genericDao.find(clazz, id, propertyPaths);
72 }
73
74 @Override
75 public <T extends CdmBase> T find(Class<T> clazz, UUID uuid) {
76 return uuid == null ? null : genericDao.find(clazz, uuid);
77 }
78
79 @Override
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);
82 }
83
84 @Override
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);
87 return list;
88 }
89
90 @Override
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);
93 return list;
94 }
95
96
97 @Override
98 public <S extends ISourceable> S getSourcedObjectByIdInSource(Class<S> clazz, String idInSource, String idNamespace) {
99 S result = null;
100 List<S> list = originalSourceDao.findOriginalSourceByIdInSource(clazz, idInSource, idNamespace);
101 if (! list.isEmpty()){
102 result = list.get(0);
103 }return result;
104 }
105
106
107 @Override
108 public Set<CdmBase> getReferencingObjects(CdmBase referencedCdmBase){
109 return this.genericDao.getReferencingObjects(referencedCdmBase);
110 }
111
112 @Override
113 public long getReferencingObjectsCount(CdmBase referencedCdmBase){
114 return this.genericDao.getReferencingObjectsCount(referencedCdmBase);
115 }
116
117 @Override
118 public Set<CdmBase> getReferencingObjectsForDeletion(CdmBase referencedCdmBase){
119 return this.genericDao.getReferencingObjectsForDeletion(referencedCdmBase);
120 }
121 // try {
122 // Set<Class<? extends CdmBase>> allCdmClasses = genericDao.getAllCdmClasses(false); //findAllCdmClasses();
123 //
124 // referencedCdmBase = (CdmBase)HibernateProxyHelper.deproxy(referencedCdmBase);
125 // Class referencedClass = referencedCdmBase.getClass();
126 // Set<CdmBase> result = new HashSet<>();
127 // logger.debug("Referenced Class: " + referencedClass.getName());
128 //
129 // for (Class<? extends CdmBase> cdmClass : allCdmClasses){
130 // Set<Field> fields = getFields(cdmClass);
131 // for (Field field: fields){
132 // Class<?> type = field.getType();
133 // //class
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);
138 // }
139 // //interface
140 // }else if (type.isAssignableFrom(referencedClass)){
141 // handleSingleClass(referencedClass, type, field, cdmClass, result, referencedCdmBase, false);
142 // }else if (Collection.class.isAssignableFrom(type)){
143 //
144 // if (checkIsSetOfType(field, referencedClass, type) == true){
145 // handleSingleClass(referencedClass, type, field, cdmClass, result, referencedCdmBase, true);
146 // }
147 // }
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);
153 //// }
154 //// }
155 // }
156 // }
157 // return result;
158 // } catch (Exception e) {
159 // e.printStackTrace();
160 // throw new RuntimeException(e);
161 // }
162 //
163 // }
164 //
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;
174 // try {
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;
181 // }else{
182 // logger.warn("Unknown Type");
183 // return false;
184 // }
185 // if (CdmBase.class.isAssignableFrom(collectionClass) && collectionClass.isAssignableFrom(referencedClass) ){
186 // return true;
187 // }
188 // } catch (Exception e) {
189 // logger.warn(e.getMessage());
190 // }
191 // }else{
192 // logger.warn("Length of arguments <> 1");
193 // }
194 // }else{
195 // logger.warn("Not a generic type of type ParameterizedTypeImpl");
196 // }
197 // return false;
198 // }
199 //
200 //
201 //
202 //
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);
208 //
209 // logger.debug(methodName + "\t\t" + className + "\t\t" + returnTypeName);
210 //// result_old.add(method);
211 // result.addAll(getCdmBasesByFieldAndClass(field, itemClass, cdmClass, value, isCollection));
212 // }
213 // return true;
214 // }
215 //
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);
221 // }
222 // }
223 // Class superclass = clazz.getSuperclass();
224 // if (CdmBase.class.isAssignableFrom(superclass)){
225 // result.addAll(getFields(superclass));
226 // }
227 // return result;
228 // }
229 //
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));
234 // }else{
235 // result.addAll(genericDao.getCdmBasesByFieldAndClass(otherClazz, field.getName(), item));
236 // }
237 // return result;
238 // }
239
240 @Override
241 public List getHqlResult(String hqlQuery){
242 return genericDao.getHqlResult(hqlQuery);
243 }
244
245 @Override
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());
249 }
250 genericDao.merge((CdmBase)mergeFirst, (CdmBase)mergeSecond, mergeStrategy);
251 }
252
253 @Override
254 public <T extends IMergable> void merge(T mergeFirst, T mergeSecond, Class<? extends CdmBase> clazz) throws MergeException {
255 IMergeStrategy mergeStrategy;
256 if (clazz == null){
257 mergeStrategy = DefaultMergeStrategy.NewInstance(((CdmBase)mergeFirst).getClass());
258 } else {
259 mergeStrategy = DefaultMergeStrategy.NewInstance(clazz);
260 }
261 merge(mergeFirst, mergeSecond, mergeStrategy);
262 }
263
264 @Override
265 @Transactional(readOnly = false)
266 @Deprecated
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);
273 }
274
275 @Override
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.");
283 }
284 if (mergeSecond == null){
285 throw new MergeException("The merge candidate is not available anymore.");
286 }
287 mergeStrategy = DefaultMergeStrategy.NewInstance(clazz);
288 merge(mergeFirst, mergeSecond, mergeStrategy);
289 }
290
291 @Override
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);
295 }
296
297
298 @Override
299 public <T extends IMatchable> List<T> findMatching(T objectToMatch, IMatchStrategyEqual matchStrategy) throws MatchException {
300 if (matchStrategy == null){
301 matchStrategy = DefaultMatchStrategy.NewInstance(((objectToMatch).getClass()));
302 }
303 return genericDao.findMatching(objectToMatch, matchStrategy);
304 }
305
306
307
308 /* (non-Javadoc)
309 * @see eu.etaxonomy.cdm.api.service.ICommonService#findMatching(eu.etaxonomy.cdm.strategy.match.IMatchable, eu.etaxonomy.cdm.strategy.match.MatchStrategyConfigurator.MatchStrategy)
310 */
311 @Override
312 public <T extends IMatchable> List<T> findMatching(T objectToMatch, MatchStrategy strategy) throws MatchException {
313 return findMatching(objectToMatch, MatchStrategyConfigurator.getMatchStrategy(strategy));
314 }
315
316 // /* (non-Javadoc)
317 // * @see eu.etaxonomy.cdm.api.service.IService#list(java.lang.Class, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
318 // */
319 // @Override
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");
324 // return null;
325 // }
326
327
328 @Transactional(readOnly = false)
329 @Override
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);
335 }
336 }
337
338 @Override
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);
345 }
346 return result;
347 }
348
349 @Override
350 public Object initializeCollection(UUID ownerUuid, String fieldName) {
351 return genericDao.initializeCollection(ownerUuid, fieldName);
352
353 }
354
355 @Override
356 public Object initializeCollection(UUID ownerUuid, String fieldName, List<String> propertyPaths) {
357 return genericDao.initializeCollection(ownerUuid, fieldName, propertyPaths);
358
359 }
360
361 @Override
362 public boolean isEmpty(UUID ownerUuid, String fieldName) {
363 return genericDao.isEmpty(ownerUuid, fieldName);
364
365 }
366
367 @Override
368 public int size(UUID ownerUuid, String fieldName) {
369 return genericDao.size(ownerUuid, fieldName);
370 }
371
372
373 @Override
374 public Object get(UUID ownerUuid, String fieldName, int index) {
375 return genericDao.get(ownerUuid, fieldName, index);
376 }
377
378 @Override
379 public boolean contains(UUID ownerUuid, String fieldName, Object element) {
380 return genericDao.contains(ownerUuid, fieldName, element);
381 }
382
383 @Override
384 public boolean containsKey(UUID ownerUuid, String fieldName, Object key) {
385 return genericDao.containsKey(ownerUuid, fieldName, key);
386 }
387
388 @Override
389 public boolean containsValue(UUID ownerUuid, String fieldName, Object value) {
390 return genericDao.containsValue(ownerUuid, fieldName, value);
391 }
392
393 @Override
394 @Transactional(readOnly = false)
395 public void createFullSampleData() {
396 genericDao.createFullSampleData();
397 }
398
399
400
401 @Override
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);
404 }
405
406 @Override
407 public <S extends CdmBase> long count(Class<S> type) {
408 return genericDao.count(type);
409 }
410
411 @Override
412 @Transactional(readOnly = false)
413 public CdmBase save(CdmBase newInstance) {
414 return genericDao.save(newInstance);
415 }
416
417 @Override
418 @Transactional(readOnly = false)
419 public UUID delete(CdmBase instance) {
420 return genericDao.delete(instance);
421 }
422
423 @Override
424 @Transactional(readOnly = false)
425 public UUID saveOrUpdate(CdmBase newInstance) {
426 return genericDao.saveOrUpdate(newInstance);
427 }
428
429
430 @Override
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);
436 }
437
438 @Override
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);
444 }
445
446
447 @Override
448 public <T extends CdmBase> boolean isMergeable(T cdmBase1, T cdmBase2, IMergeStrategy mergeStrategy) throws MergeException {
449 return genericDao.isMergeable(cdmBase1, cdmBase2, mergeStrategy);
450 }
451
452 @Override
453 public List<UUID> listUuid(Class<? extends CdmBase> clazz) {
454 return genericDao.listUuid(clazz);
455 }
456
457 }