Project

General

Profile

Download (13.2 KB) Statistics
| Branch: | Tag: | Revision:
1 25663b56 Andreas Müller
/**
2
* Copyright (C) 2007 EDIT
3 bb5e13c1 Andreas Kohlbecker
* European Distributed Institute of Taxonomy
4 25663b56 Andreas Müller
* http://www.e-taxonomy.eu
5 bb5e13c1 Andreas Kohlbecker
*
6 25663b56 Andreas Müller
* 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 2d993c6e Andreas Müller
package eu.etaxonomy.cdm.api.service;
11
12 28dfa0a5 Andreas Kohlbecker
import java.util.ArrayList;
13 78f4027b Andreas Müller
import java.util.Collection;
14 2d993c6e Andreas Müller
import java.util.List;
15 78f4027b Andreas Müller
import java.util.Map;
16 2534611e a.babadshanjan
import java.util.Set;
17 2d993c6e Andreas Müller
import java.util.UUID;
18
19
import org.apache.log4j.Logger;
20 cb16ca65 Andreas Müller
import org.hibernate.LockOptions;
21 c822b7d1 a.babadshanjan
import org.hibernate.Session;
22 51ee66dc Andreas Kohlbecker
import org.hibernate.criterion.Criterion;
23 2d993c6e Andreas Müller
import org.springframework.context.ApplicationContext;
24
import org.springframework.context.ApplicationContextAware;
25 08d62c6f Katja Luther
import org.springframework.dao.DataAccessException;
26 2d993c6e Andreas Müller
import org.springframework.transaction.annotation.Transactional;
27
28 28dfa0a5 Andreas Kohlbecker
import eu.etaxonomy.cdm.api.service.pager.Pager;
29 51ee66dc Andreas Kohlbecker
import eu.etaxonomy.cdm.api.service.pager.impl.AbstractPagerImpl;
30 28dfa0a5 Andreas Kohlbecker
import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
31 87ffda36 Andreas Müller
import eu.etaxonomy.cdm.exception.UnpublishedException;
32 2d993c6e Andreas Müller
import eu.etaxonomy.cdm.model.common.CdmBase;
33 87ffda36 Andreas Müller
import eu.etaxonomy.cdm.model.common.IPublishable;
34 2d993c6e Andreas Müller
import eu.etaxonomy.cdm.persistence.dao.common.ICdmEntityDao;
35 51ee66dc Andreas Kohlbecker
import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
36 12b3d645 Andreas Müller
import eu.etaxonomy.cdm.persistence.dao.hibernate.common.DaoBase;
37 ce9bc492 Cherian Mathew
import eu.etaxonomy.cdm.persistence.dto.MergeResult;
38 c4e812bc ben.clark
import eu.etaxonomy.cdm.persistence.query.Grouping;
39 51ee66dc Andreas Kohlbecker
import eu.etaxonomy.cdm.persistence.query.MatchMode;
40 28dfa0a5 Andreas Kohlbecker
import eu.etaxonomy.cdm.persistence.query.OrderHint;
41 2d993c6e Andreas Müller
42 11d3d7eb Andreas Müller
public abstract class ServiceBase<T extends CdmBase, DAO extends ICdmEntityDao<T>>
43
            implements IService<T>, ApplicationContextAware {
44
45 bb5e13c1 Andreas Kohlbecker
    @SuppressWarnings("unused")
46
    private static final Logger logger = Logger.getLogger(ServiceBase.class);
47
48
    protected ApplicationContext appContext;
49
50 12b3d645 Andreas Müller
    public final static boolean NO_UNPUBLISHED = DaoBase.NO_UNPUBLISHED;  //constant for unpublished
51
    public final static boolean INCLUDE_UNPUBLISHED = DaoBase.INCLUDE_UNPUBLISHED;  //constant for unpublished
52
53 bb5e13c1 Andreas Kohlbecker
    protected DAO dao;
54
55 d3d4afa4 Andreas Kohlbecker
    @Override
56 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = true)
57 cb16ca65 Andreas Müller
    public void lock(T t, LockOptions lockOptions) {
58
        dao.lock(t, lockOptions);
59 bb5e13c1 Andreas Kohlbecker
    }
60
61 d3d4afa4 Andreas Kohlbecker
    @Override
62 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = true)
63 cb16ca65 Andreas Müller
    public void refresh(T t, LockOptions lockOptions, List<String> propertyPaths) {
64
        dao.refresh(t, lockOptions, propertyPaths);
65 bb5e13c1 Andreas Kohlbecker
    }
66
67 d3d4afa4 Andreas Kohlbecker
    @Override
68 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = false)
69
    public void clear() {
70
        dao.clear();
71
    }
72
73 d3d4afa4 Andreas Kohlbecker
    @Override
74 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = true)
75
    public int count(Class<? extends T> clazz) {
76 2a4c4dd0 Andreas Müller
        return Long.valueOf(dao.count(clazz)).intValue();
77 bb5e13c1 Andreas Kohlbecker
    }
78
79 d3d4afa4 Andreas Kohlbecker
    @Override
80 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = false)
81 0a32c706 Katja Luther
    public DeleteResult delete(UUID persistentObjectUUID) {
82 1128808d Cherian Mathew
        T persistentObject = dao.findByUuid(persistentObjectUUID);
83
        return delete(persistentObject);
84 bb5e13c1 Andreas Kohlbecker
    }
85 5901681d Cherian Mathew
86
    @Override
87
    @Transactional(readOnly = false)
88
    public DeleteResult delete(Collection<UUID> persistentObjectUUIDs) {
89
        DeleteResult result = new DeleteResult();
90
        for(UUID persistentObjectUUID : persistentObjectUUIDs) {
91 1128808d Cherian Mathew
            T persistentObject = dao.findByUuid(persistentObjectUUID);
92
            DeleteResult dr = delete(persistentObject);
93
            result.includeResult(dr);
94 5901681d Cherian Mathew
        }
95
        return result;
96
    }
97
98 51a3a962 Cherian Mathew
    @Override
99
    @Transactional(readOnly = false)
100 0a32c706 Katja Luther
    public DeleteResult delete(T persistentObject) {
101
    	DeleteResult result = new DeleteResult();
102
    	try{
103
    		dao.delete(persistentObject);
104 815a9015 Katja Luther
    		result.addDeletedObject(persistentObject);
105 0a32c706 Katja Luther
    	} catch(DataAccessException e){
106
    		result.setError();
107
    		result.addException(e);
108
    	}
109
        return result;
110 51a3a962 Cherian Mathew
    }
111
112 5901681d Cherian Mathew
113 0a32c706 Katja Luther
114 d3d4afa4 Andreas Kohlbecker
    @Override
115 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = true)
116
    public boolean exists(UUID uuid) {
117
        return dao.exists(uuid);
118
    }
119
120 d3d4afa4 Andreas Kohlbecker
    @Override
121 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = true)
122
    public List<T> find(Set<UUID> uuidSet) {
123 346d01a7 Andreas Kohlbecker
        return dao.list(uuidSet, null, null, null, null);
124 bb5e13c1 Andreas Kohlbecker
    }
125
126 a089c5d4 Andreas Müller
127
    @Override
128
    @Transactional(readOnly = true)
129
    public <S extends T> List<S> find(Class<S> clazz, Set<UUID> uuidSet) {
130
        return dao.list(clazz, uuidSet, null, null, null, null);
131
    }
132
133 d3d4afa4 Andreas Kohlbecker
    @Override
134 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = true)
135
    public List<T> findById(Set<Integer> idSet) {  //can't be called find(Set<Integer>) as this conflicts with find(Set<UUID)
136 fccd79b3 Andreas Müller
        return dao.loadList(idSet, null, null);
137 bb5e13c1 Andreas Kohlbecker
    }
138
139 f4d35a72 Andreas Kohlbecker
    @Override
140
    @Transactional(readOnly = true)
141 1ec74f53 Andreas Kohlbecker
    public List<T> loadByIds(List<Integer> idList, List<String> propertyPaths){
142 fccd79b3 Andreas Müller
        return dao.loadList(idList, null, propertyPaths);
143
    }
144
145
    @Override
146
    @Transactional(readOnly = true)
147
    public List<T> loadByIds(List<Integer> idList, List<OrderHint> orderHints, List<String> propertyPaths){
148
        return dao.loadList(idList, orderHints, propertyPaths);
149 f4d35a72 Andreas Kohlbecker
    }
150
151 d3d4afa4 Andreas Kohlbecker
    @Override
152 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = true)
153
    public T find(UUID uuid) {
154 93c7f674 Andreas Müller
        return uuid == null ? null : dao.findByUuid(uuid);
155 bb5e13c1 Andreas Kohlbecker
    }
156 51a3a962 Cherian Mathew
157 1aa19623 Cherian Mathew
    @Override
158
    @Transactional(readOnly = true)
159
    public T findWithoutFlush(UUID uuid) {
160 93c7f674 Andreas Müller
        return uuid == null ? null : dao.findByUuidWithoutFlush(uuid);
161 1aa19623 Cherian Mathew
    }
162 bb5e13c1 Andreas Kohlbecker
163 d3d4afa4 Andreas Kohlbecker
    @Override
164 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = true)
165
    public T find(int id) {
166
        return dao.findById(id);
167
    }
168
169 d3d4afa4 Andreas Kohlbecker
    @Override
170 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = true)
171
    public Session getSession() {
172
        return dao.getSession();
173
    }
174
175 d3d4afa4 Andreas Kohlbecker
    @Override
176 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = true)
177
    public List<Object[]> group(Class<? extends T> clazz,Integer limit, Integer start, List<Grouping> groups, List<String> propertyPaths) {
178
        return dao.group(clazz, limit, start, groups, propertyPaths);
179
    }
180
181 d3d4afa4 Andreas Kohlbecker
    @Override
182 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = true)
183 fdf9eec2 Andreas Müller
    public <S extends T> List<S> list(Class<S> type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths){
184 9c3b40bb Andreas Kohlbecker
        return dao.list(type,limit, start, orderHints, propertyPaths);
185 bb5e13c1 Andreas Kohlbecker
    }
186
187 d3d4afa4 Andreas Kohlbecker
    @Override
188 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = true)
189
    public T load(UUID uuid) {
190 93c7f674 Andreas Müller
        return uuid == null ? null : dao.load(uuid);
191 bb5e13c1 Andreas Kohlbecker
    }
192
193 c77f6466 Cherian Mathew
    @Override
194
    @Transactional(readOnly = true)
195
    public T loadWithUpdate(UUID uuid) {
196
        return load(uuid);
197
    }
198
199 c986e218 Andreas Kohlbecker
    @Override
200
    @Transactional(readOnly = true)
201
    public T load(int id, List<String> propertyPaths) {
202
        return dao.load(id, propertyPaths);
203
    }
204
205 d3d4afa4 Andreas Kohlbecker
    @Override
206 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = true)
207
    public T load(UUID uuid, List<String> propertyPaths){
208 93c7f674 Andreas Müller
        return uuid == null ? null : dao.load(uuid, propertyPaths);
209 bb5e13c1 Andreas Kohlbecker
    }
210
211 fbedbcd2 Cherian Mathew
    @Override
212
    @Transactional(readOnly = true)
213
    public List<T> load(List<UUID> uuids, List<String> propertyPaths){
214
        if(uuids == null) {
215
            return null;
216
        }
217
218 cfb4f036 Andreas Müller
        List<T> entities = new ArrayList<>();
219 fbedbcd2 Cherian Mathew
        for(UUID uuid : uuids) {
220
            entities.add(uuid == null ? null : dao.load(uuid, propertyPaths));
221
        }
222
        return entities;
223
    }
224
225 d3d4afa4 Andreas Kohlbecker
    @Override
226 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = false)
227
    public T merge(T newInstance) {
228
        return dao.merge(newInstance);
229
    }
230
231 eeed5bb8 Cherian Mathew
    @Override
232
    @Transactional(readOnly = false)
233 ce9bc492 Cherian Mathew
    public MergeResult<T> merge(T newInstance, boolean returnTransientEntity) {
234 eeed5bb8 Cherian Mathew
        return dao.merge(newInstance, returnTransientEntity);
235
    }
236
237 ddf0581b Cherian Mathew
    @Override
238
    @Transactional(readOnly = false)
239
    public List<T> merge(List<T> detachedObjects) {
240 da54d73f Cherian Mathew
        List<T> mergedObjects = new ArrayList<T>();
241
        for(T obj : detachedObjects) {
242
            mergedObjects.add(dao.merge(obj));
243
        }
244
        return mergedObjects;
245 d29a0062 Cherian Mathew
    }
246
247
    @Override
248
    @Transactional(readOnly = false)
249 ce9bc492 Cherian Mathew
    public List<MergeResult<T>> merge(List<T> detachedObjects, boolean returnTransientEntity) {
250
        List<MergeResult<T>> mergedObjects = new ArrayList<MergeResult<T>>();
251 ddf0581b Cherian Mathew
        for(T obj : detachedObjects) {
252 f93dab43 Katja Luther
            mergedObjects.add(dao.merge(obj, returnTransientEntity));
253 ddf0581b Cherian Mathew
        }
254
        return mergedObjects;
255
    }
256
257 d3d4afa4 Andreas Kohlbecker
    @Override
258 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = true)
259 fdf9eec2 Andreas Müller
    public  <S extends T> Pager<S> page(Class<S> type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){
260 2a4c4dd0 Andreas Müller
        Long numberOfResults = dao.count(type);
261 8c6a7c50 Andreas Müller
        List<S> results = new ArrayList<>();
262 bb5e13c1 Andreas Kohlbecker
        pageNumber = pageNumber == null ? 0 : pageNumber;
263
        if(numberOfResults > 0) { // no point checking again  //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
264
            Integer start = pageSize == null ? 0 : pageSize * pageNumber;
265 8c6a7c50 Andreas Müller
            results = dao.list(type, pageSize, start, orderHints, propertyPaths);
266 bb5e13c1 Andreas Kohlbecker
        }
267 8c6a7c50 Andreas Müller
        return new DefaultPagerImpl<>(pageNumber, numberOfResults, pageSize, results);
268 bb5e13c1 Andreas Kohlbecker
    }
269
270 d3d4afa4 Andreas Kohlbecker
    @Override
271 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = true)
272 c4e812bc ben.clark
    public UUID refresh(T persistentObject) {
273 bb5e13c1 Andreas Kohlbecker
        return dao.refresh(persistentObject);
274
    }
275
276 d3d4afa4 Andreas Kohlbecker
    @Override
277 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = false)
278
    public Map<UUID, T> save(Collection<T> newInstances) {
279
        return dao.saveAll(newInstances);
280
    }
281
282 d3d4afa4 Andreas Kohlbecker
    @Override
283 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = false)
284 94722700 Andreas Müller
    public <S extends T> S save(S newInstance) {
285 bb5e13c1 Andreas Kohlbecker
        return dao.save(newInstance);
286
    }
287
288 d3d4afa4 Andreas Kohlbecker
    @Override
289 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = false)
290
    public UUID saveOrUpdate(T transientObject) {
291
        return dao.saveOrUpdate(transientObject);
292
    }
293
294 d3d4afa4 Andreas Kohlbecker
    @Override
295 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = false)
296
    public Map<UUID, T> saveOrUpdate(Collection<T> transientInstances) {
297
        return dao.saveOrUpdateAll(transientInstances);
298
    }
299
300 d1079ab4 Andreas Müller
    @Override
301 bb5e13c1 Andreas Kohlbecker
    public void setApplicationContext(ApplicationContext appContext){
302
        this.appContext = appContext;
303
    }
304
305
306
    protected abstract void setDao(DAO dao);
307
308 d3d4afa4 Andreas Kohlbecker
    @Override
309 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = false)
310
    public UUID update(T transientObject) {
311
        return dao.update(transientObject);
312
    }
313
314 d3d4afa4 Andreas Kohlbecker
    @Override
315 bb5e13c1 Andreas Kohlbecker
    @Transactional(readOnly = true)
316 52a42c7d Andreas Müller
    public <S extends T> List<S> list(S example, Set<String> includeProperties, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
317 bb5e13c1 Andreas Kohlbecker
        return dao.list(example, includeProperties, limit, start, orderHints, propertyPaths);
318
    }
319 51a3a962 Cherian Mathew
320 51ee66dc Andreas Kohlbecker
    @Override
321 d2e6ea3e Andreas Kohlbecker
    @Transactional(readOnly = true)
322 98ce4a92 Andreas Müller
    public <S extends T> Pager<S> page(Class<S> clazz, String param, String queryString, MatchMode matchmode, List<Criterion> criteria, Integer pageSize, Integer pageIndex, List<OrderHint> orderHints, List<String> propertyPaths){
323 51ee66dc Andreas Kohlbecker
324 98ce4a92 Andreas Müller
        List<S> records;
325 51ee66dc Andreas Kohlbecker
        long resultSize = dao.countByParam(clazz, param, queryString, matchmode, criteria);
326
        if(AbstractPagerImpl.hasResultsInRange(resultSize, pageIndex, pageSize)){
327
            records = dao.findByParam(clazz, param, queryString, matchmode, criteria, pageSize, pageIndex, orderHints, propertyPaths);
328
        } else {
329
            records = new ArrayList<>();
330
        }
331 98ce4a92 Andreas Müller
        return new DefaultPagerImpl<>(pageIndex, resultSize, pageSize, records);
332 51ee66dc Andreas Kohlbecker
    }
333
334
335
    @Override
336 d2e6ea3e Andreas Kohlbecker
    @Transactional(readOnly = true)
337 2b4d0842 Andreas Kohlbecker
    public <S extends T> Pager<S> pageByParamWithRestrictions(Class<S> clazz, String param, String queryString, MatchMode matchmode, List<Restriction<?>> restrictions, Integer pageSize, Integer pageIndex, List<OrderHint> orderHints, List<String> propertyPaths){
338 51ee66dc Andreas Kohlbecker
339 98ce4a92 Andreas Müller
        List<S> records;
340 51ee66dc Andreas Kohlbecker
        long resultSize = dao.countByParamWithRestrictions(clazz, param, queryString, matchmode, restrictions);
341
        if(AbstractPagerImpl.hasResultsInRange(resultSize, pageIndex, pageSize)){
342
            records = dao.findByParamWithRestrictions(clazz, param, queryString, matchmode, restrictions, pageSize, pageIndex, orderHints, propertyPaths);
343
        } else {
344
            records = new ArrayList<>();
345
        }
346 98ce4a92 Andreas Müller
        Pager<S> pager = new DefaultPagerImpl<>(pageIndex, resultSize, pageSize, records);
347 51ee66dc Andreas Kohlbecker
        return pager;
348
    }
349
350 2b4d0842 Andreas Kohlbecker
    @Override
351
    @Transactional(readOnly = true)
352
    public <S extends T> Pager<S> page(Class<S> clazz, List<Restriction<?>> restrictions, Integer pageSize, Integer pageIndex, List<OrderHint> orderHints, List<String> propertyPaths){
353
354
        List<S> records;
355
        long resultSize = dao.count(clazz, restrictions);
356
        if(AbstractPagerImpl.hasResultsInRange(resultSize, pageIndex, pageSize)){
357
            records = dao.list(clazz, restrictions, pageSize, pageIndex, orderHints, propertyPaths);
358
        } else {
359
            records = new ArrayList<>();
360
        }
361
        Pager<S> pager = new DefaultPagerImpl<>(pageIndex, resultSize, pageSize, records);
362
        return pager;
363
    }
364
365 51a3a962 Cherian Mathew
366 87ffda36 Andreas Müller
    /**
367
     * Throws an exception if the publishable entity should not be published.
368
     * @param publishable the publishable entity
369
     * @param includeUnpublished should publish be checked
370
     * @param message the error message to include
371
     * @throws UnpublishedException thrown if entity is not public and unpublished should not be included
372
     */
373
    protected void checkPublished(IPublishable publishable, boolean includeUnpublished, String message) throws UnpublishedException {
374 bb006ee7 Andreas Müller
        if (!(includeUnpublished || publishable.isPublish())){
375 87ffda36 Andreas Müller
            throw new UnpublishedException("Access denied. "+  message);
376
        }
377
    }
378
379
380 bb5e13c1 Andreas Kohlbecker
381 2d993c6e Andreas Müller
}