better use of generics in service layer and persistence list methods
[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.LockMode;
22 import org.hibernate.Session;
23 import org.springframework.context.ApplicationContext;
24 import org.springframework.context.ApplicationContextAware;
25 import org.springframework.transaction.annotation.Transactional;
26
27 import eu.etaxonomy.cdm.api.service.exception.ReferencedObjectUndeletableException;
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.query.Grouping;
33 import eu.etaxonomy.cdm.persistence.query.OrderHint;
34
35 public abstract class ServiceBase<T extends CdmBase, DAO extends ICdmEntityDao<T>> implements IService<T>, ApplicationContextAware {
36 @SuppressWarnings("unused")
37 private static final Logger logger = Logger.getLogger(ServiceBase.class);
38
39 //flush after saving this number of objects
40 int flushAfterNo = 2000;
41 protected ApplicationContext appContext;
42
43 protected DAO dao;
44
45 @Override
46 @Transactional(readOnly = true)
47 public void lock(T t, LockMode lockMode) {
48 dao.lock(t, lockMode);
49 }
50
51 @Override
52 @Transactional(readOnly = true)
53 public void refresh(T t, LockMode lockMode, List<String> propertyPaths) {
54 dao.refresh(t, lockMode, propertyPaths);
55 }
56
57 @Override
58 @Transactional(readOnly = false)
59 public void clear() {
60 dao.clear();
61 }
62
63 @Override
64 @Transactional(readOnly = true)
65 public int count(Class<? extends T> clazz) {
66 return dao.count(clazz);
67 }
68
69 @Override
70 @Transactional(readOnly = false)
71 public String delete(T persistentObject) {
72 return dao.delete(persistentObject).toString();
73 }
74
75 @Override
76 @Transactional(readOnly = true)
77 public boolean exists(UUID uuid) {
78 return dao.exists(uuid);
79 }
80
81 @Override
82 @Transactional(readOnly = true)
83 public List<T> find(Set<UUID> uuidSet) {
84 return dao.list(uuidSet, null, null, null, null);
85 }
86
87 @Override
88 @Transactional(readOnly = true)
89 public List<T> findById(Set<Integer> idSet) { //can't be called find(Set<Integer>) as this conflicts with find(Set<UUID)
90 return dao.listByIds(idSet, null, null, null, null);
91 }
92
93 @Override
94 @Transactional(readOnly = true)
95 public T find(UUID uuid) {
96 return dao.findByUuid(uuid);
97 }
98
99 @Override
100 @Transactional(readOnly = true)
101 public T find(int id) {
102 return dao.findById(id);
103 }
104
105 @Override
106 @Transactional(readOnly = true)
107 public Session getSession() {
108 return dao.getSession();
109 }
110
111 @Override
112 @Transactional(readOnly = true)
113 public List<Object[]> group(Class<? extends T> clazz,Integer limit, Integer start, List<Grouping> groups, List<String> propertyPaths) {
114 return dao.group(clazz, limit, start, groups, propertyPaths);
115 }
116
117 @Override
118 @Transactional(readOnly = true)
119 public <S extends T> List<S> list(Class<S> type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths){
120 return dao.list(type,limit, start, orderHints,propertyPaths);
121 }
122
123 @Override
124 @Transactional(readOnly = true)
125 public T load(UUID uuid) {
126 return dao.load(uuid);
127 }
128
129 @Override
130 @Transactional(readOnly = true)
131 public T load(UUID uuid, List<String> propertyPaths){
132 return dao.load(uuid, propertyPaths);
133 }
134
135 @Override
136 @Transactional(readOnly = false)
137 public T merge(T newInstance) {
138 return dao.merge(newInstance);
139 }
140
141 @Override
142 @Transactional(readOnly = true)
143 public <S extends T> Pager<S> page(Class<S> type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){
144 Integer numberOfResults = dao.count(type);
145 List<S> results = new ArrayList<S>();
146 pageNumber = pageNumber == null ? 0 : pageNumber;
147 if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
148 Integer start = pageSize == null ? 0 : pageSize * pageNumber;
149 results = dao.list(type, pageSize, start, orderHints,propertyPaths);
150 }
151 return new DefaultPagerImpl<S>(pageNumber, numberOfResults, pageSize, results);
152 }
153
154 @Override
155 @Transactional(readOnly = true)
156 public UUID refresh(T persistentObject) {
157 return dao.refresh(persistentObject);
158 }
159
160 /**
161 * FIXME Candidate for harmonization
162 * is this method used, and if so, should it be exposed in the service layer?
163 * it seems a bit incongruous that we use an ORM to hide the fact that there is a
164 * database, then expose a method that talks about "rows" . . .
165 */
166 @Override
167 @Transactional(readOnly = true)
168 public List<T> rows(String tableName, int limit, int start) {
169 return dao.rows(tableName, limit, start);
170 }
171
172 @Override
173 @Transactional(readOnly = false)
174 public Map<UUID, T> save(Collection<T> newInstances) {
175 return dao.saveAll(newInstances);
176 }
177
178 @Override
179 @Transactional(readOnly = false)
180 public UUID save(T newInstance) {
181 return dao.save(newInstance);
182 }
183
184 @Override
185 @Transactional(readOnly = false)
186 public UUID saveOrUpdate(T transientObject) {
187 return dao.saveOrUpdate(transientObject);
188 }
189
190 @Override
191 @Transactional(readOnly = false)
192 public Map<UUID, T> saveOrUpdate(Collection<T> transientInstances) {
193 return dao.saveOrUpdateAll(transientInstances);
194 }
195
196 @Override
197 public void setApplicationContext(ApplicationContext appContext){
198 this.appContext = appContext;
199 }
200
201
202 protected abstract void setDao(DAO dao);
203
204 @Override
205 @Transactional(readOnly = false)
206 public UUID update(T transientObject) {
207 return dao.update(transientObject);
208 }
209
210 @Override
211 @Transactional(readOnly = true)
212 public List<T> list(T example, Set<String> includeProperties, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
213 return dao.list(example, includeProperties, limit, start, orderHints, propertyPaths);
214 }
215
216
217
218 }