Project

General

Profile

Download (13.9 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2009 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* 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
package eu.etaxonomy.cdm.persistence.dao.hibernate.common;
11

    
12
import java.util.ArrayList;
13
import java.util.List;
14
import java.util.Set;
15
import java.util.UUID;
16

    
17
import org.apache.log4j.Logger;
18
import org.hibernate.criterion.Criterion;
19
import org.hibernate.envers.AuditReader;
20
import org.hibernate.envers.AuditReaderFactory;
21
import org.hibernate.envers.query.AuditEntity;
22
import org.hibernate.envers.query.AuditQuery;
23
import org.hibernate.envers.query.criteria.AuditCriterion;
24

    
25
import eu.etaxonomy.cdm.model.common.VersionableEntity;
26
import eu.etaxonomy.cdm.model.view.AuditEvent;
27
import eu.etaxonomy.cdm.model.view.AuditEventRecord;
28
import eu.etaxonomy.cdm.model.view.AuditEventRecordImpl;
29
import eu.etaxonomy.cdm.model.view.context.AuditEventContext;
30
import eu.etaxonomy.cdm.model.view.context.AuditEventContextHolder;
31
import eu.etaxonomy.cdm.persistence.dao.common.AuditEventSort;
32
import eu.etaxonomy.cdm.persistence.dao.common.IVersionableDao;
33
import eu.etaxonomy.cdm.persistence.dao.common.OperationNotSupportedInPriorViewException;
34
import eu.etaxonomy.cdm.persistence.query.MatchMode;
35
import eu.etaxonomy.cdm.persistence.query.OrderHint;
36

    
37
public abstract class VersionableDaoBase<T extends VersionableEntity> extends CdmEntityDaoBase<T> implements IVersionableDao<T> {
38
	private static final Logger logger = Logger.getLogger(VersionableDaoBase.class);
39

    
40
	protected AuditReader getAuditReader() {
41
		return AuditReaderFactory.get(getSession());
42
	}
43

    
44
	public VersionableDaoBase(Class<T> type) {
45
		super(type);
46
	}
47

    
48
	 protected AuditEvent getAuditEventFromContext() {
49
		AuditEventContext auditEventContext = AuditEventContextHolder.getContext();
50

    
51
	   	AuditEvent auditEvent = auditEventContext.getAuditEvent();
52
	   	if(auditEvent != null) {
53
	   		logger.debug(" AuditEvent found, returning " + auditEvent);
54
	  	    return auditEvent;
55
	    } else {
56
	    	logger.debug(" AuditEvent is NULL, returning AuditEvent.CURRENT_VIEW");
57
	   		return AuditEvent.CURRENT_VIEW;
58
	   	}
59
	}
60

    
61
	protected void checkNotInPriorView(String message) {
62
		AuditEvent auditEvent = getAuditEventFromContext();
63
		if(!auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
64
			throw new OperationNotSupportedInPriorViewException(message);
65
		}
66
	}
67

    
68
	@Override
69
	public T findByUuid(UUID uuid) {
70
		AuditEvent auditEvent = getAuditEventFromContext();
71
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
72
			return super.findByUuid(uuid);
73
		} else {
74
			AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(type,auditEvent.getRevisionNumber());
75
			query.add(AuditEntity.property("uuid").eq(uuid));
76
			// TODO initialize bits
77
			return (T)query.getSingleResult();
78
		}
79
	}
80

    
81
    @Override
82
	protected List<T> findByParam(Class<? extends T> clazz, String param, String queryString, MatchMode matchmode, List<Criterion> criterion, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
83
    	checkNotInPriorView("IdentifiableDaoBase.findByParam(Class<? extends T> clazz, String queryString, MatchMode matchmode, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths)");
84
    	return super.findByParam(clazz, param, queryString, matchmode, criterion, pageSize, pageNumber, orderHints, propertyPaths);
85
    }
86

    
87
	@Override
88
	public T load(UUID uuid) {
89
		AuditEvent auditEvent = getAuditEventFromContext();
90
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
91
			return super.load(uuid);
92
		} else {
93
			AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(type,auditEvent.getRevisionNumber());
94
			query.add(AuditEntity.property("uuid").eq(uuid));
95
			T t = (T)query.getSingleResult();
96
			defaultBeanInitializer.load(t);
97
			return t;
98
		}
99
	}
100

    
101
	@Override
102
	public T load(UUID uuid, List<String> propertyPaths) {
103
		AuditEvent auditEvent = getAuditEventFromContext();
104
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
105
			return super.load(uuid,propertyPaths);
106
		} else {
107
			AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(type,auditEvent.getRevisionNumber());
108
			query.add(AuditEntity.property("uuid").eq(uuid));
109
			T t = (T)query.getSingleResult();
110
			defaultBeanInitializer.initialize(t, propertyPaths);
111
			return t;
112
		}
113
	}
114

    
115

    
116
	@Override
117
	public Boolean exists(UUID uuid) {
118
		AuditEvent auditEvent = getAuditEventFromContext();
119
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
120
			return super.exists(uuid);
121
		} else {
122
			AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(type,auditEvent.getRevisionNumber());
123
			query.add(AuditEntity.property("uuid").eq(uuid));
124
			return null != (T)query.getSingleResult();
125
		}
126
	}
127

    
128
	@Override
129
	public int count() {
130
		AuditEvent auditEvent = getAuditEventFromContext();
131
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
132
			return super.count();
133
		} else {
134
			return this.count(null);
135
		}
136
	}
137

    
138
	@Override
139
	public int count(Class<? extends T> clazz) {
140
		AuditEvent auditEvent = getAuditEventFromContext();
141
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
142
			return super.count(clazz);
143
		} else {
144
			AuditQuery query = null;
145
			if(clazz == null) {
146
			    query = getAuditReader().createQuery().forEntitiesAtRevision(type,auditEvent.getRevisionNumber());
147
			} else {
148
				query = getAuditReader().createQuery().forEntitiesAtRevision(clazz,auditEvent.getRevisionNumber());
149
			}
150

    
151
			query.addProjection(AuditEntity.id().count("id"));
152
			return ((Long)query.getSingleResult()).intValue();
153
		}
154
	}
155

    
156
	@Override
157
	public List<T> list(Integer limit, Integer start) {
158
		AuditEvent auditEvent = getAuditEventFromContext();
159
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
160
			return super.list(limit, start);
161
		} else {
162
			return this.list(null, limit, start);
163
		}
164
	}
165

    
166
	@Override
167
	public <S extends T> List<S> list(Class<S> type, Integer limit, Integer start) {
168
		AuditEvent auditEvent = getAuditEventFromContext();
169
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
170
			return super.list(type,limit, start);
171
		} else {
172
			return this.list(type, limit, start, null,null);
173
		}
174
	}
175

    
176
	@Override
177
	public <S extends T> List<S> list(Class<S> clazz, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
178
		AuditEvent auditEvent = getAuditEventFromContext();
179
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
180
			return super.list(clazz, limit, start, orderHints, propertyPaths);
181
		} else {
182
			AuditQuery query = null;
183

    
184
			if(clazz == null) {
185
				query = getAuditReader().createQuery().forEntitiesAtRevision(type,auditEvent.getRevisionNumber());
186
			} else {
187
				query = getAuditReader().createQuery().forEntitiesAtRevision(clazz,auditEvent.getRevisionNumber());
188
			}
189

    
190
			addOrder(query,orderHints);
191

    
192
			if(limit != null) {
193
		   	  query.setMaxResults(limit);
194
			  query.setFirstResult(start);
195
			}
196

    
197
			List<S> result = query.getResultList();
198
			defaultBeanInitializer.initializeAll(result, propertyPaths);
199
		    return result;
200
		}
201
	}
202

    
203
	protected void addOrder(AuditQuery query, List<OrderHint> orderHints) {
204
		if(orderHints != null && !orderHints.isEmpty()) {
205
		   for(OrderHint orderHint : orderHints) {
206
			   orderHint.add(query);
207
		   }
208
		}
209
	}
210

    
211
	public List<AuditEventRecord<T>> getAuditEvents(T t, Integer pageSize, Integer pageNumber, AuditEventSort sort, List<String> propertyPaths) {
212
		AuditEvent auditEvent = getAuditEventFromContext();
213

    
214
		AuditQuery query = getAuditReader().createQuery().forRevisionsOfEntity(type, false, true);
215
		query.add(AuditEntity.id().eq(t.getId()));
216
		if(sort == null) {
217
		  sort = AuditEventSort.BACKWARDS;
218
		}
219

    
220
		if(sort.equals(AuditEventSort.BACKWARDS)) {
221
            if(!auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
222
		  	  query.add(AuditEntity.revisionNumber().lt(auditEvent.getRevisionNumber()));
223
		    }
224
		    query.addOrder(AuditEntity.revisionNumber().desc());
225
     	} else {
226
     		if(!auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
227
  		  	  query.add(AuditEntity.revisionNumber().gt(auditEvent.getRevisionNumber()));
228
  		    }
229
  		    query.addOrder(AuditEntity.revisionNumber().asc());
230
     	}
231

    
232
		if(pageSize != null) {
233
		    query.setMaxResults(pageSize);
234
		    if(pageNumber != null) {
235
		        query.setFirstResult(pageNumber * pageSize);
236
		    } else {
237
		    	query.setFirstResult(0);
238
		    }
239
		}
240

    
241
        /**
242
         * At the moment we need to transform the data manually
243
         */
244
        List<Object[]> objs = (List<Object[]>)query.getResultList();
245
        List<AuditEventRecord<T>> records = new ArrayList<AuditEventRecord<T>>();
246

    
247
        for(Object[] obj : objs) {
248
        	records.add(new AuditEventRecordImpl<T>(obj));
249
        }
250

    
251
        for(AuditEventRecord<T> record : records) {
252
        	defaultBeanInitializer.initialize(record.getAuditableObject(), propertyPaths);
253
        }
254
		return records;
255
	}
256

    
257
	public int countAuditEvents(T t, AuditEventSort sort) {
258
		AuditEvent auditEvent = getAuditEventFromContext();
259

    
260
		AuditQuery query = getAuditReader().createQuery().forRevisionsOfEntity(type, false, true);
261
		query.add(AuditEntity.id().eq(t.getId()));
262

    
263
		if(!auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
264
			if(sort == null) {
265
				sort = AuditEventSort.BACKWARDS;
266
			}
267

    
268
			if(sort.equals(AuditEventSort.BACKWARDS)) {
269
				query.add(AuditEntity.revisionNumber().lt(auditEvent.getRevisionNumber()));
270
			} else {
271
				query.add(AuditEntity.revisionNumber().gt(auditEvent.getRevisionNumber()));
272
			}
273
		}
274

    
275
		query.addProjection(AuditEntity.revisionNumber().count());
276

    
277
		return ((Long)query.getSingleResult()).intValue();
278
	}
279

    
280
	public AuditEventRecord<T> getNextAuditEvent(T t) {
281
		List<AuditEventRecord<T>> auditEvents = getAuditEvents(t,1,0,AuditEventSort.FORWARDS, null);
282
		if(auditEvents.isEmpty()) {
283
			return null;
284
		} else {
285
		    return auditEvents.get(0);
286
		}
287
	}
288

    
289
	public AuditEventRecord<T> getPreviousAuditEvent(T t) {
290
		List<AuditEventRecord<T>> auditEvents = getAuditEvents(t,1,0,AuditEventSort.BACKWARDS, null);
291
		if(auditEvents.isEmpty()) {
292
			return null;
293
		} else {
294
		    return auditEvents.get(0);
295
		}
296
	}
297

    
298
	public int countAuditEvents(Class<? extends T> clazz, AuditEvent from,	AuditEvent to, List<AuditCriterion> criteria) {
299
		AuditQuery query = null;
300

    
301
		if(clazz == null) {
302
		   query = getAuditReader().createQuery().forRevisionsOfEntity(type, false, true);
303
		} else {
304
		   query = getAuditReader().createQuery().forRevisionsOfEntity(clazz, false, true);
305
		}
306

    
307
		if(from != null) {
308
			query.add(AuditEntity.revisionNumber().ge(from.getRevisionNumber()));
309
		}
310

    
311
		if(to != null && !to.equals(AuditEvent.CURRENT_VIEW)) {
312
			query.add(AuditEntity.revisionNumber().lt(to.getRevisionNumber()));
313
		}
314

    
315
		addCriteria(query,criteria);
316

    
317
		query.addProjection(AuditEntity.revisionNumber().count());
318

    
319
		return ((Long)query.getSingleResult()).intValue();
320
	}
321

    
322
	protected void addCriteria(AuditQuery query, List<AuditCriterion> criteria) {
323
		if(criteria != null) {
324
			for(AuditCriterion c : criteria) {
325
				query.add(c);
326
			}
327
		}
328
	}
329

    
330
	public List<AuditEventRecord<T>> getAuditEvents(Class<? extends T> clazz,AuditEvent from, AuditEvent to, List<AuditCriterion> criteria,	Integer pageSize, Integer pageNumber, AuditEventSort sort,	List<String> propertyPaths) {
331
        AuditQuery query = null;
332

    
333
		if(clazz == null) {
334
		   query = getAuditReader().createQuery().forRevisionsOfEntity(type, false, true);
335
		} else {
336
		   query = getAuditReader().createQuery().forRevisionsOfEntity(clazz, false, true);
337
		}
338

    
339
		if(from != null) {
340
			query.add(AuditEntity.revisionNumber().ge(from.getRevisionNumber()));
341
		}
342

    
343
		if(to != null && !to.equals(AuditEvent.CURRENT_VIEW)) {
344
			query.add(AuditEntity.revisionNumber().lt(to.getRevisionNumber()));
345
		}
346

    
347
		if(sort.equals(AuditEventSort.BACKWARDS)) {
348
		    query.addOrder(AuditEntity.revisionNumber().desc());
349
     	} else {
350
  		    query.addOrder(AuditEntity.revisionNumber().asc());
351
     	}
352

    
353
		addCriteria(query,criteria);
354

    
355
		if(pageSize != null) {
356
		    query.setMaxResults(pageSize);
357
		    if(pageNumber != null) {
358
		        query.setFirstResult(pageNumber * pageSize);
359
		    } else {
360
		    	query.setFirstResult(0);
361
		    }
362
		}
363

    
364
		/**
365
         * At the moment we need to transform the data manually
366
         */
367
        List<Object[]> objs = (List<Object[]>)query.getResultList();
368
        List<AuditEventRecord<T>> records = new ArrayList<AuditEventRecord<T>>();
369

    
370
        for(Object[] obj : objs) {
371
        	records.add(new AuditEventRecordImpl<T>(obj));
372
        }
373

    
374
        for(AuditEventRecord<T> record : records) {
375
        	defaultBeanInitializer.initialize(record.getAuditableObject(), propertyPaths);
376
        }
377
		return records;
378
	}
379

    
380
	@Override
381
	protected int countByParam(Class<? extends T> clazz, String param, String queryString, MatchMode matchmode, List<Criterion> criterion) {
382
    	checkNotInPriorView("IdentifiableDaoBase.findByParam(Class<? extends T> clazz, String queryString, MatchMode matchmode, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths)");
383
    	return super.countByParam(clazz, param, queryString, matchmode, criterion);
384
	}
385

    
386
	@Override
387
	public int count(T example, Set<String> includeProperties) {
388
		this.checkNotInPriorView("count(T example, Set<String> includeProperties)");
389
		return super.count(example, includeProperties);
390
	}
391

    
392
	public List<T> list(T example, Set<String> includeProperties, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
393
		this.checkNotInPriorView("list(T example, Set<String> includeProperties, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {");
394
		return super.list(example, includeProperties, limit, start, orderHints, propertyPaths);
395
	}
396
}
(22-22/22)