Project

General

Profile

Download (29.7 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2009 EDIT European Distributed Institute of Taxonomy
3
 * http://www.e-taxonomy.eu
4
 *
5
 * The contents of this file are subject to the Mozilla Public License Version
6
 * 1.1 See LICENSE.TXT at the top of this package for the full license terms.
7
 */
8

    
9
package eu.etaxonomy.cdm.remote.controller;
10

    
11
import java.io.IOException;
12
import java.util.ArrayList;
13
import java.util.Arrays;
14
import java.util.Collection;
15
import java.util.EnumSet;
16
import java.util.HashSet;
17
import java.util.List;
18
import java.util.Set;
19
import java.util.UUID;
20

    
21
import javax.servlet.http.HttpServletRequest;
22
import javax.servlet.http.HttpServletResponse;
23

    
24
import org.apache.commons.lang.BooleanUtils;
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

    
33
import eu.etaxonomy.cdm.api.service.IClassificationService;
34
import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
35
import eu.etaxonomy.cdm.api.service.ITaxonService;
36
import eu.etaxonomy.cdm.api.service.ITermService;
37
import eu.etaxonomy.cdm.api.service.TaxaAndNamesSearchMode;
38
import eu.etaxonomy.cdm.api.service.config.FindTaxaAndNamesConfiguratorImpl;
39
import eu.etaxonomy.cdm.api.service.config.IFindTaxaAndNamesConfigurator;
40
import eu.etaxonomy.cdm.api.service.dto.IdentifiedEntityDTO;
41
import eu.etaxonomy.cdm.api.service.dto.MarkedEntityDTO;
42
import eu.etaxonomy.cdm.api.service.pager.Pager;
43
import eu.etaxonomy.cdm.api.service.search.LuceneMultiSearchException;
44
import eu.etaxonomy.cdm.api.service.search.LuceneParseException;
45
import eu.etaxonomy.cdm.api.service.search.SearchResult;
46
import eu.etaxonomy.cdm.model.common.CdmBase;
47
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
48
import eu.etaxonomy.cdm.model.common.Language;
49
import eu.etaxonomy.cdm.model.common.MarkerType;
50
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
51
import eu.etaxonomy.cdm.model.description.Feature;
52
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
53
import eu.etaxonomy.cdm.model.location.NamedArea;
54
import eu.etaxonomy.cdm.model.name.Rank;
55
import eu.etaxonomy.cdm.model.taxon.Classification;
56
import eu.etaxonomy.cdm.model.taxon.Synonym;
57
import eu.etaxonomy.cdm.model.taxon.Taxon;
58
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
59
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
60
import eu.etaxonomy.cdm.model.term.DefinedTerm;
61
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
62
import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
63
import eu.etaxonomy.cdm.persistence.query.MatchMode;
64
import eu.etaxonomy.cdm.persistence.query.NameSearchOrder;
65
import eu.etaxonomy.cdm.persistence.query.OrderHint;
66
import eu.etaxonomy.cdm.persistence.query.TaxonTitleType;
67
import eu.etaxonomy.cdm.remote.controller.util.PagerParameters;
68
import eu.etaxonomy.cdm.remote.editor.DefinedTermBaseList;
69
import eu.etaxonomy.cdm.remote.editor.MatchModePropertyEditor;
70
import eu.etaxonomy.cdm.remote.editor.RankPropertyEditor;
71
import eu.etaxonomy.cdm.remote.editor.TermBaseListPropertyEditor;
72
import eu.etaxonomy.cdm.remote.editor.TermBasePropertyEditor;
73
import eu.etaxonomy.cdm.remote.editor.UuidList;
74
import io.swagger.annotations.Api;
75

    
76
/**
77
 * TODO write controller documentation
78
 *
79
 * @author a.kohlbecker
80
 * @since 20.03.2009
81
 */
82
@Controller
83
@Api("taxon")
84
@RequestMapping(value = {"/taxon"})
85
public class TaxonListController extends AbstractIdentifiableListController<TaxonBase, ITaxonService> {
86

    
87
    private static final List<String> SIMPLE_TAXON_INIT_STRATEGY = DEFAULT_INIT_STRATEGY;
88

    
89
    protected List<String> getSimpleTaxonInitStrategy() {
90
        return SIMPLE_TAXON_INIT_STRATEGY;
91
    }
92

    
93
    public TaxonListController(){
94
        super();
95
        setInitializationStrategy(Arrays.asList(new String[]{
96
                "$",
97
                "name.nomenclaturalSource.citation"
98
                }));
99
    }
100

    
101
    @Override
102
    @Autowired
103
    public void setService(ITaxonService service) {
104
        this.service = service;
105
    }
106

    
107
    @Autowired
108
    private IClassificationService classificationService;
109

    
110
    @Autowired
111
    private ITaxonNodeService taxonNodeService;
112

    
113
    @Autowired
114
    private ITermService termService;
115

    
116
    @InitBinder
117
    @Override
118
    public void initBinder(WebDataBinder binder) {
119
        super.initBinder(binder);
120
        binder.registerCustomEditor(DefinedTermBaseList.class, new TermBaseListPropertyEditor<NamedArea>(termService));
121
        binder.registerCustomEditor(MatchMode.class, new MatchModePropertyEditor());
122
        binder.registerCustomEditor(Rank.class, new RankPropertyEditor());
123
        binder.registerCustomEditor(PresenceAbsenceTerm.class, new TermBasePropertyEditor<PresenceAbsenceTerm>(termService));
124
    }
125

    
126
    /**
127
     * Find Taxa, Synonyms, Common Names by name, either globally or in a specific geographic area.
128
     * <p>
129
     * URI: <b>taxon&#x002F;search</b>
130
     *
131
     * @param query
132
     *            the string to query for. Since the wildcard character '*'
133
     *            internally always is appended to the query string, a search
134
     *            always compares the query string with the beginning of a name.
135
     *            - <i>required parameter</i>
136
     * @param classificationUuid
137
     *            the {@link UUID} of the {@link Classification} to which the
138
     *            search is to be restricted. - <i>optional parameter</i>
139
     * @param areas
140
     *            restrict the search to a set of geographic {@link NamedArea}s.
141
     *            The parameter currently takes a list of TDWG area labels.
142
     *            - <i>optional parameter</i>
143
     * @param pageIndex
144
     *            the number of the page to be returned, the first page has the
145
     *            pageNumber = 1 - <i>optional parameter</i>
146
     * @param pageSize
147
     *            the maximum number of entities returned per page (can be -1
148
     *            to return all entities in a single page) - <i>optional parameter</i>
149
     * @param doTaxa
150
     *            weather to search for instances of {@link Taxon} - <i>optional parameter</i>
151
     * @param doSynonyms
152
     *            weather to search for instances of {@link Synonym} - <i>optional parameter</i>
153
     * @param doTaxaByCommonNames
154
     *            for instances of {@link Taxon} by a common name used - <i>optional parameter</i>
155
     * @return a Pager on a list of {@link IdentifiableEntity}s initialized by
156
     *         the following strategy {@link #SIMPLE_TAXON_INIT_STRATEGY}
157
     * @throws IOException
158
     * @throws LuceneMultiSearchException
159
     * @throws ParseException
160
     */
161
    @RequestMapping(method = RequestMethod.GET, value={"search"})
162
    public Pager<SearchResult<TaxonBase>> doSearch(
163
            @RequestParam(value = "query", required = true) String query,
164
            @RequestParam(value = "tree", required = false) UUID classificationUuid,
165
            @RequestParam(value = "subtree", required = false) UUID subtreeUuid,
166
            @RequestParam(value = "area", required = false) DefinedTermBaseList<NamedArea> areaList,
167
            @RequestParam(value = "status", required = false) PresenceAbsenceTerm[] status,
168
            @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
169
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
170
            @RequestParam(value = "doTaxa", required = false) Boolean doTaxa,
171
            @RequestParam(value = "doSynonyms", required = false) Boolean doSynonyms,
172
            @RequestParam(value = "doMisappliedNames", required = false) Boolean doMisappliedNames,
173
            @RequestParam(value = "doTaxaByCommonNames", required = false) Boolean doTaxaByCommonNames,
174
            HttpServletRequest request,
175
            HttpServletResponse response
176
            ) throws IOException, LuceneParseException, LuceneMultiSearchException {
177

    
178
        boolean includeUnpublished = NO_UNPUBLISHED;
179

    
180

    
181
        logger.info("doSearch() " + requestPathAndQuery(request) );
182

    
183
        Set<NamedArea> areaSet = null;
184
        if(areaList != null){
185
            areaSet = new HashSet<>(areaList.size());
186
            areaSet.addAll(areaList);
187
            TaxonListController.includeAllSubAreas(areaSet, termService);
188
        }
189

    
190
        PagerParameters pagerParams = new PagerParameters(pageSize, pageIndex);
191
        pagerParams.normalizeAndValidate(response);
192

    
193
        // TODO change type of do* parameters  to TaxaAndNamesSearchMode
194
        EnumSet<TaxaAndNamesSearchMode> searchModes = EnumSet.noneOf(TaxaAndNamesSearchMode.class);
195
        if(BooleanUtils.toBoolean(doTaxa)) {
196
            searchModes.add(TaxaAndNamesSearchMode.doTaxa);
197
        }
198
        if(BooleanUtils.toBoolean(doSynonyms)) {
199
            searchModes.add(TaxaAndNamesSearchMode.doSynonyms);
200
        }
201
        if(BooleanUtils.toBoolean(doMisappliedNames)) {
202
            searchModes.add(TaxaAndNamesSearchMode.doMisappliedNames);
203
        }
204
        if(BooleanUtils.toBoolean(doTaxaByCommonNames)) {
205
            searchModes.add(TaxaAndNamesSearchMode.doTaxaByCommonNames);
206
        }
207
        if(includeUnpublished) {
208
            searchModes.add(TaxaAndNamesSearchMode.includeUnpublished);
209
        }
210

    
211
        Classification classification = getClassificationOrError(classificationUuid, classificationService, response);
212
        TaxonNode subtree = getSubtreeOrError(subtreeUuid, taxonNodeService, response);
213

    
214
        Set<PresenceAbsenceTerm> statusSet = null;
215
        if(status != null) {
216
                statusSet = new HashSet<>(Arrays.asList(status));
217
        }
218

    
219
        return service.findTaxaAndNamesByFullText(searchModes, query,
220
                classification, subtree, areaSet, statusSet, null,
221
                false, pagerParams.getPageSize(), pagerParams.getPageIndex(),
222
                OrderHint.NOMENCLATURAL_SORT_ORDER.asList(), getSimpleTaxonInitStrategy());
223
    }
224

    
225
    /**
226
     * Find Taxa, Synonyms, Common Names by name, either globally or in a specific geographic area.
227
     * <p>
228
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;find</b>
229
     *
230
     * @param query
231
     *            the string to query for. Since the wildcard character '*'
232
     *            internally always is appended to the query string, a search
233
     *            always compares the query string with the beginning of a name.
234
     *            - <i>required parameter</i>
235
     * @param treeUuid
236
     *            the {@link UUID} of a {@link Classification} to which the
237
     *            search is to be restricted. - <i>optional parameter</i>
238
     * @param areas
239
     *            restrict the search to a set of geographic {@link NamedArea}s.
240
     *            The parameter currently takes a list of TDWG area labels.
241
     *            - <i>optional parameter</i>
242
     * @param pageIndex
243
     *            the number of the page to be returned, the first page has the
244
     *            pageNumber = 1 - <i>optional parameter</i>
245
     * @param pageSize
246
     *            the maximum number of entities returned per page (can be -1
247
     *            to return all entities in a single page) - <i>optional parameter</i>
248
     * @param doTaxa
249
     *            weather to search for instances of {@link Taxon} - <i>optional parameter</i>
250
     * @param doSynonyms
251
     *            weather to search for instances of {@link Synonym} - <i>optional parameter</i>
252
     * @param doTaxaByCommonNames
253
     *            for instances of {@link Taxon} by a common name used - <i>optional parameter</i>
254
     * @param matchMode
255
     *           valid values are "EXACT", "BEGINNING", "ANYWHERE", "END" (case sensitive !!!)
256
     * @return a Pager on a list of {@link IdentifiableEntity}s initialized by
257
     *         the following strategy {@link #SIMPLE_TAXON_INIT_STRATEGY}
258
     * @throws IOException
259
     */
260
    @RequestMapping(method = RequestMethod.GET, value={"find"})
261
    public Pager<IdentifiableEntity> doFind(
262
            @RequestParam(value = "query", required = true) String query,
263
            @RequestParam(value = "tree", required = false) UUID classificationUuid,
264
            @RequestParam(value = "subtree", required = false) UUID subtreeUuid,
265
            @RequestParam(value = "area", required = false) Set<NamedArea> areas,
266
            @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
267
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
268
            @RequestParam(value = "doTaxa", required = false) Boolean doTaxa,
269
            @RequestParam(value = "doSynonyms", required = false) Boolean doSynonyms,
270
            @RequestParam(value = "doMisappliedNames", required = false) Boolean doMisappliedNames,
271
            @RequestParam(value = "doTaxaByCommonNames", required = false) Boolean doTaxaByCommonNames,
272
            @RequestParam(value = "matchMode", required = false) MatchMode matchMode,
273
            @RequestParam(value = "order", required = false, defaultValue="ALPHA") NameSearchOrder order,
274
            @RequestParam(value = "includeAuthors", required = false) Boolean includeAuthors,
275
            HttpServletRequest request,
276
            HttpServletResponse response
277
            )
278
             throws IOException {
279

    
280
        boolean includeUnpublished = NO_UNPUBLISHED;
281

    
282
        logger.info("doFind() " + requestPathAndQuery(request));
283

    
284
        PagerParameters pagerParams = new PagerParameters(pageSize, pageIndex);
285
        pagerParams.normalizeAndValidate(response);
286

    
287

    
288
        IFindTaxaAndNamesConfigurator config = FindTaxaAndNamesConfiguratorImpl.NewInstance();
289
        config.setIncludeUnpublished(includeUnpublished);
290
        config.setPageNumber(pagerParams.getPageIndex());
291
        config.setPageSize(pagerParams.getPageSize());
292
        config.setTitleSearchString(query);
293
        config.setDoTaxa(doTaxa!= null ? doTaxa : Boolean.FALSE );
294
        config.setDoSynonyms(doSynonyms != null ? doSynonyms : Boolean.FALSE );
295
        config.setDoMisappliedNames(doMisappliedNames != null ? doMisappliedNames : Boolean.FALSE);
296
        config.setDoTaxaByCommonNames(doTaxaByCommonNames != null ? doTaxaByCommonNames : Boolean.FALSE );
297
        config.setMatchMode(matchMode != null ? matchMode : MatchMode.BEGINNING);
298
        config.setTaxonPropertyPath(getSimpleTaxonInitStrategy());
299
        config.setNamedAreas(areas);
300
        config.setDoIncludeAuthors(includeAuthors != null ? includeAuthors : Boolean.FALSE);
301
        config.setOrder(order);
302

    
303
        if(classificationUuid != null){
304
            Classification classification = classificationService.find(classificationUuid);
305
            config.setClassification(classification);
306
        }
307

    
308
        TaxonNode subtree = getSubtreeOrError(subtreeUuid, taxonNodeService, response);
309
        config.setSubtree(subtree);
310

    
311
        return service.findTaxaAndNames(config);
312

    
313
    }
314

    
315

    
316
    /**
317
     * @param clazz
318
     * @param queryString
319
     * @param treeUuid TODO unimplemented in TaxonServiceImpl !!!!
320
     * @param languages
321
     * @param pageIndex
322
     * @param pageSize
323
     * @param request
324
     * @param response
325
     * @return
326
     * @throws IOException
327
     * @throws ParseException
328
     */
329
    @RequestMapping(method = RequestMethod.GET, value={"findByDescriptionElementFullText"})
330
    public Pager<SearchResult<TaxonBase>> doFindByDescriptionElementFullText(
331
            @RequestParam(value = "clazz", required = false) Class<? extends DescriptionElementBase> clazz,
332
            @RequestParam(value = "query", required = true) String queryString,
333
            @RequestParam(value = "tree", required = false) UUID treeUuid,
334
            @RequestParam(value = "subtree", required = false) UUID subtreeUuid,
335
            @RequestParam(value = "features", required = false) UuidList featureUuids,
336
            @RequestParam(value = "languages", required = false) List<Language> languages,
337
            @RequestParam(value = "hl", required = false) Boolean highlighting,
338
            @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
339
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
340
            HttpServletRequest request,
341
            HttpServletResponse response
342
            )
343
             throws IOException, LuceneParseException {
344

    
345
         logger.info("findByDescriptionElementFullText : " + requestPathAndQuery(request) );
346

    
347
         PagerParameters pagerParams = new PagerParameters(pageSize, pageIndex);
348
         pagerParams.normalizeAndValidate(response);
349

    
350
         if(highlighting == null){
351
             highlighting = false;
352
         }
353

    
354
         Classification classification = getClassificationOrError(treeUuid, classificationService, response);
355
         TaxonNode subtree = getSubtreeOrError(subtreeUuid, taxonNodeService, response);
356

    
357
         List<Feature> features = null;
358
         if(featureUuids != null){
359
            features = new ArrayList<>(featureUuids.size());
360
            for(UUID uuid : featureUuids){
361
                //TODO error if null
362
                Feature feature = (Feature) termService.find(uuid);
363
                features.add(feature);
364
            }
365
         }
366

    
367
         Pager<SearchResult<TaxonBase>> pager = service.findByDescriptionElementFullText(
368
                clazz, queryString, classification, subtree, features, languages, highlighting,
369
                pagerParams.getPageSize(), pagerParams.getPageIndex(),
370
                ((List<OrderHint>)null), getSimpleTaxonInitStrategy());
371
         return pager;
372
    }
373

    
374
    @RequestMapping(method = RequestMethod.GET, value={"findByFullText"})
375
    public Pager<SearchResult<TaxonBase>> doFindByFullText(
376
            @RequestParam(value = "clazz", required = false) Class<? extends TaxonBase> clazz,
377
            @RequestParam(value = "query", required = true) String queryString,
378
            @RequestParam(value = "tree", required = false) UUID classificationUuid,
379
            @RequestParam(value = "subtree", required = false) UUID subtreeUuid,
380
            @RequestParam(value = "languages", required = false) List<Language> languages,
381
            @RequestParam(value = "hl", required = false) Boolean highlighting,
382
            @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
383
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
384
            HttpServletRequest request,
385
            HttpServletResponse response
386
            )
387
             throws IOException, LuceneParseException {
388

    
389
        boolean includeUnpublished = NO_UNPUBLISHED;
390

    
391
        logger.info("doFindByFullText() " + requestPathAndQuery(request)  );
392

    
393
        PagerParameters pagerParams = new PagerParameters(pageSize, pageIndex);
394
        pagerParams.normalizeAndValidate(response);
395

    
396
        if(highlighting == null){
397
            highlighting = false;
398
        }
399

    
400
        Classification classification = null;
401
        if(classificationUuid != null){
402
            classification = classificationService.find(classificationUuid);
403
        }
404
        TaxonNode subtree = getSubtreeOrError(subtreeUuid, taxonNodeService, response);
405

    
406
        Pager<SearchResult<TaxonBase>> pager = service.findByFullText(clazz, queryString, classification, subtree,
407
                includeUnpublished,
408
                languages, highlighting, pagerParams.getPageSize(), pagerParams.getPageIndex(), ((List<OrderHint>) null),
409
                initializationStrategy);
410
        return pager;
411
    }
412

    
413
    /**
414
     * @deprecated see {@link ITaxonService#findByEverythingFullText(String, Classification, boolean, List, boolean, Integer, Integer, List, List)}
415
     */
416
    @RequestMapping(method = RequestMethod.GET, value={"findByEverythingFullText"})
417
    @Deprecated
418
    public Pager<SearchResult<TaxonBase>> doFindByEverythingFullText(
419
            @RequestParam(value = "clazz", required = false) Class<? extends TaxonBase> clazz,
420
            @RequestParam(value = "query", required = true) String queryString,
421
            @RequestParam(value = "tree", required = false) UUID treeUuid,
422
            @RequestParam(value = "subtree", required = false) UUID subtreeUuid,
423
            @RequestParam(value = "languages", required = false) List<Language> languages,
424
            @RequestParam(value = "hl", required = false) Boolean highlighting,
425
            @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
426
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
427
            HttpServletRequest request,
428
            HttpServletResponse response
429
            )
430
            throws IOException, LuceneParseException, LuceneMultiSearchException {
431

    
432
         logger.info("findByEverythingFullText : " + requestPathAndQuery(request) );
433

    
434
         boolean includeUnpublished = NO_UNPUBLISHED;
435

    
436
         PagerParameters pagerParams = new PagerParameters(pageSize, pageIndex);
437
         pagerParams.normalizeAndValidate(response);
438

    
439
         if(highlighting == null){
440
             highlighting = false;
441
         }
442

    
443
         Classification classification = null;
444
         if(treeUuid != null){
445
            classification = classificationService.find(treeUuid);
446
         }
447
         TaxonNode subtree = getSubtreeOrError(subtreeUuid, taxonNodeService, response);
448

    
449
         Pager<SearchResult<TaxonBase>> pager = service.findByEverythingFullText(
450
                queryString, classification, subtree, includeUnpublished, languages, highlighting,
451
                pagerParams.getPageSize(), pagerParams.getPageIndex(),
452
                ((List<OrderHint>)null), initializationStrategy);
453
         return pager;
454
    }
455

    
456
    /**
457
     * @param areaSet
458
     */
459
    static public void includeAllSubAreas(Set<NamedArea> areaSet, ITermService termService) {
460
        Collection<NamedArea> tmpAreas = new HashSet<>(areaSet);
461
        // expand all areas to include also the sub areas
462
        Pager<NamedArea> pager = null;
463
        while(true){
464
            pager = termService.getIncludes(tmpAreas, 1000, null, null);
465
            if(pager.getCount() == 0){
466
                break;
467
            }
468
            tmpAreas = pager.getRecords();
469
            tmpAreas.removeAll(areaSet);
470
            areaSet.addAll(tmpAreas);
471
        }
472
    }
473

    
474
    @RequestMapping(value = "findBestMatchingTaxon", method = RequestMethod.GET)
475
    public TaxonBase doFindBestMatchingTaxon(
476
            @RequestParam(value = "query", required = true) String taxonName,
477
            HttpServletRequest request,
478
            HttpServletResponse response)throws IOException {
479

    
480
        logger.info("doFindBestMatchingTaxon : " + requestPathAndQuery(request) );
481

    
482
        Taxon bestMatchingTaxon =  service.findBestMatchingTaxon(taxonName);
483

    
484
        return bestMatchingTaxon;
485
    }
486

    
487
    /**
488
     * list IdentifiableEntity objects by identifiers
489
     *
490
     * @param type
491
     * @param identifierType
492
     * @param identifier
493
     * @param pageIndex
494
     * @param pageSize
495
     * @param matchMode
496
     * @param request
497
     * @param response
498
     * @return
499
     * @see AbstractIdentifiableListController#doFindByIdentifier(Class, String, String, Integer, Integer, MatchMode, Boolean, HttpServletRequest, HttpServletResponse)
500
     * @throws IOException
501
     */
502
    @RequestMapping(method = RequestMethod.GET, value={"findByIdentifier"}, params={"subtree"})
503
    public <T extends TaxonBase>  Pager<IdentifiedEntityDTO<T>> doFindByIdentifier(
504
            @RequestParam(value = "class", required = false) Class<T> type,
505
            @RequestParam(value = "identifierType", required = false) UUID identifierType,
506
            @RequestParam(value = "identifier", required = false) String identifier,
507
            @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
508
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
509
            @RequestParam(value = "matchMode", required = false) MatchMode matchMode,
510
            @RequestParam(value = "includeEntity", required = false, defaultValue="false") Boolean includeEntity,
511
            @RequestParam(value = "subtree", required = true) UUID subtreeUuid,
512
            HttpServletRequest request,
513
            HttpServletResponse response
514
            )
515
             throws IOException {
516

    
517
        DefinedTerm definedTerm = null;
518
        if(identifierType != null){
519
            definedTerm = CdmBase.deproxy(termService.find(identifierType), DefinedTerm.class);
520
        }
521

    
522
        TaxonNode subTree;
523
        Classification cl = classificationService.load(subtreeUuid);
524
        if (cl != null){
525
            subTree = cl.getRootNode();
526
        }else{
527
            subTree = taxonNodeService.find(subtreeUuid);
528
        }
529

    
530
        logger.info("doFindByIdentifier [subtreeUuid]  : " + request.getRequestURI() + "?" + request.getQueryString() );
531

    
532

    
533
        PagerParameters pagerParams = new PagerParameters(pageSize, pageIndex).normalizeAndValidate(response);
534

    
535
        matchMode = matchMode != null ? matchMode : MatchMode.EXACT;
536
        return service.findByIdentifier(type, identifier, definedTerm , subTree, matchMode, includeEntity, pagerParams.getPageSize(), pagerParams.getPageIndex(), initializationStrategy);
537
    }
538

    
539
    /**
540
     * List taxa by markers using a subtree filter
541
     *
542
     * @param type
543
     * @param markerType
544
     * @param value
545
     * @param pageIndex
546
     * @param pageSize
547
     * @param request
548
     * @param response
549
     * @return
550
     * @see AbstractIdentifiableListController#doFindByMarker(Class, UUID, Boolean, Integer, Integer, Boolean, HttpServletRequest, HttpServletResponse)
551
     * @see TaxonListController#doFindByIdentifier(Class, UUID, String, Integer, Integer, MatchMode, Boolean, UUID, HttpServletRequest, HttpServletResponse)
552
     * @see AbstractIdentifiableListController#doFindByIdentifier(Class, String, String, Integer, Integer, MatchMode, Boolean, HttpServletRequest, HttpServletResponse)
553
     * @throws IOException
554
     */
555
    @RequestMapping(method = RequestMethod.GET, value={"findByMarker"}, params={"subtree"})
556
    public <T extends TaxonBase>  Pager<MarkedEntityDTO<T>> doFindByMarker(
557
            @RequestParam(value = "class", required = false) Class<T> type,
558
            @RequestParam(value = "markerType", required = true) UUID markerTypeUuid,
559
            @RequestParam(value = "value", required = false) Boolean value,
560
            @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
561
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
562
            @RequestParam(value = "includeEntity", required = false, defaultValue="false") Boolean includeEntity,
563
            @RequestParam(value = "subtree", required = true) UUID subtreeUuid,
564
            @RequestParam(value = "titleType", required = false) TaxonTitleType titleType,
565
            HttpServletRequest request,
566
            HttpServletResponse response
567
            )
568
            throws IOException {
569

    
570
        MarkerType markerType = null;
571
        if(markerTypeUuid != null){
572
            DefinedTermBase<?> term = CdmBase.deproxy(termService.find(markerTypeUuid), MarkerType.class);
573
            if (term != null && term.isInstanceOf(MarkerType.class)){
574
                markerType = CdmBase.deproxy(term, MarkerType.class);
575
            }
576
        }
577

    
578
        TaxonNode subTree;
579
        Classification cl = classificationService.load(subtreeUuid);
580
        if (cl != null){
581
            subTree = cl.getRootNode();
582
        }else{
583
            subTree = taxonNodeService.find(subtreeUuid);
584
        }
585

    
586
        if (logger.isDebugEnabled()){logger.info("doFindByMarker [subtreeUuid]  : " + request.getRequestURI() + "?" + request.getQueryString() );}
587

    
588
        PagerParameters pagerParams = new PagerParameters(pageSize, pageIndex).normalizeAndValidate(response);
589
        return service.findByMarker(type, markerType, value, subTree, includeEntity, titleType, pagerParams.getPageSize(), pagerParams.getPageIndex(), initializationStrategy);
590
    }
591

    
592
    @RequestMapping(value = "doFindByNameParts", method = RequestMethod.GET)
593
    public Pager<TaxonBase> doFindByNameParts(
594
            @RequestParam(value = "genusOrUninomial", required = false) String genusOrUninomial,
595
            @RequestParam(value = "infragenericEpithet", required = false) String infragenericEpithet,
596
            @RequestParam(value = "specificEpithet", required = false) String specificEpithet,
597
            @RequestParam(value = "infraspecificEpithet", required = false) String infraspecificEpithet,
598
            @RequestParam(value = "authorshipCache", required = false) String authorshipCache,
599
            @RequestParam(value = "rankUuid", required = false) UUID rankUuid,
600
            @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
601
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
602
            HttpServletRequest request,
603
            HttpServletResponse response)throws IOException {
604

    
605
        logger.info("doFindByNameParts : " + requestPathAndQuery(request) );
606

    
607
        if (genusOrUninomial == null && infragenericEpithet == null && specificEpithet == null && infraspecificEpithet == null){
608
            response.sendError(404 , "At least 1 name part must be defined " );
609
            return null;
610
        }
611

    
612
        Rank rank = null;
613
        if (rankUuid != null){
614
             rank = findRank(rankUuid);
615
        }
616

    
617
        Pager<TaxonBase> result = service.findTaxaByName(null, genusOrUninomial, infragenericEpithet, specificEpithet, infraspecificEpithet,
618
                authorshipCache, rank, pageSize, pageIndex, initializationStrategy);
619

    
620
        return result;
621
    }
622

    
623
    @Override
624
    protected Pager<TaxonBase> pageByRestrictions(Class<TaxonBase> type, List<String> initStrategy, OrderHintPreset orderBy,
625
            PagerParameters pagerParameters, ArrayList<Restriction<?>> restrictions) {
626
        return service.page(type, restrictions, pagerParameters.getPageSize(), pagerParameters.getPageIndex(), orderBy.orderHints(), initStrategy, false);
627
    }
628

    
629
    private Rank findRank(UUID rankUuid) {
630
        Rank rank = null;
631
        if(rankUuid != null){
632
            DefinedTermBase<?> definedTermBase =  termService.find(rankUuid);
633
            if(definedTermBase instanceof Rank){
634
                rank = (Rank) definedTermBase;
635
            } else {
636
               throw new IllegalArgumentException("DefinedTermBase is not a Rank");
637
            }
638
        }
639
        return rank;
640
    }
641

    
642
}
(59-59/76)