Project

General

Profile

Download (36.3 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
	private static final int REFERENCE_LINK_RECURSION_DEPTH = 1;
48

    
49
	private static final Logger logger = Logger
50
			.getLogger(StatisticsDaoHibernateImpl.class);
51

    
52
	@Override
53
	public Long countDescriptiveSourceReferences() {
54

    
55
		List<String> queryStrings = new ArrayList<String>();
56

    
57
		// this query does not work...
58

    
59
		// query = getSession().createQuery(
60
		// "select count(distinct(r.id, desc.id)) from DescriptionBase as d "
61
		// + "join d.descriptionElements as de "
62
		// + "join de.sources as des "
63
		// + "join des.citation as desc "
64
		// + "join d.descriptionSources as r "
65
		// + "where "
66
		// + "desc is not null"
67
		// + " and "
68
		// + "r is not null ");
69

    
70
		// ... here is the manual version:
71

    
72
		// count sources from Descriptions:
73
		// as the descriptionSources of DescriptionBase are depricated:
74
		// queryStrings.add("select distinct r.id from DescriptionBase as d "
75
		// + "join d.descriptionSources as r ");
76

    
77
		// count sources from DescriptionElements:
78
		queryStrings
79
				.add("SELECT DISTINCT s.citation.uuid "
80
				        + " FROM DescriptionElementBase as d "
81
						+ " JOIN d.sources as s "
82
						+ " WHERE s.citation is not null ");
83

    
84
		return Long.valueOf(processQueriesWithIdDistinctListResult(
85
				queryStrings, null).size());
86
	}
87

    
88
	@Override
89
	public Long countDescriptive(Boolean sourceRef,
90
			Classification classification) {
91
		return Long.valueOf(listDescriptiveIds(sourceRef, classification)
92
				.size());
93
	}
94

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

    
184
	private Set<UUID> listDescriptiveIds(Boolean sourceReferences,
185
			Classification classification) {
186

    
187
		// Boolean sourceReferences = true;
188
		String sourceRefJoins = "";
189
		String sourceRefWhere = "";
190
//		String selection = "d.id ";
191
		String selection = "d.uuid ";
192

    
193
		if (sourceReferences) {
194
			sourceRefJoins = "join d.descriptionElements as de "
195
					+ "join de.sources as des ";
196
			sourceRefWhere = "and des.citation is not null ";
197
//			selection = "des.citation.id ";
198
			selection = "des.citation.uuid ";
199
		}
200

    
201
		if (classification == null)
202
         {
203
            return null; // or MAYDO: throw some Exception???
204
        }
205

    
206
		Map<String, Object> parameters = new HashMap<String, Object>();
207

    
208
		List<String> queryStrings = new ArrayList<String>();
209

    
210
		// // Taxon description elements:
211
		queryStrings.add("select distinct " + selection
212
				+ "from TaxonNode as tn " + "join tn.taxon.descriptions as d "
213
				+ sourceRefJoins + "where tn.classification=:classification "
214
				+ sourceRefWhere);
215

    
216
		parameters.put("classification", classification);
217

    
218
		// TaxonNameBase description elements for taxa:
219
		queryStrings.add("select distinct " + selection + "from TaxonNode tn "
220
				+ "join tn.taxon.name.descriptions as d " + sourceRefJoins
221
				+ "where tn.classification=:classification "
222
				+ "and tn.taxon is not null "
223
				+ "and tn.taxon.name is not null " + sourceRefWhere);
224

    
225
		// TaxonNameBase description elements for synonyms:
226
		queryStrings.add("select distinct " + selection + "from TaxonNode tn "
227
				+ "join tn.taxon.synonyms as sy "
228
				+ "join sy.name.descriptions as d " + sourceRefJoins
229
				+ "where tn.classification=:classification " + sourceRefWhere
230
				+ "and sy is not null " // TODO:
231
										// is
232
										// this
233
										// case
234
										// actually
235
										// possible???
236
				+ "and sy.name is not null ");
237

    
238
		// SpecimenOrObservationBase description elements:
239
		// 1. via determinations
240
		queryStrings.add("select distinct " + selection
241
				+ "from DescriptionBase d, TaxonNode tn "
242
				+ "join d.describedSpecimenOrObservation as so "
243
				+ "join so.determinations as det " + sourceRefJoins
244
				+ "where tn.classification=:classification "
245
				+ "and tn.taxon=det.taxon " + sourceRefWhere);
246

    
247
		// 2. via derived units in taxon description
248
		// already done with the taxon/synonym descriptions
249

    
250
		// 3. via SpecimenTypeDesignation in TaxonName:
251
		// a. taxon names:
252
		queryStrings.add("select distinct " + selection + "from TaxonNode tn "
253
				+ " join tn.taxon.name.typeDesignations as tdes "
254
				+ "join tdes.typeSpecimen.descriptions as d " + sourceRefJoins
255
				+ "where tn.classification=:classification "
256
				+ "and tdes.class=:type " + "and tn.taxon is not null "
257
				+ "and tn.taxon.name is not null " + sourceRefWhere);
258

    
259
		parameters.put("type", "SpecimenTypeDesignation");
260

    
261
		// b. synonym names:
262
		queryStrings.add("select distinct " + selection + "from TaxonNode tn "
263

    
264
		+ "join tn.taxon.synonyms as sy "
265
				+ " join sy.name.typeDesignations as tdes "
266
				+ "join tdes.typeSpecimen.descriptions as d " + sourceRefJoins
267
				+ "where tn.classification=:classification "
268
				+ "and tdes.class=:type " + "and tn.taxon is not null "
269
				+ "and sy.name is not null " + sourceRefWhere);
270

    
271
		// 4. via HomotypicalGroup in TaxonBase
272
		// we get this automatically with the names
273

    
274
		//###TODO
275
		return processQueriesWithIdDistinctListResult(queryStrings, parameters);
276
//		return null;
277
	}
278

    
279
	/*
280
	 * (non-Javadoc)
281
	 *
282
	 * @see eu.etaxonomy.cdm.persistence.dao.statistics.IStatisticsDao#
283
	 * countTaxaInClassification(java.lang.Class,
284
	 * eu.etaxonomy.cdm.model.taxon.Classification)
285
	 */
286
	@Override
287
	public Long countTaxaInClassification(Class<? extends TaxonBase> clazz,
288
			Classification classification) {
289
		if (classification == null)
290
         {
291
            return null; // or MAYDO: throw some Exception???
292
        }
293

    
294
		if (clazz.equals(TaxonBase.class)) {
295

    
296
			return countTaxaInClassification(Taxon.class, classification)
297
					+ countTaxaInClassification(Synonym.class, classification);
298
		}
299

    
300
		if (clazz.equals(Taxon.class)) {
301
			Criteria criteria = getSession().createCriteria(TaxonNode.class);
302

    
303
			criteria.add(Restrictions.eq("classification", classification));
304
			criteria.setProjection(Projections.rowCount());
305
			return Long.valueOf((Long) criteria.uniqueResult());
306
		}
307

    
308
		else if (clazz.equals(Synonym.class)) {
309
			// criteria= getSession().createCriteria(TaxonNode.class);
310

    
311
			Query query = getSession().createQuery(
312
					"SELECT COUNT(DISTINCT s.uuid) FROM TaxonNode tn "
313
							+ " JOIN tn.taxon.synonyms as s "
314
							+ " WHERE tn.classification=:classification ");
315
			query.setParameter("classification", classification);
316
			return (Long) query.uniqueResult();
317
		}
318
		// this should never happen:
319
		return null;
320

    
321
	}
322

    
323
	/*
324
	 * (non-Javadoc)
325
	 *
326
	 * @see
327
	 * eu.etaxonomy.cdm.persistence.dao.statistics.IStatisticsDao#countTaxonNames
328
	 * (eu.etaxonomy.cdm.model.taxon.Classification)
329
	 */
330
	@Override
331
	public Long countTaxonNames(Classification classification) {
332

    
333
		if (classification == null)
334
         {
335
            return null; // or MAYDO: throw some Exception???
336
        }
337

    
338
		Map<String, Object> parameters = new HashMap<String, Object>();
339

    
340
		parameters.put("classification", classification);
341
		// the query would be:
342
		// "select count (distinct n) from (
343
		// + "select distinct tn.taxon.name as c from TaxonNode tn "
344
		// + "where tn.classification=:classification "
345
		// + "UNION "
346
		// + "select distinct s.name as c from TaxonNode tn "
347
		// + "join tn.taxon.synonyms s "
348
		// + "where tn.classification=:classification "
349
		// ") as n "
350

    
351
		// as hibernate does not accept brackets in from and no unions
352
		// we have to do it otherwise:
353

    
354
		// so instead of "UNION" we use 2 queries
355
		// and count the names manually
356
		List<String> queryStrings = new ArrayList<String>();
357
		queryStrings
358
				.add("select distinct tn.taxon.name.uuid as c from TaxonNode tn "
359
						+ "where tn.classification=:classification "
360
						+ "and tn.taxon.name is not null ");
361
		queryStrings
362
				.add("select distinct s.name.uuid as c from TaxonNode tn "
363
						+ "join tn.taxon.synonyms s "
364
						+ "where tn.classification=:classification "
365
						+ "and s.name is not null ");
366

    
367
		return Long.valueOf(processQueriesWithIdDistinctListResult(
368
				queryStrings, parameters).size());
369

    
370
	}
371

    
372
	/*
373
	 * (non-Javadoc)
374
	 *
375
	 * @see eu.etaxonomy.cdm.persistence.dao.statistics.IStatisticsDao#
376
	 * countNomenclaturalReferences()
377
	 */
378
	// @Override
379
	@Override
380
    public Long countNomenclaturalReferences() {
381
		Query query = getSession()
382
				.createQuery(
383
						"select count(distinct nomenclaturalReference) from TaxonNameBase ");
384
		return (Long) query.uniqueResult();
385
	}
386

    
387

    
388
	 @Override
389
	public Long countNomenclaturalReferences(
390
			Classification classification) {
391

    
392
		if (classification == null)
393
         {
394
            return null; // or MAYDO: throw some Exception???
395
        }
396

    
397
		Map<String, Object> parameters = new HashMap<String, Object>();
398

    
399
		parameters.put("classification", classification);
400
		// so instead of "UNION" we use 2 queries
401
		// and count the names manually
402
		List<String> queryStrings = new ArrayList<String>();
403
		queryStrings
404
				.add("SELECT DISTINCT tn.taxon.name.nomenclaturalReference.uuid "
405
				        + " FROM TaxonNode tn "
406
						+ " WHERE tn.classification=:classification "
407
						+ " AND tn.taxon.name.nomenclaturalReference IS NOT NULL ");
408
		queryStrings
409
				.add("SELECT DISTINCT s.name.nomenclaturalReference.uuid as c "
410
				        + " FROM TaxonNode tn "
411
						+ " JOIN tn.taxon.synonyms as s "
412
						+ " WHERE tn.classification=:classification "
413
						+ "    AND s.name.nomenclaturalReference is not null ");
414

    
415
		return Long.valueOf(processQueriesWithIdDistinctListResult(
416
				queryStrings, parameters).size());
417
	}
418

    
419

    
420
	@Override
421
	public Long countReferencesInClassificationWithUuids(Classification classification) {
422
		if (classification == null)
423
         {
424
            return null; // or MAYDO: throw some Exception???
425
        }
426

    
427
		// get all the descriptive source reference ids
428
		// ---------------------------------------------
429

    
430
		// preparation
431
		List<String> queryStrings = new ArrayList<String>();
432
		Map<String, Object> parameters = new HashMap<String, Object>();
433

    
434
		parameters.put("classification", classification);
435

    
436
		// get the ids from the Descriptive source references to add them to the
437
		// count
438

    
439
		//TODO
440
		//Set<Integer> ids = listDescriptiveIds(true, classification);
441
		Set<UUID> ids = new HashSet<UUID>();
442

    
443
		// get classification reference
444
		queryStrings.add("select c.reference.uuid from Classification as c "
445
				+ "where c.uuid=:classificationId ");
446
		// TODO ???
447
		// +"join c.souces as s "
448
		// +"join s.citation "
449

    
450
		parameters.put("classificationId", classification.getUuid());
451

    
452
		// get node relations references:
453
		queryStrings
454
				.add("select distinct tn.referenceForParentChildRelation.uuid as c from TaxonNode tn "
455
						+ "where tn.classification=:classification "
456
						+ "and tn.referenceForParentChildRelation is not null ");
457

    
458
		// get sec references
459
		// -------------------------------------------------------------------
460
		// taxa
461
		queryStrings
462
				.add("select distinct tn.taxon.sec.uuid as c from TaxonNode tn "
463
						+ "where tn.classification=:classification "
464
						+ "and tn.taxon.sec is not null ");
465

    
466
		// synonyms
467
		queryStrings
468
				.add("SELECT DISTINCT s.sec.uuid AS c FROM TaxonNode tn "
469
						+ "JOIN tn.taxon.synonyms s "
470
						+ "WHERE tn.classification=:classification "
471
						+ "AND s.sec IS NOT NULL ");
472

    
473
		// get relationship citations
474
		// ---------------------------------------------------------------
475

    
476
		// taxon relations
477
		queryStrings.add("select distinct tr.citation.uuid from TaxonNode tn "
478
				+ "join tn.taxon.relationsFromThisTaxon as tr "
479
				+ "where tn.classification=:classification "
480
				+ "and tn.taxon is not null and tr.citation is not null ");
481

    
482

    
483
		// get hybrid relation citations
484
		// Taxa:
485
		queryStrings.add("select distinct hr.citation.uuid "
486
		        + "from TaxonNode tn "
487
				+ "join tn.taxon.name.hybridParentRelations as hr "
488
				+ "where tn.classification=:classification "
489
				+ " and tn.taxon is not null "
490
				+ " and tn.taxon.name is not null ");
491

    
492
		// synonyms:
493
		queryStrings.add("select distinct hr.citation.uuid "
494
		        + "from TaxonNode tn "
495
				+ " join tn.taxon.synonyms as sy "
496
				+ " join sy.name.hybridParentRelations as hr "
497
				+ "where tn.classification=:classification "
498
				+ " and sy is not null "
499
				// TODO: is this case actually possible???
500
				+ " and sy.name is not null ");
501

    
502
		// get name relations references:
503
		// -------------------------------------------------------
504
		// Taxa:
505
		queryStrings.add("select distinct nr.citation.uuid from TaxonNode tn "
506
				+ "join tn.taxon.name.relationsFromThisName as nr "
507
				+ "where tn.classification=:classification "
508
				+ "and tn.taxon is not null "
509
				+ "and tn.taxon.name is not null ");
510

    
511
		// synonyms:
512
		queryStrings.add("select distinct nr.citation.uuid from TaxonNode tn "
513
				+ "join tn.taxon.synonyms as sy "
514
				+ "join sy.name.relationsFromThisName as nr "
515
				+ "where tn.classification=:classification "
516
				+ "and sy is not null " // TODO: is this case actually
517
										// possible???
518
				+ "and sy.name is not null ");
519

    
520
		// get Nomenclatural status citation
521

    
522
		// Taxa:
523
		queryStrings.add("select distinct s.citation.uuid from TaxonNode tn "
524
				+ "join tn.taxon.name.status as s "
525
				+ "where tn.classification=:classification "
526
				+ "and tn.taxon is not null "
527
				+ "and tn.taxon.name is not null ");
528

    
529

    
530
		// get sequences which contain citations and publishedIn ------
531
		// and contain "Media" which could be of the subtype
532
		// "ReferencedMediaBase"
533
		// which has a citation
534

    
535
		queryStrings.add("select distinct cit.uuid " + " from TaxonNode tn "
536
				+ "join tn.taxon.descriptions as db "
537

    
538
				+ "join db.describedSpecimenOrObservation as so "
539
				+ "join so.sequences as seq " + "join seq.citations as cit "
540

    
541
				+ "where so.class=:dnaSample "
542
				+ "and tn.classification=:classification "
543
				+ "and cit is not null ");
544

    
545
		// traverse to specimenOrObservation via individualsAssociation
546

    
547
		queryStrings.add("select distinct cit.uuid from TaxonNode tn "
548
				+ "join tn.taxon.descriptions as db "
549
				+ "join db.descriptionElements as ia "
550
				+ "join ia.associatedSpecimenOrObservation as so "
551
				+ "join so.sequences as seq " + "join seq.citations as cit "
552

    
553
				+ "where so.class=:dnaSample "
554
				+ "and ia.class=:individualsAssociation "
555
				+ "and tn.classification=:classification "
556
				+ "and cit is not null ");
557

    
558
		// we do assume, that a name description would not have a
559
		// SpecimenOrObservation element
560

    
561
		parameters.put("dnaSample", "DnaSample");
562
		parameters.put("individualsAssociation", "IndividualsAssociation");
563

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

    
764
		// ------------------------------------------------------------------
765
		// TODO get all objects that inherit IdentifiableEntity because it has
766
		// an
767
		// IdentifiableSource which inherits from OriginalSourceBase
768
		// which inherits from ReferencedEntityBase
769
		// which has a citation
770
		// furthermore recources can recursivly link to recources:
771
		// get sources of all references from ids and add the references of
772
		// the sources...
773
		// iterate in a certain depth REFERENCE_LINK_RECURSION_DEPTH
774

    
775
		// ----------------------------------------------------------
776

    
777
		ids.addAll(processQueriesWithIdDistinctListResult(queryStrings,
778
				parameters));
779

    
780
		return Long.valueOf(ids.size());
781
	}
782

    
783

    
784
	// TODO!!!
785
	// TODO this is the old reference counter where i counted the referenced
786
	// media as well and fetched ids from the database to erase dublettes
787
	@Override
788
	public Long countReferencesInClassification(Classification classification) {
789
		if (classification == null)
790
         {
791
            return null; // or MAYDO: throw some Exception???
792
        }
793

    
794
		// get all the descriptive source reference ids
795
		// ---------------------------------------------
796

    
797
		// preparation
798
		List<String> queryStrings = new ArrayList<>();
799
		Map<String, Object> parameters = new HashMap<>();
800

    
801
		parameters.put("classification", classification);
802

    
803
		// get the ids from the Descriptive source references to add them to the
804
		// count
805
		//###TODO
806
//		Set<Integer> ids = listDescriptiveIds(true, classification);
807

    
808
		// get classification reference
809
		queryStrings.add("select count(c.reference.id) from Classification as c "
810
				+ "where c.id=:classificationId ");
811
		// TODO ???
812
		// +"join c.souces as s "
813
		// +"join s.citation "
814

    
815
		parameters.put("classificationId", classification.getId());
816

    
817
		// get node relations references:
818
		queryStrings
819
				.add("select count(distinct tn.referenceForParentChildRelation.id) as c "
820
				        + "from TaxonNode tn "
821
						+ "where tn.classification=:classification "
822
						+ " and tn.referenceForParentChildRelation is not null ");
823

    
824
		// get sec references
825
		// -------------------------------------------------------------------
826
		// taxa
827
		queryStrings
828
				.add("select count(distinct tn.taxon.sec.id) as c "
829
				        + "from TaxonNode tn "
830
						+ "where tn.classification=:classification "
831
						+ " and tn.taxon.sec is not null ");
832

    
833
		// synonyms
834
		queryStrings
835
				.add("select count(distinct s.sec.id) as c "
836
				        + "from TaxonNode tn "
837
						+ "join tn.taxon.synonyms s "
838
						+ "where tn.classification=:classification "
839
						+ " and sr.relatedFrom.sec is not null ");
840

    
841
		// get relationship citations
842
		// ---------------------------------------------------------------
843

    
844
		// taxon relations
845
		queryStrings.add("select count(distinct tr.citation.id) from TaxonNode tn "
846
				+ "join tn.taxon.relationsFromThisTaxon as tr "
847
				+ "where tn.classification=:classification "
848
				+ "and tn.taxon is not null " + "and tr.citation is not null ");
849

    
850
		// get hybrid relation citations
851
		// Taxa:
852
		queryStrings.add("select count(distinct hr.citation.id) from TaxonNode tn "
853
				+ "join tn.taxon.name.hybridParentRelations as hr "
854
				+ "where tn.classification=:classification "
855
				+ " and tn.taxon is not null "
856
				+ " and tn.taxon.name is not null ");
857

    
858

    
859
		// synonyms:
860
		queryStrings.add("select count(distinct hr.citation.id) from TaxonNode tn "
861
				+ "join tn.taxon.synonyms as sy "
862
				+ "join sy.name.hybridParentRelations as hr "
863
				+ "where tn.classification=:classification "
864
				+ " and sy is not null "
865
				// TODO: is this case actually possible???
866
				+ " and sy.name is not null ");
867

    
868
		// get name relations references:
869
		// -------------------------------------------------------
870
		// Taxa:
871
		queryStrings.add("select count(distinct nr.citation.id) from TaxonNode tn "
872
				+ "join tn.taxon.name.relationsFromThisName as nr "
873
				+ "where tn.classification=:classification "
874
				+ "and tn.taxon is not null "
875
				+ "and tn.taxon.name is not null ");
876

    
877
		// synonyms:
878
		queryStrings.add("select count(distinct nr.citation.id) from TaxonNode tn "
879
				+ "join tn.taxon.synonyms as sy "
880
				+ "join sy.name.relationsFromThisName as nr "
881
				+ "where tn.classification=:classification "
882
				+ " and sy is not null " // TODO: is this case actually
883
										// possible???
884
				+ " and sy.name is not null ");
885

    
886
		// get Nomenclatural status citation
887

    
888
		// Taxa:
889
		queryStrings.add("select count(distinct s.citation.id) "
890
		        + "from TaxonNode tn "
891
				+ "join tn.taxon.name.status as s "
892
				+ "where tn.classification=:classification "
893
				+ " and tn.taxon is not null "
894
				+ " and tn.taxon.name is not null ");
895

    
896
		// synonyms:
897
		queryStrings.add("select count(distinct s.citation.id) "
898
		        + "from TaxonNode tn "
899
				+ "join tn.taxon.synonyms as sy "
900
				+ "join sy.name.status as s "
901
				+ "where tn.classification=:classification "
902
				+ " and sy is not null " // TODO: is this case actually
903
										// possible???
904
				+ " and sy.name is not null ");
905

    
906
		// get sequences which contain citations and publishedIn ------
907
		// and contain "Media" which could be of the subtype
908
		// "ReferencedMediaBase"
909
		// which has a citation
910

    
911
		queryStrings.add("select count(distinct cit.id) "
912
		        + "from TaxonNode tn "
913
				+ "join tn.taxon.descriptions as db "
914

    
915
				+ "join db.describedSpecimenOrObservation as so "
916
				+ "join so.sequences as seq "
917
				+ "join seq.citations as cit "
918
				+ "where so.class=:dnaSample "
919
				+ " and tn.classification=:classification "
920
				+ " and cit is not null ");
921

    
922
		// traverse to specimenOrObservation via individualsAssociation
923

    
924
		queryStrings.add("select count(distinct cit.id) "
925
		        + "from TaxonNode tn "
926
				+ "join tn.taxon.descriptions as db "
927
				+ "join db.descriptionElements as ia "
928
				+ "join ia.associatedSpecimenOrObservation as so "
929
				+ "join so.sequences as seq "
930
				+ "join seq.citations as cit "
931
				+ "where so.class=:dnaSample "
932
				+ " and ia.class=:individualsAssociation "
933
				+ " and tn.classification=:classification "
934
				+ " and cit is not null ");
935

    
936
		// we do assume, that a name description would not have a
937
		// SpecimenOrObservation element
938

    
939
		parameters.put("dnaSample", "DnaSample");
940
		parameters.put("individualsAssociation", "IndividualsAssociation");
941

    
942
		//###TODO???
943
		//		ids.addAll(processQueriesWithIdDistinctListResult(queryStrings,
944
//				parameters));
945

    
946
		return processQueries(queryStrings, parameters);
947
	}
948

    
949
// TODO: this is used by countReferencesInClassificationWithIds()
950

    
951
	private Set<UUID> processQueriesWithIdDistinctListResult(
952
			List<String> queryStrings, Map<String, Object> parameters) {
953

    
954
		// MAYDO catch error if queries deliver wrong type
955
		Query query;
956
		Set<UUID> ids = new HashSet<>();
957
		List<UUID> queryList;
958
		for (String queryString : queryStrings) {
959

    
960
			query = getSession().createQuery(queryString);
961

    
962
			List<String> queryParameters = new ArrayList<>(
963
					Arrays.asList(query.getNamedParameters()));
964

    
965
			if (parameters != null) {
966
				for (Map.Entry<String, Object> entry : parameters.entrySet()) {
967

    
968
					if (queryParameters.contains(entry.getKey())) {
969
						query.setParameter(entry.getKey(), entry.getValue());
970
					}
971
				}
972
			}
973

    
974
			queryList = query.list();
975

    
976
			ids.addAll(queryList);
977
		}
978
		return ids;
979
	}
980

    
981

    
982

    
983
	/**
984
	 * @param queryStrings
985
	 *            - should be a list of strings that each represent a count hibernate query
986
	 * @param parameters parameters for all the queries
987
	 *
988
	 * @return sum of the values all queries result in
989
	 */
990
	private Long processQueries(
991
			List<String> queryStrings, Map<String, Object> parameters) {
992

    
993
		// MAYDO catch error if queries deliver wrong type
994
		Query query;
995
		Long all = new Long(0);
996
		Long result;
997

    
998

    
999
		for (String queryString : queryStrings) {
1000

    
1001
			query = getSession().createQuery(queryString);
1002

    
1003
			//add matching parameters to query
1004
			List<String> queryParameters = new ArrayList<>(
1005
					Arrays.asList(query.getNamedParameters()));
1006

    
1007
			if (parameters != null) {
1008
				for (Map.Entry<String, Object> entry : parameters.entrySet()) {
1009

    
1010
					if (queryParameters.contains(entry.getKey())) {
1011
						query.setParameter(entry.getKey(), entry.getValue());
1012
					}
1013
				}
1014
			}
1015
			result=(Long)query.uniqueResult();
1016
			all += result;
1017
		}
1018
		return all;
1019

    
1020
	}
1021

    
1022

    
1023
	@Override
1024
	public List<UUID> getTaxonTree(IdentifiableEntity filter) {
1025
		// TODO Auto-generated method stub
1026
		return null;
1027
	}
1028

    
1029
	@Override
1030
	public List<UUID> getAllChildNodeIds(UUID rootUuid) {
1031

    
1032
		Set<UUID> uuids = new HashSet<>();
1033
		List<UUID> children = new ArrayList<>();
1034
		List<UUID> parents = new ArrayList<>();
1035

    
1036
		// it should be this one!
1037
		// queryString="select distinct chn.uuid from TaxonNode tn " +
1038
		// "join tn.childNodes as chn " +
1039
		// "where tn.uuid in (:parents) ";
1040

    
1041
		// just for testing, but does not work anyway
1042
		String queryString = "select distinct chn.uuid from TaxonNode tn "
1043
				+ "join tn.childNodes as chn " + "where tn.uuid = :parent ";
1044

    
1045
		Query query = getSession().createQuery(queryString);
1046

    
1047
		parents.add(rootUuid);
1048
		uuids.add(rootUuid);
1049

    
1050
		// while(!(parents.isEmpty())){
1051
		// query.setParameterList("parents",parents);
1052
		query.setParameter("parent", parents.get(0));
1053
		children = query.list();
1054
		uuids.addAll(children);
1055
		parents = children;
1056
		// }
1057
		List<UUID> uuidList = new ArrayList<>();
1058
		uuidList.addAll(uuids);
1059
		return uuidList;
1060

    
1061
	}
1062

    
1063
	// @Override
1064
	// public List<UUID> getAllTaxonIds(UUID rootUuid){
1065
	//
1066
	// Set<UUID> uuids= new HashSet<UUID>();
1067
	// List<UUID> children= new ArrayList<UUID>();
1068
	// List<UUID> parents= new ArrayList<UUID>();
1069
	// String queryString;
1070
	// String parameter;
1071
	//
1072
	// queryString="select distinct chn.taxon.uuid from TaxonNode tn " +
1073
	// "join tn.childNodes as chn " +
1074
	// "where tn.taxon.uuid in :parents ";
1075
	//
1076
	// Query query= getSession().createQuery(queryString);
1077
	//
1078
	// parents.add(rootUuid);
1079
	//
1080
	// //while(!(parents.isEmpty())){
1081
	// parents.add(UUID.fromString("54e767ee-894e-4540-a758-f906ecb4e2d9"));
1082
	// parameter=parents.toString();
1083
	// System.out.println("parameter: "+parameter);
1084
	//
1085
	// //children = query.list();
1086
	// // parents=children
1087
	// //}
1088
	//
1089
	// return parents;
1090
	//
1091
	// }
1092

    
1093
	@Override
1094
	public void getAllTaxonIds() {
1095

    
1096
		Set<UUID> uuids = new HashSet<>();
1097

    
1098
		// return (List<UUID>) uuids;
1099

    
1100
	}
1101

    
1102
}
    (1-1/1)