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