Project

General

Profile

Download (38.6 KB) Statistics
| Branch: | Tag: | Revision:
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.http.HttpRequest;
29
import org.apache.log4j.Logger;
30
import org.springframework.beans.factory.annotation.Autowired;
31
import org.springframework.stereotype.Controller;
32
import org.springframework.web.bind.WebDataBinder;
33
import org.springframework.web.bind.annotation.InitBinder;
34
import org.springframework.web.bind.annotation.PathVariable;
35
import org.springframework.web.bind.annotation.RequestMapping;
36
import org.springframework.web.bind.annotation.RequestMethod;
37
import org.springframework.web.bind.annotation.RequestParam;
38
import org.springframework.web.servlet.ModelAndView;
39

    
40
import eu.etaxonomy.cdm.api.service.IDescriptionService;
41
import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
42
import eu.etaxonomy.cdm.api.service.INameService;
43
import eu.etaxonomy.cdm.api.service.IOccurrenceService;
44
import eu.etaxonomy.cdm.api.service.ITaxonService;
45
import eu.etaxonomy.cdm.api.service.IClassificationService;
46
import eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator;
47
import eu.etaxonomy.cdm.api.service.config.TaxonServiceConfiguratorImpl;
48
import eu.etaxonomy.cdm.api.service.pager.Pager;
49
import eu.etaxonomy.cdm.database.UpdatableRoutingDataSource;
50
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
51
import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
52
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
53
import eu.etaxonomy.cdm.model.description.TaxonDescription;
54
import eu.etaxonomy.cdm.model.location.NamedArea;
55
import eu.etaxonomy.cdm.model.media.Media;
56
import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
57
import eu.etaxonomy.cdm.model.media.MediaUtils;
58
import eu.etaxonomy.cdm.model.name.NameRelationship;
59
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
60
import eu.etaxonomy.cdm.model.taxon.Synonym;
61
import eu.etaxonomy.cdm.model.taxon.Taxon;
62
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
63
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
64
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
65
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
66
import eu.etaxonomy.cdm.model.taxon.Classification;
67
import eu.etaxonomy.cdm.persistence.query.MatchMode;
68
import eu.etaxonomy.cdm.remote.editor.CdmTypePropertyEditor;
69
import eu.etaxonomy.cdm.remote.editor.MatchModePropertyEditor;
70
import eu.etaxonomy.cdm.remote.editor.NamedAreaPropertyEditor;
71

    
72
/**
73
 * The TaxonPortalController class is a Spring MVC Controller.
74
 * <p>
75
 * The syntax of the mapped service URIs contains the the {datasource-name} path element.
76
 * The available {datasource-name}s are defined in a configuration file which
77
 * is loaded by the {@link UpdatableRoutingDataSource}. If the
78
 * UpdatableRoutingDataSource is not being used in the actual application
79
 * context any arbitrary {datasource-name} may be used.
80
 * <p>
81
 * Methods mapped at type level, inherited from super classes ({@link BaseController}):
82
 * <blockquote>
83
 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}</b>
84
 *
85
 * Get the {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
86
 * The returned Taxon is initialized by
87
 * the following strategy {@link #TAXON_INIT_STRATEGY}
88
 * </blockquote>
89
 *
90
 * @author a.kohlbecker
91
 * @date 20.07.2009
92
 *
93
 */
94
@Controller
95
@RequestMapping(value = {"/portal/taxon/{uuid}"})
96
public class TaxonPortalController extends BaseController<TaxonBase, ITaxonService>
97
{
98
    public static final Logger logger = Logger.getLogger(TaxonPortalController.class);
99

    
100
    @Autowired
101
    private INameService nameService;
102

    
103
    @Autowired
104
    private IDescriptionService descriptionService;
105

    
106
    @Autowired
107
    private IOccurrenceService occurrenceService;
108

    
109
    @Autowired
110
    private IClassificationService classificationService;
111

    
112
    @Autowired
113
    private ITaxonService taxonService;
114

    
115
    @Autowired
116
    private IFeatureTreeService featureTreeService;
117

    
118
    private static final List<String> TAXON_INIT_STRATEGY = Arrays.asList(new String []{
119
            "*",
120
            // taxon relations
121
            "relationsToThisName.fromTaxon.name",
122
            // the name
123
            "name.$",
124
            "name.rank.representations",
125
            "name.status.type.representations",
126

    
127
            // taxon descriptions
128
            "descriptions.elements.area.$",
129
            "descriptions.elements.multilanguageText",
130
            "descriptions.elements.media.representations.parts",
131
            "descriptions.elements.media.title",
132

    
133
            });
134

    
135
    private static final List<String> TAXON_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{
136
            "taxonNodes.$",
137
            "taxonNodes.classification.$",
138
            "taxonNodes.childNodes.$"
139
            });
140

    
141
    private static final List<String> SIMPLE_TAXON_INIT_STRATEGY = Arrays.asList(new String []{
142
            "*",
143
            // taxon relations
144
            "relationsToThisName.fromTaxon.name",
145
            // the name
146
            "name.$",
147
            "name.rank.representations",
148
            "name.status.type.representations",
149
            "name.nomenclaturalReference"
150
            });
151

    
152
    private static final List<String> SYNONYMY_INIT_STRATEGY = Arrays.asList(new String []{
153
            // initialize homotypical and heterotypical groups; needs synonyms
154
            "synonymRelations.$",
155
            "synonymRelations.synonym.$",
156
            "synonymRelations.synonym.name.status.type.representation",
157
            "synonymRelations.synonym.name.nomenclaturalReference.inReference",
158
            "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
159
            "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
160
            "synonymRelations.synonym.name.combinationAuthorTeam.$",
161

    
162
            "name.typeDesignations",
163

    
164
            "name.homotypicalGroup.$",
165
            "name.homotypicalGroup.typifiedNames.$",
166
            "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorTeam",
167

    
168
            "name.homotypicalGroup.typifiedNames.taxonBases.$"
169
    });
170

    
171
    private static final List<String> SYNONYMY_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{
172
            // initialize homotypical and heterotypical groups; needs synonyms
173
            "synonymRelations.$",
174
            "synonymRelations.synonym.$",
175
            "synonymRelations.synonym.name.status.type.representation",
176
            "synonymRelations.synonym.name.nomenclaturalReference.inReference",
177
            "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
178
            "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
179
            "synonymRelations.synonym.name.combinationAuthorTeam.$",
180

    
181
            "name.homotypicalGroup.$",
182
            "name.homotypicalGroup.typifiedNames.$",
183
            "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorTeam",
184

    
185
            "name.homotypicalGroup.typifiedNames.taxonBases.$",
186

    
187
            "taxonNodes.$",
188
            "taxonNodes.classification.$",
189
            "taxonNodes.childNodes.$"
190
    });
191
    private static final List<String> SIMPLE_TAXON_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{
192
            "*",
193
            // taxon relations
194
            "relationsToThisName.fromTaxon.name",
195
            // the name
196
            "name.$",
197
            "name.rank.representations",
198
            "name.status.type.representations",
199
            "name.nomenclaturalReference",
200

    
201
            "taxonNodes.$",
202
            "taxonNodes.classification.$",
203
            "taxonNodes.childNodes.$"
204
            });
205

    
206

    
207
    private static final List<String> TAXONRELATIONSHIP_INIT_STRATEGY = Arrays.asList(new String []{
208
            "$",
209
            "type.inverseRepresentations",
210
            "fromTaxon.sec",
211
            "fromTaxon.name"
212
    });
213

    
214
    private static final List<String> NAMERELATIONSHIP_INIT_STRATEGY = Arrays.asList(new String []{
215
            "$",
216
            "type.inverseRepresentations",
217
            "fromName",
218
            "toName.$",
219
    });
220

    
221

    
222
    protected static final List<String> TAXONDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{
223
            "$",
224
            "elements.$",
225
            "elements.sources.citation.authorTeam",
226
            "elements.sources.nameUsedInSource.originalNameString",
227
            "elements.multilanguageText",
228
            "elements.media.representations.parts",
229
            "elements.media.title",
230
    });
231

    
232
    protected static final List<String> DESCRIPTION_ELEMENT_INIT_STRATEGY = Arrays.asList(new String []{
233
            "$",
234
            "sources.citation.authorTeam",
235
            "sources.nameUsedInSource.originalNameString",
236
            "multilanguageText",
237
            "media.representations.parts",
238
            "media.title",
239
    });
240

    
241

    
242
//	private static final List<String> NAMEDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{
243
//			"uuid",
244
//			"feature",
245
//			"elements.$",
246
//			"elements.multilanguageText",
247
//			"elements.media.representations.parts",
248
//			"elements.media.title",
249
//	});
250

    
251
    protected static final List<String> TAXONDESCRIPTION_MEDIA_INIT_STRATEGY = Arrays.asList(new String []{
252
            "elements.media.representations.parts",
253
            "elements.media.title"
254

    
255
    });
256

    
257
    private static final List<String> TYPEDESIGNATION_INIT_STRATEGY = Arrays.asList(new String []{
258
            //"$",
259
            "typeSpecimen.$",
260
            "citation.authorTeam.$",
261
            "typeName",
262
    });
263

    
264
    protected static final List<String> TAXONNODE_WITHTAXON_INIT_STRATEGY = Arrays.asList(new String []{
265
            "childNodes.taxon",
266
    });
267

    
268
    protected static final List<String> TAXONNODE_INIT_STRATEGY = Arrays.asList(new String []{
269
            "taxonNodes.classification"
270
    });
271

    
272

    
273

    
274
    private static final String featureTreeUuidPattern = "^/taxon(?:(?:/)([^/?#&\\.]+))+.*";
275

    
276
    public TaxonPortalController(){
277
        super();
278
        setInitializationStrategy(TAXON_INIT_STRATEGY);
279
    }
280

    
281
    /* (non-Javadoc)
282
     * @see eu.etaxonomy.cdm.remote.controller.GenericController#setService(eu.etaxonomy.cdm.api.service.IService)
283
     */
284
    @Autowired
285
    @Override
286
    public void setService(ITaxonService service) {
287
        this.service = service;
288
    }
289

    
290
    @InitBinder
291
    @Override
292
    public void initBinder(WebDataBinder binder) {
293
        super.initBinder(binder);
294
        binder.registerCustomEditor(NamedArea.class, new NamedAreaPropertyEditor());
295
        binder.registerCustomEditor(MatchMode.class, new MatchModePropertyEditor());
296
        binder.registerCustomEditor(Class.class, new CdmTypePropertyEditor());
297
    }
298

    
299

    
300
    /* (non-Javadoc)
301
     * @see eu.etaxonomy.cdm.remote.controller.BaseController#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
302

    
303
    @Override
304
    @RequestMapping(method = RequestMethod.GET)
305
    public TaxonBase doGet(HttpServletRequest request, HttpServletResponse response)throws IOException {
306
        logger.info("doGet()");
307
        TaxonBase tb = getCdmBase(request, response, TAXON_INIT_STRATEGY, TaxonBase.class);
308
        return tb;
309
    }
310
     */
311
    /**
312
     * Find Taxa, Synonyms, Common Names by name, either globally or in a specific geographic area.
313
     * <p>
314
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;find</b>
315
     *
316
     * @param query
317
     *            the string to query for. Since the wildcard character '*'
318
     *            internally always is appended to the query string, a search
319
     *            always compares the query string with the beginning of a name.
320
     *            - <i>required parameter</i>
321
     * @param treeUuid
322
     *            the {@link UUID} of a {@link Classification} to which the
323
     *            search is to be restricted. - <i>optional parameter</i>
324
     * @param areas
325
     *            restrict the search to a set of geographic {@link NamedArea}s.
326
     *            The parameter currently takes a list of TDWG area labels.
327
     *            - <i>optional parameter</i>
328
     * @param pageNumber
329
     *            the number of the page to be returned, the first page has the
330
     *            pageNumber = 1 - <i>optional parameter</i>
331
     * @param pageSize
332
     *            the maximum number of entities returned per page (can be -1
333
     *            to return all entities in a single page) - <i>optional parameter</i>
334
     * @param doTaxa
335
     *            weather to search for instances of {@link Taxon} - <i>optional parameter</i>
336
     * @param doSynonyms
337
     *            weather to search for instances of {@link Synonym} - <i>optional parameter</i>
338
     * @param doTaxaByCommonNames
339
     *            for instances of {@link Taxon} by a common name used - <i>optional parameter</i>
340
     * @param matchMode
341
     *           valid values are "EXACT", "BEGINNING", "ANYWHERE", "END" (case sensitive !!!)
342
     * @return a Pager on a list of {@link IdentifiableEntity}s initialized by
343
     *         the following strategy {@link #SIMPLE_TAXON_INIT_STRATEGY}
344
     * @throws IOException
345
     */
346
    @RequestMapping(method = RequestMethod.GET,
347
            value = {"/portal/taxon/find"}) //TODO map to path /*/portal/taxon/
348
    public Pager<IdentifiableEntity> doFind(
349
            @RequestParam(value = "query", required = false) String query,
350
            @RequestParam(value = "tree", required = false) UUID treeUuid,
351
            @RequestParam(value = "area", required = false) Set<NamedArea> areas,
352
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
353
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
354
            @RequestParam(value = "doTaxa", required = false) Boolean doTaxa,
355
            @RequestParam(value = "doSynonyms", required = false) Boolean doSynonyms,
356
            @RequestParam(value = "doTaxaByCommonNames", required = false) Boolean doTaxaByCommonNames,
357
            @RequestParam(value = "matchMode", required = false) MatchMode matchMode,
358
            HttpServletRequest request,
359
            HttpServletResponse response
360
            )
361
             throws IOException {
362

    
363
        logger.info("doFind : " + request.getRequestURI() + request.getQueryString() );
364

    
365
        BaseListController.normalizeAndValidatePagerParameters(pageNumber, pageSize, response);
366

    
367
        ITaxonServiceConfigurator config = new TaxonServiceConfiguratorImpl();
368
        config.setPageNumber(pageNumber);
369
        config.setPageSize(pageSize);
370
        config.setTitleSearchString(query);
371
        config.setDoTaxa(doTaxa!= null ? doTaxa : Boolean.FALSE );
372
        config.setDoSynonyms(doSynonyms != null ? doSynonyms : Boolean.FALSE );
373
        config.setDoTaxaByCommonNames(doTaxaByCommonNames != null ? doTaxaByCommonNames : Boolean.FALSE );
374
        config.setMatchMode(matchMode != null ? matchMode : MatchMode.BEGINNING);
375
        config.setTaxonPropertyPath(SIMPLE_TAXON_INIT_STRATEGY);
376
        config.setNamedAreas(areas);
377
        if(treeUuid != null){
378
            Classification classification = classificationService.find(treeUuid);
379
            config.setClassification(classification);
380
        }
381

    
382
        return (Pager<IdentifiableEntity>) service.findTaxaAndNames(config);
383
    }
384

    
385
    /**
386
     * Get the synonymy for a taxon identified by the <code>{taxon-uuid}</code>.
387
     * The synonymy consists
388
     * of two parts: The group of homotypic synonyms of the taxon and the
389
     * heterotypic synonymy groups of the taxon. The synonymy is ordered
390
     * historically by the type designations and by the publication date of the
391
     * nomenclatural reference
392
     * <p>
393
     * URI:
394
     * <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;synonymy</b>
395
     *
396
     *
397
     * @param request
398
     * @param response
399
     * @return a Map with to entries which are mapped by the following keys:
400
     *         "homotypicSynonymsByHomotypicGroup", "heterotypicSynonymyGroups",
401
     *         containing lists of {@link Synonym}s which are initialized using the
402
     *         following initialization strategy: {@link #SYNONYMY_INIT_STRATEGY}
403
     *
404
     * @throws IOException
405
     */
406
    @RequestMapping(
407
            value = {"synonymy"},
408
            method = RequestMethod.GET)
409
    public ModelAndView doGetSynonymy(@PathVariable("uuid") UUID uuid,
410
            HttpServletRequest request, HttpServletResponse response)throws IOException {
411

    
412
        if(request != null){
413
            logger.info("doGetSynonymy() " + request.getServletPath());
414
        }
415
        ModelAndView mv = new ModelAndView();
416
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
417
        Map<String, List<?>> synonymy = new Hashtable<String, List<?>>();
418
        synonymy.put("homotypicSynonymsByHomotypicGroup", service.getHomotypicSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY));
419
        synonymy.put("heterotypicSynonymyGroups", service.getHeterotypicSynonymyGroups(taxon, SYNONYMY_INIT_STRATEGY));
420
        mv.addObject(synonymy);
421
        return mv;
422
    }
423

    
424
    /**
425
     * Get the set of accepted {@link Taxon} entities for a given
426
     * {@link TaxonBase} entity identified by the <code>{taxon-uuid}</code>.
427
     * <p>
428
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;accepted</b>
429
     *
430
     * @param request
431
     * @param response
432
     * @return a Set of {@link Taxon} entities which are initialized
433
     *         using the following initialization strategy:
434
     *         {@link #SYNONYMY_INIT_STRATEGY}
435
     * @throws IOException
436
     */
437
    @RequestMapping(value = "accepted/{classification_uuid}", method = RequestMethod.GET)
438
    public Set<TaxonBase> getAccepted(
439
                @PathVariable("uuid") UUID uuid,
440
                @PathVariable("classification_uuid") UUID classification_uuid,
441
                HttpServletRequest request,
442
                HttpServletResponse response)
443
                throws IOException {
444

    
445
        if(request != null){
446
            logger.info("getAccepted() " + request.getServletPath());
447
        }
448

    
449
        TaxonBase tb = service.load(uuid, SYNONYMY_WITH_NODES_INIT_STRATEGY);
450
        if(tb == null){
451
            response.sendError(HttpServletResponse.SC_NOT_FOUND, "A taxon with the uuid " + uuid + " does not exist");
452
            return null;
453
        }
454

    
455
        HashSet<TaxonBase> resultset = new HashSet<TaxonBase>();
456

    
457
        if (tb instanceof Taxon){
458
            Taxon taxon = (Taxon) tb;
459
            Set<TaxonNode> nodes = taxon.getTaxonNodes();
460
            for (TaxonNode taxonNode : nodes) {
461
                if (taxonNode.getClassification().compareTo(classification_uuid) == 0){
462
                    resultset.add((Taxon) tb);
463
                }
464
            }
465
            if (resultset.size() > 1){
466
                //error!! A taxon is not allow to have more taxonnodes for a given classification
467
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
468
                "A taxon with the uuid " + uuid + " has more than one taxon node for the given classification" + classification_uuid);
469
            }
470
        }else{
471
            Synonym syn = (Synonym) tb;
472
            for(TaxonBase accepted : syn.getAcceptedTaxa()){
473
                tb = service.load(accepted.getUuid(), SIMPLE_TAXON_WITH_NODES_INIT_STRATEGY);
474
                if (tb instanceof Taxon){
475
                    Taxon taxon = (Taxon) tb;
476
                    Set<TaxonNode> nodes = taxon.getTaxonNodes();
477
                    for (TaxonNode taxonNode : nodes) {
478
                        if (taxonNode.getClassification().compareTo(classification_uuid) == 0){
479
                            resultset.add((Taxon) tb);
480
                        }
481
                    }
482
                    if (resultset.size() > 1){
483
                        //error!! A taxon is not allow to have more taxonnodes for a given classification
484
                        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
485
                        "A taxon with the uuid " + uuid + " has more than one taxon node for the given classification" + classification_uuid);
486
                    }
487
                }else{
488
                    //ERROR!! perhaps missapplied name????
489
                    //syn.getRelationType((Taxon)accepted);
490
                }
491
            }
492
        }
493
/**
494
 * OLD CODE!!
495
        if(tb instanceof Taxon){
496
            //the taxon already is accepted
497
            //FIXME take the current view into account once views are implemented!!!
498
            resultset.add((Taxon)tb);
499
        } else {
500
            Synonym syn = (Synonym)tb;
501
            for(TaxonBase accepted : syn.getAcceptedTaxa()){
502
                accepted = service.load(accepted.getUuid(), SIMPLE_TAXON_INIT_STRATEGY);
503
                resultset.add(accepted);
504
            }
505
        }
506
*/
507
        return resultset;
508
    }
509

    
510
    /**
511
     * Get the list of {@link TaxonRelationship}s for the given
512
     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
513
     * <p>
514
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;taxonRelationships</b>
515
     *
516
     * @param request
517
     * @param response
518
     * @return a List of {@link TaxonRelationship} entities which are initialized
519
     *         using the following initialization strategy:
520
     *         {@link #TAXONRELATIONSHIP_INIT_STRATEGY}
521
     * @throws IOException
522
     */
523
    @RequestMapping(
524
            value = {"taxonRelationships"},
525
            method = RequestMethod.GET)
526
    public List<TaxonRelationship> doGetTaxonRelations(@PathVariable("uuid") UUID uuid,
527
            HttpServletRequest request, HttpServletResponse response)throws IOException {
528

    
529
        logger.info("doGetTaxonRelations()" + request.getServletPath());
530
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
531
        List<TaxonRelationship> relations = new ArrayList<TaxonRelationship>();
532
        List<TaxonRelationship> results = service.listToTaxonRelationships(taxon, TaxonRelationshipType.MISAPPLIED_NAME_FOR(), null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);
533
        relations.addAll(results);
534
        results = service.listToTaxonRelationships(taxon, TaxonRelationshipType.INVALID_DESIGNATION_FOR(), null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);
535
        relations.addAll(results);
536

    
537
        return relations;
538
    }
539

    
540
    /**
541
     * Get the list of {@link NameRelationship}s of the Name associated with the
542
     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
543
     * <p>
544
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>
545
     *
546
     * @param request
547
     * @param response
548
     * @return a List of {@link NameRelationship} entities which are initialized
549
     *         using the following initialization strategy:
550
     *         {@link #NAMERELATIONSHIP_INIT_STRATEGY}
551
     * @throws IOException
552
     */
553
    @RequestMapping(
554
            value = {"toNameRelationships"},
555
            method = RequestMethod.GET)
556
    public List<NameRelationship> doGetToNameRelations(@PathVariable("uuid") UUID uuid,
557
            HttpServletRequest request, HttpServletResponse response)throws IOException {
558
        logger.info("doGetNameRelations()" + request.getServletPath());
559
        TaxonBase taxonBase = getCdmBaseInstance(TaxonBase.class, uuid, response, (List<String>)null);
560
        List<NameRelationship> list = nameService.listNameRelationships(taxonBase.getName(), Direction.relatedTo, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY);
561
        //List<NameRelationship> list = nameService.listToNameRelationships(taxonBase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
562
        return list;
563
    }
564

    
565
    /**
566
     * Get the list of {@link NameRelationship}s of the Name associated with the
567
     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
568
     * <p>
569
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>
570
     *
571
     * @param request
572
     * @param response
573
     * @return a List of {@link NameRelationship} entities which are initialized
574
     *         using the following initialization strategy:
575
     *         {@link #NAMERELATIONSHIP_INIT_STRATEGY}
576
     * @throws IOException
577
     */
578
    @RequestMapping(
579
            value = {"fromNameRelationships"},
580
            method = RequestMethod.GET)
581
    public List<NameRelationship> doGetFromNameRelations(@PathVariable("uuid") UUID uuid,
582
            HttpServletRequest request, HttpServletResponse response)throws IOException {
583
        logger.info("doGetNameFromNameRelations()" + request.getServletPath());
584

    
585
        TaxonBase taxonbase = getCdmBaseInstance(TaxonBase.class, uuid, response, SIMPLE_TAXON_INIT_STRATEGY);
586
        List<NameRelationship> list = nameService.listNameRelationships(taxonbase.getName(), Direction.relatedFrom, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY);
587
        //List<NameRelationship> list = nameService.listFromNameRelationships(taxonbase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
588
        return list;
589
    }
590

    
591
    /**
592
     * Get the list of {@link TypeDesignationBase}s of the
593
     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
594
     * <p>
595
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameTypeDesignations</b>
596
     *
597
     * @param request
598
     * @param response
599
     * @return a List of {@link TypeDesignationBase} entities which are initialized
600
     *         using the following initialization strategy:
601
     *         {@link #TYPEDESIGNATION_INIT_STRATEGY}
602
     * @throws IOException
603
     * @Deprecated use &#x002F;name&#x002F;{uuid}&#x002F;typeDesignations & &#x002F;derivedunitfacade&#x002F;{uuid} instead
604
     * also see http://dev.e-taxonomy.eu/trac/ticket/2280
605
     */
606
    @Deprecated
607
    @RequestMapping(
608
            value = {"nameTypeDesignations"},
609
            method = RequestMethod.GET)
610
    public List<TypeDesignationBase> doGetNameTypeDesignations(@PathVariable("uuid") UUID uuid,
611
            HttpServletRequest request, HttpServletResponse response)throws IOException {
612
        logger.info("doGetNameTypeDesignations()" + request.getServletPath());
613
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, SIMPLE_TAXON_INIT_STRATEGY);
614
        Pager<TypeDesignationBase> p = nameService.getTypeDesignations(taxon.getName(), null, null, null, TYPEDESIGNATION_INIT_STRATEGY);
615
        return p.getRecords();
616
    }
617

    
618
    @RequestMapping(value = "taxonNodes", method = RequestMethod.GET)
619
    public Set<TaxonNode>  doGetTaxonNodes(
620
            @PathVariable("uuid") UUID uuid,
621
            HttpServletRequest request,
622
            HttpServletResponse response) throws IOException {
623
        TaxonBase tb = service.load(uuid, TAXONNODE_INIT_STRATEGY);
624
        if(tb instanceof Taxon){
625
            return ((Taxon)tb).getTaxonNodes();
626
        } else {
627
            HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
628
            return null;
629
        }
630
    }
631

    
632
    /**
633
     * Get the list of {@link TaxonDescription}s of the
634
     * {@link Taxon} instance identified by the <code>{taxon-uuid}</code>.
635
     * <p>
636
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;descriptions</b>
637
     *
638
     * @param request
639
     * @param response
640
     * @return a List of {@link TaxonDescription} entities which are initialized
641
     *         using the following initialization strategy:
642
     *         {@link #TAXONDESCRIPTION_INIT_STRATEGY}
643
     * @throws IOException
644
     */
645
    @RequestMapping(
646
            value = {"descriptions"},
647
            method = RequestMethod.GET)
648
    public List<TaxonDescription> doGetDescriptions(
649
            @PathVariable("uuid") UUID uuid,
650
            HttpServletRequest request,
651
            HttpServletResponse response)throws IOException {
652
        if(request != null){
653
            logger.info("doGetDescriptions()" + request.getServletPath());
654
        }
655
        Taxon t = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
656
        Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions(t, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
657
        return p.getRecords();
658
    }
659

    
660
    @RequestMapping(value = "descriptions/elementsByType/{classSimpleName}", method = RequestMethod.GET)
661
    public ModelAndView doGetDescriptionElementsByType(
662
            @PathVariable("uuid") UUID uuid,
663
            @PathVariable("classSimpleName") String classSimpleName,
664
            @RequestParam(value = "count", required = false, defaultValue = "false") Boolean doCount,
665
            HttpServletRequest request,
666
            HttpServletResponse response) throws IOException {
667
        logger.info("doGetDescriptionElementsByType() - " + request.getServletPath());
668

    
669
        ModelAndView mv = new ModelAndView();
670

    
671
        List<DescriptionElementBase> allElements = new ArrayList<DescriptionElementBase>();
672
        List<DescriptionElementBase> elements;
673
        int count = 0;
674

    
675
        List<String> initStrategy = doCount ? null : DESCRIPTION_ELEMENT_INIT_STRATEGY;
676

    
677
        List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, request, response);
678
        try {
679
            Class type;
680
            type = Class.forName("eu.etaxonomy.cdm.model.description."
681
                    + classSimpleName);
682
            if (taxonDescriptions != null) {
683
                for (TaxonDescription description : taxonDescriptions) {
684
                    elements = descriptionService.listDescriptionElements(description, null, type, null, 0, initStrategy);
685
                    allElements.addAll(elements);
686
                    count += elements.size();
687
                }
688

    
689
            }
690
        } catch (ClassNotFoundException e) {
691
            HttpStatusMessage.fromString(e.getLocalizedMessage()).send(response);
692
        }
693
        if(doCount){
694
            mv.addObject(count);
695
        } else {
696
            mv.addObject(allElements);
697
        }
698
        return mv;
699
    }
700

    
701
//	@RequestMapping(value = "specimens", method = RequestMethod.GET)
702
//	public ModelAndView doGetSpecimens(
703
//			@PathVariable("uuid") UUID uuid,
704
//			HttpServletRequest request,
705
//			HttpServletResponse response) throws IOException, ClassNotFoundException {
706
//		logger.info("doGetSpecimens() - " + request.getServletPath());
707
//
708
//		ModelAndView mv = new ModelAndView();
709
//
710
//		List<DerivedUnitFacade> derivedUnitFacadeList = new ArrayList<DerivedUnitFacade>();
711
//
712
//		// find speciemens in the TaxonDescriptions
713
//		List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, request, response);
714
//		if (taxonDescriptions != null) {
715
//
716
//			for (TaxonDescription description : taxonDescriptions) {
717
//				derivedUnitFacadeList.addAll( occurrenceService.listDerivedUnitFacades(description, null) );
718
//			}
719
//		}
720
//		// TODO find speciemens in the NameDescriptions ??
721
//
722
//		// TODO also find type specimens
723
//
724
//		mv.addObject(derivedUnitFacadeList);
725
//
726
//		return mv;
727
//	}
728

    
729
    /**
730
     * Get the {@link Media} attached to the {@link Taxon} instance
731
     * identified by the <code>{taxon-uuid}</code>.
732
     *
733
     * Usage &#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-
734
     * uuid}&#x002F;media&#x002F;{mime type
735
     * list}&#x002F;{size}[,[widthOrDuration}][,{height}]&#x002F;
736
     *
737
     * Whereas
738
     * <ul>
739
     * <li><b>{mime type list}</b>: a comma separated list of mime types, in the
740
     * order of preference. The forward slashes contained in the mime types must
741
     * be replaced by a colon. Regular expressions can be used. Each media
742
     * associated with this given taxon is being searched whereas the first
743
     * matching mime type matching a representation always rules.</li>
744
     * <li><b>{size},{widthOrDuration},{height}</b>: <i>not jet implemented</i>
745
     * valid values are an integer or the asterisk '*' as a wildcard</li>
746
     * </ul>
747
     *
748
     * @param request
749
     * @param response
750
     * @return a List of {@link Media} entities which are initialized
751
     *         using the following initialization strategy:
752
     *         {@link #TAXONDESCRIPTION_INIT_STRATEGY}
753
     * @throws IOException
754
     */
755
    @RequestMapping(
756
        value = {"media"},
757
        method = RequestMethod.GET)
758
    public List<Media> doGetMedia(
759
            @PathVariable("uuid") UUID uuid,
760
            @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,
761
            @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,
762
            @RequestParam(value = "widthOrDuration", required = false) Integer  widthOrDuration,
763
            @RequestParam(value = "height", required = false) Integer height,
764
            @RequestParam(value = "size", required = false) Integer size,
765
            HttpServletRequest request, HttpServletResponse response) throws IOException {
766

    
767
        logger.info("doGetMedia()" + request.getServletPath());
768
        Taxon t = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
769
        String path = request.getServletPath();
770
        List<Media> returnMedia = getMediaForTaxon(t, type, mimeTypes, widthOrDuration, height, size);
771
        return returnMedia;
772
    }
773

    
774
    @RequestMapping(
775
            value = {"subtree/media"},
776
            method = RequestMethod.GET)
777
        public List<Media> doGetSubtreeMedia(
778
                @PathVariable("uuid") UUID uuid,
779
                @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,
780
                @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,
781
                @RequestParam(value = "widthOrDuration", required = false) Integer  widthOrDuration,
782
                @RequestParam(value = "height", required = false) Integer height,
783
                @RequestParam(value = "size", required = false) Integer size,
784
                HttpServletRequest request, HttpServletResponse response)throws IOException {
785
        logger.info("doGetMedia()" + request.getServletPath());
786
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, TAXON_WITH_NODES_INIT_STRATEGY);
787
        String requestPath = request.getServletPath();
788
        List<Media> returnMedia = getMediaForTaxon(taxon, type, mimeTypes, widthOrDuration, height, size);
789
        TaxonNode node;
790
        //looking for all medias of genus
791
        if (taxon.getTaxonNodes().size()>0){
792
            Set<TaxonNode> nodes = taxon.getTaxonNodes();
793
            Iterator<TaxonNode> iterator = nodes.iterator();
794
            //TaxonNode holen
795
            node = iterator.next();
796
            //Check if TaxonNode belongs to the current tree
797

    
798
            node = classificationService.loadTaxonNode(node, TAXONNODE_WITHTAXON_INIT_STRATEGY);
799
            Set<TaxonNode> children = node.getChildNodes();
800
            Taxon childTaxon;
801
            for (TaxonNode child : children){
802
                childTaxon = child.getTaxon();
803
                childTaxon = (Taxon)taxonService.load(childTaxon.getUuid(), null);
804
                returnMedia.addAll(getMediaForTaxon(childTaxon, type, mimeTypes, widthOrDuration, height, size));
805
            }
806
        }
807
        return returnMedia;
808
    }
809

    
810

    
811
    private List<Media> getMediaForTaxon(Taxon taxon, Class<? extends MediaRepresentationPart> type, String[] mimeTypes,
812
            Integer widthOrDuration, Integer height, Integer size){
813

    
814
        Pager<TaxonDescription> p =
815
            descriptionService.getTaxonDescriptions(taxon, null, null, null, null, TAXONDESCRIPTION_MEDIA_INIT_STRATEGY);
816

    
817
        // pars the media and quality parameters
818

    
819

    
820
        // collect all media of the given taxon
821
        boolean limitToGalleries = false;
822
        List<Media> taxonMedia = new ArrayList<Media>();
823
        for(TaxonDescription desc : p.getRecords()){
824
            if(!limitToGalleries || desc.isImageGallery()){
825
                for(DescriptionElementBase element : desc.getElements()){
826
                    for(Media media : element.getMedia()){
827
                        taxonMedia.add(media);
828
                    }
829
                }
830
            }
831
        }
832

    
833
        List<Media> returnMedia = MediaUtils.findPreferredMedia(taxonMedia, type,
834
                mimeTypes, null, widthOrDuration, height, size);
835

    
836
        return returnMedia;
837
    }
838

    
839

    
840
// ---------------------- code snippet preserved for possible later use --------------------
841
//	@RequestMapping(
842
//			value = {"/*/portal/taxon/*/descriptions"},
843
//			method = RequestMethod.GET)
844
//	public List<TaxonDescription> doGetDescriptionsbyFeatureTree(HttpServletRequest request, HttpServletResponse response)throws IOException {
845
//		TaxonBase tb = getCdmBase(request, response, null, Taxon.class);
846
//		if(tb instanceof Taxon){
847
//			//T O D O this is a quick and dirty implementation -> generalize
848
//			UUID featureTreeUuid = readValueUuid(request, featureTreeUuidPattern);
849
//
850
//			FeatureTree featureTree = descriptionService.getFeatureTreeByUuid(featureTreeUuid);
851
//			Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions((Taxon)tb, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
852
//			List<TaxonDescription> descriptions = p.getRecords();
853
//
854
//			if(!featureTree.isDescriptionSeparated()){
855
//
856
//				TaxonDescription superDescription = TaxonDescription.NewInstance();
857
//				//put all descriptionElements in superDescription and make it invisible
858
//				for(TaxonDescription description: descriptions){
859
//					for(DescriptionElementBase element: description.getElements()){
860
//						superDescription.addElement(element);
861
//					}
862
//				}
863
//				List<TaxonDescription> separatedDescriptions = new ArrayList<TaxonDescription>(descriptions.size());
864
//				separatedDescriptions.add(superDescription);
865
//				return separatedDescriptions;
866
//			}else{
867
//				return descriptions;
868
//			}
869
//		} else {
870
//			response.sendError(HttpServletResponse.SC_NOT_FOUND, "invalid type; Taxon expected but " + tb.getClass().getSimpleName() + " found.");
871
//			return null;
872
//		}
873
//	}
874

    
875
}
(44-44/48)