1 // $Id: TaxonController.java 5473 2009-03-25 13:42:07Z a.kohlbecker $
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
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.
11 package eu
.etaxonomy
.cdm
.remote
.controller
;
13 import java
.io
.IOException
;
14 import java
.util
.ArrayList
;
15 import java
.util
.Arrays
;
16 import java
.util
.Hashtable
;
17 import java
.util
.List
;
19 import java
.util
.UUID
;
21 import javax
.servlet
.http
.HttpServletRequest
;
22 import javax
.servlet
.http
.HttpServletResponse
;
24 import org
.apache
.log4j
.Logger
;
25 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
26 import org
.springframework
.stereotype
.Controller
;
27 import org
.springframework
.web
.bind
.WebDataBinder
;
28 import org
.springframework
.web
.bind
.annotation
.InitBinder
;
29 import org
.springframework
.web
.bind
.annotation
.RequestMapping
;
30 import org
.springframework
.web
.bind
.annotation
.RequestMethod
;
31 import org
.springframework
.web
.bind
.annotation
.RequestParam
;
32 import org
.springframework
.web
.servlet
.ModelAndView
;
34 import eu
.etaxonomy
.cdm
.api
.service
.IDescriptionService
;
35 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
36 import eu
.etaxonomy
.cdm
.api
.service
.IReferenceService
;
37 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
38 import eu
.etaxonomy
.cdm
.api
.service
.config
.ITaxonServiceConfigurator
;
39 import eu
.etaxonomy
.cdm
.api
.service
.config
.impl
.TaxonServiceConfiguratorImpl
;
40 import eu
.etaxonomy
.cdm
.api
.service
.pager
.Pager
;
41 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
42 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
43 import eu
.etaxonomy
.cdm
.model
.description
.TaxonNameDescription
;
44 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationship
;
45 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
46 import eu
.etaxonomy
.cdm
.model
.name
.TypeDesignationBase
;
47 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
48 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
49 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
50 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationship
;
51 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationshipType
;
52 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
53 import eu
.etaxonomy
.cdm
.remote
.editor
.UUIDPropertyEditor
;
56 * @author a.kohlbecker
61 @RequestMapping(value
= {"/*/portal/taxon/*", "/*/portal/taxon/*/*", "/*/portal/name/*/*"})
62 public class TaxonPortalController
extends BaseController
<TaxonBase
, ITaxonService
>
64 public static final Logger logger
= Logger
.getLogger(TaxonPortalController
.class);
67 private INameService nameService
;
69 private IDescriptionService descriptionService
;
71 private IReferenceService referenceService
;
74 private static final List
<String
> TAXON_INIT_STRATEGY
= Arrays
.asList(new String
[]{
77 "relationsToThisName.fromTaxon.name.taggedName",
81 "name.rank.representations",
82 "name.status.type.representations",
85 "descriptions.elements.$",
86 "descriptions.elements.area",
87 "descriptions.elements.area.$",
88 "descriptions.elements.multilanguageText",
89 "descriptions.elements.media.representations.parts",
91 // // typeDesignations
92 // "name.typeDesignations.$",
93 // "name.typeDesignations.citation.authorTeam",
94 // "name.typeDesignations.typeName.$",
95 // "name.typeDesignations.typeStatus.representations",
96 // "name.typeDesignations.typeSpecimen.media.representations.parts"
100 private static final List
<String
> SIMPLE_TAXON_INIT_STRATEGY
= Arrays
.asList(new String
[]{
103 "relationsToThisName.fromTaxon.name.taggedName",
107 "name.rank.representations",
108 "name.status.type.representations"
111 private static final List
<String
> SYNONYMY_INIT_STRATEGY
= Arrays
.asList(new String
[]{
112 // initialize homotypical and heterotypical groups; needs synonyms
113 "synonymRelations.$",
114 "synonymRelations.synonym.$",
115 "synonymRelations.synonym.name.taggedName",
116 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
117 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.name.taggedName",
118 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
119 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.name.taggedName",
121 "name.homotypicalGroup.$",
122 "name.homotypicalGroup.typifiedNames.$",
123 "name.homotypicalGroup.typifiedNames.name.taggedName",
124 "name.homotypicalGroup.typifiedNames.taxonBases.$",
125 "name.homotypicalGroup.typifiedNames.taxonBases.name.taggedName"
128 private static final List
<String
> TAXONRELATIONSHIP_INIT_STRATEGY
= Arrays
.asList(new String
[]{
130 "type.inverseRepresentations",
131 "fromTaxon.sec.authorTeam",
132 "fromTaxon.name.taggedName"
135 private static final List
<String
> NAMERELATIONSHIP_INIT_STRATEGY
= Arrays
.asList(new String
[]{
137 "type.inverseRepresentations",
138 "fromName.taggedName",
142 protected static final List
<String
> TAXONDESCRIPTION_INIT_STRATEGY
= Arrays
.asList(new String
[]{
145 "elements.citation.authorTeam",
146 "elements.multilanguageText",
147 "elements.media.representations.parts",
150 private static final List
<String
> NAMEDESCRIPTION_INIT_STRATEGY
= Arrays
.asList(new String
[]{
155 "elements.multilanguageText",
156 "elements.media.representations.parts",
159 private static final List
<String
> TYPEDESIGNATION_INIT_STRATEGY
= Arrays
.asList(new String
[]{
162 "typeStatus.representations",
163 "citation.authorTeam",
164 "typeName.taggedName"
169 private static final String featureTreeUuidPattern
= "^/(?:[^/]+)/taxon(?:(?:/)([^/?#&\\.]+))+.*";
171 public TaxonPortalController(){
173 setUuidParameterPattern("^/(?:[^/]+)/portal/(?:[^/]+)/([^/?#&\\.]+).*");
177 * @see eu.etaxonomy.cdm.remote.controller.GenericController#setService(eu.etaxonomy.cdm.api.service.IService)
181 public void setService(ITaxonService service
) {
182 this.service
= service
;
186 public void initBinder(WebDataBinder binder
) {
187 binder
.registerCustomEditor(UUID
.class, new UUIDPropertyEditor());
192 @RequestMapping(method
= RequestMethod
.GET
)
193 public TaxonBase
doGet(HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
194 TaxonBase tb
= getCdmBase(request
, response
, TAXON_INIT_STRATEGY
, TaxonBase
.class);
198 @RequestMapping(method
= RequestMethod
.GET
,
199 value
= {"/*/portal/taxon/find"}) //TODO map to path /*/portal/taxon/
200 public Pager
<IdentifiableEntity
> doFind(
201 @RequestParam(value
= "q", required
= false) String query
,
202 @RequestParam(value
= "page", required
= false) Integer page
,
203 @RequestParam(value
= "pageSize", required
= false) Integer pageSize
,
204 @RequestParam(value
= "doTaxa", required
= false) Boolean doTaxa
,
205 @RequestParam(value
= "doSynonyms", required
= false) Boolean doSynonyms
,
206 @RequestParam(value
= "doTaxaByCommonNames", required
= false) Boolean doTaxaByCommonNames
,
207 @RequestParam(value
= "secUuid", required
= false) UUID secUuid
) throws IOException
{
209 if(page
== null){ page
= BaseListController
.DEFAULT_PAGE
;}
210 if(pageSize
== null){ pageSize
= BaseListController
.DEFAULT_PAGESIZE
;}
212 ITaxonServiceConfigurator config
= new TaxonServiceConfiguratorImpl();
213 config
.setPageNumber(page
);
214 config
.setPageSize(pageSize
);
215 config
.setSearchString(query
);
216 config
.setDoTaxa(doTaxa
!= null ? doTaxa
: Boolean
.FALSE
);
217 config
.setDoSynonyms(doSynonyms
!= null ? doSynonyms
: Boolean
.FALSE
);
218 config
.setDoTaxaByCommonNames(doTaxaByCommonNames
!= null ? doTaxaByCommonNames
: Boolean
.FALSE
);
219 config
.setMatchMode(MatchMode
.BEGINNING
);
220 config
.setTaxonPropertyPath(SIMPLE_TAXON_INIT_STRATEGY
);
222 ReferenceBase sec
= referenceService
.findByUuid(secUuid
);
226 return (Pager
<IdentifiableEntity
>) service
.findTaxaAndNames(config
);
231 value
= {"/*/portal/taxon/*/synonymy"},
232 method
= RequestMethod
.GET
)
233 public ModelAndView
doGetSynonymy(HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
234 ModelAndView mv
= new ModelAndView();
235 TaxonBase tb
= getCdmBase(request
, response
, null, Taxon
.class);
236 Taxon taxon
= (Taxon
)tb
;
237 Map
<String
, List
<?
>> synonymy
= new Hashtable
<String
, List
<?
>>();
238 synonymy
.put("homotypicSynonymsByHomotypicGroup", service
.getHomotypicSynonymsByHomotypicGroup(taxon
, SYNONYMY_INIT_STRATEGY
));
239 synonymy
.put("heterotypicSynonymyGroups", service
.getHeterotypicSynonymyGroups(taxon
, SYNONYMY_INIT_STRATEGY
));
240 mv
.addObject(synonymy
);
245 value
= {"/*/portal/taxon/*/taxonRelationships"},
246 method
= RequestMethod
.GET
)
247 public List
<TaxonRelationship
> doGetTaxonRelations(HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
249 TaxonBase tb
= getCdmBase(request
, response
, null, Taxon
.class);
250 Taxon taxon
= (Taxon
)tb
;
251 List
<TaxonRelationship
> relations
= new ArrayList
<TaxonRelationship
>();
252 List
<TaxonRelationship
> results
= service
.listToTaxonRelationships(taxon
, TaxonRelationshipType
.MISAPPLIED_NAME_FOR(), null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY
);
253 relations
.addAll(results
);
254 results
= service
.listToTaxonRelationships(taxon
, TaxonRelationshipType
.INVALID_DESIGNATION_FOR(), null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY
);
255 relations
.addAll(results
);
261 value
= {"/*/portal/taxon/*/nameRelationships"},
262 method
= RequestMethod
.GET
)
263 public List
<NameRelationship
> doGetNameRelations(HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
264 TaxonBase tb
= getCdmBase(request
, response
, SIMPLE_TAXON_INIT_STRATEGY
, Taxon
.class);
265 List
<NameRelationship
> list
= nameService
.listToNameRelationships(tb
.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY
);
270 value
= {"/*/portal/name/*/descriptions"},
271 method
= RequestMethod
.GET
)
272 public List
<TaxonNameDescription
> doGetNameDescriptions(HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
273 UUID nameUuuid
= readValueUuid(request
, null);
274 TaxonNameBase tnb
= nameService
.load(nameUuuid
, null);
275 Pager
<TaxonNameDescription
> p
= descriptionService
.getTaxonNameDescriptions(tnb
, null, null, NAMEDESCRIPTION_INIT_STRATEGY
);
276 return p
.getRecords();
280 value
= {"/*/portal/taxon/*/nameTypeDesignations"},
281 method
= RequestMethod
.GET
)
282 public List
<TypeDesignationBase
> doGetNameTypeDesignations(HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
283 TaxonBase tb
= getCdmBase(request
, response
, SIMPLE_TAXON_INIT_STRATEGY
, Taxon
.class);
284 Pager
<TypeDesignationBase
> p
= nameService
.getTypeDesignations(tb
.getName(), null, null, null, TYPEDESIGNATION_INIT_STRATEGY
);
285 return p
.getRecords();
289 value
= {"/*/portal/taxon/*/descriptions"},
290 method
= RequestMethod
.GET
)
291 public List
<TaxonDescription
> doGetDescriptions(HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
292 TaxonBase tb
= getCdmBase(request
, response
, null, Taxon
.class);
293 if(tb
instanceof Taxon
){
294 Pager
<TaxonDescription
> p
= descriptionService
.getTaxonDescriptions((Taxon
)tb
, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY
);
295 return p
.getRecords();
297 response
.sendError(HttpServletResponse
.SC_NOT_FOUND
, "invalid type; Taxon expected but " + tb
.getClass().getSimpleName() + " found.");
303 // value = {"/*/portal/taxon/*/descriptions"},
304 // method = RequestMethod.GET)
305 // public List<TaxonDescription> doGetDescriptionsbyFeatureTree(HttpServletRequest request, HttpServletResponse response)throws IOException {
306 // TaxonBase tb = getCdmBase(request, response, null, Taxon.class);
307 // if(tb instanceof Taxon){
308 // //TODO this is a quick and dirty implementation -> generalize
309 // UUID featureTreeUuid = readValueUuid(request, featureTreeUuidPattern);
311 // FeatureTree featureTree = descriptionService.getFeatureTreeByUuid(featureTreeUuid);
312 // Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions((Taxon)tb, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
313 // List<TaxonDescription> descriptions = p.getRecords();
315 // if(!featureTree.isDescriptionSeparated()){
317 // TaxonDescription superDescription = TaxonDescription.NewInstance();
318 // //put all descriptionElements in superDescription and make it invisible
319 // for(TaxonDescription description: descriptions){
320 // for(DescriptionElementBase element: description.getElements()){
321 // superDescription.addElement(element);
324 // List<TaxonDescription> separatedDescriptions = new ArrayList<TaxonDescription>(descriptions.size());
325 // separatedDescriptions.add(superDescription);
326 // return separatedDescriptions;
328 // return descriptions;
331 // response.sendError(HttpServletResponse.SC_NOT_FOUND, "invalid type; Taxon expected but " + tb.getClass().getSimpleName() + " found.");