Project

General

Profile

Download (36.9 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2009 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.persistence.dao.hibernate.statistics;
10

    
11
import java.util.ArrayList;
12
import java.util.HashMap;
13
import java.util.HashSet;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.Set;
17
import java.util.UUID;
18

    
19
import org.apache.logging.log4j.LogManager;
20
import org.apache.logging.log4j.Logger;
21
import org.hibernate.Criteria;
22
import org.hibernate.criterion.Projections;
23
import org.hibernate.criterion.Restrictions;
24
import org.hibernate.query.Query;
25
import org.springframework.stereotype.Repository;
26

    
27
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
28
import eu.etaxonomy.cdm.model.taxon.Classification;
29
import eu.etaxonomy.cdm.model.taxon.Synonym;
30
import eu.etaxonomy.cdm.model.taxon.Taxon;
31
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
32
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
33
import eu.etaxonomy.cdm.persistence.dao.hibernate.common.DaoBase;
34
import eu.etaxonomy.cdm.persistence.dao.statistics.IStatisticsDao;
35

    
36
/**
37
 * this dao provides counting methods for elements in a database in general or
38
 * in a specific class (or tree - TODO) in the database.
39
 *
40
 * only functionality, that is not covered by other daos is implemented
41
 *
42
 * MAYDO: restructure and using {@link Criteria} and methods like prepareQuery
43
 *
44
 * @author s.buers
45
 *
46
 */
47
@Repository
48
public class StatisticsDaoHibernateImpl
49
        extends DaoBase
50
        implements IStatisticsDao {
51

    
52
	// TODO remove every commented query related to
53
	// DescriptionBase.descriptionSources
54

    
55
	private static final int REFERENCE_LINK_RECURSION_DEPTH = 1;
56

    
57
	@SuppressWarnings("unused")
58
    private static final Logger logger = LogManager.getLogger(StatisticsDaoHibernateImpl.class);
59

    
60
	@Override
61
	public Long countDescriptiveSourceReferences() {
62

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

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

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

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

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

    
85
		// count sources from DescriptionElements:
86
		queryStrings
87
				.add("SELECT DISTINCT s.citation.uuid "
88
				        + "FROM DescriptionElementBase as d "
89
						+ "  JOIN d.sources as s "
90
						+ "WHERE s.citation is not null ");
91

    
92
		return Long.valueOf(processQueriesWithIdDistinctListResult(
93
				queryStrings, null).size());
94
	}
95

    
96
	@Override
97
	public Long countDescriptive(Boolean sourceRef,
98
			Classification classification) {
99
		return Long.valueOf(listDescriptiveIds(sourceRef, classification)
100
				.size());
101
	}
102

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

    
192
	private Set<UUID> listDescriptiveIds(Boolean sourceReferences,
193
			Classification classification) {
194

    
195
		// Boolean sourceReferences = true;
196
		String sourceRefJoins = "";
197
		String sourceRefWhere = "";
198
//		String selection = "d.id ";
199
		String selection = "d.uuid ";
200

    
201
		if (sourceReferences) {
202
			sourceRefJoins = "JOIN d.descriptionElements as de "
203
					+ "JOIN de.sources as des ";
204
			sourceRefWhere = "AND des.citation is not null ";
205
//			selection = "des.citation.id ";
206
			selection = "des.citation.uuid ";
207
		}
208

    
209
		if (classification == null)
210
         {
211
            return null; // or MAYDO: throw some Exception???
212
        }
213

    
214
		Map<String, Object> parameters = new HashMap<String, Object>();
215

    
216
		List<String> queryStrings = new ArrayList<String>();
217

    
218
		// // Taxon description elements:
219
		queryStrings.add("SELECT DISTINCT " + selection
220
				+ "FROM TaxonNode as tn "
221
		        + "  JOIN tn.taxon.descriptions as d "
222
				+ sourceRefJoins
223
				+ "WHERE tn.classification=:classification "
224
				+ sourceRefWhere);
225

    
226
		parameters.put("classification", classification);
227

    
228
		// TaxonName description elements for taxa:
229
		queryStrings.add("SELECT DISTINCT " + selection +
230
		          "FROM TaxonNode tn "
231
				+ "  JOIN tn.taxon.name.descriptions as d " + sourceRefJoins
232
				+ "where tn.classification=:classification "
233
				+ "and tn.taxon is not null "
234
				+ "and tn.taxon.name is not null " + sourceRefWhere);
235

    
236
		// TaxonName description elements for synonyms:
237
		queryStrings.add("select distinct " + selection + "from TaxonNode tn "
238
				+ "join tn.taxon.synonyms as sy "
239
				+ "join sy.name.descriptions as d " + sourceRefJoins
240
				+ "where tn.classification=:classification " + sourceRefWhere
241
				+ "and sy is not null " // TODO:
242
										// is
243
										// this
244
										// case
245
										// actually
246
										// possible???
247
				+ "and sy.name is not null ");
248

    
249
		// SpecimenOrObservationBase description elements:
250
		// 1. via determinations
251
		queryStrings.add("select distinct " + selection
252
				+ "from DescriptionBase d, TaxonNode tn "
253
				+ "join d.describedSpecimenOrObservation as so "
254
				+ "join so.determinations as det " + sourceRefJoins
255
				+ "where tn.classification=:classification "
256
				+ "and tn.taxon=det.taxon " + sourceRefWhere);
257

    
258
		// 2. via derived units in taxon description
259
		// already done with the taxon/synonym descriptions
260

    
261
		// 3. via SpecimenTypeDesignation in TaxonName:
262
		// a. taxon names:
263
		queryStrings.add("select distinct " + selection + "from TaxonNode tn "
264
				+ " join tn.taxon.name.typeDesignations as tdes "
265
				+ "join tdes.typeSpecimen.descriptions as d " + sourceRefJoins
266
				+ "where tn.classification=:classification "
267
				+ "and tdes.class=:type " + "and tn.taxon is not null "
268
				+ "and tn.taxon.name is not null " + sourceRefWhere);
269

    
270
		parameters.put("type", "SpecimenTypeDesignation");
271

    
272
		// b. synonym names:
273
		queryStrings.add("select distinct " + selection + "from TaxonNode tn "
274

    
275
		+ "join tn.taxon.synonyms as sy "
276
				+ " join sy.name.typeDesignations as tdes "
277
				+ "join tdes.typeSpecimen.descriptions as d " + sourceRefJoins
278
				+ "where tn.classification=:classification "
279
				+ "and tdes.class=:type " + "and tn.taxon is not null "
280
				+ "and sy.name is not null " + sourceRefWhere);
281

    
282
		// 4. via HomotypicalGroup in TaxonBase
283
		// we get this automatically with the names
284

    
285
		//###TODO
286
		return processQueriesWithIdDistinctListResult(queryStrings, parameters);
287
//		return null;
288
	}
289

    
290
	@Override
291
	public Long countTaxaInClassification(Class<? extends TaxonBase> clazz,
292
			Classification classification) {
293
		if (classification == null)
294
         {
295
            return null; // or MAYDO: throw some Exception???
296
        }
297

    
298
		if (clazz.equals(TaxonBase.class)) {
299

    
300
			return countTaxaInClassification(Taxon.class, classification)
301
					+ countTaxaInClassification(Synonym.class, classification);
302
		}
303

    
304
		if (clazz.equals(Taxon.class)) {
305
			Criteria criteria = getSession().createCriteria(TaxonNode.class);
306

    
307
			criteria.add(Restrictions.eq("classification", classification));
308
			criteria.setProjection(Projections.rowCount());
309
			return Long.valueOf((Long) criteria.uniqueResult());
310
		}
311

    
312
		else if (clazz.equals(Synonym.class)) {
313
			// criteria= getSession().createCriteria(TaxonNode.class);
314

    
315
			Query<Long> query = getSession().createQuery(
316
					"SELECT COUNT(DISTINCT s.uuid) FROM TaxonNode tn "
317
							+ " JOIN tn.taxon.synonyms as s "
318
							+ " WHERE tn.classification=:classification ",
319
							Long.class);
320
			query.setParameter("classification", classification);
321
			return query.uniqueResult();
322
		}
323
		// this should never happen:
324
		return null;
325

    
326
	}
327

    
328
	/*
329
	 * (non-Javadoc)
330
	 *
331
	 * @see
332
	 * eu.etaxonomy.cdm.persistence.dao.statistics.IStatisticsDao#countTaxonNames
333
	 * (eu.etaxonomy.cdm.model.taxon.Classification)
334
	 */
335
	@Override
336
	public Long countTaxonNames(Classification classification) {
337

    
338
		if (classification == null)
339
         {
340
            return null; // or MAYDO: throw some Exception???
341
        }
342

    
343
		Map<String, Object> parameters = new HashMap<String, Object>();
344

    
345
		parameters.put("classification", classification);
346
		// the query would be:
347
		// "select count (distinct n) from (
348
		// + "select distinct tn.taxon.name as c from TaxonNode tn "
349
		// + "where tn.classification=:classification "
350
		// + "UNION "
351
		// + "select distinct s.name as c from TaxonNode tn "
352
		// + "join tn.taxon.synonyms s "
353
		// + "where tn.classification=:classification "
354
		// ") as n "
355

    
356
		// as hibernate does not accept brackets in from and no unions
357
		// we have to do it otherwise:
358

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

    
372
		return Long.valueOf(processQueriesWithIdDistinctListResult(
373
				queryStrings, parameters).size());
374

    
375
	}
376

    
377
	@Override
378
    public Long countNomenclaturalReferences() {
379
		Query<Long> query = getSession()
380
				.createQuery(
381
						" SELECT COUNT(DISTINCT ns.citation) "
382
						+ " FROM TaxonName n"
383
						+ " JOIN n.nomenclaturalSource ns ",
384
						Long.class);
385
		return query.uniqueResult();
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<>();
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.nomenclaturalSource.citation.uuid "
405
				        + " FROM TaxonNode tn "
406
						+ " WHERE tn.classification=:classification "
407
						+ " AND tn.taxon.name.nomenclaturalSource.citation IS NOT NULL ");
408
		queryStrings
409
				.add("SELECT DISTINCT s.name.nomenclaturalSource.citation.uuid as c "
410
				        + " FROM TaxonNode tn "
411
						+ " JOIN tn.taxon.synonyms as s "
412
						+ " WHERE tn.classification=:classification "
413
						+ "    AND s.name.nomenclaturalSource.citation is NOT NULL ");
414

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

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

    
425
		// get all the descriptive source reference ids
426
		// ---------------------------------------------
427

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

    
432
		parameters.put("classification", classification);
433

    
434
		// get the ids from the Descriptive source references to add them to the
435
		// count
436

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

    
441
		// get classification reference
442
		queryStrings.add("SELECT c.source.citation.uuid FROM Classification as c "
443
				+ "WHERE c.uuid=:classificationId ");
444
		// TODO ???
445
		// +"join c.souces as s "
446
		// +"join s.citation "
447

    
448
		parameters.put("classificationId", classification.getUuid());
449

    
450
		// get node relations references:
451
		queryStrings
452
				.add(" SELECT DISTINCT ts.citation.uuid AS c "
453
				   + " FROM TaxonNode tn "
454
				   + " LEFT JOIN tn.source ts "
455
                   + " WHERE tn.classification = :classification "
456
				   + "     AND ts.citation IS NOT NULL ");
457

    
458
		// get sec references
459
		// -------------------------------------------------------------------
460
		// taxa
461
		queryStrings
462
				.add("SELECT DISTINCT tn.taxon.secSource.citation.uuid AS c FROM TaxonNode tn "
463
						+ "WHERE tn.classification=:classification "
464
						+ "  AND tn.taxon.secSource.citation IS NOT NULL ");
465

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

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

    
476
		// taxon relations
477
		queryStrings.add("SELECT DISTINCT tr.source.citation.uuid "
478
		        + "FROM TaxonNode tn "
479
				+ "  JOIN tn.taxon.relationsFromThisTaxon as tr "
480
				+ "WHERE tn.classification=:classification "
481
				+ "  AND tn.taxon IS NOT NULL "
482
				+ "  AND tr.source.citation IS NOT NULL ");
483

    
484

    
485
		// get hybrid relation citations
486
		// Taxa:
487
		queryStrings.add("SELECT DISTINCT hr.source.citation.uuid "
488
		        + "FROM TaxonNode tn "
489
				+ "  JOIN tn.taxon.name.hybridParentRelations as hr "
490
				+ "WHERE tn.classification=:classification "
491
				+ "  AND tn.taxon IS NOT NULL "
492
				+ "  AND tn.taxon.name IS NOT NULL ");
493

    
494
		// synonyms:
495
		queryStrings.add("SELECT distinct hr.source.citation.uuid "
496
		        + "FROM TaxonNode tn "
497
				+ "  JOIN tn.taxon.synonyms as sy "
498
				+ "  JOIN sy.name.hybridParentRelations as hr "
499
				+ "WHERE tn.classification=:classification "
500
				+ "  AND sy IS NOT NULL "
501
				// TODO: is this case actually possible???
502
				+ "  AND sy.name IS NOT NULL ");
503

    
504
		// get name relations references:
505
		// -------------------------------------------------------
506
		// Taxa:
507
		queryStrings.add("SELECT distinct nr.source.citation.uuid from TaxonNode tn "
508
				+ "JOIN tn.taxon.name.relationsFromThisName as nr "
509
				+ "WHERE tn.classification=:classification "
510
				+ "  AND tn.taxon IS NOT NULL "
511
				+ "  AND tn.taxon.name IS NOT NULL ");
512

    
513
		// synonyms:
514
		queryStrings.add("SELECT distinct nr.source.citation.uuid "
515
		        + "FROM TaxonNode tn "
516
				+ "  JOIN tn.taxon.synonyms as sy "
517
				+ "  JOIN sy.name.relationsFromThisName as nr "
518
				+ "WHERE tn.classification=:classification "
519
				+ "  AND sy IS NOT NULL " // TODO: is this case actually possible???
520
				+ "  AND sy.name IS NOT NULL ");
521

    
522
		// get Nomenclatural status citation
523

    
524
		// Taxa:
525
		queryStrings.add("SELECT DISTINCT s.source.citation.uuid "
526
		        + "FROM TaxonNode tn "
527
				+ "  JOIN tn.taxon.name.status as s "
528
				+ "WHERE tn.classification=:classification "
529
				+ "  AND tn.taxon IS NOT NULL "
530
				+ "  AND tn.taxon.name IS NOT NULL ");
531

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

    
537
		queryStrings.add("SELECT DISTINCT cit.uuid "
538
		        + "FROM TaxonNode tn "
539
				+ "  JOIN tn.taxon.descriptions as db "
540
				+ "  JOIN db.describedSpecimenOrObservation as so "
541
				+ "  JOIN so.sequences as seq "
542
				+ "  JOIN seq.citations as cit "
543
				+ "WHERE so.class=:dnaSample "
544
				+ "  AND tn.classification=:classification "
545
				+ "  AND cit IS NOT NULL ");
546

    
547
		// traverse to specimenOrObservation via individualsAssociation
548

    
549
		queryStrings.add("SELECT DISTINCT cit.uuid "
550
		        + "FROM TaxonNode tn "
551
				+ "  JOIN tn.taxon.descriptions as db "
552
				+ "  JOIN db.descriptionElements as ia "
553
				+ "  JOIN ia.associatedSpecimenOrObservation as so "
554
				+ "  JOIN so.sequences as seq "
555
				+ "  JOIN seq.citations as cit "
556
				+ "WHERE so.class=:dnaSample "
557
				+ "  AND ia.class=:individualsAssociation "
558
				+ "  AND tn.classification=:classification "
559
				+ "  AND cit IS NOT NULL ");
560

    
561
		// we do assume, that a name description would not have a
562
		// SpecimenOrObservation element
563

    
564
		parameters.put("dnaSample", "DnaSample");
565
		parameters.put("individualsAssociation", "IndividualsAssociation");
566

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

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

    
777
		// ----------------------------------------------------------
778

    
779
		ids.addAll(processQueriesWithIdDistinctListResult(queryStrings,
780
				parameters));
781

    
782
		return Long.valueOf(ids.size());
783
	}
784

    
785

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

    
796
		// get all the descriptive source reference ids
797
		// ---------------------------------------------
798

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

    
803
		parameters.put("classification", classification);
804

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

    
810
		// get classification reference
811
		queryStrings.add("SELECT COUNT(c.source.citation.id) "
812
		        + "FROM Classification as c "
813
				+ "WHERE c.id=:classificationId ");
814
		// TODO ???
815
		// +"join c.souces as s "
816
		// +"join s.citation "
817

    
818
		parameters.put("classificationId", classification.getId());
819

    
820
		// get node relations references:
821
		queryStrings
822
				.add("SELECT COUNT(DISTINCT ts.citation.id) as c "
823
				    + "FROM TaxonNode tn "
824
				    + "   LEFT JOIN tn.source ts "
825
                    + "WHERE tn.classification = :classification "
826
					+ "  AND tn.source.citation is not null ");
827

    
828
		// get sec references
829
		// -------------------------------------------------------------------
830
		// taxa
831
		queryStrings
832
				.add("SELECT COUNT(DISTINCT tn.taxon.secSource.citation.id) as c "
833
				        + "from TaxonNode tn "
834
						+ "where tn.classification = :classification "
835
						+ " and tn.taxon.secSource.citation is not null ");
836

    
837
		// synonyms
838
		queryStrings
839
				.add("SELECT COUNT(DISTINCT s.secSource.citation.id) AS c "
840
				        + "FROM TaxonNode tn "
841
						+ "JOIN tn.taxon.synonyms s "
842
						+ "WHERE tn.classification=:classification "
843
						+ " AND sr.relatedFrom.secSource.citation IS NOT NULL ");
844

    
845
		// get relationship citations
846
		// ---------------------------------------------------------------
847

    
848
		// taxon relations
849
		queryStrings.add("SELECT COUNT(DISTINCT tr.citation.id) "
850
		        + "FROM TaxonNode tn "
851
				+ "  JOIN tn.taxon.relationsFromThisTaxon as tr "
852
				+ "WHERE tn.classification=:classification "
853
				+ "  AND tn.taxon IS NOT NULL "
854
				+ "  AND tr.source.citation is not null ");
855

    
856
		// get hybrid relation citations
857
		// Taxa:
858
		queryStrings.add("SELECT COUNT(DISTINCT hr.source.citation.id) "
859
		        + "FROM TaxonNode tn "
860
				+ "  JOIN tn.taxon.name.hybridParentRelations as hr "
861
				+ "WHERE tn.classification=:classification "
862
				+ "  AND tn.taxon is not null "
863
				+ "  AND tn.taxon.name is not null ");
864

    
865
		// synonyms:
866
		queryStrings.add("SELECT COUNT(DISTINCT hr.source.citation.id) from TaxonNode tn "
867
				+ "join tn.taxon.synonyms as sy "
868
				+ "join sy.name.hybridParentRelations as hr "
869
				+ "where tn.classification=:classification "
870
				+ " and sy is not null "
871
				// TODO: is this case actually possible???
872
				+ " and sy.name is not null ");
873

    
874
		// get name relations references:
875
		// -------------------------------------------------------
876
		// Taxa:
877
		queryStrings.add("SELECT COUNT(DISTINCT nr.source.citation.id) from TaxonNode tn "
878
				+ "join tn.taxon.name.relationsFromThisName as nr "
879
				+ "where tn.classification=:classification "
880
				+ "and tn.taxon is not null "
881
				+ "and tn.taxon.name is not null ");
882

    
883
		// synonyms:
884
		queryStrings.add("SELECT COUNT(DISTINCT nr.source.citation.id) from TaxonNode tn "
885
				+ "join tn.taxon.synonyms as sy "
886
				+ "join sy.name.relationsFromThisName as nr "
887
				+ "where tn.classification=:classification "
888
				+ " and sy is not null " // TODO: is this case actually
889
										// possible???
890
				+ " and sy.name is not null ");
891

    
892
		// get Nomenclatural status citation
893

    
894
		// Taxa:
895
		queryStrings.add("SELECT COUNT(DISTINCT s.citation.id) "
896
		        + "from TaxonNode tn "
897
				+ "join tn.taxon.name.status as s "
898
				+ "where tn.classification=:classification "
899
				+ " and tn.taxon is not null "
900
				+ " and tn.taxon.name is not null ");
901

    
902
		// synonyms:
903
		queryStrings.add("SELECT COUNT(DISTINCT s.source.citation.id) "
904
		        + "from TaxonNode tn "
905
				+ "join tn.taxon.synonyms as sy "
906
				+ "join sy.name.status as s "
907
				+ "where tn.classification=:classification "
908
				+ " and sy is not null " // TODO: is this case actually
909
										// possible???
910
				+ " and sy.name is not null ");
911

    
912
		// get sequences which contain citations and publishedIn ------
913
		// and contain "Media" which could be of the subtype
914
		// "ReferencedMediaBase"
915
		// which has a citation
916

    
917
		queryStrings.add("SELECT COUNT(DISTINCT cit.id) "
918
		        + "from TaxonNode tn "
919
				+ "join tn.taxon.descriptions as db "
920

    
921
				+ "join db.describedSpecimenOrObservation as so "
922
				+ "join so.sequences as seq "
923
				+ "join seq.citations as cit "
924
				+ "where so.class=:dnaSample "
925
				+ " and tn.classification=:classification "
926
				+ " and cit is not null ");
927

    
928
		// traverse to specimenOrObservation via individualsAssociation
929

    
930
		queryStrings.add("SELECT COUNT(DISTINCT cit.id) "
931
		        + "from TaxonNode tn "
932
				+ "join tn.taxon.descriptions as db "
933
				+ "join db.descriptionElements as ia "
934
				+ "join ia.associatedSpecimenOrObservation as so "
935
				+ "join so.sequences as seq "
936
				+ "join seq.citations as cit "
937
				+ "where so.class=:dnaSample "
938
				+ " and ia.class=:individualsAssociation "
939
				+ " and tn.classification=:classification "
940
				+ " and cit is not null ");
941

    
942
		// we do assume, that a name description would not have a
943
		// SpecimenOrObservation element
944

    
945
		parameters.put("dnaSample", "DnaSample");
946
		parameters.put("individualsAssociation", "IndividualsAssociation");
947

    
948
		//###TODO???
949
		//		ids.addAll(processQueriesWithIdDistinctListResult(queryStrings,
950
//				parameters));
951

    
952
		return processQueries(queryStrings, parameters);
953
	}
954

    
955
// TODO: this is used by countReferencesInClassificationWithIds()
956

    
957
	private Set<UUID> processQueriesWithIdDistinctListResult(
958
			List<String> queryStrings, Map<String, Object> parameters) {
959

    
960
		// MAYDO catch error if queries deliver wrong type
961
		Set<UUID> ids = new HashSet<>();
962
		for (String queryString : queryStrings) {
963
//		    System.out.println(queryString);
964
		    Query<UUID> query = getSession().createQuery(queryString, UUID.class);
965

    
966
		    Set<String> parameterNames = query.getParameterMetadata().getNamedParameterNames();
967
			List<String> queryParameters = new ArrayList<>(parameterNames);
968

    
969
			if (parameters != null) {
970
				for (Map.Entry<String, Object> entry : parameters.entrySet()) {
971

    
972
					if (queryParameters.contains(entry.getKey())) {
973
						query.setParameter(entry.getKey(), entry.getValue());
974
					}
975
				}
976
			}
977

    
978
            List<UUID> queryList = query.list();
979
			ids.addAll(queryList);
980
		}
981
		return ids;
982
	}
983

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

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

    
999

    
1000
		for (String queryString : queryStrings) {
1001

    
1002
			query = getSession().createQuery(queryString, Long.class);
1003

    
1004
			//add matching parameters to query
1005
			Set<String> parameterNames = query.getParameterMetadata().getNamedParameterNames();
1006
            List<String> queryParameters = new ArrayList<>(parameterNames);
1007

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

    
1011
					if (queryParameters.contains(entry.getKey())) {
1012
						query.setParameter(entry.getKey(), entry.getValue());
1013
					}
1014
				}
1015
			}
1016
			result=query.uniqueResult();
1017
			all += result;
1018
		}
1019
		return all;
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<UUID> query = getSession().createQuery(queryString, UUID.class);
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)