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
.ArrayList
;
13 import java
.util
.Arrays
;
14 import java
.util
.HashMap
;
15 import java
.util
.HashSet
;
16 import java
.util
.List
;
19 import java
.util
.UUID
;
21 import org
.apache
.log4j
.Logger
;
22 import org
.hibernate
.criterion
.Criterion
;
23 import org
.springframework
.transaction
.annotation
.Transactional
;
25 import eu
.etaxonomy
.cdm
.api
.service
.config
.IIdentifiableEntityServiceConfigurator
;
26 import eu
.etaxonomy
.cdm
.api
.service
.dto
.CdmEntityIdentifier
;
27 import eu
.etaxonomy
.cdm
.api
.service
.dto
.IdentifiedEntityDTO
;
28 import eu
.etaxonomy
.cdm
.api
.service
.dto
.MarkedEntityDTO
;
29 import eu
.etaxonomy
.cdm
.api
.service
.pager
.Pager
;
30 import eu
.etaxonomy
.cdm
.api
.service
.pager
.impl
.DefaultPagerImpl
;
31 import eu
.etaxonomy
.cdm
.common
.monitor
.DefaultProgressMonitor
;
32 import eu
.etaxonomy
.cdm
.common
.monitor
.IProgressMonitor
;
33 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
34 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
35 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
36 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableSource
;
37 import eu
.etaxonomy
.cdm
.model
.common
.LSID
;
38 import eu
.etaxonomy
.cdm
.model
.common
.MarkerType
;
39 import eu
.etaxonomy
.cdm
.model
.media
.Rights
;
40 import eu
.etaxonomy
.cdm
.model
.reference
.ISourceable
;
41 import eu
.etaxonomy
.cdm
.model
.term
.DefinedTerm
;
42 import eu
.etaxonomy
.cdm
.persistence
.dao
.common
.IIdentifiableDao
;
43 import eu
.etaxonomy
.cdm
.persistence
.dao
.common
.Restriction
;
44 import eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
.HibernateBeanInitializer
;
45 import eu
.etaxonomy
.cdm
.persistence
.dao
.initializer
.AutoPropertyInitializer
;
46 import eu
.etaxonomy
.cdm
.persistence
.dto
.UuidAndTitleCache
;
47 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
48 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
49 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
.SortOrder
;
50 import eu
.etaxonomy
.cdm
.strategy
.cache
.common
.IIdentifiableEntityCacheStrategy
;
51 import eu
.etaxonomy
.cdm
.strategy
.match
.DefaultMatchStrategy
;
52 import eu
.etaxonomy
.cdm
.strategy
.match
.IMatchStrategyEqual
;
53 import eu
.etaxonomy
.cdm
.strategy
.match
.IMatchable
;
54 import eu
.etaxonomy
.cdm
.strategy
.match
.MatchException
;
55 import eu
.etaxonomy
.cdm
.strategy
.merge
.IMergable
;
56 import eu
.etaxonomy
.cdm
.strategy
.merge
.IMergeStrategy
;
57 import eu
.etaxonomy
.cdm
.strategy
.merge
.MergeException
;
59 public abstract class IdentifiableServiceBase
<T
extends IdentifiableEntity
, DAO
extends IIdentifiableDao
<T
>> extends AnnotatableServiceBase
<T
,DAO
>
60 implements IIdentifiableEntityService
<T
>{
63 protected static final int UPDATE_TITLE_CACHE_DEFAULT_STEP_SIZE
= 1000;
64 protected static final Logger logger
= Logger
.getLogger(IdentifiableServiceBase
.class);
67 @Transactional(readOnly
= true)
68 public Pager
<Rights
> getRights(T t
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
69 long numberOfResults
= dao
.countRights(t
);
71 List
<Rights
> results
= new ArrayList
<>();
72 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
73 results
= dao
.getRights(t
, pageSize
, pageNumber
,propertyPaths
);
76 return new DefaultPagerImpl
<>(pageNumber
, numberOfResults
, pageSize
, results
);
80 @Transactional(readOnly
= true)
81 public Pager
<IdentifiableSource
> getSources(T t
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
82 long numberOfResults
= dao
.countSources(t
);
84 List
<IdentifiableSource
> results
= new ArrayList
<>();
85 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
86 results
= dao
.getSources(t
, pageSize
, pageNumber
,propertyPaths
);
89 return new DefaultPagerImpl
<>(pageNumber
, numberOfResults
, pageSize
, results
);
93 @Transactional(readOnly
= false)
95 public T
replace(T x
, T y
) {
96 return dao
.replace(x
, y
);
100 * TODO - Migrated from CommonServiceBase
102 @Transactional(readOnly
= true)
104 public ISourceable
getSourcedObjectByIdInSource(Class clazz
, String idInSource
, String idNamespace
) {
105 ISourceable
<?
> result
= null;
107 List
<T
> list
= dao
.findOriginalSourceByIdInSource(idInSource
, idNamespace
);
108 if (! list
.isEmpty()){
109 result
= list
.get(0);
114 @Transactional(readOnly
= true)
116 public List
<UuidAndTitleCache
<T
>> getUuidAndTitleCache(Integer limit
, String pattern
) {
117 return dao
.getUuidAndTitleCache(limit
, pattern
);
120 @Transactional(readOnly
= true)
122 public <S
extends T
> List
<UuidAndTitleCache
<S
>> getUuidAndTitleCache(Class
<S
> clazz
,Integer limit
, String pattern
) {
123 return dao
.getUuidAndTitleCache(clazz
, limit
, pattern
);
126 @Transactional(readOnly
= true)
128 public String
getTitleCache(UUID uuid
, boolean refresh
){
129 return dao
.getTitleCache(uuid
, refresh
);
132 @Transactional(readOnly
= true)
134 public <S
extends T
> Pager
<S
> findByTitle(Class
<S
> clazz
, String queryString
,MatchMode matchmode
, List
<Criterion
> criteria
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
135 long numberOfResults
= dao
.countByTitle(clazz
, queryString
, matchmode
, criteria
);
137 List
<S
> results
= new ArrayList
<>();
138 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
139 results
= dao
.findByTitle(clazz
, queryString
, matchmode
, criteria
, pageSize
, pageNumber
, orderHints
, propertyPaths
);
142 return new DefaultPagerImpl
<>(pageNumber
, numberOfResults
, pageSize
, results
);
145 @Transactional(readOnly
= true)
147 public <S
extends T
> Pager
<S
> findByTitleWithRestrictions(Class
<S
> clazz
, String queryString
, MatchMode matchmode
, List
<Restriction
<?
>> restrictions
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
148 long numberOfResults
= dao
.countByTitleWithRestrictions(clazz
, queryString
, matchmode
, restrictions
);
150 List
<S
> results
= new ArrayList
<>();
151 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
152 results
= dao
.findByTitleWithRestrictions(clazz
, queryString
, matchmode
, restrictions
, pageSize
, pageNumber
, orderHints
, propertyPaths
);
155 return new DefaultPagerImpl
<>(pageNumber
, numberOfResults
, pageSize
, results
);
159 @Transactional(readOnly
= true)
161 public <S
extends T
> Pager
<S
> findByTitle(IIdentifiableEntityServiceConfigurator
<S
> config
){
163 boolean withRestrictions
= config
.getRestrictions() != null && !config
.getRestrictions().isEmpty();
164 boolean withCriteria
= config
.getCriteria() != null && !config
.getCriteria().isEmpty();
166 if(withCriteria
&& withRestrictions
){
167 throw new RuntimeException("Restrictions and Criteria can not be used at the same time");
168 } else if(withRestrictions
){
169 return findByTitleWithRestrictions((Class
<S
>)config
.getClazz(), config
.getTitleSearchStringSqlized(), config
.getMatchMode(), config
.getRestrictions(), config
.getPageSize(), config
.getPageNumber(), config
.getOrderHints(), config
.getPropertyPaths());
171 return findByTitle((Class
<S
>) config
.getClazz(), config
.getTitleSearchStringSqlized(), config
.getMatchMode(), config
.getCriteria(), config
.getPageSize(), config
.getPageNumber(), config
.getOrderHints(), config
.getPropertyPaths());
175 @Transactional(readOnly
= true)
177 public <S
extends T
> List
<S
> listByTitle(Class
<S
> clazz
, String queryString
,MatchMode matchmode
, List
<Criterion
> criteria
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
178 long numberOfResults
= dao
.countByTitle(clazz
, queryString
, matchmode
, criteria
);
180 List
<S
> results
= new ArrayList
<>();
181 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
182 results
= dao
.findByTitle(clazz
, queryString
, matchmode
, criteria
, pageSize
, pageNumber
, orderHints
, propertyPaths
);
187 @Transactional(readOnly
= true)
189 public <S
extends T
> List
<S
> listByTitleWithRestrictions(Class
<S
> clazz
, String queryString
,MatchMode matchmode
, List
<Restriction
<?
>> restrictions
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
190 long numberOfResults
= dao
.countByTitleWithRestrictions(clazz
, queryString
, matchmode
, restrictions
);
192 List
<S
> results
= new ArrayList
<>();
193 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
194 results
= dao
.findByTitleWithRestrictions(clazz
, queryString
, matchmode
, restrictions
, pageSize
, pageNumber
, orderHints
, propertyPaths
);
199 @Transactional(readOnly
= true)
201 public Pager
<String
> findTitleCache(Class
<?
extends T
> clazz
, String queryString
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, MatchMode matchMode
){
202 long numberOfResults
= dao
.countTitleCache(clazz
, queryString
, matchMode
);
204 List
<String
> results
= new ArrayList
<>();
205 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
206 results
= dao
.findTitleCache(clazz
, queryString
, pageSize
, pageNumber
, orderHints
, matchMode
);
209 r
+= numberOfResults
;
211 return new DefaultPagerImpl
<>(pageNumber
, r
, pageSize
, results
);
214 @Transactional(readOnly
= true)
216 public <S
extends T
> List
<S
> listByReferenceTitle(Class
<S
> clazz
, String queryString
,MatchMode matchmode
, List
<Criterion
> criteria
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
217 long numberOfResults
= dao
.countByReferenceTitle(clazz
, queryString
, matchmode
, criteria
);
219 List
<S
> results
= new ArrayList
<>();
220 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
221 results
= dao
.findByReferenceTitle(clazz
, queryString
, matchmode
, criteria
, pageSize
, pageNumber
, orderHints
, propertyPaths
);
226 @Transactional(readOnly
= true)
228 public <S
extends T
> List
<S
> listByReferenceTitleWithRestrictions(Class
<S
> clazz
, String queryString
,MatchMode matchmode
, List
<Restriction
<?
>> restrictions
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
229 long numberOfResults
= dao
.countByReferenceTitleWithRestrictions(clazz
, queryString
, matchmode
, restrictions
);
231 List
<S
> results
= new ArrayList
<>();
232 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
233 results
= dao
.findByReferenceTitleWithRestrictions(clazz
, queryString
, matchmode
, restrictions
, pageSize
, pageNumber
, orderHints
, propertyPaths
);
238 @Transactional(readOnly
= true)
240 public T
find(LSID lsid
) {
241 return dao
.find(lsid
);
244 @Transactional(readOnly
= true)
246 public Pager
<T
> search(Class
<?
extends T
> clazz
, String queryString
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
247 // public <S extends T> Pager<S> search(Class<S> clazz, String queryString, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
248 long numberOfResults
= dao
.count(clazz
,queryString
);
250 List
<T
> results
= new ArrayList
<>();
251 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
252 results
= dao
.search(clazz
,queryString
, pageSize
, pageNumber
, orderHints
, propertyPaths
);
255 return new DefaultPagerImpl
<>(pageNumber
, numberOfResults
, pageSize
, results
);
259 @Transactional(readOnly
= false)
260 public UpdateResult
updateCaches() {
261 return updateCaches(null, null, null, null);
264 @Transactional(readOnly
= false) //TODO check transactional behavior, e.g. what happens with the session if count is very large
265 protected <S
extends T
> UpdateResult
updateCachesImpl(Class
<S
> clazz
, Integer stepSize
, IIdentifiableEntityCacheStrategy
<T
> cacheStrategy
, IProgressMonitor subMonitor
) {
266 if (stepSize
== null){
267 stepSize
= UPDATE_TITLE_CACHE_DEFAULT_STEP_SIZE
;
269 if (subMonitor
== null){
270 subMonitor
= DefaultProgressMonitor
.NewInstance();
272 UpdateResult result
= new UpdateResult();
273 long count
= dao
.count(clazz
);
274 long countUpdated
= 0;
277 subMonitor
.beginTask("update titles for " + clazz
.getSimpleName(), Long
.valueOf(count
).intValue());
278 subMonitor
.setTaskName("Update " + clazz
.getSimpleName());
281 //SubProgressMonitor subMonitor = monitor.("update titles for " + clazz.getSimpleName(), Long.valueOf(count).intValue());
283 Set
<CdmEntityIdentifier
> updatedCdmIds
= new HashSet();
284 for(int i
= 0 ; i
< count
; i
= i
+ stepSize
){
285 // not sure if such strict ordering is necessary here, but for safety reasons I do it
286 ArrayList
<OrderHint
> orderHints
= new ArrayList
<>();
287 orderHints
.add( new OrderHint("id", OrderHint
.SortOrder
.ASCENDING
));
290 Map
<Class
<?
extends CdmBase
>, AutoPropertyInitializer
<CdmBase
>> oldAutoInit
= switchOfAutoinitializer();
291 List
<S
> list
= this.list(clazz
, stepSize
, i
, orderHints
, null);
292 switchOnOldAutoInitializer(oldAutoInit
);
294 List
<T
> entitiesToUpdate
= new ArrayList
<>();
295 for (T entity
: list
){
296 entity
= HibernateProxyHelper
.deproxy(entity
);
297 if (entity
.updateCaches(cacheStrategy
)){
299 updatedCdmIds
.add(new CdmEntityIdentifier(entity
.getId(), clazz
));
302 subMonitor
.internalWorked(1);
306 if (subMonitor
.isCanceled()){
310 result
.addUpdatedCdmIds(updatedCdmIds
);
319 * Brings back all auto initializers to the bean initializer
320 * @see #switchOfAutoinitializer()
323 protected void switchOnOldAutoInitializer(
324 Map
<Class
<?
extends CdmBase
>, AutoPropertyInitializer
<CdmBase
>> oldAutoInit
) {
325 HibernateBeanInitializer initializer
= (HibernateBeanInitializer
)this.appContext
.getBean("defaultBeanInitializer");
326 initializer
.setBeanAutoInitializers(oldAutoInit
);
330 * Removes all auto initializers from the bean initializer
332 * @see #switchOnOldAutoInitializer(Map)
335 protected Map
<Class
<?
extends CdmBase
>, AutoPropertyInitializer
<CdmBase
>> switchOfAutoinitializer() {
336 HibernateBeanInitializer initializer
= (HibernateBeanInitializer
)this.appContext
.getBean("defaultBeanInitializer");
337 Map
<Class
<?
extends CdmBase
>, AutoPropertyInitializer
<CdmBase
>> oldAutoInitializers
= initializer
.getBeanAutoInitializers();
338 Map
<Class
<?
extends CdmBase
>, AutoPropertyInitializer
<CdmBase
>> map
= new HashMap
<>();
339 initializer
.setBeanAutoInitializers(map
);
340 return oldAutoInitializers
;
343 private class DeduplicateState
{
344 String lastTitleCache
;
345 Integer pageSize
= 50;
348 boolean isCompleted
= false;
353 @Transactional(readOnly
= false)
354 public int deduplicate(Class
<?
extends T
> clazz
, IMatchStrategyEqual matchStrategy
, IMergeStrategy mergeStrategy
) {
355 DeduplicateState dedupState
= new DeduplicateState();
358 logger
.warn("Deduplication clazz must not be null!");
361 if (! ( IMatchable
.class.isAssignableFrom(clazz
) && IMergable
.class.isAssignableFrom(clazz
) ) ){
362 logger
.warn("Deduplication implemented only for classes implementing IMatchable and IMergeable. No deduplication performed!");
365 Class matchableClass
= clazz
;
366 if (matchStrategy
== null){
367 matchStrategy
= DefaultMatchStrategy
.NewInstance(matchableClass
);
369 List
<T
> nextGroup
= new ArrayList
<>();
372 // double countTotal = count(clazz);
374 // Number countPagesN = Math.ceil(countTotal/dedupState.pageSize.doubleValue()) ;
375 // int countPages = countPagesN.intValue();
378 List
<OrderHint
> orderHints
= Arrays
.asList(new OrderHint
[]{new OrderHint("titleCache", SortOrder
.ASCENDING
)});
380 while (! dedupState
.isCompleted
){
382 List
<?
extends T
> objectList
= getPages(clazz
, dedupState
, orderHints
);
383 //after each page check if any changes took place
384 int nUnEqualPages
= handleAllPages(objectList
, dedupState
, nextGroup
, matchStrategy
, mergeStrategy
);
385 nUnEqualPages
= nUnEqualPages
+ dedupState
.pageSize
* dedupState
.startPage
;
386 //refresh start page counter
387 int finishedPages
= nUnEqualPages
/ dedupState
.pageSize
;
388 dedupState
.startPage
= finishedPages
;
391 result
+= handleLastGroup(nextGroup
, matchStrategy
, mergeStrategy
);
396 private int handleAllPages(List
<?
extends T
> objectList
, DeduplicateState dedupState
, List
<T
> nextGroup
, IMatchStrategyEqual matchStrategy
, IMergeStrategy mergeStrategy
) {
398 for (T object
: objectList
){
399 String currentTitleCache
= object
.getTitleCache();
400 if (currentTitleCache
!= null && currentTitleCache
.equals(dedupState
.lastTitleCache
)){
402 nextGroup
.add(object
);
405 dedupState
.result
+= handleLastGroup(nextGroup
, matchStrategy
, mergeStrategy
);
406 nextGroup
= new ArrayList
<>();
407 nextGroup
.add(object
);
410 dedupState
.lastTitleCache
= currentTitleCache
;
412 handleLastGroup(nextGroup
, matchStrategy
, mergeStrategy
);
416 private <S
extends T
> List
<S
> getPages(Class
<S
> clazz
, DeduplicateState dedupState
, List
<OrderHint
> orderHints
) {
417 List
<S
> result
= new ArrayList
<>();
418 for (int pageNo
= dedupState
.startPage
; pageNo
< dedupState
.startPage
+ dedupState
.nPages
; pageNo
++){
419 List
<S
> objectList
= listByTitleWithRestrictions(clazz
, null, null, null, dedupState
.pageSize
, pageNo
, orderHints
, null);
420 result
.addAll(objectList
);
422 if (result
.size()< dedupState
.nPages
* dedupState
.pageSize
){
423 dedupState
.isCompleted
= true;
428 private int handleLastGroup(List
<T
> group
, IMatchStrategyEqual matchStrategy
, IMergeStrategy mergeStrategy
) {
430 int size
= group
.size();
431 Set
<Integer
> exclude
= new HashSet
<>(); //set to collect all objects, that have been merged already
432 for (int i
= 0; i
< size
- 1; i
++){
433 if (exclude
.contains(i
)){
436 for (int j
= i
+ 1; j
< size
; j
++){
437 if (exclude
.contains(j
)){
440 T firstObject
= group
.get(i
);
441 T secondObject
= group
.get(j
);
444 if (matchStrategy
.invoke((IMatchable
)firstObject
, (IMatchable
)secondObject
).isSuccessful()){
445 commonService
.merge((IMergable
)firstObject
, (IMergable
)secondObject
, mergeStrategy
);
449 } catch (MatchException e
) {
450 logger
.warn("MatchException when trying to match " + firstObject
.getTitleCache());
452 } catch (MergeException e
) {
453 logger
.warn("MergeException when trying to merge " + firstObject
.getTitleCache());
461 @Transactional(readOnly
= true)
463 public long countByTitle(Class
<?
extends T
> clazz
, String queryString
,MatchMode matchmode
, List
<Criterion
> criteria
){
464 long numberOfResults
= dao
.countByTitle(clazz
, queryString
, matchmode
, criteria
);
466 return numberOfResults
;
469 @Transactional(readOnly
= true)
471 public long countByTitleWithRestrictions(Class
<?
extends T
> clazz
, String queryString
, MatchMode matchmode
, List
<Restriction
<?
>> restrictions
){
472 long numberOfResults
= dao
.countByTitleWithRestrictions(clazz
, queryString
, matchmode
, restrictions
);
474 return numberOfResults
;
477 @Transactional(readOnly
= true)
479 public long countByTitle(IIdentifiableEntityServiceConfigurator
<T
> config
){
481 boolean withRestrictions
= config
.getRestrictions() != null && !config
.getRestrictions().isEmpty();
482 boolean withCriteria
= config
.getCriteria() != null && !config
.getCriteria().isEmpty();
484 if(withCriteria
&& withRestrictions
){
485 throw new RuntimeException("Restrictions and Criteria can not be used at the same time");
486 } else if(withRestrictions
){
487 return countByTitleWithRestrictions(config
.getClazz(), config
.getTitleSearchStringSqlized(), config
.getMatchMode(), config
.getRestrictions());
489 return countByTitle(config
.getClazz(), config
.getTitleSearchStringSqlized(), config
.getMatchMode(), config
.getCriteria());
495 @Transactional(readOnly
= true)
496 public <S
extends T
> Pager
<IdentifiedEntityDTO
<S
>> findByIdentifier(
497 Class
<S
> clazz
, String identifier
, DefinedTerm identifierType
, MatchMode matchmode
,
498 boolean includeEntity
, Integer pageSize
,
499 Integer pageNumber
, List
<String
> propertyPaths
) {
501 long numberOfResults
= dao
.countByIdentifier(clazz
, identifier
, identifierType
, matchmode
);
502 List
<Object
[]> daoResults
= new ArrayList
<>();
503 if(numberOfResults
> 0) { // no point checking again
504 daoResults
= dao
.findByIdentifier(clazz
, identifier
, identifierType
,
505 matchmode
, includeEntity
, pageSize
, pageNumber
, propertyPaths
);
508 List
<IdentifiedEntityDTO
<S
>> result
= new ArrayList
<>();
509 for (Object
[] daoObj
: daoResults
){
511 result
.add(new IdentifiedEntityDTO
<>((DefinedTerm
)daoObj
[0], (String
)daoObj
[1], (S
)daoObj
[2]));
513 result
.add(new IdentifiedEntityDTO
<>((DefinedTerm
)daoObj
[0], (String
)daoObj
[1], (UUID
)daoObj
[2], (String
)daoObj
[3], null));
516 return new DefaultPagerImpl
<>(pageNumber
, numberOfResults
, pageSize
, result
);
520 @Transactional(readOnly
= true)
521 public <S
extends T
> List
<IdentifiedEntityDTO
<S
>> listByIdentifier(
522 Class
<S
> clazz
, String identifier
, DefinedTerm identifierType
, MatchMode matchmode
,
523 boolean includeEntity
, List
<String
> propertyPaths
, Integer limit
) {
525 long numberOfResults
= dao
.countByIdentifier(clazz
, identifier
, identifierType
, matchmode
);
526 List
<Object
[]> daoResults
= new ArrayList
<>();
527 if(numberOfResults
> 0) { // no point checking again
528 daoResults
= dao
.findByIdentifier(clazz
, identifier
, identifierType
,
529 matchmode
, includeEntity
, limit
, 0, propertyPaths
);
532 List
<IdentifiedEntityDTO
<S
>> result
= new ArrayList
<>();
533 for (Object
[] daoObj
: daoResults
){
535 result
.add(new IdentifiedEntityDTO
<>((DefinedTerm
)daoObj
[0], (String
)daoObj
[1], (S
)daoObj
[2]));
537 result
.add(new IdentifiedEntityDTO
<>((DefinedTerm
)daoObj
[0], (String
)daoObj
[1], (UUID
)daoObj
[2], (String
)daoObj
[3], null));
545 @Transactional(readOnly
= true)
546 public <S
extends T
> Pager
<MarkedEntityDTO
<S
>> findByMarker(
547 Class
<S
> clazz
, MarkerType markerType
, Boolean markerValue
,
548 boolean includeEntity
, Integer pageSize
,
549 Integer pageNumber
, List
<String
> propertyPaths
) {
551 Long numberOfResults
= dao
.countByMarker(clazz
, markerType
, markerValue
);
552 List
<Object
[]> daoResults
= new ArrayList
<>();
553 if(numberOfResults
> 0) { // no point checking again
554 daoResults
= dao
.findByMarker(clazz
, markerType
, markerValue
, includeEntity
,
555 pageSize
, pageNumber
, propertyPaths
);
558 List
<MarkedEntityDTO
<S
>> result
= new ArrayList
<>();
559 for (Object
[] daoObj
: daoResults
){
561 result
.add(new MarkedEntityDTO
<>((MarkerType
)daoObj
[0], (Boolean
)daoObj
[1], (S
)daoObj
[2]));
563 result
.add(new MarkedEntityDTO
<>((MarkerType
)daoObj
[0], (Boolean
)daoObj
[1], (UUID
)daoObj
[2], (String
)daoObj
[3]));
566 return new DefaultPagerImpl
<>(pageNumber
, numberOfResults
, pageSize
, result
);
570 @Transactional(readOnly
= true)
571 public List
<UuidAndTitleCache
<T
>> findUuidAndTitleCacheByMarker(Integer limit
, String pattern
,
572 MarkerType markerType
){
574 Long numberOfResults
= dao
.countByMarker(null, markerType
, null);
575 List
<UuidAndTitleCache
<T
>> daoResults
= new ArrayList
<>();
576 if(numberOfResults
> 0) { // no point checking again
577 daoResults
= dao
.getUuidAndTitleCacheByMarker(limit
, pattern
, markerType
);