1 package eu
.etaxonomy
.cdm
.remote
.controller
;
3 import java
.io
.IOException
;
4 import java
.util
.ArrayList
;
5 import java
.util
.Arrays
;
6 import java
.util
.LinkedHashMap
;
10 import java
.util
.UUID
;
12 import javax
.servlet
.http
.HttpServletRequest
;
13 import javax
.servlet
.http
.HttpServletResponse
;
15 import java
.util
.Hashtable
;
16 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
17 import org
.springframework
.stereotype
.Controller
;
18 import org
.springframework
.web
.bind
.annotation
.RequestMapping
;
19 import org
.springframework
.web
.bind
.annotation
.RequestMethod
;
20 import org
.springframework
.web
.bind
.annotation
.RequestParam
;
21 import org
.springframework
.web
.servlet
.ModelAndView
;
23 import eu
.etaxonomy
.cdm
.api
.service
.IClassificationService
;
24 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
25 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
27 import eu
.etaxonomy
.cdm
.remote
.dto
.common
.ErrorResponse
;
28 import eu
.etaxonomy
.cdm
.remote
.dto
.common
.RemoteResponse
;
29 import eu
.etaxonomy
.cdm
.remote
.dto
.namecatalogue
.NameInformation
;
30 import eu
.etaxonomy
.cdm
.remote
.dto
.namecatalogue
.NameSearch
;
31 import eu
.etaxonomy
.cdm
.remote
.dto
.namecatalogue
.TaxonInformation
;
32 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
33 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
34 import eu
.etaxonomy
.cdm
.model
.name
.TypeDesignationBase
;
35 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
36 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
37 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
38 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
39 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
40 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
43 * The controller class for the namespace 'name_catalogue'.
44 * This controller provides search mechanisims for searching by taxon name as well as taxon.
48 * @created 15-Apr-2012
52 @RequestMapping(value
= {"/name_catalogue"})
53 public class NameCatalogueController
extends BaseController
<TaxonNameBase
, INameService
> {
55 /** Taxon status strings*/
56 public static final String ACCECPTED_NAME_STATUS
= "accepted_name";
57 public static final String SYNONYM_STATUS
= "synonym";
60 public static final String DOUBTFUL_FLAG
= "doubtful";
63 private ITaxonService taxonService
;
66 private IClassificationService classificationService
;
68 private static final List
<String
> NAME_SEARCH_INIT_STRATEGY
= Arrays
.asList(new String
[]{
69 "combinationAuthorTeam.$",
70 "exCombinationAuthorTeam.$",
71 "basionymAuthorTeam.$",
72 "exBasionymAuthorTeam.$",
76 private static final List
<String
> NAME_INFORMATION_INIT_STRATEGY
= Arrays
.asList(new String
[]{
79 "nomenclaturalReference.$",
80 "combinationAuthorTeam.$",
81 "exCombinationAuthorTeam.$",
82 "basionymAuthorTeam.$",
83 "exBasionymAuthorTeam.$",
84 "relationsToThisName.$",
85 "relationsFromThisName.$"
88 private static final List
<String
> TAXON_INFORMATION_INIT_STRATEGY
= Arrays
.asList(new String
[]{
91 "taxonNodes.classification"
94 private static final List
<String
> TAXON_NODE_INIT_STRATEGY
= Arrays
.asList(new String
[]{
98 "classification.reference.$",
99 "classification.reference.authorTeam.$"
102 public NameCatalogueController(){
104 setInitializationStrategy(Arrays
.asList(new String
[]{"$"})); //TODO still needed????
108 * @see eu.etaxonomy.cdm.remote.controller.GenericController#setService(eu.etaxonomy.cdm.api.service.IService)
112 public void setService(INameService service
) {
113 this.service
= service
;
117 * Returns a list of taxon names matching the <code>{query}</code> string pattern.
118 * Each of these taxon names is accompanied by a list of name uuids and
119 * a list of taxon uuids.
121 * URI: <b>/{datasource-name}/name_catalogue</b>
124 * The taxon name pattern(s) to query for. The query can contain wildcard characters ('*').
125 * The query can be performed with no wildcard or with the wildcard at the begin and / or end
126 * depending on the search pattern.
129 * @return a List of {@link NameSearch} objects each corresponding to a single query. These are built from
130 * {@TaxonNameBase} entities which are in turn initialized using the {@link #NAME_SEARCH_INIT_STRATEGY}
131 * @throws IOException
133 @RequestMapping(value
= {""},
134 method
= RequestMethod
.GET
)
135 public ModelAndView
doGetNameSearch(@RequestParam(value
= "query", required
= true) String
[] queries
,
136 HttpServletRequest request
,
137 HttpServletResponse response
) throws IOException
{
138 ModelAndView mv
= new ModelAndView();
139 List
<RemoteResponse
> nsList
= new ArrayList
<RemoteResponse
>();
140 for(String query
: queries
) {
142 String queryWOWildcards
= getQueryWithoutWildCards(query
);
143 MatchMode mm
= getMatchModeFromQuery(query
);
144 logger
.info("doGetNameSearch()" + request
.getServletPath() + " for query \"" + query
+ "\" without wild cards : " + queryWOWildcards
+ " and match mode : " + mm
);
145 List
<NonViralName
> nameList
= (List
<NonViralName
>)service
.findNamesByTitleCache(queryWOWildcards
, mm
, NAME_SEARCH_INIT_STRATEGY
);
146 if(nameList
== null || !nameList
.isEmpty()) {
147 System
.out
.println("Size : " + nameList
.size());
149 NameSearch ns
= new NameSearch();
150 ns
.setRequest(query
);
152 for (NonViralName nvn
: nameList
)
154 String titleCacheString
= nvn
.getTitleCache();
155 ns
.addToResponseList(titleCacheString
, nvn
.getUuid().toString(), nvn
.getTaxonBases());
160 ErrorResponse er
= new ErrorResponse();
161 er
.setErrorMessage("No Taxon Name for given query : " + query
);
165 mv
.addObject(nsList
);
170 * Returns information related to the taxon name matching the given <code>{nameUuid}</code>.
171 * The information includes the name string, relationships, rank, list of related lsids / taxon uuids, etc.
173 * URI: <b>/{datasource-name}/name_catalogue</b>
176 * The taxon name pattern(s) to query for. The query can contain wildcard characters ('*').
177 * The query can be performed with no wildcard or with the wildcard at the begin and / or end
178 * depending on the search pattern.
181 * @return a List of {@link NameSearch} objects each corresponding to a single query. These are built from
182 * {@TaxonNameBase} entities which are in turn initialized using the {@link #NAME_SEARCH_INIT_STRATEGY}
183 * @throws IOException
185 @RequestMapping(value
= {"name"},
186 method
= RequestMethod
.GET
)
187 public ModelAndView
doGetNameInformation(@RequestParam(value
= "nameUuid", required
= true) String
[] nameUuids
,
188 HttpServletRequest request
,
189 HttpServletResponse response
) throws IOException
{
190 ModelAndView mv
= new ModelAndView();
191 List
<RemoteResponse
> niList
= new ArrayList
<RemoteResponse
>();
192 for(String nameUuid
: nameUuids
) {
193 logger
.info("doGetNameInformation()" + request
.getServletPath() + " for name uuid \"" + nameUuid
);
194 NonViralName nvn
= (NonViralName
)service
.findNameByUuid(UUID
.fromString(nameUuid
), NAME_INFORMATION_INIT_STRATEGY
);
196 NameInformation ni
= new NameInformation();
197 ni
.setRequest(nameUuid
);
198 Reference ref
= (Reference
) nvn
.getNomenclaturalReference();
199 String citation
= "";
200 String citation_details
= "";
202 citation
= ref
.getTitleCache();
204 ni
.setResponse(nvn
.getTitleCache(),
205 nvn
.getRank().getTitleCache(),
208 nvn
.getRelationsFromThisName(),
209 nvn
.getRelationsToThisName(),
210 nvn
.getTaxonBases());
213 ErrorResponse re
= new ErrorResponse();
214 re
.setErrorMessage("No Taxon Name for given UUID : " + nameUuid
);
218 mv
.addObject(niList
);
222 @RequestMapping(value
= {"taxon"},
223 method
= RequestMethod
.GET
)
224 public ModelAndView
doGetTaxonInformation(@RequestParam(value
= "taxonUuid", required
= true) String
[] taxonUuids
,
225 HttpServletRequest request
,
226 HttpServletResponse response
) throws IOException
{
227 ModelAndView mv
= new ModelAndView();
228 List
<RemoteResponse
> tiList
= new ArrayList
<RemoteResponse
>();
229 for(String taxonUuid
: taxonUuids
) {
230 logger
.info("doGetTaxonInformation()" + request
.getServletPath() + " for taxon uuid \"" + taxonUuid
);
231 TaxonBase tb
= taxonService
.findTaxonByUuid(UUID
.fromString(taxonUuid
), TAXON_INFORMATION_INIT_STRATEGY
);
233 System
.out
.println("Name : " + tb
.getTitleCache());
234 TaxonInformation ti
= new TaxonInformation();
235 ti
.setRequest(taxonUuid
);
237 if(tb
.isInstanceOf(Taxon
.class)) {
238 Taxon taxon
= (Taxon
)tb
;
239 System
.out
.println("Is a Taxon");
240 ti
.setResponseTaxon(tb
.getTitleCache(),
241 ACCECPTED_NAME_STATUS
,
243 buildClassificationMap(taxon
));
244 Set
<Synonym
> synonyms
= taxon
.getSynonyms();
245 for(Synonym syn
: synonyms
) {
246 String uuid
= syn
.getUuid().toString();
247 String name
= syn
.getTitleCache();
248 String status
= SYNONYM_STATUS
;
249 ti
.addToResponseRelatedTaxa(taxonUuid
, name
, status
, "");
251 } else if(tb
instanceof Synonym
) {
252 Synonym synonym
= (Synonym
)tb
;
253 System
.out
.println("Is a Synonym");
254 ti
.setResponseTaxon(tb
.getTitleCache(),
258 Set
<Taxon
> acceptedTaxa
= synonym
.getAcceptedTaxa();
259 for(Taxon taxon
: acceptedTaxa
) {
260 String uuid
= taxon
.getUuid().toString();
261 String name
= taxon
.getTitleCache();
262 String status
= ACCECPTED_NAME_STATUS
;
263 ti
.addToResponseRelatedTaxa(taxonUuid
, name
, status
, "");
268 ErrorResponse re
= new ErrorResponse();
269 re
.setErrorMessage("No Taxon for given UUID : " + taxonUuid
);
273 mv
.addObject(tiList
);
277 private MatchMode
getMatchModeFromQuery(String query
) {
278 if(query
.startsWith("*") && query
.endsWith("*")) {
279 return MatchMode
.ANYWHERE
;
280 } else if(query
.startsWith("*")) {
281 return MatchMode
.END
;
282 } else if(query
.endsWith("*")) {
283 return MatchMode
.BEGINNING
;
285 return MatchMode
.EXACT
;
289 private String
getQueryWithoutWildCards(String query
) {
291 String newQuery
= query
;
292 if(query
.startsWith("*")) {
293 newQuery
= newQuery
.substring(1, newQuery
.length());
296 if(query
.endsWith("*")) {
297 newQuery
= newQuery
.substring(0, newQuery
.length()-1);
302 private Map
<String
, String
> buildFlagMap(TaxonBase tb
) {
303 Map
<String
, String
> flags
= new Hashtable
<String
, String
>();
304 flags
.put(DOUBTFUL_FLAG
, Boolean
.toString(tb
.isDoubtful()));
308 private Map
<String
, Map
> buildClassificationMap(Taxon taxon
) {
309 Map
<String
, Map
> classificationMap
= new Hashtable
<String
, Map
>();
310 Set
<TaxonNode
> taxonNodes
= taxon
.getTaxonNodes();
312 for(TaxonNode tn
: taxonNodes
) {
313 Map
<String
, String
> classification
= new LinkedHashMap
<String
, String
>();
314 List
<TaxonNode
> tnList
= classificationService
.loadTreeBranchToTaxon(taxon
, tn
.getClassification(), null, TAXON_NODE_INIT_STRATEGY
);
315 for(TaxonNode classificationtn
: tnList
) {
317 classification
.put(classificationtn
.getTaxon().getName().getRank().getTitleCache(),
318 classificationtn
.getTaxon().getName().getTitleCache());
319 System
.out
.println("Classification : " + classificationtn
.getTaxon().getName().getRank().getTitleCache());
322 System
.out
.println("CTitle : " + tn
.getClassification().getTitleCache());
323 String cname
= tn
.getClassification().getTitleCache();
324 String
[] words
= cname
.split("\\s+");
325 //"\\s+" in regular expression language meaning one or more spaces
326 StringBuilder builder
= new StringBuilder();
327 for (String word
: words
){
328 builder
.append(word
);
330 cname
= builder
.toString();
331 classificationMap
.put(cname
, classification
);
333 return classificationMap
;