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.IClassificationService;
37 import eu.etaxonomy.cdm.api.service.INameService;
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 IClassificationService classificationService;
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 protected static final List<String> TAXONNODE_INIT_STRATEGY = Arrays.asList(new String []{
231 "taxonNodes.classification"
232 });
233
234
235
236 private static final String featureTreeUuidPattern = "^/taxon(?:(?:/)([^/?#&\\.]+))+.*";
237
238
239 public TaxonPortalController(){
240 super();
241 setInitializationStrategy(TAXON_INIT_STRATEGY);
242 }
243
244 @Autowired
245 @Override
246 public void setService(ITaxonService service) {
247 this.service = service;
248 }
249
250 @InitBinder
251 @Override
252 public void initBinder(WebDataBinder binder) {
253 super.initBinder(binder);
254 binder.registerCustomEditor(NamedArea.class, new NamedAreaPropertyEditor());
255 binder.registerCustomEditor(MatchMode.class, new MatchModePropertyEditor());
256 binder.registerCustomEditor(Class.class, new CdmTypePropertyEditor());
257 binder.registerCustomEditor(UuidList.class, new UUIDListPropertyEditor());
258 binder.registerCustomEditor(DefinedTermBaseList.class, new TermBaseListPropertyEditor<>(termService));
259
260 }
261
262
263 /* @Override
264 @RequestMapping(method = RequestMethod.GET)
265 public TaxonBase doGet(HttpServletRequest request, HttpServletResponse response)throws IOException {
266 logger.info("doGet()");
267 TaxonBase tb = getCdmBase(request, response, TAXON_INIT_STRATEGY, TaxonBase.class);
268 return tb;
269 }
270 */
271
272
273
274 /**
275 * Get the synonymy for a taxon identified by the <code>{taxon-uuid}</code>.
276 * The synonymy consists
277 * of two parts: The group of homotypic synonyms of the taxon and the
278 * heterotypic synonymy groups of the taxon. The synonymy is ordered
279 * historically by the type designations and by the publication date of the
280 * nomenclatural reference
281 * <p>
282 * URI:
283 * <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;synonymy</b>
284 *
285 *
286 * @param request
287 * @param response
288 * @return a Map with to entries which are mapped by the following keys:
289 * "homotypicSynonymsByHomotypicGroup", "heterotypicSynonymyGroups",
290 * containing lists of {@link Synonym}s which are initialized using the
291 * following initialization strategy: {@link #SYNONYMY_INIT_STRATEGY}
292 *
293 * @throws IOException
294 */
295 @RequestMapping(
296 value = {"synonymy"},
297 method = RequestMethod.GET)
298 public ModelAndView doGetSynonymy(@PathVariable("uuid") UUID uuid,
299 HttpServletRequest request, HttpServletResponse response)throws IOException {
300
301 boolean includeUnpublished = NO_UNPUBLISHED;
302 if(request != null){
303 logger.info("doGetSynonymy() " + requestPathAndQuery(request));
304 }
305 ModelAndView mv = new ModelAndView();
306 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
307 Map<String, List<?>> synonymy = new Hashtable<>();
308
309 //new
310 List<List<Synonym>> synonymyGroups = service.getSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY);
311 if(!includeUnpublished){
312 removeUnpublishedSynonyms(synonymyGroups);
313 }
314
315 synonymy.put("homotypicSynonymsByHomotypicGroup", synonymyGroups.get(0));
316 synonymyGroups.remove(0);
317 synonymy.put("heterotypicSynonymyGroups", synonymyGroups);
318
319 //old
320 // synonymy.put("homotypicSynonymsByHomotypicGroup", service.getHomotypicSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY));
321 // synonymy.put("heterotypicSynonymyGroups", service.getHeterotypicSynonymyGroups(taxon, SYNONYMY_INIT_STRATEGY));
322
323 mv.addObject(synonymy);
324 return mv;
325 }
326
327
328 /**
329 * @param synonymyGroups
330 */
331 private List<List<Synonym>> removeUnpublishedSynonyms(List<List<Synonym>> synonymyGroups) {
332 List<List<Synonym>> result = new ArrayList<>();
333 for (List<Synonym> oldList : synonymyGroups){
334 List<Synonym> newList = new ArrayList<>();
335 for (Synonym oldSyn : oldList){
336 if (oldSyn.isPublish()){
337 newList.add(oldSyn);
338 }
339 }
340 if (!newList.isEmpty()){
341 result.add(newList);
342 }
343 }
344 return result;
345 }
346
347 /**
348 * {@inheritDoc}
349 */
350 @Override
351 protected List<String> getTaxonDescriptionInitStrategy() {
352 return TAXONDESCRIPTION_INIT_STRATEGY;
353 }
354
355 @Override
356 protected List<String> getTaxonDescriptionElementInitStrategy() {
357 return DESCRIPTION_ELEMENT_INIT_STRATEGY;
358 }
359
360 /**
361 * Get the list of {@link TaxonRelationship}s for the given
362 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
363 * <p>
364 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;taxonRelationships</b>
365 *
366 * @param request
367 * @param response
368 * @return a List of {@link TaxonRelationship} entities which are initialized
369 * using the following initialization strategy:
370 * {@link #TAXONRELATIONSHIP_INIT_STRATEGY}
371 * @throws IOException
372 */
373 @RequestMapping(
374 value = {"taxonRelationships"},
375 method = RequestMethod.GET)
376 public List<TaxonRelationship> doGetTaxonRelations(@PathVariable("uuid") UUID uuid,
377 HttpServletRequest request, HttpServletResponse response)throws IOException {
378
379 logger.info("doGetTaxonRelations()" + requestPathAndQuery(request));
380 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
381 List<TaxonRelationship> toRelationships = service.listToTaxonRelationships(taxon, null, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);
382 List<TaxonRelationship> fromRelationships = service.listFromTaxonRelationships(taxon, null, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);
383
384 List<TaxonRelationship> allRelationships = new ArrayList<>(toRelationships.size() + fromRelationships.size());
385 allRelationships.addAll(toRelationships);
386 allRelationships.addAll(fromRelationships);
387
388 return allRelationships;
389 }
390
391 /**
392 * Get the list of {@link NameRelationship}s of the Name associated with the
393 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
394 * <p>
395 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>
396 *
397 * @param request
398 * @param response
399 * @return a List of {@link NameRelationship} entities which are initialized
400 * using the following initialization strategy:
401 * {@link #NAMERELATIONSHIP_INIT_STRATEGY}
402 * @throws IOException
403 */
404 @RequestMapping(
405 value = {"toNameRelationships"},
406 method = RequestMethod.GET)
407 public List<NameRelationship> doGetToNameRelations(@PathVariable("uuid") UUID uuid,
408 HttpServletRequest request, HttpServletResponse response)throws IOException {
409 logger.info("doGetNameRelations()" + request.getRequestURI());
410 TaxonBase<?> taxonBase = getCdmBaseInstance(TaxonBase.class, uuid, response, (List<String>)null);
411 List<NameRelationship> list = nameService.listNameRelationships(taxonBase.getName(), Direction.relatedTo, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY);
412 //List<NameRelationship> list = nameService.listToNameRelationships(taxonBase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
413 return list;
414 }
415
416 /**
417 * Get the list of {@link NameRelationship}s of the Name associated with the
418 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
419 * <p>
420 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>
421 *
422 * @param request
423 * @param response
424 * @return a List of {@link NameRelationship} entities which are initialized
425 * using the following initialization strategy:
426 * {@link #NAMERELATIONSHIP_INIT_STRATEGY}
427 * @throws IOException
428 */
429 @RequestMapping(
430 value = {"fromNameRelationships"},
431 method = RequestMethod.GET)
432 public List<NameRelationship> doGetFromNameRelations(@PathVariable("uuid") UUID uuid,
433 HttpServletRequest request, HttpServletResponse response)throws IOException {
434 logger.info("doGetNameFromNameRelations()" + requestPathAndQuery(request));
435
436 TaxonBase<?> taxonbase = getCdmBaseInstance(TaxonBase.class, uuid, response, SIMPLE_TAXON_INIT_STRATEGY);
437 List<NameRelationship> list = nameService.listNameRelationships(taxonbase.getName(), Direction.relatedFrom, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY);
438 //List<NameRelationship> list = nameService.listFromNameRelationships(taxonbase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
439 return list;
440 }
441
442 @Override
443 @RequestMapping(value = "taxonNodes", method = RequestMethod.GET)
444 public Set<TaxonNode> doGetTaxonNodes(
445 @PathVariable("uuid") UUID uuid,
446 HttpServletRequest request,
447 HttpServletResponse response) throws IOException {
448
449 logger.info("doGetTaxonNodes" + requestPathAndQuery(request));
450 TaxonBase<?> taxon = service.load(uuid, NO_UNPUBLISHED, TAXONNODE_INIT_STRATEGY);
451 if(taxon instanceof Taxon){
452 return ((Taxon)taxon).getTaxonNodes();
453 } else {
454 HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
455 return null;
456 }
457 }
458
459 // @RequestMapping(value = "specimens", method = RequestMethod.GET)
460 // public ModelAndView doGetSpecimens(
461 // @PathVariable("uuid") UUID uuid,
462 // HttpServletRequest request,
463 // HttpServletResponse response) throws IOException, ClassNotFoundException {
464 // logger.info("doGetSpecimens() - " + request.getRequestURI());
465 //
466 // ModelAndView mv = new ModelAndView();
467 //
468 // List<DerivedUnitFacade> derivedUnitFacadeList = new ArrayList<>();
469 //
470 // // find speciemens in the TaxonDescriptions
471 // List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, request, response);
472 // if (taxonDescriptions != null) {
473 //
474 // for (TaxonDescription description : taxonDescriptions) {
475 // derivedUnitFacadeList.addAll( occurrenceService.listDerivedUnitFacades(description, null) );
476 // }
477 // }
478 // // TODO find specimens in the NameDescriptions ??
479 //
480 // // TODO also find type specimens
481 //
482 // mv.addObject(derivedUnitFacadeList);
483 //
484 // return mv;
485 // }
486
487 /**
488 * Get the {@link Media} attached to the {@link Taxon} instance
489 * identified by the <code>{taxon-uuid}</code>.
490 *
491 * Usage &#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-
492 * uuid}&#x002F;media&#x002F;{mime type
493 * list}&#x002F;{size}[,[widthOrDuration}][,{height}]&#x002F;
494 *
495 * Whereas
496 * <ul>
497 * <li><b>{mime type list}</b>: a comma separated list of mime types, in the
498 * order of preference. The forward slashes contained in the mime types must
499 * be replaced by a colon. Regular expressions can be used. Each media
500 * associated with this given taxon is being searched whereas the first
501 * matching mime type matching a representation always rules.</li>
502 * <li><b>{size},{widthOrDuration},{height}</b>: <i>not jet implemented</i>
503 * valid values are an integer or the asterisk '*' as a wildcard</li>
504 * </ul>
505 *
506 * @param request
507 * @param response
508 * @return a List of {@link Media} entities which are initialized
509 * using the following initialization strategy:
510 * {@link #TAXONDESCRIPTION_INIT_STRATEGY}
511 * @throws IOException
512 */
513 @RequestMapping(
514 value = {"media"},
515 method = RequestMethod.GET)
516 public List<Media> doGetMedia(
517 @PathVariable("uuid") UUID uuid,
518 @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,
519 @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,
520 @RequestParam(value = "relationships", required = false) UuidList relationshipUuids,
521 @RequestParam(value = "relationshipsInvers", required = false) UuidList relationshipInversUuids,
522 @RequestParam(value = "includeTaxonDescriptions", required = true) Boolean includeTaxonDescriptions,
523 @RequestParam(value = "includeOccurrences", required = true) Boolean includeOccurrences,
524 @RequestParam(value = "includeTaxonNameDescriptions", required = true) Boolean includeTaxonNameDescriptions,
525 @RequestParam(value = "widthOrDuration", required = false) Integer widthOrDuration,
526 @RequestParam(value = "height", required = false) Integer height,
527 @RequestParam(value = "size", required = false) Integer size,
528 HttpServletRequest request, HttpServletResponse response) throws IOException {
529
530 logger.info("doGetMedia() " + requestPathAndQuery(request));
531
532 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
533
534 Set<TaxonRelationshipEdge> includeRelationships = ControllerUtils.loadIncludeRelationships(relationshipUuids, relationshipInversUuids, termService);
535
536 List<Media> returnMedia = getMediaForTaxon(taxon, includeRelationships,
537 includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
538 type, mimeTypes, widthOrDuration, height, size);
539 return returnMedia;
540 }
541
542 @RequestMapping(
543 value = {"subtree/media"},
544 method = RequestMethod.GET)
545 public List<Media> doGetSubtreeMedia(
546 @PathVariable("uuid") UUID uuid,
547 @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,
548 @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,
549 @RequestParam(value = "relationships", required = false) UuidList relationshipUuids,
550 @RequestParam(value = "relationshipsInvers", required = false) UuidList relationshipInversUuids,
551 @RequestParam(value = "includeTaxonDescriptions", required = true) Boolean includeTaxonDescriptions,
552 @RequestParam(value = "includeOccurrences", required = true) Boolean includeOccurrences,
553 @RequestParam(value = "includeTaxonNameDescriptions", required = true) Boolean includeTaxonNameDescriptions,
554 @RequestParam(value = "widthOrDuration", required = false) Integer widthOrDuration,
555 @RequestParam(value = "height", required = false) Integer height,
556 @RequestParam(value = "size", required = false) Integer size,
557 HttpServletRequest request, HttpServletResponse response)throws IOException {
558
559 logger.info("doGetSubtreeMedia() " + requestPathAndQuery(request));
560
561 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, TAXON_WITH_NODES_INIT_STRATEGY);
562
563 Set<TaxonRelationshipEdge> includeRelationships = ControllerUtils.loadIncludeRelationships(relationshipUuids, relationshipInversUuids, termService);
564
565 List<Media> returnMedia = getMediaForTaxon(taxon, includeRelationships,
566 includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
567 type, mimeTypes, widthOrDuration, height, size);
568 TaxonNode node;
569 //looking for all medias of genus
570 if (taxon.getTaxonNodes().size()>0){
571 Set<TaxonNode> nodes = taxon.getTaxonNodes();
572 Iterator<TaxonNode> iterator = nodes.iterator();
573 //TaxonNode holen
574 node = iterator.next();
575 //Check if TaxonNode belongs to the current tree
576
577 node = classificationService.loadTaxonNode(node, TAXONNODE_WITHTAXON_INIT_STRATEGY);
578 List<TaxonNode> children = node.getChildNodes();
579 Taxon childTaxon;
580 for (TaxonNode child : children){
581 childTaxon = child.getTaxon();
582 if(childTaxon != null) {
583 childTaxon = (Taxon)taxonService.load(childTaxon.getUuid(), NO_UNPUBLISHED, null);
584 returnMedia.addAll(getMediaForTaxon(childTaxon, includeRelationships,
585 includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
586 type, mimeTypes, widthOrDuration, height, size));
587 }
588 }
589 }
590 return returnMedia;
591 }
592
593 /**
594 *
595 * @param taxon
596 * @param includeRelationships
597 * @param type
598 * @param mimeTypes
599 * @param widthOrDuration
600 * @param height
601 * @param size
602 * @return
603 */
604 private List<Media> getMediaForTaxon(Taxon taxon, Set<TaxonRelationshipEdge> includeRelationships,
605 Boolean includeTaxonDescriptions, Boolean includeOccurrences, Boolean includeTaxonNameDescriptions,
606 Class<? extends MediaRepresentationPart> type, String[] mimeTypes, Integer widthOrDuration,
607 Integer height, Integer size) {
608
609 // list the media
610 logger.trace("getMediaForTaxon() - list the media");
611 List<Media> taxonGalleryMedia = service.listMedia(taxon, includeRelationships,
612 false, includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, null);
613
614 // filter by preferred size and type
615
616 logger.trace("getMediaForTaxon() - filter the media");
617 Map<Media, MediaRepresentation> mediaRepresentationMap = MediaUtils.findPreferredMedia(
618 taxonGalleryMedia, type, mimeTypes, null, widthOrDuration, height, size);
619
620 List<Media> filteredMedia = new ArrayList<>(mediaRepresentationMap.size());
621 for (Media media : mediaRepresentationMap.keySet()) {
622 media.getRepresentations().clear();
623 media.addRepresentation(mediaRepresentationMap.get(media));
624 filteredMedia.add(media);
625 }
626
627 logger.trace("getMediaForTaxon() - END ");
628
629 return filteredMedia;
630 }
631
632 // ---------------------- code snippet preserved for possible later use --------------------
633 // @RequestMapping(
634 // value = {"//*/portal/taxon/*/descriptions"}, // mapped as absolute path, see CdmAntPathMatcher
635 // method = RequestMethod.GET)
636 // public List<TaxonDescription> doGetDescriptionsbyFeatureTree(HttpServletRequest request, HttpServletResponse response)throws IOException {
637 // TaxonBase tb = getCdmBase(request, response, null, Taxon.class);
638 // if(tb instanceof Taxon){
639 // //T O D O this is a quick and dirty implementation -> generalize
640 // UUID featureTreeUuid = readValueUuid(request, featureTreeUuidPattern);
641 //
642 // FeatureTree featureTree = descriptionService.getFeatureTreeByUuid(featureTreeUuid);
643 // Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions((Taxon)tb, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
644 // List<TaxonDescription> descriptions = p.getRecords();
645 //
646 // if(!featureTree.isDescriptionSeparated()){
647 //
648 // TaxonDescription superDescription = TaxonDescription.NewInstance();
649 // //put all descriptionElements in superDescription and make it invisible
650 // for(TaxonDescription description: descriptions){
651 // for(DescriptionElementBase element: description.getElements()){
652 // superDescription.addElement(element);
653 // }
654 // }
655 // List<TaxonDescription> separatedDescriptions = new ArrayList<TaxonDescription>(descriptions.size());
656 // separatedDescriptions.add(superDescription);
657 // return separatedDescriptions;
658 // }else{
659 // return descriptions;
660 // }
661 // } else {
662 // response.sendError(HttpServletResponse.SC_NOT_FOUND, "invalid type; Taxon expected but " + tb.getClass().getSimpleName() + " found.");
663 // return null;
664 // }
665 // }
666
667 }