Project

General

Profile

Download (38.4 KB) Statistics
| Branch: | Tag: | Revision:
1
package eu.etaxonomy.cdm.persistence.dao.hibernate.statistics;
2

    
3
import java.util.ArrayList;
4
import java.util.Arrays;
5
import java.util.HashMap;
6
import java.util.HashSet;
7
import java.util.List;
8
import java.util.Map;
9
import java.util.Set;
10
import java.util.UUID;
11

    
12
import org.apache.log4j.Logger;
13
import org.hibernate.Criteria;
14
import org.hibernate.Query;
15
import org.hibernate.criterion.Projections;
16
import org.hibernate.criterion.Restrictions;
17
import org.springframework.stereotype.Repository;
18

    
19
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
20
import eu.etaxonomy.cdm.model.taxon.Classification;
21
import eu.etaxonomy.cdm.model.taxon.Synonym;
22
import eu.etaxonomy.cdm.model.taxon.Taxon;
23
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
24
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
25
import eu.etaxonomy.cdm.persistence.dao.hibernate.common.DaoBase;
26
import eu.etaxonomy.cdm.persistence.dao.statistics.IStatisticsDao;
27

    
28
/**
29
 * this dao provides counting methods for elements in a database in general or
30
 * in a specific class (or tree - TODO) in the database.
31
 * 
32
 * only functionality, that is not covered by other daos is implemented
33
 * 
34
 * MAYDO: restructure and using {@link Criteria} and methods like prepareQuery
35
 * 
36
 * @author s.buers
37
 * 
38
 */
39

    
40
@Repository
41
public class StatisticsDaoHibernateImpl extends DaoBase implements
42
		IStatisticsDao {
43

    
44
	// TODO remove every commented query related to
45
	// DescriptionBase.descriptionSources
46

    
47
	/*
48
	 * (non-Javadoc)
49
	 * 
50
	 * @see eu.etaxonomy.cdm.persistence.dao.statistics.IStatisticsDao#
51
	 * countDescriptiveSourceReferences()
52
	 */
53

    
54
	private static final int REFERENCE_LINK_RECURSION_DEPTH = 1;
55

    
56
	private static final Logger logger = Logger
57
			.getLogger(StatisticsDaoHibernateImpl.class);
58

    
59
	@Override
60
	public Long countDescriptiveSourceReferences() {
61

    
62
		List<String> queryStrings = new ArrayList<String>();
63

    
64
		// this query does not work...
65

    
66
		// query = getSession().createQuery(
67
		// "select count(distinct(r.id, desc.id)) from DescriptionBase as d "
68
		// + "join d.descriptionElements as de "
69
		// + "join de.sources as des "
70
		// + "join des.citation as desc "
71
		// + "join d.descriptionSources as r "
72
		// + "where "
73
		// + "desc is not null"
74
		// + " and "
75
		// + "r is not null ");
76

    
77
		// ... here is the manual version:
78

    
79
		// count sources from Descriptions:
80
		// as the descriptionSources of DescriptionBase are depricated:
81
		// queryStrings.add("select distinct r.id from DescriptionBase as d "
82
		// + "join d.descriptionSources as r ");
83

    
84
		// count sources from DescriptionElements:
85
		queryStrings
86
				.add("select distinct s.citation.uuid from DescriptionElementBase as d "
87
						+ "join d.sources as s where s.citation is not null ");
88

    
89
		return Long.valueOf(processQueriesWithIdDistinctListResult(
90
				queryStrings, null).size());
91
	}
92

    
93
	/*
94
	 * (non-Javadoc)
95
	 * 
96
	 * @see eu.etaxonomy.cdm.persistence.dao.statistics.IStatisticsDao#
97
	 * countDescriptiveSourceReferences
98
	 * (eu.etaxonomy.cdm.model.taxon.Classification)
99
	 */
100
	@Override
101
	public Long countDescriptive(Boolean sourceRef,
102
			Classification classification) {
103
		return Long.valueOf(listDescriptiveIds(sourceRef, classification)
104
				.size());
105
	}
106

    
107
	// private Set<Integer> listDescriptiveSourceReferenceIds(
108
	// Classification classification) {
109
	//
110
	// if (classification == null)
111
	// return null; // or MAYDO: throw some Exception???
112
	//
113
	// Map<String, Object> parameters = new HashMap<String, Object>();
114
	//
115
	// List<String> queryStrings = new ArrayList<String>();
116
	//
117
	// // // Taxon description elements:
118
	// queryStrings
119
	// .add("select distinct des.citation.id from TaxonNode as tn "
120
	// + "join tn.taxon.descriptions as d "
121
	// + "join d.descriptionElements as de "
122
	// + "join de.sources as des "
123
	// + "where tn.classification=:classification "
124
	// + "and des.citation is not null ");
125
	//
126
	// parameters.put("classification", classification);
127
	//
128
	// // TaxonNameBase description elements for taxa:
129
	// queryStrings.add("select distinct des.citation.id from TaxonNode tn "
130
	// + "join tn.taxon.name.descriptions as d "
131
	// + "join d.descriptionElements as de "
132
	// + "join de.sources as des "
133
	// + "where tn.classification=:classification "
134
	// + "and tn.taxon is not null "
135
	// + "and tn.taxon.name is not null "
136
	// + "and des.citation is not null ");
137
	//
138
	// // TaxonNameBase description elements for synonyms:
139
	// queryStrings.add("select distinct des.citation.id from TaxonNode tn "
140
	// + "join tn.taxon.synonymRelations as syr "
141
	// + "join syr.relatedFrom as sy "
142
	// + "join sy.name.descriptions as d "
143
	// + "join d.descriptionElements as de "
144
	// + "join de.sources as des "
145
	// + "where tn.classification=:classification "
146
	// + "and des.citation is not null " + "and sy is not null " // TODO:
147
	// // is
148
	// // this
149
	// // case
150
	// // actually
151
	// // possible???
152
	// + "and sy.name is not null ");
153
	//
154
	// // SpecimenOrObservationBase description elements:
155
	// // 1. via determinations
156
	// queryStrings
157
	// .add("select distinct des.citation.id from DescriptionBase db, TaxonNode tn "
158
	// + "join db.describedSpecimenOrObservation as so "
159
	// + "join so.determinations as det "
160
	// + "join db.descriptionElements as de "
161
	// + "join de.sources as des "
162
	// + "where tn.classification=:classification "
163
	// + "and tn.taxon=det.taxon ");
164
	//
165
	// // 2. via derived units in taxon description
166
	// // already done with the taxon/synonym descriptions
167
	//
168
	// // 3. via SpecimenTypeDesignation in TaxonName:
169
	// // a. taxon names:
170
	// queryStrings.add("select distinct des.citation.id from TaxonNode tn "
171
	// + " join tn.taxon.name.typeDesignations as tdes "
172
	// + "join tdes.typeSpecimen.descriptions as d "
173
	// + "join d.descriptionElements as de "
174
	// + "join de.sources as des "
175
	// + "where tn.classification=:classification "
176
	// + "and tdes.class=:type " + "and tn.taxon is not null "
177
	// + "and tn.taxon.name is not null "
178
	// + "and des.citation is not null ");
179
	//
180
	// parameters.put("type", "SpecimenTypeDesignation");
181
	//
182
	// // b. synonym names:
183
	// queryStrings.add("select distinct des.citation.id from TaxonNode tn "
184
	//
185
	// + "join tn.taxon.synonymRelations as syr "
186
	// + "join syr.relatedFrom as sy "
187
	// + " join sy.name.typeDesignations as tdes "
188
	// + "join tdes.typeSpecimen.descriptions as d "
189
	// + "join d.descriptionElements as de "
190
	// + "join de.sources as des "
191
	// + "where tn.classification=:classification "
192
	// + "and tdes.class=:type " + "and tn.taxon is not null "
193
	// + "and sy.name is not null " + "and des.citation is not null ");
194
	//
195
	// // 4. via HomotypicalGroup in TaxonBase
196
	// // we get this automatically with the names
197
	//
198
	// return processQueriesWithIdDistinctListResult(queryStrings, parameters);
199
	//
200
	// }
201

    
202
	private Set<UUID> listDescriptiveIds(Boolean sourceReferences,
203
			Classification classification) {
204

    
205
		// Boolean sourceReferences = true;
206
		String sourceRefJoins = "";
207
		String sourceRefWhere = "";
208
//		String selection = "d.id ";
209
		String selection = "d.uuid ";
210

    
211
		if (sourceReferences) {
212
			sourceRefJoins = "join d.descriptionElements as de "
213
					+ "join de.sources as des ";
214
			sourceRefWhere = "and des.citation is not null ";
215
//			selection = "des.citation.id ";
216
			selection = "des.citation.uuid ";
217
		}
218

    
219
		if (classification == null)
220
			return null; // or MAYDO: throw some Exception???
221

    
222
		Map<String, Object> parameters = new HashMap<String, Object>();
223

    
224
		List<String> queryStrings = new ArrayList<String>();
225

    
226
		// // Taxon description elements:
227
		queryStrings.add("select distinct " + selection
228
				+ "from TaxonNode as tn " + "join tn.taxon.descriptions as d "
229
				+ sourceRefJoins + "where tn.classification=:classification "
230
				+ sourceRefWhere);
231

    
232
		parameters.put("classification", classification);
233

    
234
		// TaxonNameBase description elements for taxa:
235
		queryStrings.add("select distinct " + selection + "from TaxonNode tn "
236
				+ "join tn.taxon.name.descriptions as d " + sourceRefJoins
237
				+ "where tn.classification=:classification "
238
				+ "and tn.taxon is not null "
239
				+ "and tn.taxon.name is not null " + sourceRefWhere);
240

    
241
		// TaxonNameBase description elements for synonyms:
242
		queryStrings.add("select distinct " + selection + "from TaxonNode tn "
243
				+ "join tn.taxon.synonymRelations as syr "
244
				+ "join syr.relatedFrom as sy "
245
				+ "join sy.name.descriptions as d " + sourceRefJoins
246
				+ "where tn.classification=:classification " + sourceRefWhere
247
				+ "and sy is not null " // TODO:
248
										// is
249
										// this
250
										// case
251
										// actually
252
										// possible???
253
				+ "and sy.name is not null ");
254

    
255
		// SpecimenOrObservationBase description elements:
256
		// 1. via determinations
257
		queryStrings.add("select distinct " + selection
258
				+ "from DescriptionBase d, TaxonNode tn "
259
				+ "join d.describedSpecimenOrObservation as so "
260
				+ "join so.determinations as det " + sourceRefJoins
261
				+ "where tn.classification=:classification "
262
				+ "and tn.taxon=det.taxon " + sourceRefWhere);
263

    
264
		// 2. via derived units in taxon description
265
		// already done with the taxon/synonym descriptions
266

    
267
		// 3. via SpecimenTypeDesignation in TaxonName:
268
		// a. taxon names:
269
		queryStrings.add("select distinct " + selection + "from TaxonNode tn "
270
				+ " join tn.taxon.name.typeDesignations as tdes "
271
				+ "join tdes.typeSpecimen.descriptions as d " + sourceRefJoins
272
				+ "where tn.classification=:classification "
273
				+ "and tdes.class=:type " + "and tn.taxon is not null "
274
				+ "and tn.taxon.name is not null " + sourceRefWhere);
275

    
276
		parameters.put("type", "SpecimenTypeDesignation");
277

    
278
		// b. synonym names:
279
		queryStrings.add("select distinct " + selection + "from TaxonNode tn "
280

    
281
		+ "join tn.taxon.synonymRelations as syr "
282
				+ "join syr.relatedFrom as sy "
283
				+ " join sy.name.typeDesignations as tdes "
284
				+ "join tdes.typeSpecimen.descriptions as d " + sourceRefJoins
285
				+ "where tn.classification=:classification "
286
				+ "and tdes.class=:type " + "and tn.taxon is not null "
287
				+ "and sy.name is not null " + sourceRefWhere);
288

    
289
		// 4. via HomotypicalGroup in TaxonBase
290
		// we get this automatically with the names
291

    
292
		//###TODO
293
		return processQueriesWithIdDistinctListResult(queryStrings, parameters);
294
//		return null;
295
	}
296

    
297
	/*
298
	 * (non-Javadoc)
299
	 * 
300
	 * @see eu.etaxonomy.cdm.persistence.dao.statistics.IStatisticsDao#
301
	 * countTaxaInClassification(java.lang.Class,
302
	 * eu.etaxonomy.cdm.model.taxon.Classification)
303
	 */
304
	@Override
305
	public Long countTaxaInClassification(Class<? extends TaxonBase> clazz,
306
			Classification classification) {
307
		if (classification == null)
308
			return null; // or MAYDO: throw some Exception???
309

    
310
		if (clazz.equals(TaxonBase.class)) {
311

    
312
			return countTaxaInClassification(Taxon.class, classification)
313
					+ countTaxaInClassification(Synonym.class, classification);
314
		}
315

    
316
		if (clazz.equals(Taxon.class)) {
317
			Criteria criteria = getSession().createCriteria(TaxonNode.class);
318

    
319
			criteria.add(Restrictions.eq("classification", classification));
320
			criteria.setProjection(Projections.rowCount());
321
			return Long.valueOf((Long) criteria.uniqueResult());
322
		}
323

    
324
		else if (clazz.equals(Synonym.class)) {
325
			// criteria= getSession().createCriteria(TaxonNode.class);
326

    
327
			Query query = getSession().createQuery(
328
					"select count(distinct sr.relatedFrom.uuid) from TaxonNode tn "
329
							+ "join tn.taxon.synonymRelations as sr "
330
							+ "where tn.classification=:classification ");
331
			query.setParameter("classification", classification);
332
			return (Long) query.uniqueResult();
333
		}
334
		// this should never happen:
335
		return null;
336

    
337
	}
338

    
339
	/*
340
	 * (non-Javadoc)
341
	 * 
342
	 * @see
343
	 * eu.etaxonomy.cdm.persistence.dao.statistics.IStatisticsDao#countTaxonNames
344
	 * (eu.etaxonomy.cdm.model.taxon.Classification)
345
	 */
346
	@Override
347
	public Long countTaxonNames(Classification classification) {
348

    
349
		if (classification == null)
350
			return null; // or MAYDO: throw some Exception???
351

    
352
		Map<String, Object> parameters = new HashMap<String, Object>();
353

    
354
		parameters.put("classification", classification);
355
		// the query would be:
356
		// "select count (distinct n) from (
357
		// + "select distinct tn.taxon.name as c from TaxonNode tn "
358
		// + "where tn.classification=:classification "
359
		// + "UNION "
360
		// + "select distinct sr.relatedFrom.name as c from TaxonNode tn "
361
		// + "join tn.taxon.synonymRelations sr "
362
		// + "where tn.classification=:classification "
363
		// ") as n "
364

    
365
		// as hibernate does not accept brackets in from and no unions
366
		// we have to do it otherwise:
367

    
368
		// so instead of "UNION" we use 2 queries
369
		// and count the names manually
370
		List<String> queryStrings = new ArrayList<String>();
371
		queryStrings
372
				.add("select distinct tn.taxon.name.uuid as c from TaxonNode tn "
373
						+ "where tn.classification=:classification "
374
						+ "and tn.taxon.name is not null ");
375
		queryStrings
376
				.add("select distinct sr.relatedFrom.name.uuid as c from TaxonNode tn "
377
						+ "join tn.taxon.synonymRelations sr "
378
						+ "where tn.classification=:classification "
379
						+ "and sr.relatedFrom.name is not null ");
380

    
381
		return Long.valueOf(processQueriesWithIdDistinctListResult(
382
				queryStrings, parameters).size());
383

    
384
	}
385

    
386
	/*
387
	 * (non-Javadoc)
388
	 * 
389
	 * @see eu.etaxonomy.cdm.persistence.dao.statistics.IStatisticsDao#
390
	 * countNomenclaturalReferences()
391
	 */
392
	// @Override
393
	public Long countNomenclaturalReferences() {
394
		Query query = getSession()
395
				.createQuery(
396
						"select count(distinct nomenclaturalReference) from TaxonNameBase ");
397
		return (Long) query.uniqueResult();
398
	}
399

    
400

    
401
	 @Override
402
	public Long countNomenclaturalReferences(
403
			Classification classification) {
404

    
405
		if (classification == null)
406
			return null; // or MAYDO: throw some Exception???
407

    
408
		Map<String, Object> parameters = new HashMap<String, Object>();
409

    
410
		parameters.put("classification", classification);
411
		// so instead of "UNION" we use 2 queries
412
		// and count the names manually
413
		List<String> queryStrings = new ArrayList<String>();
414
		queryStrings
415
				.add("select distinct tn.taxon.name.nomenclaturalReference.uuid from TaxonNode tn "
416
						+ "where tn.classification=:classification "
417
						+ "and tn.taxon.name.nomenclaturalReference is not null ");
418
		queryStrings
419
				.add("select distinct sr.relatedFrom.name.nomenclaturalReference.uuid as c from TaxonNode tn "
420
						+ "join tn.taxon.synonymRelations as sr "
421
						+ "where tn.classification=:classification "
422
						+ "and sr.relatedFrom.name.nomenclaturalReference is not null ");
423

    
424
		return Long.valueOf(processQueriesWithIdDistinctListResult(
425
				queryStrings, parameters).size());
426
	}
427

    
428

    
429
	@Override
430
	public Long countReferencesInClassificationWithUuids(Classification classification) {
431
		if (classification == null)
432
			return null; // or MAYDO: throw some Exception???
433

    
434
		// get all the descriptive source reference ids
435
		// ---------------------------------------------
436

    
437
		// preparation
438
		List<String> queryStrings = new ArrayList<String>();
439
		Map<String, Object> parameters = new HashMap<String, Object>();
440

    
441
		parameters.put("classification", classification);
442

    
443
		// get the ids from the Descriptive source references to add them to the
444
		// count
445
		
446
		//TODO
447
		//Set<Integer> ids = listDescriptiveIds(true, classification);
448
		Set<UUID> ids = new HashSet<UUID>();
449
		
450
		// get classification reference
451
		queryStrings.add("select c.reference.uuid from Classification as c "
452
				+ "where c.uuid=:classificationId ");
453
		// TODO ???
454
		// +"join c.souces as s "
455
		// +"join s.citation "
456

    
457
		parameters.put("classificationId", classification.getUuid());
458

    
459
		// get node relations references:
460
		queryStrings
461
				.add("select distinct tn.referenceForParentChildRelation.uuid as c from TaxonNode tn "
462
						+ "where tn.classification=:classification "
463
						+ "and tn.referenceForParentChildRelation is not null ");
464

    
465
		// get sec references
466
		// -------------------------------------------------------------------
467
		// taxa
468
		queryStrings
469
				.add("select distinct tn.taxon.sec.uuid as c from TaxonNode tn "
470
						+ "where tn.classification=:classification "
471
						+ "and tn.taxon.sec is not null ");
472

    
473
		// synonyms
474
		queryStrings
475
				.add("select distinct sr.relatedFrom.sec.uuid as c from TaxonNode tn "
476
						+ "join tn.taxon.synonymRelations sr "
477
						+ "where tn.classification=:classification "
478
						+ "and sr.relatedFrom.sec is not null ");
479

    
480
		// get relationship citations
481
		// ---------------------------------------------------------------
482

    
483
		// taxon relations
484
		queryStrings.add("select distinct tr.citation.uuid from TaxonNode tn "
485
				+ "join tn.taxon.relationsFromThisTaxon as tr "
486
				+ "where tn.classification=:classification "
487
				+ "and tn.taxon is not null " + "and tr.citation is not null ");
488

    
489
		// synonym relations
490

    
491
		queryStrings.add("select distinct sr.citation.uuid from TaxonNode tn "
492
				+ "join tn.taxon.synonymRelations as sr "
493
				+ "where tn.classification=:classification "
494
				+ "and tn.taxon is not null " + "and sr.citation is not null ");
495

    
496
		// get hybrid relation citations
497
		// Taxa:
498
		queryStrings.add("select distinct hr.citation.uuid from TaxonNode tn "
499
				+ "join tn.taxon.name.hybridParentRelations as hr "
500
				+ "where tn.classification=:classification "
501
				+ "and tn.taxon.name.class=:nonViralName "
502
				+ "and tn.taxon is not null "
503
				+ "and tn.taxon.name is not null ");
504

    
505
		parameters.put("nonViralName", "NonViralName");
506

    
507
		// synonyms:
508
		queryStrings.add("select distinct hr.citation.uuid from TaxonNode tn "
509
				+ "join tn.taxon.synonymRelations as syr "
510
				+ "join syr.relatedFrom as sy "
511
				+ "join sy.name.hybridParentRelations as hr "
512
				+ "where tn.classification=:classification "
513
				+ "and sy.name.class=:nonViralName " + "and sy is not null " // TODO:
514
																				// is
515
																				// this
516
																				// case
517
																				// actually
518
																				// possible???
519
				+ "and sy.name is not null ");
520

    
521
		// get name relations references:
522
		// -------------------------------------------------------
523
		// Taxa:
524
		queryStrings.add("select distinct nr.citation.uuid from TaxonNode tn "
525
				+ "join tn.taxon.name.relationsFromThisName as nr "
526
				+ "where tn.classification=:classification "
527
				+ "and tn.taxon is not null "
528
				+ "and tn.taxon.name is not null ");
529

    
530
		// synonyms:
531
		queryStrings.add("select distinct nr.citation.uuid from TaxonNode tn "
532
				+ "join tn.taxon.synonymRelations as syr "
533
				+ "join syr.relatedFrom as sy "
534
				+ "join sy.name.relationsFromThisName as nr "
535
				+ "where tn.classification=:classification "
536
				+ "and sy is not null " // TODO: is this case actually
537
										// possible???
538
				+ "and sy.name is not null ");
539

    
540
		// get Nomenclatural status citation
541

    
542
		// Taxa:
543
		queryStrings.add("select distinct s.citation.uuid from TaxonNode tn "
544
				+ "join tn.taxon.name.status as s "
545
				+ "where tn.classification=:classification "
546
				+ "and tn.taxon is not null "
547
				+ "and tn.taxon.name is not null ");
548

    
549
		// synonyms:
550
		queryStrings.add("select distinct s.citation.uuid from TaxonNode tn "
551
				+ "join tn.taxon.synonymRelations as syr "
552
				+ "join syr.relatedFrom as sy " + "join sy.name.status as s "
553
				+ "where tn.classification=:classification "
554
				+ "and sy is not null " // TODO: is this case actually
555
										// possible???
556
				+ "and sy.name is not null ");
557

    
558
		// get sequences which contain citations and publishedIn ------
559
		// and contain "Media" which could be of the subtype
560
		// "ReferencedMediaBase"
561
		// which has a citation
562

    
563
		queryStrings.add("select distinct cit.uuid " + " from TaxonNode tn "
564
				+ "join tn.taxon.descriptions as db "
565

    
566
				+ "join db.describedSpecimenOrObservation as so "
567
				+ "join so.sequences as seq " + "join seq.citations as cit "
568

    
569
				+ "where so.class=:dnaSample "
570
				+ "and tn.classification=:classification "
571
				+ "and cit is not null ");
572

    
573
		// traverse to specimenOrObservation via individualsAssociation
574

    
575
		queryStrings.add("select distinct cit.uuid from TaxonNode tn "
576
				+ "join tn.taxon.descriptions as db "
577
				+ "join db.descriptionElements as ia "
578
				+ "join ia.associatedSpecimenOrObservation as so "
579
				+ "join so.sequences as seq " + "join seq.citations as cit "
580

    
581
				+ "where so.class=:dnaSample "
582
				+ "and ia.class=:individualsAssociation "
583
				+ "and tn.classification=:classification "
584
				+ "and cit is not null ");
585

    
586
		// we do assume, that a name description would not have a
587
		// SpecimenOrObservation element
588

    
589
		//
590
		parameters.put("dnaSample", "DnaSample");
591
		parameters.put("individualsAssociation", "IndividualsAssociation");
592

    
593
		//
594
		//
595
		// //### TODO v3.3, preliminary removed for adaptation to model v3.3
596
		// this was all about ReferencedMedia
597
		{
598
			// // media
599
			// queryStrings.add("select distinct me.citation.id from TaxonNode tn "
600
			// + "join tn.taxon.descriptions as db "
601
			// + "join db.describedSpecimenOrObservation as so "
602
			// + "join so.sequences as seq "
603
			// + "join seq.chromatograms as me "
604
			//
605
			// + "where so.class=:dnaSample "
606
			// + "and me.class=:referencedMediaBase "
607
			// + "and tn.classification=:classification "
608
			//
609
			// + "and me.citation is not null ");
610
			//
611
			// // traverse to specimenOrObservation via individualsAssociation
612
			//
613
			// queryStrings.add("select distinct me.citation.id from TaxonNode tn "
614
			// + "join tn.taxon.descriptions as db "
615
			// + "join db.descriptionElements as ia "
616
			// + "join ia.associatedSpecimenOrObservation as so "
617
			// + "join so.sequences as seq "
618
			// + "join seq.chromatograms as me "
619
			// + "where so.class=:dnaSample "
620
			// + "and ia.class=:individualsAssociation "
621
			// + "and me.class=:referencedMediaBase "
622
			// + "and tn.classification=:classification "
623
			//
624
			// + "and me.citation is not null ");
625
			//
626
			// // TODO v3.3, preliminary removed for adaptation to model v3.3,
627
			// Media.citation does not exist anymore, use OriginalSource instead
628
			// // via media via name description
629
			// // Taxa:
630
			// queryStrings.add("select distinct me.citation.id from TaxonNode tn "
631
			// + "join tn.taxon.name.descriptions as d "
632
			// + "join d.descriptionElements as de "
633
			// + "join de.media as me "
634
			// + "where tn.classification=:classification "
635
			// + "and tn.taxon.name is not null "
636
			// + "and me.class=:referencedMediaBase "
637
			// + "and me.citation is not null " + "and tn.taxon is not null "
638
			// + "and tn.taxon.name is not null ");
639
			//
640
			// // synonyms:
641
			// queryStrings.add("select distinct me.citation.id from TaxonNode tn "
642
			// + "join tn.taxon.synonymRelations as syr "
643
			// + "join syr.relatedFrom as sy "
644
			// + "join sy.name.descriptions as d "
645
			// + "join d.descriptionElements as de "
646
			// + "join de.media as me "
647
			// + "where tn.classification=:classification "
648
			// + "and sy.name is not null "
649
			// + "and me.class=:referencedMediaBase "
650
			// + "and me.citation is not null " + "and tn.taxon is not null "
651
			// + "and tn.taxon.name is not null ");
652
			//
653
			// // get all "Media" from everywhere because it could be
654
			// // of the subtype "ReferencedMediaBase"
655
			// // which has a citation
656
			//
657
			// // TODO do we need the media from DefinedTermBase???
658
			// // what can be a Feature!
659
			//
660
			// // from description element
661
			// queryStrings.add("select distinct me.citation.id from TaxonNode as tn "
662
			// + "join tn.taxon.descriptions as d "
663
			// + "join d.descriptionElements as de "
664
			// + "join de.media as me "
665
			// + "where tn.classification=:classification "
666
			// + "and me.class=:referencedMediaBase "
667
			// + "and me.citation is not null ");
668
			//
669
			// // via NamedArea that has 2 media parameter
670
			// // and a waterbodyOrContinet that has media parameter and has
671
			// continent
672
			// // parameter
673
			// // which also has media parameter:
674
			//
675
			//
676
			//
677
			// // from CommonTaxonName or Distribution
678
			// queryStrings
679
			// .add("select distinct de.area.shape.citation.id, me1.citation.id, "
680
			// + "me2.citation.id, me3.citation.id from TaxonNode as tn "
681
			// + "join tn.taxon.descriptions as d "
682
			// + "join d.descriptionElements as de "
683
			// + "join de.area.media as me1 "
684
			// + "join de.area.waterbodiesOrCountries as wboc "
685
			// + "join wboc.media as me2 "
686
			// + "join wboc.continents as co "
687
			// + "join co.media as me3 "
688
			// + "where tn.classification=:classification "
689
			// + "and (de.class=:commonTaxonName or de.class=:distribution) "
690
			// + "and me1.class=:referencedMediaBase "
691
			// + "and me1.citation is not null "
692
			// + "and me2.class=:referencedMediaBase "
693
			// + "and me2.citation is not null "
694
			// + "and me3.class=:referencedMediaBase "
695
			// + "and me3.citation is not null "
696
			// + "and de.area.shape.class=:referencedMediaBase "
697
			// + "and de.area is not null "
698
			// + "and de.area.shape is not null ");
699
			//
700
			// parameters.put("commonTaxonName", "CommonTaxonName");
701
			// parameters.put("distribution", "Distribution");
702
			// //***
703
			// // from TaxonDescription:
704
			// queryStrings
705
			// .add("select distinct na.shape.citation.id, me1.citation.id, "
706
			// + "me2.citation.id, me3.citation.id from TaxonNode as tn "
707
			// + "join tn.taxon.descriptions as d "
708
			// + "join d.geoScopes as na " + "join na.media as me1 "
709
			// + "join na.waterbodiesOrCountries as wboc "
710
			// + "join wboc.media as me2 "
711
			// + "join wboc.continents as co "
712
			// + "join co.media as me3 "
713
			// + "where tn.classification=:classification "
714
			// + "and me1.class=:referencedMediaBase "
715
			// + "and me1.citation is not null "
716
			// + "and me2.class=:referencedMediaBase "
717
			// + "and me2.citation is not null "
718
			// + "and me3.class=:referencedMediaBase "
719
			// + "and me3.citation is not null "
720
			// + "and na.shape.class=:referencedMediaBase "
721
			// + "and na.shape is not null ");
722
			//
723
			// // from gathering event
724
			// queryStrings
725
			// .add("select fo.gatheringEvent.country.shape.citation.id, ca.shape.citation.id "
726
			// +
727
			// " from TaxonNode tn "
728
			// + "join tn.taxon.descriptions as db "
729
			// + "join db.describedSpecimenOrObservation as fo "
730
			// + "join fo.gatheringEvent.collectingAreas as ca "
731
			// + "where fo.class=:fieldObservation "
732
			// + "and fo.gatheringEvent is not null "
733
			// + "and fo.gatheringEvent.country is not null "
734
			// + "and fo.gatheringEvent.country.shape is not null "
735
			// + "and ca.shape is not null "
736
			// + "and ca.shape.class=:referencedMediaBase "
737
			// + "and ca.shape.citation is not null "
738
			// +
739
			// "and fo.gatheringEvent.country.shape.class=:referencedMediaBase "
740
			// + " and fo.gatheringEvent.country.shape.citation is not null "
741
			// + "and tn.classification=:classification ");
742
			//
743
			// // traverse to specimenOrObservation via individualsAssociation
744
			//
745
			// queryStrings
746
			// .add("select fo.gatheringEvent.country.shape.citation.id, ca.shape.citation.id "
747
			// + "from TaxonNode tn "
748
			// + "join tn.taxon.descriptions as db "
749
			// + "join db.descriptionElements as ia "
750
			// + "join ia.associatedSpecimenOrObservation as fo "
751
			// + "join fo.gatheringEvent.collectingAreas as ca "
752
			// + "where fo.class=:fieldObservation "
753
			// + "and fo.gatheringEvent is not null "
754
			// + "and fo.gatheringEvent.country is not null "
755
			// + "and fo.gatheringEvent.country.shape is not null "
756
			// + "and ca.shape is not null "
757
			// + "and ca.shape.class=:referencedMediaBase "
758
			// + "and ca.shape.citation is not null "
759
			// +
760
			// "and fo.gatheringEvent.country.shape.class=:referencedMediaBase "
761
			// + " and fo.gatheringEvent.country.shape.citation is not null "
762
			// + "and ia.class=:individualsAssociation "
763
			// + "and tn.classification=:classification ");
764
			//
765
			//
766
			//
767
			// parameters.put("fieldObservation", "FieldObservation");
768
			// parameters.put("referencedMediaBase", "ReferencedMediaBase");
769
			//
770
			// parameters.put("classification", classification);
771
			//
772
			// // via events
773
			// // ----------------------------------------
774
			// // determination event:
775
			// // taxa
776
			// queryStrings
777
			// .add("select distinct sor.id from DeterminationEvent dtev, TaxonNode tn "
778
			// + "join dtev.setOfReferences as sor "
779
			//
780
			// + "where tn.classification=:classification "
781
			// + "and tn.taxon=dtev.taxon ");
782
			//
783
			// // synonyms
784
			//
785
			// queryStrings
786
			// .add("select distinct sor.id from DeterminationEvent dtev, TaxonNode tn "
787
			// + "join dtev.setOfReferences as sor "
788
			// + "join tn.taxon.synonymRelations as syr "
789
			// + "join syr.relatedTo as sy "
790
			// + "where tn.classification=:classification "
791
			// + "and sy=dtev.taxon ");
792
			//
793
		}
794

    
795
		// ------------------------------------------------------------------
796
		// TODO get all objects that inherit IdentifiableEntity because it has
797
		// an
798
		// IdentifiableSource which inherits from OriginalSourceBase
799
		// which inherits from ReferencedEntityBase
800
		// which has a citation
801
		// furthermore recources can recursivly link to recources:
802
		// get sources of all references from ids and add the references of
803
		// the sources...
804
		// iterate in a certain depth REFERENCE_LINK_RECURSION_DEPTH
805

    
806
		// ----------------------------------------------------------
807

    
808
		ids.addAll(processQueriesWithIdDistinctListResult(queryStrings,
809
				parameters));
810

    
811
		return Long.valueOf(ids.size());
812
	}
813

    
814

    
815
	// TODO!!!
816
	// TODO this is the old reference counter where i counted the referenced
817
	// media as well and fetched ids from the database to erase dublettes
818
	@Override
819
	public Long countReferencesInClassification(Classification classification) {
820
		if (classification == null)
821
			return null; // or MAYDO: throw some Exception???
822

    
823
		// get all the descriptive source reference ids
824
		// ---------------------------------------------
825

    
826
		// preparation
827
		List<String> queryStrings = new ArrayList<String>();
828
		Map<String, Object> parameters = new HashMap<String, Object>();
829

    
830
		parameters.put("classification", classification);
831

    
832
		// get the ids from the Descriptive source references to add them to the
833
		// count
834
		//###TODO
835
//		Set<Integer> ids = listDescriptiveIds(true, classification);
836

    
837
		// get classification reference
838
		queryStrings.add("select count(c.reference.id) from Classification as c "
839
				+ "where c.id=:classificationId ");
840
		// TODO ???
841
		// +"join c.souces as s "
842
		// +"join s.citation "
843

    
844
		parameters.put("classificationId", classification.getId());
845

    
846
		// get node relations references:
847
		queryStrings
848
				.add("select count(distinct tn.referenceForParentChildRelation.id) as c from TaxonNode tn "
849
						+ "where tn.classification=:classification "
850
						+ "and tn.referenceForParentChildRelation is not null ");
851

    
852
		// get sec references
853
		// -------------------------------------------------------------------
854
		// taxa
855
		queryStrings
856
				.add("select count(distinct tn.taxon.sec.id) as c from TaxonNode tn "
857
						+ "where tn.classification=:classification "
858
						+ "and tn.taxon.sec is not null ");
859

    
860
		// synonyms
861
		queryStrings
862
				.add("select count(distinct sr.relatedFrom.sec.id) as c from TaxonNode tn "
863
						+ "join tn.taxon.synonymRelations sr "
864
						+ "where tn.classification=:classification "
865
						+ "and sr.relatedFrom.sec is not null ");
866

    
867
		// get relationship citations
868
		// ---------------------------------------------------------------
869

    
870
		// taxon relations
871
		queryStrings.add("select count(distinct tr.citation.id) from TaxonNode tn "
872
				+ "join tn.taxon.relationsFromThisTaxon as tr "
873
				+ "where tn.classification=:classification "
874
				+ "and tn.taxon is not null " + "and tr.citation is not null ");
875

    
876
		// synonym relations
877
//TODO
878
		queryStrings.add("select count(distinct sr.citation.id) from TaxonNode tn "
879
				+ "join tn.taxon.synonymRelations as sr "
880
				+ "where tn.classification=:classification "
881
				+ "and tn.taxon is not null " + "and sr.citation is not null ");
882

    
883
		// get hybrid relation citations
884
		// Taxa:
885
		queryStrings.add("select count(distinct hr.citation.id) from TaxonNode tn "
886
				+ "join tn.taxon.name.hybridParentRelations as hr "
887
				+ "where tn.classification=:classification "
888
				+ "and tn.taxon.name.class=:nonViralName "
889
				+ "and tn.taxon is not null "
890
				+ "and tn.taxon.name is not null ");
891

    
892
		parameters.put("nonViralName", "NonViralName");
893

    
894
		// synonyms:
895
		queryStrings.add("select count(distinct hr.citation.id) from TaxonNode tn "
896
				+ "join tn.taxon.synonymRelations as syr "
897
				+ "join syr.relatedFrom as sy "
898
				+ "join sy.name.hybridParentRelations as hr "
899
				+ "where tn.classification=:classification "
900
				+ "and sy.name.class=:nonViralName " + "and sy is not null " // TODO:
901
																				// is
902
																				// this
903
																				// case
904
																				// actually
905
																				// possible???
906
				+ "and sy.name is not null ");
907

    
908
		// get name relations references:
909
		// -------------------------------------------------------
910
		// Taxa:
911
		queryStrings.add("select count(distinct nr.citation.id) from TaxonNode tn "
912
				+ "join tn.taxon.name.relationsFromThisName as nr "
913
				+ "where tn.classification=:classification "
914
				+ "and tn.taxon is not null "
915
				+ "and tn.taxon.name is not null ");
916

    
917
		// synonyms:
918
		queryStrings.add("select count(distinct nr.citation.id) from TaxonNode tn "
919
				+ "join tn.taxon.synonymRelations as syr "
920
				+ "join syr.relatedFrom as sy "
921
				+ "join sy.name.relationsFromThisName as nr "
922
				+ "where tn.classification=:classification "
923
				+ "and sy is not null " // TODO: is this case actually
924
										// possible???
925
				+ "and sy.name is not null ");
926

    
927
		// get Nomenclatural status citation
928

    
929
		// Taxa:
930
		queryStrings.add("select count(distinct s.citation.id) from TaxonNode tn "
931
				+ "join tn.taxon.name.status as s "
932
				+ "where tn.classification=:classification "
933
				+ "and tn.taxon is not null "
934
				+ "and tn.taxon.name is not null ");
935

    
936
		// synonyms:
937
		queryStrings.add("select count(distinct s.citation.id) from TaxonNode tn "
938
				+ "join tn.taxon.synonymRelations as syr "
939
				+ "join syr.relatedFrom as sy " + "join sy.name.status as s "
940
				+ "where tn.classification=:classification "
941
				+ "and sy is not null " // TODO: is this case actually
942
										// possible???
943
				+ "and sy.name is not null ");
944

    
945
		// get sequences which contain citations and publishedIn ------
946
		// and contain "Media" which could be of the subtype
947
		// "ReferencedMediaBase"
948
		// which has a citation
949

    
950
		queryStrings.add("select count(distinct cit.id) from TaxonNode tn "
951
				+ "join tn.taxon.descriptions as db "
952

    
953
				+ "join db.describedSpecimenOrObservation as so "
954
				+ "join so.sequences as seq " + "join seq.citations as cit "
955

    
956
				+ "where so.class=:dnaSample "
957
				+ "and tn.classification=:classification "
958
				+ "and cit is not null ");
959

    
960
		// traverse to specimenOrObservation via individualsAssociation
961

    
962
		queryStrings.add("select count(distinct cit.id) from TaxonNode tn "
963
				+ "join tn.taxon.descriptions as db "
964
				+ "join db.descriptionElements as ia "
965
				+ "join ia.associatedSpecimenOrObservation as so "
966
				+ "join so.sequences as seq " + "join seq.citations as cit "
967

    
968
				+ "where so.class=:dnaSample "
969
				+ "and ia.class=:individualsAssociation "
970
				+ "and tn.classification=:classification "
971
				+ "and cit is not null ");
972

    
973
		// we do assume, that a name description would not have a
974
		// SpecimenOrObservation element
975

    
976
		parameters.put("dnaSample", "DnaSample");
977
		parameters.put("individualsAssociation", "IndividualsAssociation");
978

    
979
		//###TODO???
980
		//		ids.addAll(processQueriesWithIdDistinctListResult(queryStrings,
981
//				parameters));
982

    
983
		return processQueries(queryStrings, parameters);
984
	}
985

    
986
// TODO: this is used by countReferencesInClassificationWithIds()
987
	
988
	private Set<UUID> processQueriesWithIdDistinctListResult(
989
			List<String> queryStrings, Map<String, Object> parameters) {
990

    
991
		// MAYDO catch error if queries deliver wrong type
992
		Query query;
993
		Set<UUID> ids = new HashSet<UUID>();
994
		List queryList;
995
		for (String queryString : queryStrings) {
996

    
997
			query = getSession().createQuery(queryString);
998

    
999
			List<String> queryParameters = new ArrayList<String>(
1000
					Arrays.asList(query.getNamedParameters()));
1001

    
1002
			if (parameters != null) {
1003
				for (Map.Entry<String, Object> entry : parameters.entrySet()) {
1004

    
1005
					if (queryParameters.contains(entry.getKey())) {
1006
						query.setParameter(entry.getKey(), entry.getValue());
1007
					}
1008
				}
1009
			}
1010
			
1011
			queryList = query.list();
1012
			
1013
			ids.addAll((ArrayList<UUID>) queryList);
1014
			System.out.println();
1015
		}
1016
		return ids;
1017
	}
1018
	
1019
	
1020

    
1021
	/**
1022
	 * @param queryStrings
1023
	 *            - should be a list of strings that each represent a count hibernate query
1024
	 * @param parameters parameters for all the queries
1025
	 * 
1026
	 * @return sum of the values all queries result in
1027
	 */
1028
	private Long processQueries(
1029
			List<String> queryStrings, Map<String, Object> parameters) {
1030

    
1031
		// MAYDO catch error if queries deliver wrong type
1032
		Query query;
1033
		Long all = new Long(0);
1034
		Long result;
1035
	
1036

    
1037
		for (String queryString : queryStrings) {
1038

    
1039
			query = getSession().createQuery(queryString);
1040

    
1041
			//add matching parameters to query
1042
			List<String> queryParameters = new ArrayList<String>(
1043
					Arrays.asList(query.getNamedParameters()));
1044

    
1045
			if (parameters != null) {
1046
				for (Map.Entry<String, Object> entry : parameters.entrySet()) {
1047

    
1048
					if (queryParameters.contains(entry.getKey())) {
1049
						query.setParameter(entry.getKey(), entry.getValue());
1050
					}
1051
				}
1052
			}
1053
			result=(Long)query.uniqueResult();
1054
			all += result;
1055
		}
1056
		return all;
1057
		
1058
	}
1059
	
1060

    
1061
	@Override
1062
	public List<UUID> getTaxonTree(IdentifiableEntity filter) {
1063
		// TODO Auto-generated method stub
1064
		return null;
1065
	}
1066

    
1067
	@Override
1068
	public List<UUID> getAllChildNodeIds(UUID rootUuid) {
1069

    
1070
		Set<UUID> uuids = new HashSet<UUID>();
1071
		List<UUID> children = new ArrayList<UUID>();
1072
		List<UUID> parents = new ArrayList<UUID>();
1073
		String queryString;
1074
		String parameter;
1075

    
1076
		// it should be this one!
1077
		// queryString="select distinct chn.uuid from TaxonNode tn " +
1078
		// "join tn.childNodes as chn " +
1079
		// "where tn.uuid in (:parents) ";
1080

    
1081
		// just for testing, but does not work anyway
1082
		queryString = "select distinct chn.uuid from TaxonNode tn "
1083
				+ "join tn.childNodes as chn " + "where tn.uuid = :parent ";
1084

    
1085
		Query query = getSession().createQuery(queryString);
1086

    
1087
		parents.add(rootUuid);
1088
		uuids.add(rootUuid);
1089

    
1090
		// while(!(parents.isEmpty())){
1091
		// query.setParameterList("parents",parents);
1092
		query.setParameter("parent", parents.get(0));
1093
		children = query.list();
1094
		uuids.addAll(children);
1095
		parents = children;
1096
		// }
1097
		List<UUID> uuidList = new ArrayList<UUID>();
1098
		uuidList.addAll(uuids);
1099
		return uuidList;
1100

    
1101
	}
1102

    
1103
	// @Override
1104
	// public List<UUID> getAllTaxonIds(UUID rootUuid){
1105
	//
1106
	// Set<UUID> uuids= new HashSet<UUID>();
1107
	// List<UUID> children= new ArrayList<UUID>();
1108
	// List<UUID> parents= new ArrayList<UUID>();
1109
	// String queryString;
1110
	// String parameter;
1111
	//
1112
	// queryString="select distinct chn.taxon.uuid from TaxonNode tn " +
1113
	// "join tn.childNodes as chn " +
1114
	// "where tn.taxon.uuid in :parents ";
1115
	//
1116
	// Query query= getSession().createQuery(queryString);
1117
	//
1118
	// parents.add(rootUuid);
1119
	//
1120
	// //while(!(parents.isEmpty())){
1121
	// parents.add(UUID.fromString("54e767ee-894e-4540-a758-f906ecb4e2d9"));
1122
	// parameter=parents.toString();
1123
	// System.out.println("parameter: "+parameter);
1124
	//
1125
	// //children = query.list();
1126
	// // parents=children
1127
	// //}
1128
	//
1129
	// return parents;
1130
	//
1131
	// }
1132

    
1133
	@Override
1134
	public void getAllTaxonIds() {
1135

    
1136
		Set<UUID> uuids = new HashSet<UUID>();
1137

    
1138
		// return (List<UUID>) uuids;
1139

    
1140
	}
1141

    
1142
}
    (1-1/1)