97a8368c7983ca654ea8f37fa7d175cbaaf5cd89
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / IdentifiableServiceBase.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.cdm.api.service;
12
13 import java.util.ArrayList;
14 import java.util.List;
15
16 import org.apache.log4j.Logger;
17 import org.hibernate.criterion.Criterion;
18 import org.springframework.transaction.annotation.Transactional;
19
20 import eu.etaxonomy.cdm.api.service.config.IIdentifiableEntityServiceConfigurator;
21 import eu.etaxonomy.cdm.api.service.pager.Pager;
22 import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
23 import eu.etaxonomy.cdm.model.common.CdmBase;
24 import eu.etaxonomy.cdm.model.common.ISourceable;
25 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
26 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
27 import eu.etaxonomy.cdm.model.common.LSID;
28 import eu.etaxonomy.cdm.model.common.UuidAndTitleCache;
29 import eu.etaxonomy.cdm.model.media.Rights;
30 import eu.etaxonomy.cdm.persistence.dao.common.IIdentifiableDao;
31 import eu.etaxonomy.cdm.persistence.query.MatchMode;
32 import eu.etaxonomy.cdm.persistence.query.OrderHint;
33 import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
34
35 public abstract class IdentifiableServiceBase<T extends IdentifiableEntity,DAO extends IIdentifiableDao<T>> extends AnnotatableServiceBase<T,DAO>
36 implements IIdentifiableEntityService<T>{
37
38 protected static final int UPDATE_TITLE_CACHE_DEFAULT_STEP_SIZE = 1000;
39 protected static final Logger logger = Logger.getLogger(IdentifiableServiceBase.class);
40
41 @Transactional(readOnly = true)
42 public Pager<Rights> getRights(T t, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
43 Integer numberOfResults = dao.countRights(t);
44
45 List<Rights> results = new ArrayList<Rights>();
46 if(numberOfResults > 0) { // no point checking again
47 results = dao.getRights(t, pageSize, pageNumber,propertyPaths);
48 }
49
50 return new DefaultPagerImpl<Rights>(pageNumber, numberOfResults, pageSize, results);
51 }
52
53 @Transactional(readOnly = true)
54 public Pager<IdentifiableSource> getSources(T t, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
55 Integer numberOfResults = dao.countSources(t);
56
57 List<IdentifiableSource> results = new ArrayList<IdentifiableSource>();
58 if(numberOfResults > 0) { // no point checking again
59 results = dao.getSources(t, pageSize, pageNumber,propertyPaths);
60 }
61
62 return new DefaultPagerImpl<IdentifiableSource>(pageNumber, numberOfResults, pageSize, results);
63 }
64
65 @Transactional(readOnly = true)
66 protected List<T> findByTitle(IIdentifiableEntityServiceConfigurator config){
67 return ((IIdentifiableDao)dao).findByTitle(config.getTitleSearchString(),
68 config.getMatchMode(), 0, -1, null);
69 // TODO: Implement parameters pageSize, pageNumber, and criteria
70 }
71
72 @Transactional(readOnly = false)
73 public T replace(T x, T y) {
74 return dao.replace(x, y);
75 }
76 /**
77 * FIXME Candidate for harmonization
78 * Given that this method is strongly typed, and generic, could we not simply expose it as
79 * List<T> findByTitle(String title) as it is somewhat less cumbersome. Admittedly, I don't
80 * understand what is going on with the configurators etc. so maybe there is a good reason for
81 * the design of this method.
82 * @param title
83 * @return
84 */
85 @Transactional(readOnly = true)
86 protected List<T> findCdmObjectsByTitle(String title){
87 return ((IIdentifiableDao)dao).findByTitle(title);
88 }
89
90 @Transactional(readOnly = true)
91 protected List<T> findCdmObjectsByTitle(String title, Class<T> clazz){
92 return ((IIdentifiableDao)dao).findByTitleAndClass(title, clazz);
93 }
94 @Transactional(readOnly = true)
95 protected List<T> findCdmObjectsByTitle(String title, CdmBase sessionObject){
96 return ((IIdentifiableDao)dao).findByTitle(title, sessionObject);
97 }
98
99 /*
100 * TODO - Migrated from CommonServiceBase
101 * (non-Javadoc)
102 * @see eu.etaxonomy.cdm.api.service.ICommonService#getSourcedObjectById(java.lang.String, java.lang.String)
103 */
104 @Transactional(readOnly = true)
105 public ISourceable getSourcedObjectByIdInSource(Class clazz, String idInSource, String idNamespace) {
106 ISourceable result = null;
107
108 List<T> list = dao.findOriginalSourceByIdInSource(idInSource, idNamespace);
109 if (! list.isEmpty()){
110 result = list.get(0);
111 }
112 return result;
113 }
114
115 /* (non-Javadoc)
116 * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#getUuidAndTitleCache()
117 */
118 @Transactional(readOnly = true)
119 public List<UuidAndTitleCache<T>> getUuidAndTitleCache() {
120 return dao.getUuidAndTitleCache();
121 }
122
123 @Transactional(readOnly = true)
124 public Pager<T> findByTitle(Class<? extends T> clazz, String queryString,MatchMode matchmode, List<Criterion> criteria, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
125 Integer numberOfResults = dao.countByTitle(clazz, queryString, matchmode, criteria);
126
127 List<T> results = new ArrayList<T>();
128 if(numberOfResults > 0) { // no point checking again
129 results = dao.findByTitle(clazz, queryString, matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths);
130 }
131
132 return new DefaultPagerImpl<T>(pageNumber, numberOfResults, pageSize, results);
133 }
134
135 @Transactional(readOnly = true)
136 public T find(LSID lsid) {
137 return dao.find(lsid);
138 }
139
140 @Transactional(readOnly = true)
141 public Pager<T> search(Class<? extends T> clazz, String queryString, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
142 Integer numberOfResults = dao.count(clazz,queryString);
143
144 List<T> results = new ArrayList<T>();
145 if(numberOfResults > 0) { // no point checking again
146 results = dao.search(clazz,queryString, pageSize, pageNumber, orderHints, propertyPaths);
147 }
148
149 return new DefaultPagerImpl<T>(pageNumber, numberOfResults, pageSize, results);
150 }
151
152 @Transactional(readOnly = false)
153 public void updateTitleCache(Class<? extends T> clazz) {
154 IIdentifiableEntityCacheStrategy<T> cacheStrategy = null;
155 updateTitleCache(clazz, UPDATE_TITLE_CACHE_DEFAULT_STEP_SIZE, cacheStrategy);
156 }
157
158
159 @Transactional(readOnly = false)
160 public void updateTitleCache(Class<? extends T> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<T> cacheStrategy) {
161 if (stepSize == null){
162 stepSize = UPDATE_TITLE_CACHE_DEFAULT_STEP_SIZE;
163 }
164
165 int count = dao.count(clazz);
166 for(int i = 0 ; i < count ; i = i + stepSize){
167 // not sure if such strict ordering is necessary here, but for safety reasons I do it
168 ArrayList<OrderHint> orderHints = new ArrayList<OrderHint>();
169 orderHints.add( new OrderHint("id", OrderHint.SortOrder.ASCENDING));
170 List<T> list = this.list(clazz, stepSize, i, orderHints, null);
171 for (T entity : list){
172 if (entity.isProtectedTitleCache() == false){
173 if (cacheStrategy != null){
174 entity.setCacheStrategy(cacheStrategy);
175 }
176 entity.setTitleCache(null);
177 setOtherCachesNull(entity);
178 entity.getTitleCache();
179 }
180 }
181 saveOrUpdateAll(list);
182
183 }
184 }
185
186 /**
187 * Needs override if not only the title cache should be set to null to
188 * generate the correct new title cache
189 */
190 protected void setOtherCachesNull(T entity) {
191 return;
192 }
193 }
194