minor
[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.commons.lang.ObjectUtils;
28 import org.apache.log4j.Logger;
29 import org.springframework.beans.factory.annotation.Autowired;
30 import org.springframework.stereotype.Controller;
31 import org.springframework.web.bind.WebDataBinder;
32 import org.springframework.web.bind.annotation.InitBinder;
33 import org.springframework.web.bind.annotation.PathVariable;
34 import org.springframework.web.bind.annotation.RequestMapping;
35 import org.springframework.web.bind.annotation.RequestMethod;
36 import org.springframework.web.bind.annotation.RequestParam;
37 import org.springframework.web.servlet.ModelAndView;
38
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.IReferenceService;
43 import eu.etaxonomy.cdm.api.service.ITaxonService;
44 import eu.etaxonomy.cdm.api.service.ITaxonTreeService;
45 import eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator;
46 import eu.etaxonomy.cdm.api.service.config.impl.TaxonServiceConfiguratorImpl;
47 import eu.etaxonomy.cdm.api.service.pager.Pager;
48 import eu.etaxonomy.cdm.database.UpdatableRoutingDataSource;
49 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
50 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
51 import eu.etaxonomy.cdm.model.description.Feature;
52 import eu.etaxonomy.cdm.model.description.FeatureTree;
53 import eu.etaxonomy.cdm.model.description.TaxonDescription;
54 import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
55 import eu.etaxonomy.cdm.model.location.NamedArea;
56 import eu.etaxonomy.cdm.model.media.Media;
57 import eu.etaxonomy.cdm.model.media.MediaUtils;
58 import eu.etaxonomy.cdm.model.name.NameRelationship;
59 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
60 import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
61 import eu.etaxonomy.cdm.model.taxon.Synonym;
62 import eu.etaxonomy.cdm.model.taxon.Taxon;
63 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
64 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
65 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
66 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
67 import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;
68 import eu.etaxonomy.cdm.persistence.query.MatchMode;
69 import eu.etaxonomy.cdm.remote.editor.MatchModePropertyEditor;
70 import eu.etaxonomy.cdm.remote.editor.NamedAreaPropertyEditor;
71 import eu.etaxonomy.cdm.remote.editor.UUIDPropertyEditor;
72
73 /**
74 * The TaxonPortalController class is a Spring MVC Controller.
75 * <p>
76 * The syntax of the mapped service URIs contains the the {datasource-name} path element.
77 * The available {datasource-name}s are defined in a configuration file which
78 * is loaded by the {@link UpdatableRoutingDataSource}. If the
79 * UpdatableRoutingDataSource is not being used in the actual application
80 * context any arbitrary {datasource-name} may be used.
81 * <p>
82 * Methods mapped at type level, inherited from super classes ({@link BaseController}):
83 * <blockquote>
84 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}</b>
85 *
86 * Get the {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
87 * The returned Taxon is initialized by
88 * the following strategy {@link #TAXON_INIT_STRATEGY}
89 * </blockquote>
90 *
91 * @author a.kohlbecker
92 * @date 20.07.2009
93 *
94 */
95 @Controller
96 @RequestMapping(value = {"/portal/taxon/{uuid}"})
97 public class TaxonPortalController extends BaseController<TaxonBase, ITaxonService>
98 {
99 public static final Logger logger = Logger.getLogger(TaxonPortalController.class);
100
101 @Autowired
102 private INameService nameService;
103
104 @Autowired
105 private IDescriptionService descriptionService;
106
107 @Autowired
108 private ITaxonTreeService taxonTreeService;
109
110 @Autowired
111 private ITaxonService taxonService;
112
113 @Autowired
114 private IFeatureTreeService featureTreeService;
115
116 private static final List<String> TAXON_INIT_STRATEGY = Arrays.asList(new String []{
117 "*",
118 // taxon relations
119 "relationsToThisName.fromTaxon.name",
120 // the name
121 "name.$",
122 "name.rank.representations",
123 "name.status.type.representations",
124
125 // taxon descriptions
126 "descriptions.elements.area.$",
127 "descriptions.elements.multilanguageText",
128 "descriptions.elements.media.representations.parts",
129 "descriptions.elements.media.title",
130
131 });
132
133 private static final List<String> TAXON_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{
134 "taxonNodes.$",
135 "taxonNodes.taxonomicTree.$",
136 "taxonNodes.childNodes.$"
137 });
138
139 private static final List<String> SIMPLE_TAXON_INIT_STRATEGY = Arrays.asList(new String []{
140 "*",
141 // taxon relations
142 "relationsToThisName.fromTaxon.name",
143 // the name
144 "name.$",
145 "name.rank.representations",
146 "name.status.type.representations",
147 "name.nomenclaturalReference"
148 });
149
150 private static final List<String> SYNONYMY_INIT_STRATEGY = Arrays.asList(new String []{
151 // initialize homotypical and heterotypical groups; needs synonyms
152 "synonymRelations.$",
153 "synonymRelations.synonym.$",
154 "synonymRelations.synonym.name.status.type.representation",
155 "synonymRelations.synonym.name.nomenclaturalReference.inReference",
156 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
157 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
158 "synonymRelations.synonym.name.combinationAuthorTeam.$",
159
160 "name.homotypicalGroup.$",
161 "name.homotypicalGroup.typifiedNames.$",
162 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorTeam",
163
164 "name.homotypicalGroup.typifiedNames.taxonBases.$"
165 });
166
167 private static final List<String> TAXONRELATIONSHIP_INIT_STRATEGY = Arrays.asList(new String []{
168 "$",
169 "type.inverseRepresentations",
170 "fromTaxon.sec",
171 "fromTaxon.name"
172 });
173
174 private static final List<String> NAMERELATIONSHIP_INIT_STRATEGY = Arrays.asList(new String []{
175 "$",
176 "type.inverseRepresentations",
177 "fromName",
178 "toName.$",
179 });
180
181
182 protected static final List<String> TAXONDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{
183 "$",
184 "elements.$",
185 "elements.sources.citation.authorTeam",
186 "elements.sources.nameUsedInSource.originalNameString",
187 "elements.multilanguageText",
188 "elements.media.representations.parts",
189 "elements.media.title",
190 });
191
192
193 // private static final List<String> NAMEDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{
194 // "uuid",
195 // "feature",
196 // "elements.$",
197 // "elements.multilanguageText",
198 // "elements.media.representations.parts",
199 // "elements.media.title",
200 // });
201
202 protected static final List<String> TAXONDESCRIPTION_MEDIA_INIT_STRATEGY = Arrays.asList(new String []{
203 "elements.media.representations.parts",
204 "elements.media.title"
205
206 });
207
208 private static final List<String> TYPEDESIGNATION_INIT_STRATEGY = Arrays.asList(new String []{
209 //"$",
210 "typeSpecimen.$",
211 "citation",
212 "typeName",
213 });
214
215 protected static final List<String> TAXONNODE_WITHTAXON_INIT_STRATEGY = Arrays.asList(new String []{
216 "childNodes.taxon",
217 });
218
219 protected static final List<String> TAXONNODE_INIT_STRATEGY = Arrays.asList(new String []{
220 "taxonNodes.taxonomicTree"
221 });
222
223
224
225 private static final String featureTreeUuidPattern = "^/taxon(?:(?:/)([^/?#&\\.]+))+.*";
226
227 public TaxonPortalController(){
228 super();
229 setInitializationStrategy(TAXON_INIT_STRATEGY);
230 }
231
232 /* (non-Javadoc)
233 * @see eu.etaxonomy.cdm.remote.controller.GenericController#setService(eu.etaxonomy.cdm.api.service.IService)
234 */
235 @Autowired
236 @Override
237 public void setService(ITaxonService service) {
238 this.service = service;
239 }
240
241 @InitBinder
242 public void initBinder(WebDataBinder binder) {
243 binder.registerCustomEditor(UUID.class, new UUIDPropertyEditor());
244 binder.registerCustomEditor(NamedArea.class, new NamedAreaPropertyEditor());
245 binder.registerCustomEditor(MatchMode.class, new MatchModePropertyEditor());
246 }
247
248
249 /* (non-Javadoc)
250 * @see eu.etaxonomy.cdm.remote.controller.BaseController#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
251
252 @Override
253 @RequestMapping(method = RequestMethod.GET)
254 public TaxonBase doGet(HttpServletRequest request, HttpServletResponse response)throws IOException {
255 logger.info("doGet()");
256 TaxonBase tb = getCdmBase(request, response, TAXON_INIT_STRATEGY, TaxonBase.class);
257 return tb;
258 }
259 */
260 /**
261 * Find Taxa, Synonyms, Common Names by name, either globally or in a specific geographic area.
262 * <p>
263 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;find</b>
264 *
265 * @param query
266 * the string to query for. Since the wildcard character '*'
267 * internally always is appended to the query string, a search
268 * always compares the query string with the beginning of a name.
269 * - <i>required parameter</i>
270 * @param treeUuid
271 * the {@link UUID} of a {@link TaxonomicTree} to which the
272 * search is to be restricted. - <i>optional parameter</i>
273 * @param areas
274 * restrict the search to a set of geographic {@link NamedArea}s.
275 * The parameter currently takes a list of TDWG area labels.
276 * - <i>optional parameter</i>
277 * @param page
278 * the number of the page to be returned, the first page has the
279 * pageNumber = 1 - <i>optional parameter</i>
280 * @param pageSize
281 * the maximum number of entities returned per page (can be -1
282 * to return all entities in a single page) - <i>optional parameter</i>
283 * @param doTaxa
284 * weather to search for instances of {@link Taxon} - <i>optional parameter</i>
285 * @param doSynonyms
286 * weather to search for instances of {@link Synonym} - <i>optional parameter</i>
287 * @param doTaxaByCommonNames
288 * for instances of {@link Taxon} by a common name used - <i>optional parameter</i>
289 * @param matchMode
290 * valid values are "EXACT", "BEGINNING", "ANYWHERE", "END" (case sensitive !!!)
291 * @return a Pager on a list of {@link IdentifiableEntity}s initialized by
292 * the following strategy {@link #SIMPLE_TAXON_INIT_STRATEGY}
293 * @throws IOException
294 */
295 @RequestMapping(method = RequestMethod.GET,
296 value = {"/portal/taxon/find"}) //TODO map to path /*/portal/taxon/
297 public Pager<IdentifiableEntity> doFind(
298 @RequestParam(value = "query", required = false) String query,
299 @RequestParam(value = "tree", required = false) UUID treeUuid,
300 @RequestParam(value = "area", required = false) Set<NamedArea> areas,
301 @RequestParam(value = "page", required = false) Integer page,
302 @RequestParam(value = "pageSize", required = false) Integer pageSize,
303 @RequestParam(value = "doTaxa", required = false) Boolean doTaxa,
304 @RequestParam(value = "doSynonyms", required = false) Boolean doSynonyms,
305 @RequestParam(value = "doTaxaByCommonNames", required = false) Boolean doTaxaByCommonNames,
306 @RequestParam(value = "matchMode", required = false) MatchMode matchMode
307 )
308 throws IOException {
309
310 logger.info("doFind( " +
311 "query=\"" + ObjectUtils.toString(query) + "\", treeUuid=" + ObjectUtils.toString(treeUuid) +
312 ", area=" + ObjectUtils.toString(areas) +
313 ", pageSize=" + ObjectUtils.toString(pageSize) + ", page=" + ObjectUtils.toString(page) +
314 ", doTaxa=" + ObjectUtils.toString(doTaxa) + ", doSynonyms=" + ObjectUtils.toString(doSynonyms)
315 +", doTaxaByCommonNames=" + ObjectUtils.toString(doTaxaByCommonNames) +")" );
316
317 if(page == null){ page = BaseListController.DEFAULT_PAGE_NUMBER;}
318 if(pageSize == null){ pageSize = BaseListController.DEFAULT_PAGESIZE;}
319 if(pageSize == -1){
320 pageSize = null;
321 }
322
323 ITaxonServiceConfigurator config = new TaxonServiceConfiguratorImpl();
324 config.setPageNumber(page);
325 config.setPageSize(pageSize);
326 config.setSearchString(query);
327 config.setDoTaxa(doTaxa!= null ? doTaxa : Boolean.FALSE );
328 config.setDoSynonyms(doSynonyms != null ? doSynonyms : Boolean.FALSE );
329 config.setDoTaxaByCommonNames(doTaxaByCommonNames != null ? doTaxaByCommonNames : Boolean.FALSE );
330 config.setMatchMode(matchMode != null ? matchMode : MatchMode.BEGINNING);
331 config.setTaxonPropertyPath(SIMPLE_TAXON_INIT_STRATEGY);
332 config.setNamedAreas(areas);
333 if(treeUuid != null){
334 TaxonomicTree taxonomicTree = taxonTreeService.find(treeUuid);
335 config.setTaxonomicTree(taxonomicTree);
336 }
337
338 return (Pager<IdentifiableEntity>) service.findTaxaAndNames(config);
339 }
340
341 /**
342 * Get the synonymy for a taxon identified by the <code>{taxon-uuid}</code>.
343 * The synonymy consists
344 * of two parts: The group of homotypic synonyms of the taxon and the
345 * heterotypic synonymy groups of the taxon. The synonymy is ordered
346 * historically by the type designations and by the publication date of the
347 * nomenclatural reference
348 * <p>
349 * URI:
350 * <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;synonymy</b>
351 *
352 *
353 * @param request
354 * @param response
355 * @return a Map with to entries which are mapped by the following keys:
356 * "homotypicSynonymsByHomotypicGroup", "heterotypicSynonymyGroups",
357 * containing lists of {@link Synonym}s which are initialized using the
358 * following initialization strategy: {@link #SYNONYMY_INIT_STRATEGY}
359 *
360 * @throws IOException
361 */
362 @RequestMapping(
363 value = {"synonymy"},
364 method = RequestMethod.GET)
365 public ModelAndView doGetSynonymy(@PathVariable("uuid") UUID uuid,
366 HttpServletRequest request, HttpServletResponse response)throws IOException {
367
368 if(request != null){
369 logger.info("doGetSynonymy() " + request.getServletPath());
370 }
371 ModelAndView mv = new ModelAndView();
372 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
373 Map<String, List<?>> synonymy = new Hashtable<String, List<?>>();
374 synonymy.put("homotypicSynonymsByHomotypicGroup", service.getHomotypicSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY));
375 synonymy.put("heterotypicSynonymyGroups", service.getHeterotypicSynonymyGroups(taxon, SYNONYMY_INIT_STRATEGY));
376 mv.addObject(synonymy);
377 return mv;
378 }
379
380 /**
381 * Get the set of accepted {@link Taxon} entities for a given
382 * {@link TaxonBase} entity identified by the <code>{taxon-uuid}</code>.
383 * <p>
384 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;accepted</b>
385 *
386 * @param request
387 * @param response
388 * @return a Set of {@link Taxon} entities which are initialized
389 * using the following initialization strategy:
390 * {@link #SYNONYMY_INIT_STRATEGY}
391 * @throws IOException
392 */
393 @RequestMapping(value = "accepted", method = RequestMethod.GET)
394 public Set<TaxonBase> getAccepted(@PathVariable("uuid") UUID uuid,
395 HttpServletRequest request, HttpServletResponse response) throws IOException {
396
397 if(request != null){
398 logger.info("getAccepted() " + request.getServletPath());
399 }
400
401 TaxonBase tb = service.load(uuid, SYNONYMY_INIT_STRATEGY);
402 if(tb == null){
403 response.sendError(HttpServletResponse.SC_NOT_FOUND, "A taxon with the uuid " + uuid + " does not exist");
404 return null;
405 }
406 HashSet<TaxonBase> resultset = new HashSet<TaxonBase>();
407 if(tb instanceof Taxon){
408 //the taxon already is accepted
409 //FIXME take the current view into account once views are implemented!!!
410 resultset.add((Taxon)tb);
411 } else {
412 Synonym syn = (Synonym)tb;
413 for(TaxonBase accepted : syn.getAcceptedTaxa()){
414 accepted = service.load(accepted.getUuid(), SIMPLE_TAXON_INIT_STRATEGY);
415 resultset.add(accepted);
416 }
417 }
418 return resultset;
419 }
420
421 /**
422 * Get the list of {@link TaxonRelationship}s for the given
423 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
424 * <p>
425 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;taxonRelationships</b>
426 *
427 * @param request
428 * @param response
429 * @return a List of {@link TaxonRelationship} entities which are initialized
430 * using the following initialization strategy:
431 * {@link #TAXONRELATIONSHIP_INIT_STRATEGY}
432 * @throws IOException
433 */
434 @RequestMapping(
435 value = {"taxonRelationships"},
436 method = RequestMethod.GET)
437 public List<TaxonRelationship> doGetTaxonRelations(@PathVariable("uuid") UUID uuid,
438 HttpServletRequest request, HttpServletResponse response)throws IOException {
439
440 logger.info("doGetTaxonRelations()" + request.getServletPath());
441 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
442 List<TaxonRelationship> relations = new ArrayList<TaxonRelationship>();
443 List<TaxonRelationship> results = service.listToTaxonRelationships(taxon, TaxonRelationshipType.MISAPPLIED_NAME_FOR(), null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);
444 relations.addAll(results);
445 results = service.listToTaxonRelationships(taxon, TaxonRelationshipType.INVALID_DESIGNATION_FOR(), null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);
446 relations.addAll(results);
447
448 return relations;
449 }
450
451 /**
452 * Get the list of {@link NameRelationship}s of the Name associated with the
453 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
454 * <p>
455 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>
456 *
457 * @param request
458 * @param response
459 * @return a List of {@link NameRelationship} entities which are initialized
460 * using the following initialization strategy:
461 * {@link #NAMERELATIONSHIP_INIT_STRATEGY}
462 * @throws IOException
463 */
464 @RequestMapping(
465 value = {"toNameRelationships"},
466 method = RequestMethod.GET)
467 public List<NameRelationship> doGetToNameRelations(@PathVariable("uuid") UUID uuid,
468 HttpServletRequest request, HttpServletResponse response)throws IOException {
469 logger.info("doGetNameRelations()" + request.getServletPath());
470 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
471 List<NameRelationship> list = nameService.listToNameRelationships(taxon.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
472 return list;
473 }
474
475 /**
476 * Get the list of {@link NameRelationship}s of the Name associated with the
477 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
478 * <p>
479 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>
480 *
481 * @param request
482 * @param response
483 * @return a List of {@link NameRelationship} entities which are initialized
484 * using the following initialization strategy:
485 * {@link #NAMERELATIONSHIP_INIT_STRATEGY}
486 * @throws IOException
487 */
488 @RequestMapping(
489 value = {"fromNameRelationships"},
490 method = RequestMethod.GET)
491 public List<NameRelationship> doGetFromNameRelations(@PathVariable("uuid") UUID uuid,
492 HttpServletRequest request, HttpServletResponse response)throws IOException {
493 logger.info("doGetNameFromNameRelations()" + request.getServletPath());
494
495 TaxonBase taxonbase = getCdmBaseInstance(TaxonBase.class, uuid, response, SIMPLE_TAXON_INIT_STRATEGY);
496 List<NameRelationship> list = nameService.listFromNameRelationships(taxonbase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
497 return list;
498 }
499
500 /**
501 * Get the list of {@link TypeDesignationBase}s of the
502 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
503 * <p>
504 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameTypeDesignations</b>
505 *
506 * @param request
507 * @param response
508 * @return a List of {@link TypeDesignationBase} entities which are initialized
509 * using the following initialization strategy:
510 * {@link #TYPEDESIGNATION_INIT_STRATEGY}
511 * @throws IOException
512 * @Deprecated use &#x002F;name&#x002F;{uuid}&#x002F;typeDesignations & &#x002F;derivedunitfacade&#x002F;{uuid} instead
513 */
514 @Deprecated
515 @RequestMapping(
516 value = {"nameTypeDesignations"},
517 method = RequestMethod.GET)
518 public List<TypeDesignationBase> doGetNameTypeDesignations(@PathVariable("uuid") UUID uuid,
519 HttpServletRequest request, HttpServletResponse response)throws IOException {
520 logger.info("doGetNameTypeDesignations()" + request.getServletPath());
521 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, SIMPLE_TAXON_INIT_STRATEGY);
522 Pager<TypeDesignationBase> p = nameService.getTypeDesignations(taxon.getName(), null, null, null, TYPEDESIGNATION_INIT_STRATEGY);
523 return p.getRecords();
524 }
525
526 @RequestMapping(value = "taxonNodes", method = RequestMethod.GET)
527 public Set<TaxonNode> doGetTaxonNodes(
528 @PathVariable("uuid") UUID uuid,
529 HttpServletRequest request,
530 HttpServletResponse response) throws IOException {
531 TaxonBase tb = service.load(uuid, TAXONNODE_INIT_STRATEGY);
532 if(tb instanceof Taxon){
533 return ((Taxon)tb).getTaxonNodes();
534 } else {
535 HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
536 return null;
537 }
538 }
539
540 /**
541 * Get the list of {@link TaxonDescription}s of the
542 * {@link Taxon} instance identified by the <code>{taxon-uuid}</code>.
543 * <p>
544 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;descriptions</b>
545 *
546 * @param request
547 * @param response
548 * @return a List of {@link TaxonDescription} entities which are initialized
549 * using the following initialization strategy:
550 * {@link #TAXONDESCRIPTION_INIT_STRATEGY}
551 * @throws IOException
552 */
553 @RequestMapping(
554 value = {"descriptions"},
555 method = RequestMethod.GET)
556 public List<TaxonDescription> doGetDescriptions(@PathVariable("uuid") UUID uuid,
557 HttpServletRequest request, HttpServletResponse response)throws IOException {
558 if(request != null){
559 logger.info("doGetDescriptions()" + request.getServletPath());
560 }
561 Taxon t = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
562 Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions(t, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
563 return p.getRecords();
564 }
565
566 /**
567 * Get the {@link Media} attached to the {@link Taxon} instance
568 * identified by the <code>{taxon-uuid}</code>.
569 *
570 * Usage &#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-
571 * uuid}&#x002F;media&#x002F;{mime type
572 * list}&#x002F;{size}[,[widthOrDuration}][,{height}]&#x002F;
573 *
574 * Whereas
575 * <ul>
576 * <li><b>{mime type list}</b>: a comma separated list of mime types, in the
577 * order of preference. The forward slashes contained in the mime types must
578 * be replaced by a colon. Regular expressions can be used. Each media
579 * associated with this given taxon is being searched whereas the first
580 * matching mime type matching a representation always rules.</li>
581 * <li><b>{size},{widthOrDuration},{height}</b>: <i>not jet implemented</i>
582 * valid values are an integer or the asterisk '*' as a wildcard</li>
583 * </ul>
584 *
585 * @param request
586 * @param response
587 * @return a List of {@link Media} entities which are initialized
588 * using the following initialization strategy:
589 * {@link #TAXONDESCRIPTION_INIT_STRATEGY}
590 * @throws IOException
591 */
592 @RequestMapping(
593 value = {"media/*/*"},
594 method = RequestMethod.GET)
595 public List<Media> doGetMedia(@PathVariable("uuid") UUID uuid,
596 HttpServletRequest request, HttpServletResponse response) throws IOException {
597 logger.info("doGetMedia()" + request.getServletPath());
598 Taxon t = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
599 String path = request.getServletPath();
600 List<Media> returnMedia = getMediaForTaxon(t, path, 5);
601 return returnMedia;
602 }
603
604 @RequestMapping(
605 value = {"subtree/media/*/*"},
606 method = RequestMethod.GET)
607 public List<Media> doGetSubtreeMedia(@PathVariable("uuid") UUID uuid,
608 HttpServletRequest request, HttpServletResponse response)throws IOException {
609 logger.info("doGetMedia()" + request.getServletPath());
610 Taxon t = getCdmBaseInstance(Taxon.class, uuid, response, TAXON_WITH_NODES_INIT_STRATEGY);
611 String path = request.getServletPath();
612 List<Media> returnMedia = getMediaForTaxon(t, path, 6);
613 TaxonNode node;
614 //looking for all medias of genus
615 if (t.getTaxonNodes().size()>0){
616 Set<TaxonNode> nodes = t.getTaxonNodes();
617 Iterator<TaxonNode> iterator = nodes.iterator();
618 //TaxonNode holen
619 node = iterator.next();
620 //überprüfen, ob der TaxonNode zum aktuellen Baum gehört.
621
622 node = taxonTreeService.loadTaxonNode(node, TAXONNODE_WITHTAXON_INIT_STRATEGY);
623 Set<TaxonNode> children = node.getChildNodes();
624 Taxon childTaxon;
625 for (TaxonNode child : children){
626 childTaxon = child.getTaxon();
627 childTaxon = (Taxon)taxonService.load(childTaxon.getUuid(), null);
628 returnMedia.addAll(getMediaForTaxon(childTaxon, path, 6));
629 }
630 }
631 return returnMedia;
632 }
633
634
635 private List<Media> getMediaForTaxon(Taxon taxon, String path, int mimeTypeTokenPosition){
636
637 Pager<TaxonDescription> p =
638 descriptionService.getTaxonDescriptions(taxon, null, null, null, null, TAXONDESCRIPTION_MEDIA_INIT_STRATEGY);
639
640 // pars the media and quality parameters
641
642
643 // collect all media of the given taxon
644 boolean limitToGalleries = false;
645 List<Media> taxonMedia = new ArrayList<Media>();
646 for(TaxonDescription desc : p.getRecords()){
647 if(!limitToGalleries || desc.isImageGallery()){
648 for(DescriptionElementBase element : desc.getElements()){
649 for(Media media : element.getMedia()){
650 taxonMedia.add(media);
651 }
652 }
653 }
654 }
655
656 String[] pathTokens = path.split("/");
657
658 String[] mimeTypes = pathTokens[mimeTypeTokenPosition].split(",");
659 String[] sizeTokens = pathTokens[mimeTypeTokenPosition + 1].split(",");
660 Integer widthOrDuration = null;
661 Integer height = null;
662 Integer size = null;
663
664 List<Media> returnMedia = MediaUtils.findPreferredMedia(taxonMedia, mimeTypes,
665 sizeTokens, widthOrDuration, height, size);
666
667 return returnMedia;
668 }
669
670
671 // ---------------------- code snippet preserved for possible later use --------------------
672 // @RequestMapping(
673 // value = {"/*/portal/taxon/*/descriptions"},
674 // method = RequestMethod.GET)
675 // public List<TaxonDescription> doGetDescriptionsbyFeatureTree(HttpServletRequest request, HttpServletResponse response)throws IOException {
676 // TaxonBase tb = getCdmBase(request, response, null, Taxon.class);
677 // if(tb instanceof Taxon){
678 // //T O D O this is a quick and dirty implementation -> generalize
679 // UUID featureTreeUuid = readValueUuid(request, featureTreeUuidPattern);
680 //
681 // FeatureTree featureTree = descriptionService.getFeatureTreeByUuid(featureTreeUuid);
682 // Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions((Taxon)tb, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
683 // List<TaxonDescription> descriptions = p.getRecords();
684 //
685 // if(!featureTree.isDescriptionSeparated()){
686 //
687 // TaxonDescription superDescription = TaxonDescription.NewInstance();
688 // //put all descriptionElements in superDescription and make it invisible
689 // for(TaxonDescription description: descriptions){
690 // for(DescriptionElementBase element: description.getElements()){
691 // superDescription.addElement(element);
692 // }
693 // }
694 // List<TaxonDescription> separatedDescriptions = new ArrayList<TaxonDescription>(descriptions.size());
695 // separatedDescriptions.add(superDescription);
696 // return separatedDescriptions;
697 // }else{
698 // return descriptions;
699 // }
700 // } else {
701 // response.sendError(HttpServletResponse.SC_NOT_FOUND, "invalid type; Taxon expected but " + tb.getClass().getSimpleName() + " found.");
702 // return null;
703 // }
704 // }
705
706 }