cleanup
[cdmlib.git] / cdmlib-remote / src / main / java / eu / etaxonomy / cdm / remote / controller / TaxonPortalController.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.cdm.remote.controller;
11
12 import java.io.IOException;
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.Hashtable;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Set;
20 import java.util.UUID;
21
22 import javax.servlet.http.HttpServletRequest;
23 import javax.servlet.http.HttpServletResponse;
24
25 import org.apache.log4j.Logger;
26 import org.springframework.beans.factory.annotation.Autowired;
27 import org.springframework.stereotype.Controller;
28 import org.springframework.web.bind.WebDataBinder;
29 import org.springframework.web.bind.annotation.InitBinder;
30 import org.springframework.web.bind.annotation.PathVariable;
31 import org.springframework.web.bind.annotation.RequestMapping;
32 import org.springframework.web.bind.annotation.RequestMethod;
33 import org.springframework.web.bind.annotation.RequestParam;
34 import org.springframework.web.servlet.ModelAndView;
35
36 import eu.etaxonomy.cdm.api.service.INameService;
37 import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
38 import eu.etaxonomy.cdm.api.service.ITaxonService;
39 import eu.etaxonomy.cdm.api.service.ITermService;
40 import eu.etaxonomy.cdm.api.service.util.TaxonRelationshipEdge;
41 import eu.etaxonomy.cdm.database.UpdatableRoutingDataSource;
42 import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
43 import eu.etaxonomy.cdm.model.location.NamedArea;
44 import eu.etaxonomy.cdm.model.media.Media;
45 import eu.etaxonomy.cdm.model.media.MediaRepresentation;
46 import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
47 import eu.etaxonomy.cdm.model.media.MediaUtils;
48 import eu.etaxonomy.cdm.model.name.NameRelationship;
49 import eu.etaxonomy.cdm.model.taxon.Synonym;
50 import eu.etaxonomy.cdm.model.taxon.Taxon;
51 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
52 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
53 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
54 import eu.etaxonomy.cdm.persistence.query.MatchMode;
55 import eu.etaxonomy.cdm.remote.controller.util.ControllerUtils;
56 import eu.etaxonomy.cdm.remote.editor.CdmTypePropertyEditor;
57 import eu.etaxonomy.cdm.remote.editor.DefinedTermBaseList;
58 import eu.etaxonomy.cdm.remote.editor.MatchModePropertyEditor;
59 import eu.etaxonomy.cdm.remote.editor.NamedAreaPropertyEditor;
60 import eu.etaxonomy.cdm.remote.editor.TermBaseListPropertyEditor;
61 import eu.etaxonomy.cdm.remote.editor.UUIDListPropertyEditor;
62 import eu.etaxonomy.cdm.remote.editor.UuidList;
63 import io.swagger.annotations.Api;
64
65 /**
66 * The TaxonPortalController class is a Spring MVC Controller.
67 * <p>
68 * The syntax of the mapped service URIs contains the the {datasource-name} path element.
69 * The available {datasource-name}s are defined in a configuration file which
70 * is loaded by the {@link UpdatableRoutingDataSource}. If the
71 * UpdatableRoutingDataSource is not being used in the actual application
72 * context any arbitrary {datasource-name} may be used.
73 * <p>
74 * Methods mapped at type level, inherited from super classes ({@link BaseController}):
75 * <blockquote>
76 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}</b>
77 *
78 * Get the {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
79 * The returned Taxon is initialized by
80 * the following strategy {@link #TAXON_INIT_STRATEGY}
81 * </blockquote>
82 *
83 * @author a.kohlbecker
84 * @since 20.07.2009
85 *
86 */
87 @Controller
88 @Api("portal_taxon")
89 @RequestMapping(value = {"/portal/taxon/{uuid}"})
90 public class TaxonPortalController extends TaxonController{
91
92 public static final Logger logger = Logger.getLogger(TaxonPortalController.class);
93
94 @Autowired
95 private INameService nameService;
96
97 @Autowired
98 private ITaxonNodeService taxonNodeService;
99
100 @Autowired
101 private ITaxonService taxonService;
102
103 @Autowired
104 private ITermService termService;
105
106 private static final List<String> TAXON_INIT_STRATEGY = Arrays.asList(new String []{
107 "$",
108 "sources",
109 // taxon relations
110 // "relationsToThisName.fromTaxon.name",
111 // the name
112 "name.$",
113 "name.nomenclaturalReference.authorship",
114 "name.nomenclaturalReference.inReference",
115 "name.rank.representations",
116 "name.status.type.representations",
117
118 // "descriptions" // TODO remove
119
120 });
121
122 private static final List<String> TAXON_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{
123 "taxonNodes.$",
124 "taxonNodes.classification.$",
125 "taxonNodes.childNodes.$"
126 });
127
128 private static final List<String> SIMPLE_TAXON_INIT_STRATEGY = Arrays.asList(new String []{
129 "$",
130 // the name
131 "name.$",
132 "name.rank.representations",
133 "name.status.type.representations",
134 "name.nomenclaturalReference.authorship",
135 "name.nomenclaturalReference.inReference",
136 "taxonNodes.classification",
137 });
138
139 private static final List<String> SYNONYMY_INIT_STRATEGY = Arrays.asList(new String []{
140 // initialize homotypical and heterotypical groups; needs synonyms
141 "synonyms.$",
142 "synonyms.name.status.type.representations",
143 "synonyms.name.nomenclaturalReference.authorship",
144 "synonyms.name.nomenclaturalReference.inReference",
145 // "synonyms.name.homotypicalGroup.typifiedNames.$",
146 // "synonyms.name.homotypicalGroup.typifiedNames.taxonBases.$",
147 "synonyms.name.combinationAuthorship.$",
148
149 "name.typeDesignations",
150
151 "name.homotypicalGroup.$",
152 "name.homotypicalGroup.typifiedNames.$",
153 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorship",
154 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.inReference",
155 // "name.homotypicalGroup.typifiedNames.taxonBases.$"
156 });
157
158
159 private static final List<String> TAXONRELATIONSHIP_INIT_STRATEGY = Arrays.asList(new String []{
160 "$",
161 "type.inverseRepresentations",
162 "fromTaxon.sec",
163 "fromTaxon.name",
164 "toTaxon.sec",
165 "toTaxon.name"
166 });
167
168 private static final List<String> NAMERELATIONSHIP_INIT_STRATEGY = Arrays.asList(new String []{
169 "$",
170 "type.inverseRepresentations",
171 "toName.$",
172 "toName.nomenclaturalReference.authorship",
173 "toName.nomenclaturalReference.inReference",
174 "fromName.$",
175 "fromName.nomenclaturalReference.authorship",
176 "fromName.nomenclaturalReference.inReference",
177
178 });
179
180 protected static final List<String> TAXONDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String [] {
181 "$",
182 "elements.$",
183 "elements.stateData.$",
184 "elements.sources.citation.authorship",
185 "elements.sources.nameUsedInSource",
186 "elements.multilanguageText",
187 "elements.media",
188 "elements.modifyingText",
189 "elements.modifiers",
190 "elements.kindOfUnit",
191 "name.$",
192 "name.rank.representations",
193 "name.status.type.representations",
194 "sources.$",
195 });
196
197 protected static final List<String> DESCRIPTION_ELEMENT_INIT_STRATEGY = Arrays.asList(new String []{
198 "$",
199 "sources.citation.authorship",
200 "sources.nameUsedInSource",
201 "multilanguageText",
202 "media",
203 });
204
205
206 // private static final List<String> NAMEDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{
207 // "uuid",
208 // "feature",
209 // "elements.$",
210 // "elements.multilanguageText",
211 // "elements.media",
212 // });
213
214 protected static final List<String> TAXONDESCRIPTION_MEDIA_INIT_STRATEGY = Arrays.asList(new String []{
215 "elements.media"
216
217 });
218
219 private static final List<String> TYPEDESIGNATION_INIT_STRATEGY = Arrays.asList(new String []{
220 "typeSpecimen.$",
221 "citation.authorship.$",
222 "typeName",
223 "typeStatus"
224 });
225
226 protected static final List<String> TAXONNODE_WITHTAXON_INIT_STRATEGY = Arrays.asList(new String []{
227 "childNodes.taxon",
228 });
229
230 private static final String featureTreeUuidPattern = "^/taxon(?:(?:/)([^/?#&\\.]+))+.*";
231
232
233 public TaxonPortalController(){
234 super();
235 setInitializationStrategy(TAXON_INIT_STRATEGY);
236 }
237
238 @Autowired
239 @Override
240 public void setService(ITaxonService service) {
241 this.service = service;
242 }
243
244 @InitBinder
245 @Override
246 public void initBinder(WebDataBinder binder) {
247 super.initBinder(binder);
248 binder.registerCustomEditor(NamedArea.class, new NamedAreaPropertyEditor());
249 binder.registerCustomEditor(MatchMode.class, new MatchModePropertyEditor());
250 binder.registerCustomEditor(Class.class, new CdmTypePropertyEditor());
251 binder.registerCustomEditor(UuidList.class, new UUIDListPropertyEditor());
252 binder.registerCustomEditor(DefinedTermBaseList.class, new TermBaseListPropertyEditor<>(termService));
253
254 }
255
256
257
258 /**
259 * Get the synonymy for a taxon identified by the <code>{taxon-uuid}</code>.
260 * The synonymy consists
261 * of two parts: The group of homotypic synonyms of the taxon and the
262 * heterotypic synonymy groups of the taxon. The synonymy is ordered
263 * historically by the type designations and by the publication date of the
264 * nomenclatural reference
265 * <p>
266 * URI:
267 * <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;synonymy</b>
268 *
269 *
270 * @param request
271 * @param response
272 * @return a Map with to entries which are mapped by the following keys:
273 * "homotypicSynonymsByHomotypicGroup", "heterotypicSynonymyGroups",
274 * containing lists of {@link Synonym}s which are initialized using the
275 * following initialization strategy: {@link #SYNONYMY_INIT_STRATEGY}
276 *
277 * @throws IOException
278 */
279 @RequestMapping(
280 value = {"synonymy"},
281 method = RequestMethod.GET)
282 public ModelAndView doGetSynonymy(@PathVariable("uuid") UUID uuid,
283 HttpServletRequest request, HttpServletResponse response)throws IOException {
284
285 boolean includeUnpublished = NO_UNPUBLISHED;
286 if(request != null){
287 logger.info("doGetSynonymy() " + requestPathAndQuery(request));
288 }
289 ModelAndView mv = new ModelAndView();
290 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
291 Map<String, List<?>> synonymy = new Hashtable<>();
292
293 //new
294 List<List<Synonym>> synonymyGroups = service.getSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY);
295 if(!includeUnpublished){
296 synonymyGroups = removeUnpublishedSynonyms(synonymyGroups);
297 }
298
299 synonymy.put("homotypicSynonymsByHomotypicGroup", synonymyGroups.get(0));
300 synonymyGroups.remove(0);
301 synonymy.put("heterotypicSynonymyGroups", synonymyGroups);
302
303 //old
304 // synonymy.put("homotypicSynonymsByHomotypicGroup", service.getHomotypicSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY));
305 // synonymy.put("heterotypicSynonymyGroups", service.getHeterotypicSynonymyGroups(taxon, SYNONYMY_INIT_STRATEGY));
306
307 mv.addObject(synonymy);
308 return mv;
309 }
310
311
312 /**
313 * @param synonymyGroups
314 */
315 private List<List<Synonym>> removeUnpublishedSynonyms(List<List<Synonym>> synonymyGroups) {
316 List<List<Synonym>> result = new ArrayList<>();
317 boolean isHomotypicToAccepted = true;
318
319 for (List<Synonym> oldList : synonymyGroups){
320 List<Synonym> newList = new ArrayList<>();
321 for (Synonym oldSyn : oldList){
322 if (oldSyn.isPublish()){
323 newList.add(oldSyn);
324 }
325 }
326 if (isHomotypicToAccepted || !newList.isEmpty()){
327 result.add(newList);
328 }
329 isHomotypicToAccepted = false;
330 }
331 return result;
332 }
333
334 /**
335 * {@inheritDoc}
336 */
337 @Override
338 protected List<String> getTaxonDescriptionInitStrategy() {
339 return TAXONDESCRIPTION_INIT_STRATEGY;
340 }
341
342 @Override
343 protected List<String> getTaxonDescriptionElementInitStrategy() {
344 return DESCRIPTION_ELEMENT_INIT_STRATEGY;
345 }
346
347 /**
348 * Get the list of {@link TaxonRelationship}s for the given
349 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
350 * <p>
351 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;taxonRelationships</b>
352 *
353 * @param request
354 * @param response
355 * @return a List of {@link TaxonRelationship} entities which are initialized
356 * using the following initialization strategy:
357 * {@link #TAXONRELATIONSHIP_INIT_STRATEGY}
358 * @throws IOException
359 */
360 @RequestMapping(
361 value = {"taxonRelationships"},
362 method = RequestMethod.GET)
363 public List<TaxonRelationship> doGetTaxonRelations(@PathVariable("uuid") UUID uuid,
364 HttpServletRequest request, HttpServletResponse response)throws IOException {
365
366 boolean includeUnpublished = NO_UNPUBLISHED;
367 logger.info("doGetTaxonRelations()" + requestPathAndQuery(request));
368 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
369 taxon = checkExistsAndAccess(taxon, includeUnpublished, response);
370
371 List<TaxonRelationship> toRelationships = service.listToTaxonRelationships(taxon, null,
372 includeUnpublished, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);
373 List<TaxonRelationship> fromRelationships = service.listFromTaxonRelationships(taxon, null,
374 includeUnpublished, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);
375
376 List<TaxonRelationship> allRelationships = new ArrayList<>(toRelationships.size() + fromRelationships.size());
377 allRelationships.addAll(toRelationships);
378 allRelationships.addAll(fromRelationships);
379
380 return allRelationships;
381 }
382
383 /**
384 * Get the list of {@link NameRelationship}s of the Name associated with the
385 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
386 * <p>
387 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>
388 *
389 * @param request
390 * @param response
391 * @return a List of {@link NameRelationship} entities which are initialized
392 * using the following initialization strategy:
393 * {@link #NAMERELATIONSHIP_INIT_STRATEGY}
394 * @throws IOException
395 */
396 @RequestMapping(
397 value = {"toNameRelationships"},
398 method = RequestMethod.GET)
399 public List<NameRelationship> doGetToNameRelations(@PathVariable("uuid") UUID uuid,
400 HttpServletRequest request, HttpServletResponse response)throws IOException {
401 logger.info("doGetNameRelations()" + request.getRequestURI());
402 boolean includeUnpublished = NO_UNPUBLISHED;
403
404 TaxonBase<?> taxonBase = getCdmBaseInstance(TaxonBase.class, uuid, response, (List<String>)null);
405 taxonBase = checkExistsAndAccess(taxonBase, includeUnpublished, response);
406
407 List<NameRelationship> list = nameService.listNameRelationships(taxonBase.getName(), Direction.relatedTo, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY);
408 return list;
409 }
410
411 /**
412 * Get the list of {@link NameRelationship}s of the Name associated with the
413 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
414 * <p>
415 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>
416 *
417 * @param request
418 * @param response
419 * @return a List of {@link NameRelationship} entities which are initialized
420 * using the following initialization strategy:
421 * {@link #NAMERELATIONSHIP_INIT_STRATEGY}
422 * @throws IOException
423 */
424 @RequestMapping(
425 value = {"fromNameRelationships"},
426 method = RequestMethod.GET)
427 public List<NameRelationship> doGetFromNameRelations(@PathVariable("uuid") UUID uuid,
428 HttpServletRequest request, HttpServletResponse response)throws IOException {
429 logger.info("doGetNameFromNameRelations()" + requestPathAndQuery(request));
430
431 boolean includeUnpublished = NO_UNPUBLISHED;
432
433 TaxonBase<?> taxonBase = getCdmBaseInstance(TaxonBase.class, uuid, response, SIMPLE_TAXON_INIT_STRATEGY);
434 taxonBase = checkExistsAndAccess(taxonBase, includeUnpublished, response);
435
436 List<NameRelationship> list = nameService.listNameRelationships(taxonBase.getName(), Direction.relatedFrom, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY);
437
438 return list;
439 }
440
441
442 // @RequestMapping(value = "specimens", method = RequestMethod.GET)
443 // public ModelAndView doGetSpecimens(
444 // @PathVariable("uuid") UUID uuid,
445 // HttpServletRequest request,
446 // HttpServletResponse response) throws IOException, ClassNotFoundException {
447 // logger.info("doGetSpecimens() - " + request.getRequestURI());
448 //
449 // ModelAndView mv = new ModelAndView();
450 //
451 // List<DerivedUnitFacade> derivedUnitFacadeList = new ArrayList<>();
452 //
453 // // find speciemens in the TaxonDescriptions
454 // List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, request, response);
455 // if (taxonDescriptions != null) {
456 //
457 // for (TaxonDescription description : taxonDescriptions) {
458 // derivedUnitFacadeList.addAll( occurrenceService.listDerivedUnitFacades(description, null) );
459 // }
460 // }
461 // // TODO find specimens in the NameDescriptions ??
462 //
463 // // TODO also find type specimens
464 //
465 // mv.addObject(derivedUnitFacadeList);
466 //
467 // return mv;
468 // }
469
470 /**
471 * Get the {@link Media} attached to the {@link Taxon} instance
472 * identified by the <code>{taxon-uuid}</code>.
473 *
474 * Usage &#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-
475 * uuid}&#x002F;media&#x002F;{mime type
476 * list}&#x002F;{size}[,[widthOrDuration}][,{height}]&#x002F;
477 *
478 * Whereas
479 * <ul>
480 * <li><b>{mime type list}</b>: a comma separated list of mime types, in the
481 * order of preference. The forward slashes contained in the mime types must
482 * be replaced by a colon. Regular expressions can be used. Each media
483 * associated with this given taxon is being searched whereas the first
484 * matching mime type matching a representation always rules.</li>
485 * <li><b>{size},{widthOrDuration},{height}</b>: <i>not jet implemented</i>
486 * valid values are an integer or the asterisk '*' as a wildcard</li>
487 * </ul>
488 *
489 * @param request
490 * @param response
491 * @return a List of {@link Media} entities which are initialized
492 * using the following initialization strategy:
493 * {@link #TAXONDESCRIPTION_INIT_STRATEGY}
494 * @throws IOException
495 */
496 @RequestMapping(
497 value = {"media"},
498 method = RequestMethod.GET)
499 public List<Media> doGetMedia(
500 @PathVariable("uuid") UUID uuid,
501 @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,
502 @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,
503 @RequestParam(value = "relationships", required = false) UuidList relationshipUuids,
504 @RequestParam(value = "relationshipsInvers", required = false) UuidList relationshipInversUuids,
505 @RequestParam(value = "includeTaxonDescriptions", required = true) Boolean includeTaxonDescriptions,
506 @RequestParam(value = "includeOccurrences", required = true) Boolean includeOccurrences,
507 @RequestParam(value = "includeTaxonNameDescriptions", required = true) Boolean includeTaxonNameDescriptions,
508 @RequestParam(value = "widthOrDuration", required = false) Integer widthOrDuration,
509 @RequestParam(value = "height", required = false) Integer height,
510 @RequestParam(value = "size", required = false) Integer size,
511 HttpServletRequest request, HttpServletResponse response) throws IOException {
512
513 logger.info("doGetMedia() " + requestPathAndQuery(request));
514
515 boolean includeUnpublished = NO_UNPUBLISHED;
516
517 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
518 taxon = checkExistsAndAccess(taxon, includeUnpublished, response);
519
520 Set<TaxonRelationshipEdge> includeRelationships = ControllerUtils.loadIncludeRelationships(relationshipUuids, relationshipInversUuids, termService);
521
522 List<Media> returnMedia = getMediaForTaxon(taxon, includeRelationships,
523 includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
524 type, mimeTypes, widthOrDuration, height, size);
525 return returnMedia;
526 }
527
528 @RequestMapping(
529 value = {"subtree/media"},
530 method = RequestMethod.GET)
531 public List<Media> doGetSubtreeMedia(
532 @PathVariable("uuid") UUID uuid,
533 @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,
534 @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,
535 @RequestParam(value = "relationships", required = false) UuidList relationshipUuids,
536 @RequestParam(value = "relationshipsInvers", required = false) UuidList relationshipInversUuids,
537 @RequestParam(value = "includeTaxonDescriptions", required = true) Boolean includeTaxonDescriptions,
538 @RequestParam(value = "includeOccurrences", required = true) Boolean includeOccurrences,
539 @RequestParam(value = "includeTaxonNameDescriptions", required = true) Boolean includeTaxonNameDescriptions,
540 @RequestParam(value = "widthOrDuration", required = false) Integer widthOrDuration,
541 @RequestParam(value = "height", required = false) Integer height,
542 @RequestParam(value = "size", required = false) Integer size,
543 HttpServletRequest request, HttpServletResponse response)throws IOException {
544
545
546 boolean includeUnpublished = NO_UNPUBLISHED;
547
548 logger.info("doGetSubtreeMedia() " + requestPathAndQuery(request));
549
550 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, TAXON_WITH_NODES_INIT_STRATEGY);
551 taxon = checkExistsAndAccess(taxon, includeUnpublished, response);
552
553 Set<TaxonRelationshipEdge> includeRelationships = ControllerUtils.loadIncludeRelationships(relationshipUuids, relationshipInversUuids, termService);
554
555 List<Media> returnMedia = getMediaForTaxon(taxon, includeRelationships,
556 includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
557 type, mimeTypes, widthOrDuration, height, size);
558 TaxonNode node;
559
560 //TODO use treeindex
561 //looking for all medias of genus
562 if (taxon.getTaxonNodes().size()>0){
563 Set<TaxonNode> nodes = taxon.getTaxonNodes();
564 Iterator<TaxonNode> iterator = nodes.iterator();
565 //TaxonNode holen
566 node = iterator.next();
567 //Check if TaxonNode belongs to the current tree
568
569 node = taxonNodeService.load(node.getUuid(), TAXONNODE_WITHTAXON_INIT_STRATEGY);
570 List<TaxonNode> children = node.getChildNodes();
571 Taxon childTaxon;
572 for (TaxonNode child : children){
573 childTaxon = child.getTaxon();
574 if(childTaxon != null) {
575 childTaxon = (Taxon)taxonService.load(childTaxon.getUuid(), NO_UNPUBLISHED, null);
576 returnMedia.addAll(getMediaForTaxon(childTaxon, includeRelationships,
577 includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
578 type, mimeTypes, widthOrDuration, height, size));
579 }
580 }
581 }
582 return returnMedia;
583 }
584
585 /**
586 *
587 * @param taxon
588 * @param includeRelationships
589 * @param type
590 * @param mimeTypes
591 * @param widthOrDuration
592 * @param height
593 * @param size
594 * @return
595 */
596 private List<Media> getMediaForTaxon(Taxon taxon, Set<TaxonRelationshipEdge> includeRelationships,
597 Boolean includeTaxonDescriptions, Boolean includeOccurrences, Boolean includeTaxonNameDescriptions,
598 Class<? extends MediaRepresentationPart> type, String[] mimeTypes, Integer widthOrDuration,
599 Integer height, Integer size) {
600
601 // list the media
602 logger.trace("getMediaForTaxon() - list the media");
603 List<Media> taxonGalleryMedia = service.listMedia(taxon, includeRelationships,
604 false, includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, null);
605
606 // filter by preferred size and type
607
608 logger.trace("getMediaForTaxon() - filter the media");
609 Map<Media, MediaRepresentation> mediaRepresentationMap = MediaUtils.findPreferredMedia(
610 taxonGalleryMedia, type, mimeTypes, null, widthOrDuration, height, size);
611
612 List<Media> filteredMedia = new ArrayList<>(mediaRepresentationMap.size());
613 for (Media media : mediaRepresentationMap.keySet()) {
614 media.getRepresentations().clear();
615 media.addRepresentation(mediaRepresentationMap.get(media));
616 filteredMedia.add(media);
617 }
618
619 logger.trace("getMediaForTaxon() - END ");
620
621 return filteredMedia;
622 }
623
624 // ---------------------- code snippet preserved for possible later use --------------------
625 // @RequestMapping(
626 // value = {"//*/portal/taxon/*/descriptions"}, // mapped as absolute path, see CdmAntPathMatcher
627 // method = RequestMethod.GET)
628 // public List<TaxonDescription> doGetDescriptionsbyFeatureTree(HttpServletRequest request, HttpServletResponse response)throws IOException {
629 // TaxonBase tb = getCdmBase(request, response, null, Taxon.class);
630 // if(tb instanceof Taxon){
631 // //T O D O this is a quick and dirty implementation -> generalize
632 // UUID featureTreeUuid = readValueUuid(request, featureTreeUuidPattern);
633 //
634 // FeatureTree featureTree = descriptionService.getFeatureTreeByUuid(featureTreeUuid);
635 // Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions((Taxon)tb, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
636 // List<TaxonDescription> descriptions = p.getRecords();
637 //
638 // if(!featureTree.isDescriptionSeparated()){
639 //
640 // TaxonDescription superDescription = TaxonDescription.NewInstance();
641 // //put all descriptionElements in superDescription and make it invisible
642 // for(TaxonDescription description: descriptions){
643 // for(DescriptionElementBase element: description.getElements()){
644 // superDescription.addElement(element);
645 // }
646 // }
647 // List<TaxonDescription> separatedDescriptions = new ArrayList<TaxonDescription>(descriptions.size());
648 // separatedDescriptions.add(superDescription);
649 // return separatedDescriptions;
650 // }else{
651 // return descriptions;
652 // }
653 // } else {
654 // response.sendError(HttpServletResponse.SC_NOT_FOUND, "invalid type; Taxon expected but " + tb.getClass().getSimpleName() + " found.");
655 // return null;
656 // }
657 // }
658
659 }