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