merge-update from trunk
[cdmlib.git] / cdmlib-remote / src / main / java / eu / etaxonomy / cdm / remote / controller / TaxonPortalController.java
1 // $Id: TaxonController.java 5473 2009-03-25 13:42:07Z a.kohlbecker $
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.cdm.remote.controller;
12
13 import java.io.IOException;
14 import java.util.ArrayList;
15 import java.util.Arrays;
16 import java.util.HashSet;
17 import java.util.Hashtable;
18 import java.util.Iterator;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Set;
22 import java.util.UUID;
23
24 import javax.servlet.http.HttpServletRequest;
25 import javax.servlet.http.HttpServletResponse;
26
27 import org.apache.log4j.Logger;
28 import org.springframework.beans.factory.annotation.Autowired;
29 import org.springframework.stereotype.Controller;
30 import org.springframework.web.bind.WebDataBinder;
31 import org.springframework.web.bind.annotation.InitBinder;
32 import org.springframework.web.bind.annotation.PathVariable;
33 import org.springframework.web.bind.annotation.RequestMapping;
34 import org.springframework.web.bind.annotation.RequestMethod;
35 import org.springframework.web.bind.annotation.RequestParam;
36 import org.springframework.web.servlet.ModelAndView;
37
38 import eu.etaxonomy.cdm.api.service.IClassificationService;
39 import eu.etaxonomy.cdm.api.service.IDescriptionService;
40 import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
41 import eu.etaxonomy.cdm.api.service.INameService;
42 import eu.etaxonomy.cdm.api.service.IOccurrenceService;
43 import eu.etaxonomy.cdm.api.service.ITaxonService;
44 import eu.etaxonomy.cdm.api.service.ITermService;
45 import eu.etaxonomy.cdm.api.service.pager.Pager;
46 import eu.etaxonomy.cdm.api.service.util.TaxonRelationshipEdge;
47 import eu.etaxonomy.cdm.database.UpdatableRoutingDataSource;
48 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
49 import eu.etaxonomy.cdm.model.common.MarkerType;
50 import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
51 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
52 import eu.etaxonomy.cdm.model.description.TaxonDescription;
53 import eu.etaxonomy.cdm.model.location.NamedArea;
54 import eu.etaxonomy.cdm.model.media.Media;
55 import eu.etaxonomy.cdm.model.media.MediaRepresentation;
56 import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
57 import eu.etaxonomy.cdm.model.media.MediaUtils;
58 import eu.etaxonomy.cdm.model.name.NameRelationship;
59 import eu.etaxonomy.cdm.model.taxon.Synonym;
60 import eu.etaxonomy.cdm.model.taxon.Taxon;
61 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
62 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
63 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
64 import eu.etaxonomy.cdm.persistence.query.MatchMode;
65 import eu.etaxonomy.cdm.remote.controller.util.ControllerUtils;
66 import eu.etaxonomy.cdm.remote.editor.CdmTypePropertyEditor;
67 import eu.etaxonomy.cdm.remote.editor.DefinedTermBaseList;
68 import eu.etaxonomy.cdm.remote.editor.MatchModePropertyEditor;
69 import eu.etaxonomy.cdm.remote.editor.NamedAreaPropertyEditor;
70 import eu.etaxonomy.cdm.remote.editor.TermBaseListPropertyEditor;
71 import eu.etaxonomy.cdm.remote.editor.UUIDListPropertyEditor;
72 import eu.etaxonomy.cdm.remote.editor.UuidList;
73
74 /**
75 * The TaxonPortalController class is a Spring MVC Controller.
76 * <p>
77 * The syntax of the mapped service URIs contains the the {datasource-name} path element.
78 * The available {datasource-name}s are defined in a configuration file which
79 * is loaded by the {@link UpdatableRoutingDataSource}. If the
80 * UpdatableRoutingDataSource is not being used in the actual application
81 * context any arbitrary {datasource-name} may be used.
82 * <p>
83 * Methods mapped at type level, inherited from super classes ({@link BaseController}):
84 * <blockquote>
85 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}</b>
86 *
87 * Get the {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
88 * The returned Taxon is initialized by
89 * the following strategy {@link #TAXON_INIT_STRATEGY}
90 * </blockquote>
91 *
92 * @author a.kohlbecker
93 * @date 20.07.2009
94 *
95 */
96 @Controller
97 @RequestMapping(value = {"/portal/taxon/{uuid}"})
98 public class TaxonPortalController extends TaxonController
99 {
100
101 public static final Logger logger = Logger.getLogger(TaxonPortalController.class);
102
103 @Autowired
104 private INameService nameService;
105
106 @Autowired
107 private IDescriptionService descriptionService;
108
109 @Autowired
110 private IOccurrenceService occurrenceService;
111
112 @Autowired
113 private IClassificationService classificationService;
114
115 @Autowired
116 private ITaxonService taxonService;
117
118 @Autowired
119 private ITermService termService;
120
121 @Autowired
122 private IFeatureTreeService featureTreeService;
123
124 private static final List<String> TAXON_INIT_STRATEGY = Arrays.asList(new String []{
125 "$",
126 "sources",
127 // taxon relations
128 // "relationsToThisName.fromTaxon.name",
129 // the name
130 "name.$",
131 "name.nomenclaturalReference.authorship",
132 "name.nomenclaturalReference.inReference",
133 "name.rank.representations",
134 "name.status.type.representations",
135
136 // "descriptions" // TODO remove
137
138 });
139
140 private static final List<String> TAXON_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{
141 "taxonNodes.$",
142 "taxonNodes.classification.$",
143 "taxonNodes.childNodes.$"
144 });
145
146 private static final List<String> SIMPLE_TAXON_INIT_STRATEGY = Arrays.asList(new String []{
147 "$",
148 // the name
149 "name.$",
150 "name.rank.representations",
151 "name.status.type.representations",
152 "name.nomenclaturalReference.authorship",
153 "name.nomenclaturalReference.inReference",
154 "taxonNodes.classification",
155 });
156
157 private static final List<String> SYNONYMY_INIT_STRATEGY = Arrays.asList(new String []{
158 // initialize homotypical and heterotypical groups; needs synonyms
159 "synonymRelations.$",
160 "synonymRelations.synonym.$",
161 "synonymRelations.synonym.name.status.type.representation",
162 "synonymRelations.synonym.name.nomenclaturalReference.authorship",
163 "synonymRelations.synonym.name.nomenclaturalReference.inReference",
164 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
165 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
166 "synonymRelations.synonym.name.combinationAuthorTeam.$",
167
168 "name.typeDesignations",
169
170 "name.homotypicalGroup.$",
171 "name.homotypicalGroup.typifiedNames.$",
172 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorship",
173 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.inReference",
174 "name.homotypicalGroup.typifiedNames.taxonBases.$"
175 });
176
177 private static final List<String> SYNONYMY_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{
178 // initialize homotypical and heterotypical groups; needs synonyms
179 "synonymRelations.$",
180 "synonymRelations.synonym.$",
181 "synonymRelations.synonym.name.status.type.representation",
182 "synonymRelations.synonym.name.nomenclaturalReference.authorship",
183 "synonymRelations.synonym.name.nomenclaturalReference.inReference",
184 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
185 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
186 "synonymRelations.synonym.name.combinationAuthorTeam.$",
187
188 "name.homotypicalGroup.$",
189 "name.homotypicalGroup.typifiedNames.$",
190 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorship",
191 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.inReference",
192
193 "name.homotypicalGroup.typifiedNames.taxonBases.$",
194
195 "taxonNodes.$",
196 "taxonNodes.classification.$",
197 "taxonNodes.childNodes.$"
198 });
199 private static final List<String> SIMPLE_TAXON_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{
200 "*",
201 // taxon relations
202 "relationsToThisName.fromTaxon.name",
203 // the name
204 "name.$",
205 "name.rank.representations",
206 "name.status.type.representations",
207 "name.nomenclaturalReference.authorship",
208 "name.nomenclaturalReference.inReference",
209
210 "taxonNodes.$",
211 "taxonNodes.classification.$",
212 "taxonNodes.childNodes.$"
213 });
214
215
216 private static final List<String> TAXONRELATIONSHIP_INIT_STRATEGY = Arrays.asList(new String []{
217 "$",
218 "type.inverseRepresentations",
219 "fromTaxon.sec",
220 "fromTaxon.name",
221 "toTaxon.sec",
222 "toTaxon.name"
223 });
224
225 private static final List<String> NAMERELATIONSHIP_INIT_STRATEGY = Arrays.asList(new String []{
226 "$",
227 "type.inverseRepresentations",
228 "toName.$",
229 "toName.nomenclaturalReference.authorship",
230 "toName.nomenclaturalReference.inReference",
231 "fromName.$",
232 "fromName.nomenclaturalReference.authorship",
233 "fromName.nomenclaturalReference.inReference",
234
235 });
236
237
238 protected static final List<String> TAXONDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String [] {
239 "$",
240 "elements.$",
241 "elements.stateData.$",
242 "elements.sources.citation.authorship",
243 "elements.sources.nameUsedInSource",
244 "elements.multilanguageText",
245 "elements.media",
246 "elements.modifyingText",
247 "elements.modifiers",
248 "elements.kindOfUnit",
249 "name.$",
250 "name.rank.representations",
251 "name.status.type.representations",
252 "sources.$",
253 });
254
255 protected static final List<String> DESCRIPTION_ELEMENT_INIT_STRATEGY = Arrays.asList(new String []{
256 "$",
257 "sources.citation.authorship",
258 "sources.nameUsedInSource",
259 "multilanguageText",
260 "media",
261 });
262
263
264 // private static final List<String> NAMEDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{
265 // "uuid",
266 // "feature",
267 // "elements.$",
268 // "elements.multilanguageText",
269 // "elements.media",
270 // });
271
272 protected static final List<String> TAXONDESCRIPTION_MEDIA_INIT_STRATEGY = Arrays.asList(new String []{
273 "elements.media"
274
275 });
276
277 private static final List<String> TYPEDESIGNATION_INIT_STRATEGY = Arrays.asList(new String []{
278 "typeSpecimen.$",
279 "citation.authorship.$",
280 "typeName",
281 "typeStatus"
282 });
283
284 protected static final List<String> TAXONNODE_WITHTAXON_INIT_STRATEGY = Arrays.asList(new String []{
285 "childNodes.taxon",
286 });
287
288 protected static final List<String> TAXONNODE_INIT_STRATEGY = Arrays.asList(new String []{
289 "taxonNodes.classification"
290 });
291
292
293
294 private static final String featureTreeUuidPattern = "^/taxon(?:(?:/)([^/?#&\\.]+))+.*";
295
296 public TaxonPortalController(){
297 super();
298 setInitializationStrategy(TAXON_INIT_STRATEGY);
299 }
300
301 /* (non-Javadoc)
302 * @see eu.etaxonomy.cdm.remote.controller.GenericController#setService(eu.etaxonomy.cdm.api.service.IService)
303 */
304 @Autowired
305 @Override
306 public void setService(ITaxonService service) {
307 this.service = service;
308 }
309
310 @InitBinder
311 @Override
312 public void initBinder(WebDataBinder binder) {
313 super.initBinder(binder);
314 binder.registerCustomEditor(NamedArea.class, new NamedAreaPropertyEditor());
315 binder.registerCustomEditor(MatchMode.class, new MatchModePropertyEditor());
316 binder.registerCustomEditor(Class.class, new CdmTypePropertyEditor());
317 binder.registerCustomEditor(UuidList.class, new UUIDListPropertyEditor());
318 binder.registerCustomEditor(DefinedTermBaseList.class, new TermBaseListPropertyEditor<NamedArea>(termService));
319
320 }
321
322
323 /* (non-Javadoc)
324 * @see eu.etaxonomy.cdm.remote.controller.BaseController#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
325
326 @Override
327 @RequestMapping(method = RequestMethod.GET)
328 public TaxonBase doGet(HttpServletRequest request, HttpServletResponse response)throws IOException {
329 logger.info("doGet()");
330 TaxonBase tb = getCdmBase(request, response, TAXON_INIT_STRATEGY, TaxonBase.class);
331 return tb;
332 }
333 */
334
335 /**
336 * Get the synonymy for a taxon identified by the <code>{taxon-uuid}</code>.
337 * The synonymy consists
338 * of two parts: The group of homotypic synonyms of the taxon and the
339 * heterotypic synonymy groups of the taxon. The synonymy is ordered
340 * historically by the type designations and by the publication date of the
341 * nomenclatural reference
342 * <p>
343 * URI:
344 * <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;synonymy</b>
345 *
346 *
347 * @param request
348 * @param response
349 * @return a Map with to entries which are mapped by the following keys:
350 * "homotypicSynonymsByHomotypicGroup", "heterotypicSynonymyGroups",
351 * containing lists of {@link Synonym}s which are initialized using the
352 * following initialization strategy: {@link #SYNONYMY_INIT_STRATEGY}
353 *
354 * @throws IOException
355 */
356 @RequestMapping(
357 value = {"synonymy"},
358 method = RequestMethod.GET)
359 public ModelAndView doGetSynonymy(@PathVariable("uuid") UUID uuid,
360 HttpServletRequest request, HttpServletResponse response)throws IOException {
361
362 if(request != null){
363 logger.info("doGetSynonymy() " + requestPathAndQuery(request));
364 }
365 ModelAndView mv = new ModelAndView();
366 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
367 Map<String, List<?>> synonymy = new Hashtable<String, List<?>>();
368
369 //new
370 List<List<Synonym>> synonymyGroups = service.getSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY);
371 synonymy.put("homotypicSynonymsByHomotypicGroup", synonymyGroups.get(0));
372 synonymyGroups.remove(0);
373 synonymy.put("heterotypicSynonymyGroups", synonymyGroups);
374
375 //old
376 // synonymy.put("homotypicSynonymsByHomotypicGroup", service.getHomotypicSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY));
377 // synonymy.put("heterotypicSynonymyGroups", service.getHeterotypicSynonymyGroups(taxon, SYNONYMY_INIT_STRATEGY));
378
379
380 mv.addObject(synonymy);
381 return mv;
382 }
383
384
385 /**
386 * Get the list of {@link TaxonRelationship}s for the given
387 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
388 * <p>
389 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;taxonRelationships</b>
390 *
391 * @param request
392 * @param response
393 * @return a List of {@link TaxonRelationship} entities which are initialized
394 * using the following initialization strategy:
395 * {@link #TAXONRELATIONSHIP_INIT_STRATEGY}
396 * @throws IOException
397 */
398 @RequestMapping(
399 value = {"taxonRelationships"},
400 method = RequestMethod.GET)
401 public List<TaxonRelationship> doGetTaxonRelations(@PathVariable("uuid") UUID uuid,
402 HttpServletRequest request, HttpServletResponse response)throws IOException {
403
404 logger.info("doGetTaxonRelations()" + requestPathAndQuery(request));
405 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
406 List<TaxonRelationship> toRelationships = service.listToTaxonRelationships(taxon, null, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);
407 List<TaxonRelationship> fromRelationships = service.listFromTaxonRelationships(taxon, null, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);
408
409 List<TaxonRelationship> allRelationships = new ArrayList<TaxonRelationship>(toRelationships.size() + fromRelationships.size());
410 allRelationships.addAll(toRelationships);
411 allRelationships.addAll(fromRelationships);
412
413 return allRelationships;
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 = {"toNameRelationships"},
431 method = RequestMethod.GET)
432 public List<NameRelationship> doGetToNameRelations(@PathVariable("uuid") UUID uuid,
433 HttpServletRequest request, HttpServletResponse response)throws IOException {
434 logger.info("doGetNameRelations()" + request.getRequestURI());
435 TaxonBase taxonBase = getCdmBaseInstance(TaxonBase.class, uuid, response, (List<String>)null);
436 List<NameRelationship> list = nameService.listNameRelationships(taxonBase.getName(), Direction.relatedTo, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY);
437 //List<NameRelationship> list = nameService.listToNameRelationships(taxonBase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
438 return list;
439 }
440
441 /**
442 * Get the list of {@link NameRelationship}s of the Name associated with the
443 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
444 * <p>
445 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>
446 *
447 * @param request
448 * @param response
449 * @return a List of {@link NameRelationship} entities which are initialized
450 * using the following initialization strategy:
451 * {@link #NAMERELATIONSHIP_INIT_STRATEGY}
452 * @throws IOException
453 */
454 @RequestMapping(
455 value = {"fromNameRelationships"},
456 method = RequestMethod.GET)
457 public List<NameRelationship> doGetFromNameRelations(@PathVariable("uuid") UUID uuid,
458 HttpServletRequest request, HttpServletResponse response)throws IOException {
459 logger.info("doGetNameFromNameRelations()" + requestPathAndQuery(request));
460
461 TaxonBase taxonbase = getCdmBaseInstance(TaxonBase.class, uuid, response, SIMPLE_TAXON_INIT_STRATEGY);
462 List<NameRelationship> list = nameService.listNameRelationships(taxonbase.getName(), Direction.relatedFrom, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY);
463 //List<NameRelationship> list = nameService.listFromNameRelationships(taxonbase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
464 return list;
465 }
466
467 @Override
468 @RequestMapping(value = "taxonNodes", method = RequestMethod.GET)
469 public Set<TaxonNode> doGetTaxonNodes(
470 @PathVariable("uuid") UUID uuid,
471 HttpServletRequest request,
472 HttpServletResponse response) throws IOException {
473 logger.info("doGetTaxonNodes" + requestPathAndQuery(request));
474 TaxonBase taxon = service.load(uuid, TAXONNODE_INIT_STRATEGY);
475 if(taxon instanceof Taxon){
476 return ((Taxon)taxon).getTaxonNodes();
477 } else {
478 HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
479 return null;
480 }
481 }
482
483 /**
484 * Get the list of {@link TaxonDescription}s of the
485 * {@link Taxon} instance identified by the <code>{taxon-uuid}</code>.
486 * <p>
487 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;descriptions</b>
488 *
489 * @param request
490 * @param response
491 * @return a List of {@link TaxonDescription} entities which are initialized
492 * using the following initialization strategy:
493 * {@link #TAXONDESCRIPTION_INIT_STRATEGY}
494 * @throws IOException
495 */
496 @RequestMapping(
497 value = {"descriptions"},
498 method = RequestMethod.GET)
499 public List<TaxonDescription> doGetDescriptions(
500 @PathVariable("uuid") UUID uuid,
501 @RequestParam(value = "markerTypes", required = false) UuidList markerTypeUUIDs,
502 HttpServletRequest request,
503 HttpServletResponse response)throws IOException {
504 if(request != null){
505 logger.info("doGetDescriptions()" + requestPathAndQuery(request));
506 }
507 List<DefinedTermBase> markerTypeTerms = null;
508 Set<UUID> sMarkerTypeUUIDs = null;
509
510 if(markerTypeUUIDs != null && !markerTypeUUIDs.isEmpty()){
511 sMarkerTypeUUIDs = new HashSet<UUID>(markerTypeUUIDs);
512 markerTypeTerms = termService.find(sMarkerTypeUUIDs);
513 } else if(markerTypeUUIDs != null && markerTypeUUIDs.isEmpty()){
514 markerTypeTerms = new ArrayList<DefinedTermBase>();
515 }
516 Set<MarkerType> markerTypes = new HashSet<MarkerType>();
517 List<TaxonDescription> descriptions = new ArrayList<TaxonDescription>();
518 if (markerTypeTerms != null) {
519 for (DefinedTermBase markerTypeTerm : markerTypeTerms) {
520 markerTypes.add((MarkerType)markerTypeTerm);
521 }
522 }
523 Taxon t = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
524 if (markerTypeTerms == null) {
525
526 Pager<TaxonDescription> p = descriptionService.pageTaxonDescriptions(t, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
527 descriptions = p.getRecords();
528 }
529
530 else if (markerTypeTerms != null && markerTypeTerms.isEmpty()) {
531 descriptions = descriptionService.listTaxonDescriptions(t, null, null, markerTypes, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
532
533 }
534 else {
535 descriptions = descriptionService.listTaxonDescriptions(t, null, null, markerTypes, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
536 /*for (TaxonDescription description: descriptions) {
537 for (IdentifiableSource source :description.getSources()) {
538 if (source.getOriginalNameString() != null) {
539 description.
540 }
541
542 }
543
544
545 }*/
546 }
547 return descriptions;
548 }
549
550 @RequestMapping(value = "useDescriptions", method = RequestMethod.GET)
551 public List<TaxonDescription> doGetUseDescriptions(
552 @PathVariable("uuid") UUID uuid,
553 HttpServletRequest request,
554 HttpServletResponse response) throws IOException {
555 logger.info("doGetDescriptionElements() - " + requestPathAndQuery(request));
556
557 //ModelAndView mv = new ModelAndView();
558 Taxon t = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
559
560 //MarkerType useMarkerType = (MarkerType) markerTypeService.find(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f059"));
561 MarkerType useMarkerType = (MarkerType) termService.find(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f039"));
562
563 //find(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f059"));
564 Set<MarkerType> markerTypes = new HashSet<MarkerType>();
565 markerTypes.add(useMarkerType);
566 List<TaxonDescription> descriptionElements = descriptionService.listTaxonDescriptions(t, null, null, markerTypes, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
567 //getDescriptionElements(description, features, type, pageSize, pageNumber, propertyPaths) load(uuid);
568
569 /*if(!(description instanceof TaxonDescription)){
570 HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
571 // will terminate thread
572 }*/
573
574 //boolean hasStructuredData = service. hasStructuredData(description);
575
576 //mv.addObject(hasStructuredData);
577
578 return descriptionElements;
579 }
580
581 @RequestMapping(value = "descriptions/elementsByType/{classSimpleName}", method = RequestMethod.GET)
582 public ModelAndView doGetDescriptionElementsByType(
583 @PathVariable("uuid") UUID uuid,
584 @PathVariable("classSimpleName") String classSimpleName,
585 @RequestParam(value = "markerTypes", required = false) UuidList markerTypeUUIDs,
586 @RequestParam(value = "count", required = false, defaultValue = "false") Boolean doCount,
587 HttpServletRequest request,
588 HttpServletResponse response) throws IOException {
589 logger.info("doGetDescriptionElementsByType() - " + requestPathAndQuery(request));
590
591 ModelAndView mv = new ModelAndView();
592
593 List<DescriptionElementBase> allElements = new ArrayList<DescriptionElementBase>();
594 List<DescriptionElementBase> elements;
595 int count = 0;
596
597 List<String> initStrategy = doCount ? null : DESCRIPTION_ELEMENT_INIT_STRATEGY;
598
599 List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, markerTypeUUIDs, request, response);
600 try {
601 Class type;
602 type = Class.forName("eu.etaxonomy.cdm.model.description."
603 + classSimpleName);
604 if (taxonDescriptions != null) {
605 for (TaxonDescription description : taxonDescriptions) {
606 elements = descriptionService.listDescriptionElements(description, null, type, null, 0, initStrategy);
607 allElements.addAll(elements);
608 count += elements.size();
609 }
610
611 }
612 } catch (ClassNotFoundException e) {
613 HttpStatusMessage.create(e.getLocalizedMessage(), 400).send(response);
614 }
615 if(doCount){
616 mv.addObject(count);
617 } else {
618 mv.addObject(allElements);
619 }
620 return mv;
621 }
622
623 // @RequestMapping(value = "specimens", method = RequestMethod.GET)
624 // public ModelAndView doGetSpecimens(
625 // @PathVariable("uuid") UUID uuid,
626 // HttpServletRequest request,
627 // HttpServletResponse response) throws IOException, ClassNotFoundException {
628 // logger.info("doGetSpecimens() - " + request.getRequestURI());
629 //
630 // ModelAndView mv = new ModelAndView();
631 //
632 // List<DerivedUnitFacade> derivedUnitFacadeList = new ArrayList<DerivedUnitFacade>();
633 //
634 // // find speciemens in the TaxonDescriptions
635 // List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, request, response);
636 // if (taxonDescriptions != null) {
637 //
638 // for (TaxonDescription description : taxonDescriptions) {
639 // derivedUnitFacadeList.addAll( occurrenceService.listDerivedUnitFacades(description, null) );
640 // }
641 // }
642 // // TODO find speciemens in the NameDescriptions ??
643 //
644 // // TODO also find type specimens
645 //
646 // mv.addObject(derivedUnitFacadeList);
647 //
648 // return mv;
649 // }
650
651 /**
652 * Get the {@link Media} attached to the {@link Taxon} instance
653 * identified by the <code>{taxon-uuid}</code>.
654 *
655 * Usage &#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-
656 * uuid}&#x002F;media&#x002F;{mime type
657 * list}&#x002F;{size}[,[widthOrDuration}][,{height}]&#x002F;
658 *
659 * Whereas
660 * <ul>
661 * <li><b>{mime type list}</b>: a comma separated list of mime types, in the
662 * order of preference. The forward slashes contained in the mime types must
663 * be replaced by a colon. Regular expressions can be used. Each media
664 * associated with this given taxon is being searched whereas the first
665 * matching mime type matching a representation always rules.</li>
666 * <li><b>{size},{widthOrDuration},{height}</b>: <i>not jet implemented</i>
667 * valid values are an integer or the asterisk '*' as a wildcard</li>
668 * </ul>
669 *
670 * @param request
671 * @param response
672 * @return a List of {@link Media} entities which are initialized
673 * using the following initialization strategy:
674 * {@link #TAXONDESCRIPTION_INIT_STRATEGY}
675 * @throws IOException
676 */
677 @RequestMapping(
678 value = {"media"},
679 method = RequestMethod.GET)
680 public List<Media> doGetMedia(
681 @PathVariable("uuid") UUID uuid,
682 @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,
683 @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,
684 @RequestParam(value = "relationships", required = false) UuidList relationshipUuids,
685 @RequestParam(value = "relationshipsInvers", required = false) UuidList relationshipInversUuids,
686 @RequestParam(value = "includeTaxonDescriptions", required = true) Boolean includeTaxonDescriptions,
687 @RequestParam(value = "includeOccurrences", required = true) Boolean includeOccurrences,
688 @RequestParam(value = "includeTaxonNameDescriptions", required = true) Boolean includeTaxonNameDescriptions,
689 @RequestParam(value = "widthOrDuration", required = false) Integer widthOrDuration,
690 @RequestParam(value = "height", required = false) Integer height,
691 @RequestParam(value = "size", required = false) Integer size,
692 HttpServletRequest request, HttpServletResponse response) throws IOException {
693
694 logger.info("doGetMedia() " + requestPathAndQuery(request));
695
696 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
697
698 Set<TaxonRelationshipEdge> includeRelationships = ControllerUtils.loadIncludeRelationships(relationshipUuids, relationshipInversUuids, termService);
699
700 List<Media> returnMedia = getMediaForTaxon(taxon, includeRelationships,
701 includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
702 type, mimeTypes, widthOrDuration, height, size);
703 return returnMedia;
704 }
705
706 @RequestMapping(
707 value = {"subtree/media"},
708 method = RequestMethod.GET)
709 public List<Media> doGetSubtreeMedia(
710 @PathVariable("uuid") UUID uuid,
711 @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,
712 @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,
713 @RequestParam(value = "relationships", required = false) UuidList relationshipUuids,
714 @RequestParam(value = "relationshipsInvers", required = false) UuidList relationshipInversUuids,
715 @RequestParam(value = "includeTaxonDescriptions", required = true) Boolean includeTaxonDescriptions,
716 @RequestParam(value = "includeOccurrences", required = true) Boolean includeOccurrences,
717 @RequestParam(value = "includeTaxonNameDescriptions", required = true) Boolean includeTaxonNameDescriptions,
718 @RequestParam(value = "widthOrDuration", required = false) Integer widthOrDuration,
719 @RequestParam(value = "height", required = false) Integer height,
720 @RequestParam(value = "size", required = false) Integer size,
721 HttpServletRequest request, HttpServletResponse response)throws IOException {
722
723 logger.info("doGetSubtreeMedia() " + requestPathAndQuery(request));
724
725 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, TAXON_WITH_NODES_INIT_STRATEGY);
726
727 Set<TaxonRelationshipEdge> includeRelationships = ControllerUtils.loadIncludeRelationships(relationshipUuids, relationshipInversUuids, termService);
728
729 List<Media> returnMedia = getMediaForTaxon(taxon, includeRelationships,
730 includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
731 type, mimeTypes, widthOrDuration, height, size);
732 TaxonNode node;
733 //looking for all medias of genus
734 if (taxon.getTaxonNodes().size()>0){
735 Set<TaxonNode> nodes = taxon.getTaxonNodes();
736 Iterator<TaxonNode> iterator = nodes.iterator();
737 //TaxonNode holen
738 node = iterator.next();
739 //Check if TaxonNode belongs to the current tree
740
741 node = classificationService.loadTaxonNode(node, TAXONNODE_WITHTAXON_INIT_STRATEGY);
742 List<TaxonNode> children = node.getChildNodes();
743 Taxon childTaxon;
744 for (TaxonNode child : children){
745 childTaxon = child.getTaxon();
746 childTaxon = (Taxon)taxonService.load(childTaxon.getUuid(), null);
747 returnMedia.addAll(getMediaForTaxon(childTaxon, includeRelationships,
748 includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
749 type, mimeTypes, widthOrDuration, height, size));
750 }
751 }
752 return returnMedia;
753 }
754
755 /**
756 *
757 * @param taxon
758 * @param includeRelationships
759 * @param type
760 * @param mimeTypes
761 * @param widthOrDuration
762 * @param height
763 * @param size
764 * @return
765 */
766 private List<Media> getMediaForTaxon(Taxon taxon, Set<TaxonRelationshipEdge> includeRelationships,
767 Boolean includeTaxonDescriptions, Boolean includeOccurrences, Boolean includeTaxonNameDescriptions,
768 Class<? extends MediaRepresentationPart> type, String[] mimeTypes, Integer widthOrDuration,
769 Integer height, Integer size) {
770
771 // list the media
772 logger.trace("getMediaForTaxon() - list the media");
773 List<Media> taxonGalleryMedia = service.listMedia(taxon, includeRelationships,
774 false, includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
775 TAXONDESCRIPTION_MEDIA_INIT_STRATEGY);
776
777 // filter by preferred size and type
778
779 logger.trace("getMediaForTaxon() - filter the media");
780 Map<Media, MediaRepresentation> mediaRepresentationMap = MediaUtils.findPreferredMedia(
781 taxonGalleryMedia, type, mimeTypes, null, widthOrDuration, height, size);
782
783 List<Media> filteredMedia = new ArrayList<Media>(mediaRepresentationMap.size());
784 for (Media media : mediaRepresentationMap.keySet()) {
785 media.getRepresentations().clear();
786 media.addRepresentation(mediaRepresentationMap.get(media));
787 filteredMedia.add(media);
788 }
789
790 logger.trace("getMediaForTaxon() - END ");
791
792 return filteredMedia;
793 }
794
795 // ---------------------- code snippet preserved for possible later use --------------------
796 // @RequestMapping(
797 // value = {"//*/portal/taxon/*/descriptions"}, // mapped as absolute path, see CdmAntPathMatcher
798 // method = RequestMethod.GET)
799 // public List<TaxonDescription> doGetDescriptionsbyFeatureTree(HttpServletRequest request, HttpServletResponse response)throws IOException {
800 // TaxonBase tb = getCdmBase(request, response, null, Taxon.class);
801 // if(tb instanceof Taxon){
802 // //T O D O this is a quick and dirty implementation -> generalize
803 // UUID featureTreeUuid = readValueUuid(request, featureTreeUuidPattern);
804 //
805 // FeatureTree featureTree = descriptionService.getFeatureTreeByUuid(featureTreeUuid);
806 // Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions((Taxon)tb, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
807 // List<TaxonDescription> descriptions = p.getRecords();
808 //
809 // if(!featureTree.isDescriptionSeparated()){
810 //
811 // TaxonDescription superDescription = TaxonDescription.NewInstance();
812 // //put all descriptionElements in superDescription and make it invisible
813 // for(TaxonDescription description: descriptions){
814 // for(DescriptionElementBase element: description.getElements()){
815 // superDescription.addElement(element);
816 // }
817 // }
818 // List<TaxonDescription> separatedDescriptions = new ArrayList<TaxonDescription>(descriptions.size());
819 // separatedDescriptions.add(superDescription);
820 // return separatedDescriptions;
821 // }else{
822 // return descriptions;
823 // }
824 // } else {
825 // response.sendError(HttpServletResponse.SC_NOT_FOUND, "invalid type; Taxon expected but " + tb.getClass().getSimpleName() + " found.");
826 // return null;
827 // }
828 // }
829
830 }