Project

General

Profile

Download (13.1 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.query.AuditEntity;
20
import org.hibernate.envers.query.AuditQuery;
21
import org.hibernate.envers.query.criteria.AuditCriterion;
22

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

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

    
38
	public VersionableDaoBase(Class<T> type) {
39
		super(type);
40
	}
41

    
42
	 protected AuditEvent getAuditEventFromContext() {
43
		AuditEventContext auditEventContext = AuditEventContextHolder.getContext();
44

    
45
	   	AuditEvent auditEvent = auditEventContext.getAuditEvent();
46
	   	if(auditEvent != null) {
47
	   		logger.debug(" AuditEvent found, returning " + auditEvent);
48
	  	    return auditEvent;
49
	    } else {
50
	    	logger.debug(" AuditEvent is NULL, returning AuditEvent.CURRENT_VIEW");
51
	   		return AuditEvent.CURRENT_VIEW;
52
	   	}
53
	}
54

    
55
	protected void checkNotInPriorView(String message) {
56
		AuditEvent auditEvent = getAuditEventFromContext();
57
		if(!auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
58
			throw new OperationNotSupportedInPriorViewException(message);
59
		}
60
	}
61

    
62
	@Override
63
	public T findByUuid(UUID uuid) {
64
		AuditEvent auditEvent = getAuditEventFromContext();
65
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
66
			return super.findByUuid(uuid);
67
		} else {
68
		    AuditQuery query = makeAuditQuery(null, auditEvent);
69
			query.add(AuditEntity.property("uuid").eq(uuid));
70
			@SuppressWarnings("unchecked")
71
            T result = (T)query.getSingleResult();
72
			return result;
73
		}
74
	}
75

    
76
    @Override
77
	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) {
78
    	checkNotInPriorView("IdentifiableDaoBase.findByParam(Class<? extends T> clazz, String queryString, MatchMode matchmode, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths)");
79
    	return super.findByParam(clazz, param, queryString, matchmode, criterion, pageSize, pageNumber, orderHints, propertyPaths);
80
    }
81

    
82
	@Override
83
	public T load(UUID uuid) {
84
		AuditEvent auditEvent = getAuditEventFromContext();
85
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
86
			return super.load(uuid);
87
		} else {
88
			AuditQuery query = makeAuditQuery(null, auditEvent);
89
			query.add(AuditEntity.property("uuid").eq(uuid));
90
			@SuppressWarnings("unchecked")
91
            T t = (T)query.getSingleResult();
92
			defaultBeanInitializer.load(t);
93
			return t;
94
		}
95
	}
96

    
97
	@Override
98
    public T load(UUID uuid, List<String> propertyPaths) {
99
	    return this.load(uuid, INCLUDE_UNPUBLISHED, propertyPaths);
100
	}
101

    
102
	@Override
103
    protected T load(UUID uuid, boolean includeUnpublished, List<String> propertyPaths) {
104
		AuditEvent auditEvent = getAuditEventFromContext();
105
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
106
			return super.load(uuid, includeUnpublished, propertyPaths);
107
		} else {
108
		    //TODO includeUnpublished
109
			AuditQuery query = makeAuditQuery(null, auditEvent);
110
			query.add(AuditEntity.property("uuid").eq(uuid));
111
			@SuppressWarnings("unchecked")
112
            T t = (T)query.getSingleResult();
113
			defaultBeanInitializer.initialize(t, propertyPaths);
114
			return t;
115
		}
116
	}
117

    
118

    
119
	@Override
120
	public Boolean exists(UUID uuid) {
121
		AuditEvent auditEvent = getAuditEventFromContext();
122
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
123
			return super.exists(uuid);
124
		} else {
125
			AuditQuery query = makeAuditQuery(null, auditEvent);
126
			query.add(AuditEntity.property("uuid").eq(uuid));
127
			return null != query.getSingleResult();
128
		}
129
	}
130

    
131
	@Override
132
	public long count() {
133
		AuditEvent auditEvent = getAuditEventFromContext();
134
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
135
			return super.count();
136
		} else {
137
			return this.count(null);
138
		}
139
	}
140

    
141
	@Override
142
	public long count(Class<? extends T> clazz) {
143
		AuditEvent auditEvent = getAuditEventFromContext();
144
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
145
			return super.count(clazz);
146
		} else {
147
			AuditQuery query = makeAuditQuery(clazz, auditEvent);
148

    
149
			query.addProjection(AuditEntity.id().count());
150

    
151
			return (Long)query.getSingleResult();
152
		}
153
	}
154

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

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

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

    
183
			addOrder(query,orderHints);
184
			addLimitAndStart(query, limit, start);
185

    
186
			@SuppressWarnings("unchecked")
187
            List<S> result = query.getResultList();
188
			defaultBeanInitializer.initializeAll(result, propertyPaths);
189
		    return result;
190
		}
191
	}
192

    
193
	protected void addOrder(AuditQuery query, List<OrderHint> orderHints) {
194
		if(orderHints != null && !orderHints.isEmpty()) {
195
		   for(OrderHint orderHint : orderHints) {
196
			   orderHint.add(query);
197
		   }
198
		}
199
	}
200

    
201
	@Override
202
    public List<AuditEventRecord<T>> getAuditEvents(T t, Integer pageSize, Integer pageNumber, AuditEventSort sort, List<String> propertyPaths) {
203
		AuditEvent auditEvent = getAuditEventFromContext();
204

    
205
		AuditQuery query = getAuditReader().createQuery().forRevisionsOfEntity(type, false, true);
206
		query.add(AuditEntity.id().eq(t.getId()));
207
		if(sort == null) {
208
		  sort = AuditEventSort.BACKWARDS;
209
		}
210

    
211
		if(sort.equals(AuditEventSort.BACKWARDS)) {
212
            if(!auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
213
		  	  query.add(AuditEntity.revisionNumber().lt(auditEvent.getRevisionNumber()));
214
		    }
215
		    query.addOrder(AuditEntity.revisionNumber().desc());
216
     	} else {
217
     		if(!auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
218
  		  	  query.add(AuditEntity.revisionNumber().gt(auditEvent.getRevisionNumber()));
219
  		    }
220
  		    query.addOrder(AuditEntity.revisionNumber().asc());
221
     	}
222

    
223
		if(pageSize != null) {
224
		    query.setMaxResults(pageSize);
225
		    if(pageNumber != null) {
226
		        query.setFirstResult(pageNumber * pageSize);
227
		    } else {
228
		    	query.setFirstResult(0);
229
		    }
230
		}
231

    
232
        /**
233
         * At the moment we need to transform the data manually
234
         */
235
        @SuppressWarnings("unchecked")
236
        List<Object[]> objs = query.getResultList();
237
        List<AuditEventRecord<T>> records = new ArrayList<AuditEventRecord<T>>();
238

    
239
        for(Object[] obj : objs) {
240
        	records.add(new AuditEventRecordImpl<T>(obj));
241
        }
242

    
243
        for(AuditEventRecord<T> record : records) {
244
        	defaultBeanInitializer.initialize(record.getAuditableObject(), propertyPaths);
245
        }
246
		return records;
247
	}
248

    
249
	@Override
250
    public long countAuditEvents(T t, AuditEventSort sort) {
251
		AuditEvent auditEvent = getAuditEventFromContext();
252

    
253
		AuditQuery query = getAuditReader().createQuery().forRevisionsOfEntity(type, false, true);
254
		query.add(AuditEntity.id().eq(t.getId()));
255

    
256
		if(!auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
257
			if(sort == null) {
258
				sort = AuditEventSort.BACKWARDS;
259
			}
260

    
261
			if(sort.equals(AuditEventSort.BACKWARDS)) {
262
				query.add(AuditEntity.revisionNumber().lt(auditEvent.getRevisionNumber()));
263
			} else {
264
				query.add(AuditEntity.revisionNumber().gt(auditEvent.getRevisionNumber()));
265
			}
266
		}
267

    
268
		query.addProjection(AuditEntity.revisionNumber().count());
269

    
270
		return (Long)query.getSingleResult();
271
	}
272

    
273
	@Override
274
    public AuditEventRecord<T> getNextAuditEvent(T t) {
275
		List<AuditEventRecord<T>> auditEvents = getAuditEvents(t,1,0,AuditEventSort.FORWARDS, null);
276
		if(auditEvents.isEmpty()) {
277
			return null;
278
		} else {
279
		    return auditEvents.get(0);
280
		}
281
	}
282

    
283
	@Override
284
    public AuditEventRecord<T> getPreviousAuditEvent(T t) {
285
		List<AuditEventRecord<T>> auditEvents = getAuditEvents(t,1,0,AuditEventSort.BACKWARDS, null);
286
		if(auditEvents.isEmpty()) {
287
			return null;
288
		} else {
289
		    return auditEvents.get(0);
290
		}
291
	}
292

    
293
	@Override
294
    public long countAuditEvents(Class<? extends T> clazz, AuditEvent from,	AuditEvent to, List<AuditCriterion> criteria) {
295
		AuditQuery query = null;
296

    
297
		if(clazz == null) {
298
		   query = getAuditReader().createQuery().forRevisionsOfEntity(type, false, true);
299
		} else {
300
		   query = getAuditReader().createQuery().forRevisionsOfEntity(clazz, false, true);
301
		}
302

    
303
		if(from != null) {
304
			query.add(AuditEntity.revisionNumber().ge(from.getRevisionNumber()));
305
		}
306

    
307
		if(to != null && !to.equals(AuditEvent.CURRENT_VIEW)) {
308
			query.add(AuditEntity.revisionNumber().lt(to.getRevisionNumber()));
309
		}
310

    
311
		addCriteria(query,criteria);
312

    
313
		query.addProjection(AuditEntity.revisionNumber().count());
314

    
315
		return (Long)query.getSingleResult();
316
	}
317

    
318
	protected void addCriteria(AuditQuery query, List<AuditCriterion> criteria) {
319
		if(criteria != null) {
320
			for(AuditCriterion c : criteria) {
321
				query.add(c);
322
			}
323
		}
324
	}
325

    
326
	@Override
327
    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) {
328
        AuditQuery query = null;
329

    
330
		if(clazz == null) {
331
		   query = getAuditReader().createQuery().forRevisionsOfEntity(type, false, true);
332
		} else {
333
		   query = getAuditReader().createQuery().forRevisionsOfEntity(clazz, false, true);
334
		}
335

    
336
		if(from != null) {
337
			query.add(AuditEntity.revisionNumber().ge(from.getRevisionNumber()));
338
		}
339

    
340
		if(to != null && !to.equals(AuditEvent.CURRENT_VIEW)) {
341
			query.add(AuditEntity.revisionNumber().lt(to.getRevisionNumber()));
342
		}
343

    
344
		if(sort.equals(AuditEventSort.BACKWARDS)) {
345
		    query.addOrder(AuditEntity.revisionNumber().desc());
346
     	} else {
347
  		    query.addOrder(AuditEntity.revisionNumber().asc());
348
     	}
349

    
350
		addCriteria(query,criteria);
351

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

    
361
		/**
362
         * At the moment we need to transform the data manually
363
         */
364
        @SuppressWarnings("unchecked")
365
        List<Object[]> objs = query.getResultList();
366
        List<AuditEventRecord<T>> records = new ArrayList<>();
367

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

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

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

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

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