Revert last commit (taxon node handling is done in taxeditor)
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / ServiceBase.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.Collection;
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.hibernate.LockOptions;
22 import org.hibernate.Session;
23 import org.springframework.context.ApplicationContext;
24 import org.springframework.context.ApplicationContextAware;
25 import org.springframework.dao.DataAccessException;
26 import org.springframework.transaction.annotation.Transactional;
27
28 import eu.etaxonomy.cdm.api.service.pager.Pager;
29 import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
30 import eu.etaxonomy.cdm.model.common.CdmBase;
31 import eu.etaxonomy.cdm.persistence.dao.common.ICdmEntityDao;
32 import eu.etaxonomy.cdm.persistence.dto.MergeResult;
33 import eu.etaxonomy.cdm.persistence.query.Grouping;
34 import eu.etaxonomy.cdm.persistence.query.OrderHint;
35
36 public abstract class ServiceBase<T extends CdmBase, DAO extends ICdmEntityDao<T>> implements IService<T>, ApplicationContextAware {
37 @SuppressWarnings("unused")
38 private static final Logger logger = Logger.getLogger(ServiceBase.class);
39
40 //flush after saving this number of objects
41 int flushAfterNo = 2000;
42 protected ApplicationContext appContext;
43
44 protected DAO dao;
45
46 @Override
47 @Transactional(readOnly = true)
48 public void lock(T t, LockOptions lockOptions) {
49 dao.lock(t, lockOptions);
50 }
51
52 @Override
53 @Transactional(readOnly = true)
54 public void refresh(T t, LockOptions lockOptions, List<String> propertyPaths) {
55 dao.refresh(t, lockOptions, propertyPaths);
56 }
57
58 @Override
59 @Transactional(readOnly = false)
60 public void clear() {
61 dao.clear();
62 }
63
64 @Override
65 @Transactional(readOnly = true)
66 public int count(Class<? extends T> clazz) {
67 return dao.count(clazz);
68 }
69
70 @Override
71 @Transactional(readOnly = false)
72 public DeleteResult delete(UUID persistentObjectUUID) {
73 T persistentObject = dao.findByUuid(persistentObjectUUID);
74 return delete(persistentObject);
75 }
76
77 @Override
78 @Transactional(readOnly = false)
79 public DeleteResult delete(Collection<UUID> persistentObjectUUIDs) {
80 DeleteResult result = new DeleteResult();
81 for(UUID persistentObjectUUID : persistentObjectUUIDs) {
82 T persistentObject = dao.findByUuid(persistentObjectUUID);
83 DeleteResult dr = delete(persistentObject);
84 result.includeResult(dr);
85 }
86 return result;
87 }
88
89 @Override
90 @Transactional(readOnly = false)
91 public DeleteResult delete(T persistentObject) {
92 DeleteResult result = new DeleteResult();
93 try{
94 dao.delete(persistentObject);
95 result.setCdmEntity(persistentObject);
96 } catch(DataAccessException e){
97 result.setError();
98 result.addException(e);
99 }
100 return result;
101 }
102
103
104
105 @Override
106 @Transactional(readOnly = true)
107 public boolean exists(UUID uuid) {
108 return dao.exists(uuid);
109 }
110
111 @Override
112 @Transactional(readOnly = true)
113 public List<T> find(Set<UUID> uuidSet) {
114 return dao.list(uuidSet, null, null, null, null);
115 }
116
117 @Override
118 @Transactional(readOnly = true)
119 public List<T> findById(Set<Integer> idSet) { //can't be called find(Set<Integer>) as this conflicts with find(Set<UUID)
120 return dao.listByIds(idSet, null, null, null, null);
121 }
122
123 @Override
124 @Transactional(readOnly = true)
125 public T find(UUID uuid) {
126 return uuid == null ? null : dao.findByUuid(uuid);
127 }
128
129 @Override
130 @Transactional(readOnly = true)
131 public T findWithoutFlush(UUID uuid) {
132 return uuid == null ? null : dao.findByUuidWithoutFlush(uuid);
133 }
134
135 @Override
136 @Transactional(readOnly = true)
137 public T find(int id) {
138 return dao.findById(id);
139 }
140
141 @Override
142 @Transactional(readOnly = true)
143 public Session getSession() {
144 return dao.getSession();
145 }
146
147 @Override
148 @Transactional(readOnly = true)
149 public List<Object[]> group(Class<? extends T> clazz,Integer limit, Integer start, List<Grouping> groups, List<String> propertyPaths) {
150 return dao.group(clazz, limit, start, groups, propertyPaths);
151 }
152
153 @Override
154 @Transactional(readOnly = true)
155 public <S extends T> List<S> list(Class<S> type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths){
156 return dao.list(type,limit, start, orderHints,propertyPaths);
157 }
158
159 @Override
160 @Transactional(readOnly = true)
161 public T load(UUID uuid) {
162 return uuid == null ? null : dao.load(uuid);
163 }
164
165 @Override
166 @Transactional(readOnly = true)
167 public T loadWithUpdate(UUID uuid) {
168 return load(uuid);
169 }
170
171 @Override
172 @Transactional(readOnly = true)
173 public T load(UUID uuid, List<String> propertyPaths){
174 return uuid == null ? null : dao.load(uuid, propertyPaths);
175 }
176
177 @Override
178 @Transactional(readOnly = true)
179 public List<T> load(List<UUID> uuids, List<String> propertyPaths){
180 if(uuids == null) {
181 return null;
182 }
183
184 List<T> entities = new ArrayList<T>();
185 for(UUID uuid : uuids) {
186 entities.add(uuid == null ? null : dao.load(uuid, propertyPaths));
187 }
188 return entities;
189 }
190
191 @Override
192 @Transactional(readOnly = false)
193 public T merge(T newInstance) {
194 return dao.merge(newInstance);
195 }
196
197 @Override
198 @Transactional(readOnly = false)
199 public MergeResult<T> merge(T newInstance, boolean returnTransientEntity) {
200 return dao.merge(newInstance, returnTransientEntity);
201 }
202
203 @Override
204 @Transactional(readOnly = false)
205 public List<T> merge(List<T> detachedObjects) {
206 List<T> mergedObjects = new ArrayList<T>();
207 for(T obj : detachedObjects) {
208 mergedObjects.add(dao.merge(obj));
209 }
210 return mergedObjects;
211 }
212
213 @Override
214 @Transactional(readOnly = false)
215 public List<MergeResult<T>> merge(List<T> detachedObjects, boolean returnTransientEntity) {
216 List<MergeResult<T>> mergedObjects = new ArrayList<MergeResult<T>>();
217 for(T obj : detachedObjects) {
218 mergedObjects.add(dao.merge(obj, returnTransientEntity));
219 }
220 return mergedObjects;
221 }
222
223 @Override
224 @Transactional(readOnly = true)
225 public <S extends T> Pager<S> page(Class<S> type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){
226 Integer numberOfResults = dao.count(type);
227 List<S> results = new ArrayList<S>();
228 pageNumber = pageNumber == null ? 0 : pageNumber;
229 if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
230 Integer start = pageSize == null ? 0 : pageSize * pageNumber;
231 results = dao.list(type, pageSize, start, orderHints,propertyPaths);
232 }
233 return new DefaultPagerImpl<S>(pageNumber, numberOfResults, pageSize, results);
234 }
235
236 @Override
237 @Transactional(readOnly = true)
238 public UUID refresh(T persistentObject) {
239 return dao.refresh(persistentObject);
240 }
241
242 /**
243 * FIXME Candidate for harmonization
244 * is this method used, and if so, should it be exposed in the service layer?
245 * it seems a bit incongruous that we use an ORM to hide the fact that there is a
246 * database, then expose a method that talks about "rows" . . .
247 */
248 @Override
249 @Transactional(readOnly = true)
250 public List<T> rows(String tableName, int limit, int start) {
251 return dao.rows(tableName, limit, start);
252 }
253
254 @Override
255 @Transactional(readOnly = false)
256 public Map<UUID, T> save(Collection<T> newInstances) {
257 return dao.saveAll(newInstances);
258 }
259
260 @Override
261 @Transactional(readOnly = false)
262 public T save(T newInstance) {
263 return dao.save(newInstance);
264 }
265
266 @Override
267 @Transactional(readOnly = false)
268 public UUID saveOrUpdate(T transientObject) {
269 return dao.saveOrUpdate(transientObject);
270 }
271
272 @Override
273 @Transactional(readOnly = false)
274 public Map<UUID, T> saveOrUpdate(Collection<T> transientInstances) {
275 return dao.saveOrUpdateAll(transientInstances);
276 }
277
278 @Override
279 public void setApplicationContext(ApplicationContext appContext){
280 this.appContext = appContext;
281 }
282
283
284 protected abstract void setDao(DAO dao);
285
286 @Override
287 @Transactional(readOnly = false)
288 public UUID update(T transientObject) {
289 return dao.update(transientObject);
290 }
291
292 @Override
293 @Transactional(readOnly = true)
294 public List<T> list(T example, Set<String> includeProperties, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
295 return dao.list(example, includeProperties, limit, start, orderHints, propertyPaths);
296 }
297
298
299
300 }