3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
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.
11 package eu
.etaxonomy
.cdm
.api
.service
;
13 import java
.util
.ArrayList
;
14 import java
.util
.Collection
;
15 import java
.util
.HashMap
;
16 import java
.util
.Iterator
;
17 import java
.util
.List
;
19 import java
.util
.UUID
;
21 import org
.apache
.log4j
.Logger
;
22 import org
.springframework
.beans
.factory
.annotation
.Qualifier
;
23 import org
.springframework
.context
.ApplicationContext
;
24 import org
.springframework
.context
.ApplicationContextAware
;
25 import org
.springframework
.transaction
.TransactionStatus
;
26 import org
.springframework
.transaction
.annotation
.Transactional
;
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
.OrderHint
;
34 @Transactional(readOnly
=true)
35 public abstract class ServiceBase
<T
extends CdmBase
, DAO
extends ICdmEntityDao
<T
>> implements IService
<T
>, ApplicationContextAware
{
36 private static final Logger logger
= Logger
.getLogger(ServiceBase
.class);
38 //flush after saving this number of objects
39 int flushAfterNo
= 2000;
40 protected ApplicationContext appContext
;
45 protected abstract void setDao(DAO dao
);
48 * @see eu.etaxonomy.cdm.api.service.Iyyy#setApplicationContext(org.springframework.context.ApplicationContext)
50 public void setApplicationContext(ApplicationContext appContext
){
51 this.appContext
= appContext
;
55 * FIXME Candidate for harmonization
60 public T
getCdmObjectByUuid(UUID uuid
) {
61 return dao
.findByUuid(uuid
);
65 * FIXME Candidate for harmonization
66 * the generic method arguments are a bit meaningless as
67 * we're not typing the results. this should be changed to
68 * public int count(Class<? extends T> clazz)
69 * where clazz can be null, to count all instances of type T
71 public <TYPE
extends T
> int count(Class
<TYPE
> clazz
) {
72 return dao
.count(clazz
);
76 * FIXME Candidate for harmonization
77 * merge with the above
84 * FIXME Candidate for harmonization
89 @Transactional(readOnly
= false)
90 protected UUID
saveCdmObject(T cdmObj
){
91 if (logger
.isDebugEnabled()){logger
.debug("Save cdmObj: " + (cdmObj
== null?
null: cdmObj
.toString()));}
92 return dao
.saveOrUpdate(cdmObj
);
97 * FIXME Candidate for harmonization
101 @Transactional(readOnly
= false)
102 protected UUID
saveCdmObject(T cdmObj
, TransactionStatus txStatus
){
103 // TODO: Implement with considering txStatus
104 if (logger
.isDebugEnabled()){logger
.debug("Save cdmObj: " + (cdmObj
== null?
null: cdmObj
.toString()));}
105 return dao
.saveOrUpdate(cdmObj
);
109 * FIXME Candidate for harmonization
112 * @param cdmObjCollection
115 @Transactional(readOnly
= false)
116 protected <S
extends T
> Map
<UUID
, S
> saveCdmObjectAll(Collection
<?
extends S
> cdmObjCollection
){
117 int types
= cdmObjCollection
.getClass().getTypeParameters().length
;
119 if (logger
.isDebugEnabled()){logger
.debug("ClassType: + " + cdmObjCollection
.getClass().getTypeParameters()[0]);}
122 Map
<UUID
, S
> resultMap
= new HashMap
<UUID
, S
>();
123 Iterator
<?
extends S
> iterator
= cdmObjCollection
.iterator();
125 while(iterator
.hasNext()){
126 if ( ( (i
% 5000) == 0) && (i
> 0) ){logger
.debug("Saved " + i
+ " objects" );}
127 S cdmObj
= iterator
.next();
128 UUID uuid
= saveCdmObject(cdmObj
);
129 // if (logger.isDebugEnabled()){logger.debug("Save cdmObj: " + (cdmObj == null? null: cdmObj.toString()));}
130 resultMap
.put(uuid
, cdmObj
);
132 if ( (i
% flushAfterNo
) == 0){
134 logger
.debug("flush");
137 logger
.error("UUUIIIII");
143 if ( logger
.isInfoEnabled() ){logger
.info("Saved " + i
+ " objects" );}
147 @Transactional(readOnly
= false)
148 public UUID
delete(T persistentObject
) {
149 return dao
.delete(persistentObject
);
152 public boolean exists(UUID uuid
) {
153 return dao
.exists(uuid
);
157 * FIXME Candidate for harmonization
160 public T
findByUuid(UUID uuid
) {
161 return dao
.findByUuid(uuid
);
164 public T
load(UUID uuid
) {
165 return dao
.load(uuid
);
168 public T
load(UUID uuid
, List
<String
> propertyPaths
){
169 return dao
.load(uuid
, propertyPaths
);
173 * FIXME Candidate for harmonization
174 * should be single method
175 * List<T> list(Class<? extends T> type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths)
177 public <TYPE
extends T
> List
<TYPE
> list(Class
<TYPE
> type
, int limit
,int start
) {
178 return dao
.list(type
, limit
, start
);
182 * FIXME Candidate for harmonization
185 public Pager
<T
> list(Integer pageSize
, Integer pageNumber
){
186 return list(pageSize
, pageNumber
, null);
190 * FIXME Candidate for harmonization
191 * should be single method
192 * Pager<T> page(Class<? extends T> type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths)
194 public Pager
<T
> list(Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
){
195 return list(pageSize
,pageNumber
,orderHints
,null);
199 * FIXME Candidate for harmonization
200 * should be single method
201 * Pager<T> page(Class<? extends T> type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths)
203 public Pager
<T
> list(Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
){
204 Integer numberOfResults
= dao
.count();
205 List
<T
> results
= new ArrayList
<T
>();
206 pageNumber
= pageNumber
== null ?
0 : pageNumber
;
207 if(numberOfResults
> 0) { // no point checking again
208 Integer start
= pageSize
== null ?
0 : pageSize
* (pageNumber
- 1);
209 results
= dao
.list(pageSize
, start
, orderHints
,propertyPaths
);
211 return new DefaultPagerImpl
<T
>(pageNumber
, numberOfResults
, pageSize
, results
);
215 * FIXME Candidate for harmonization
216 * should be single method
217 * Pager<T> page(Class<? extends T> type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths)
219 public <TYPE
extends T
> Pager
<TYPE
> list(Class
<TYPE
> type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
){
220 Integer numberOfResults
= dao
.count(type
);
221 List
<TYPE
> results
= new ArrayList
<TYPE
>();
222 pageNumber
= pageNumber
== null ?
0 : pageNumber
;
223 if(numberOfResults
> 0) { // no point checking again
224 Integer start
= pageSize
== null ?
0 : pageSize
* (pageNumber
- 1);
225 results
= dao
.list(type
,pageSize
, start
, orderHints
,propertyPaths
);
227 return new DefaultPagerImpl
<TYPE
>(pageNumber
, numberOfResults
, pageSize
, results
);
230 @Transactional(readOnly
= false)
231 public UUID
save(T newInstance
) {
232 return dao
.save(newInstance
);
235 @Transactional(readOnly
= false)
236 public UUID
merge(T newInstance
) {
237 return dao
.merge(newInstance
);
241 * FIXME Candidate for harmonization
244 @Transactional(readOnly
= false)
245 public Map
<UUID
, T
> saveAll(Collection
<T
> newInstances
) {
246 return dao
.saveAll(newInstances
);
249 @Transactional(readOnly
= false)
250 public UUID
saveOrUpdate(T transientObject
) {
251 return dao
.saveOrUpdate(transientObject
);
254 @Transactional(readOnly
= false)
255 public UUID
update(T transientObject
) {
256 return dao
.update(transientObject
);
259 public UUID
refresh(T persistentObject
) {
260 return dao
.refresh(persistentObject
);
264 * FIXME Candidate for harmonization
269 @Transactional(readOnly
= false)
270 protected UUID
removeCdmObject(T cdmObj
){
271 if (logger
.isDebugEnabled()){logger
.debug("Save cdmObj: " + (cdmObj
== null?
null: cdmObj
.toString()));}
272 return dao
.delete(cdmObj
);
276 * FIXME Candidate for harmonization
277 * should be single method
278 * List<T> list(Class<? extends T> type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths)
280 public List
<T
> list(int limit
, int start
) {
281 return dao
.list(limit
, start
);
285 * FIXME Candidate for harmonization
286 * is this method used, and if so, should it be exposed in the service layer?
287 * it seems a bit incongruous that we use an ORM to hide the fact that there is a
288 * database, then expose a method that talks about "rows" . . .
290 public List
<T
> rows(String tableName
, int limit
, int start
) {
291 return dao
.rows(tableName
, limit
, start
);