Project

General

Profile

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

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

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

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

    
25
import org.apache.commons.lang.BooleanUtils;
26
import org.apache.lucene.queryparser.classic.ParseException;
27
import org.springframework.beans.factory.annotation.Autowired;
28
import org.springframework.stereotype.Controller;
29
import org.springframework.web.bind.WebDataBinder;
30
import org.springframework.web.bind.annotation.InitBinder;
31
import org.springframework.web.bind.annotation.RequestMapping;
32
import org.springframework.web.bind.annotation.RequestMethod;
33
import org.springframework.web.bind.annotation.RequestParam;
34

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

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

    
85

    
86
    private static final List<String> SIMPLE_TAXON_INIT_STRATEGY = DEFAULT_INIT_STRATEGY;
87
    protected List<String> getSimpleTaxonInitStrategy() {
88
        // TODO Auto-generated method stub
89
        return SIMPLE_TAXON_INIT_STRATEGY;
90
    }
91

    
92
    /**
93
     *
94
     */
95
    public TaxonListController(){
96
        super();
97
        setInitializationStrategy(Arrays.asList(new String[]{"$","name.nomenclaturalReference"}));
98
    }
99

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

    
106
    @Autowired
107
    private IClassificationService classificationService;
108

    
109
    @Autowired
110
    private ITaxonNodeService taxonNodeService;
111

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

    
179

    
180
        logger.info("search : " + requestPathAndQuery(request) );
181

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

    
189
        PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
190
        pagerParams.normalizeAndValidate(response);
191

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

    
207
        Classification classification = classificationService.load(classificationUuid);
208

    
209
        Set<PresenceAbsenceTerm> statusSet = null;
210
        if(status != null) {
211
                statusSet = new HashSet<PresenceAbsenceTerm>(Arrays.asList(status));
212
        }
213

    
214
        return service.findTaxaAndNamesByFullText(searchModes, query,
215
                classification, areaSet, statusSet, null,
216
                false, pagerParams.getPageSize(), pagerParams.getPageIndex(),
217
                OrderHint.NOMENCLATURAL_SORT_ORDER.asList(), getSimpleTaxonInitStrategy());
218
    }
219

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

    
272

    
273
        logger.info("find : " + request.getRequestURI() + "?" + request.getQueryString() );
274

    
275
        PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
276
        pagerParams.normalizeAndValidate(response);
277

    
278
        IFindTaxaAndNamesConfigurator config = new FindTaxaAndNamesConfiguratorImpl();
279
        config.setPageNumber(pagerParams.getPageIndex());
280
        config.setPageSize(pagerParams.getPageSize());
281
        config.setTitleSearchString(query);
282
        config.setDoTaxa(doTaxa!= null ? doTaxa : Boolean.FALSE );
283
        config.setDoSynonyms(doSynonyms != null ? doSynonyms : Boolean.FALSE );
284
        config.setDoMisappliedNames(doMisappliedNames != null ? doMisappliedNames : Boolean.FALSE);
285
        config.setDoTaxaByCommonNames(doTaxaByCommonNames != null ? doTaxaByCommonNames : Boolean.FALSE );
286
        config.setMatchMode(matchMode != null ? matchMode : MatchMode.BEGINNING);
287
        config.setTaxonPropertyPath(getSimpleTaxonInitStrategy());
288
        config.setNamedAreas(areas);
289
        if(treeUuid != null){
290
            Classification classification = classificationService.find(treeUuid);
291
            config.setClassification(classification);
292
        }
293

    
294
        return service.findTaxaAndNames(config);
295

    
296
    }
297

    
298

    
299
    /**
300
     * @param clazz
301
     * @param queryString
302
     * @param treeUuid TODO unimplemented in TaxonServiceImpl !!!!
303
     * @param languages
304
     * @param pageNumber
305
     * @param pageSize
306
     * @param request
307
     * @param response
308
     * @return
309
     * @throws IOException
310
     * @throws ParseException
311
     */
312
    @RequestMapping(method = RequestMethod.GET, value={"findByDescriptionElementFullText"})
313
    public Pager<SearchResult<TaxonBase>> dofindByDescriptionElementFullText(
314
            @RequestParam(value = "clazz", required = false) Class<? extends DescriptionElementBase> clazz,
315
            @RequestParam(value = "query", required = true) String queryString,
316
            @RequestParam(value = "tree", required = false) UUID treeUuid,
317
            @RequestParam(value = "features", required = false) UuidList featureUuids,
318
            @RequestParam(value = "languages", required = false) List<Language> languages,
319
            @RequestParam(value = "hl", required = false) Boolean highlighting,
320
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
321
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
322
            HttpServletRequest request,
323
            HttpServletResponse response
324
            )
325
             throws IOException, ParseException {
326

    
327
         logger.info("findByDescriptionElementFullText : " + requestPathAndQuery(request) );
328

    
329
         PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
330
         pagerParams.normalizeAndValidate(response);
331

    
332
         if(highlighting == null){
333
             highlighting = false;
334
         }
335

    
336
         Classification classification = null;
337
        if(treeUuid != null){
338
            classification = classificationService.find(treeUuid);
339
        }
340

    
341
        List<Feature> features = null;
342
        if(featureUuids != null){
343
            features = new ArrayList<Feature>(featureUuids.size());
344
            for(UUID uuid : featureUuids){
345
                features.add((Feature) termService.find(uuid));
346
            }
347
        }
348

    
349
        Pager<SearchResult<TaxonBase>> pager = service.findByDescriptionElementFullText(
350
                clazz, queryString, classification, features, languages, highlighting,
351
                pagerParams.getPageSize(), pagerParams.getPageIndex(),
352
                ((List<OrderHint>)null), getSimpleTaxonInitStrategy());
353
        return pager;
354
    }
355

    
356
    @RequestMapping(method = RequestMethod.GET, value={"findByFullText"})
357
    public Pager<SearchResult<TaxonBase>> dofindByFullText(
358
            @RequestParam(value = "clazz", required = false) Class<? extends TaxonBase> clazz,
359
            @RequestParam(value = "query", required = true) String queryString,
360
            @RequestParam(value = "tree", required = false) UUID treeUuid,
361
            @RequestParam(value = "languages", required = false) List<Language> languages,
362
            @RequestParam(value = "hl", required = false) Boolean highlighting,
363
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
364
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
365
            HttpServletRequest request,
366
            HttpServletResponse response
367
            )
368
             throws IOException, ParseException {
369

    
370
         logger.info("findByFullText : " + requestPathAndQuery(request)  );
371

    
372
         PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
373
         pagerParams.normalizeAndValidate(response);
374

    
375
         if(highlighting == null){
376
             highlighting = false;
377
         }
378

    
379
         Classification classification = null;
380
        if(treeUuid != null){
381
            classification = classificationService.find(treeUuid);
382
        }
383

    
384
        Pager<SearchResult<TaxonBase>> pager = service.findByFullText(clazz, queryString, classification, languages,
385
                highlighting, pagerParams.getPageSize(), pagerParams.getPageIndex(), ((List<OrderHint>)  null),
386
                initializationStrategy);
387
        return pager;
388
    }
389

    
390
    @RequestMapping(method = RequestMethod.GET, value={"findByEverythingFullText"})
391
    public Pager<SearchResult<TaxonBase>> dofindByEverythingFullText(
392
            @RequestParam(value = "clazz", required = false) Class<? extends TaxonBase> clazz,
393
            @RequestParam(value = "query", required = true) String queryString,
394
            @RequestParam(value = "tree", required = false) UUID treeUuid,
395
            @RequestParam(value = "languages", required = false) List<Language> languages,
396
            @RequestParam(value = "hl", required = false) Boolean highlighting,
397
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
398
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
399
            HttpServletRequest request,
400
            HttpServletResponse response
401
            )
402
             throws IOException, ParseException, LuceneMultiSearchException {
403

    
404
         logger.info("findByEverythingFullText : " + requestPathAndQuery(request) );
405

    
406
         PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
407
         pagerParams.normalizeAndValidate(response);
408

    
409
         if(highlighting == null){
410
             highlighting = false;
411
         }
412

    
413
         Classification classification = null;
414
        if(treeUuid != null){
415
            classification = classificationService.find(treeUuid);
416
        }
417

    
418
        Pager<SearchResult<TaxonBase>> pager = service.findByEverythingFullText(
419
                queryString, classification, languages, highlighting,
420
                pagerParams.getPageSize(), pagerParams.getPageIndex(),
421
                ((List<OrderHint>)null), initializationStrategy);
422
        return pager;
423
    }
424

    
425
    /**
426
     * @param areaSet
427
     */
428
    static public void includeAllSubAreas(Set<NamedArea> areaSet, ITermService termService) {
429
        Collection<NamedArea> tmpAreas = new HashSet<NamedArea>(areaSet);
430
        // expand all areas to include also the sub areas
431
        Pager<NamedArea> pager = null;
432
        while(true){
433
            pager = termService.getIncludes(tmpAreas, 1000, null, null);
434
            if(pager.getCount() == 0){
435
                break;
436
            }
437
            tmpAreas = pager.getRecords();
438
            tmpAreas.removeAll(areaSet);
439
            areaSet.addAll(tmpAreas);
440
        }
441
    }
442

    
443
    @RequestMapping(value = "findBestMatchingTaxon", method = RequestMethod.GET)
444
    public TaxonBase doFindBestMatchingTaxon(
445
            @RequestParam(value = "query", required = true) String taxonName,
446
            HttpServletRequest request,
447
            HttpServletResponse response)throws IOException {
448

    
449
        logger.info("doFindBestMatchingTaxon : " + requestPathAndQuery(request) );
450

    
451
        Taxon bestMatchingTaxon =  service.findBestMatchingTaxon(taxonName);
452

    
453
        return bestMatchingTaxon;
454
    }
455

    
456
    /**
457
     * list IdentifiableEntity objects by identifiers
458
     *
459
     * @param type
460
     * @param identifierType
461
     * @param identifier
462
     * @param pageNumber
463
     * @param pageSize
464
     * @param matchMode
465
     * @param request
466
     * @param response
467
     * @return
468
     * @see IdentifiableListController#doFindByIdentifier(Class, String, String, Integer, Integer, MatchMode, Boolean, HttpServletRequest, HttpServletResponse)
469
     * @throws IOException
470
     */
471
    @RequestMapping(method = RequestMethod.GET, value={"findByIdentifier"}, params={"subtree"})
472
    public <T extends TaxonBase>  Pager<IdentifiedEntityDTO<T>> doFindByIdentifier(
473
            @RequestParam(value = "class", required = false) Class<T> type,
474
            @RequestParam(value = "identifierType", required = false) UUID identifierType,
475
            @RequestParam(value = "identifier", required = false) String identifier,
476
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
477
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
478
            @RequestParam(value = "matchMode", required = false) MatchMode matchMode,
479
            @RequestParam(value = "includeEntity", required = false, defaultValue="false") Boolean includeEntity,
480
            @RequestParam(value = "subtree", required = true) UUID subtreeUuid,
481
            HttpServletRequest request,
482
            HttpServletResponse response
483
            )
484
             throws IOException {
485

    
486
        DefinedTerm definedTerm = null;
487
        if(identifierType != null){
488
            definedTerm = CdmBase.deproxy(termService.find(identifierType), DefinedTerm.class);
489
        }
490

    
491
        TaxonNode subTree;
492
        Classification cl = classificationService.load(subtreeUuid);
493
        if (cl != null){
494
            subTree = cl.getRootNode();
495
        }else{
496
            subTree = taxonNodeService.find(subtreeUuid);
497
        }
498

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

    
501

    
502
        PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber).normalizeAndValidate(response);
503

    
504
        matchMode = matchMode != null ? matchMode : MatchMode.EXACT;
505
        return service.findByIdentifier(type, identifier, definedTerm , subTree, matchMode, includeEntity, pagerParams.getPageSize(), pagerParams.getPageIndex(), initializationStrategy);
506
    }
507

    
508
    /**
509
     * List taxa by markers using a subtree filter
510
     *
511
     * @param type
512
     * @param markerType
513
     * @param value
514
     * @param pageNumber
515
     * @param pageSize
516
     * @param request
517
     * @param response
518
     * @return
519
     * @see IdentifiableListController#doFindByMarker(Class, UUID, Boolean, Integer, Integer, Boolean, HttpServletRequest, HttpServletResponse)
520
     * @see TaxonListController#doFindByIdentifier(Class, UUID, String, Integer, Integer, MatchMode, Boolean, UUID, HttpServletRequest, HttpServletResponse)
521
     * @see IdentifiableListController#doFindByIdentifier(Class, String, String, Integer, Integer, MatchMode, Boolean, HttpServletRequest, HttpServletResponse)
522
     * @throws IOException
523
     */
524
    @RequestMapping(method = RequestMethod.GET, value={"findByMarker"}, params={"subtree"})
525
    public <T extends TaxonBase>  Pager<MarkedEntityDTO<T>> doFindByMarker(
526
            @RequestParam(value = "class", required = false) Class<T> type,
527
            @RequestParam(value = "markerType", required = true) UUID markerTypeUuid,
528
            @RequestParam(value = "value", required = false) Boolean value,
529
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
530
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
531
            @RequestParam(value = "includeEntity", required = false, defaultValue="false") Boolean includeEntity,
532
            @RequestParam(value = "subtree", required = true) UUID subtreeUuid,
533
            HttpServletRequest request,
534
            HttpServletResponse response
535
            )
536
            throws IOException {
537

    
538
        MarkerType markerType = null;
539
        if(markerTypeUuid != null){
540
            DefinedTermBase<?> term = CdmBase.deproxy(termService.find(markerTypeUuid), MarkerType.class);
541
            if (term != null && term.isInstanceOf(MarkerType.class)){
542
                markerType = CdmBase.deproxy(term, MarkerType.class);
543
            }
544
        }
545

    
546
        TaxonNode subTree;
547
        Classification cl = classificationService.load(subtreeUuid);
548
        if (cl != null){
549
            subTree = cl.getRootNode();
550
        }else{
551
            subTree = taxonNodeService.find(subtreeUuid);
552
        }
553

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

    
556
        PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber).normalizeAndValidate(response);
557
        includeEntity  = true;
558
        return service.findByMarker(type, markerType, value, subTree, includeEntity, pagerParams.getPageSize(), pagerParams.getPageIndex(), initializationStrategy);
559
    }
560

    
561
    @RequestMapping(value = "doFindByNameParts", method = RequestMethod.GET)
562
    public Pager<TaxonBase> doFindByNameParts(
563
            @RequestParam(value = "genusOrUninomial", required = false) String genusOrUninomial,
564
            @RequestParam(value = "infragenericEpithet", required = false) String infragenericEpithet,
565
            @RequestParam(value = "specificEpithet", required = false) String specificEpithet,
566
            @RequestParam(value = "infraspecificEpithet", required = false) String infraspecificEpithet,
567
            @RequestParam(value = "authorship", required = false) String authorship,
568
            @RequestParam(value = "rankUuid", required = false) UUID rankUuid,
569
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
570
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
571
            HttpServletRequest request,
572
            HttpServletResponse response)throws IOException {
573

    
574
        logger.info("doFindByNameParts : " + requestPathAndQuery(request) );
575

    
576
        if (genusOrUninomial == null && infragenericEpithet == null && specificEpithet == null && infraspecificEpithet == null){
577
            response.sendError(404 , "At least 1 name part must be defined " );
578
            return null;
579
        }
580

    
581
        Rank rank = null;
582
        if (rankUuid != null){
583
             rank = findRank(rankUuid);
584
        }
585

    
586
        Pager<TaxonBase> result = service.findTaxaByName(null, genusOrUninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, authorship, rank, pageSize, pageNumber);
587

    
588
        return result;
589
    }
590

    
591

    
592
    private Rank findRank(UUID rankUuid) {
593
        Rank rank = null;
594
        if(rankUuid != null){
595
            DefinedTermBase<?> definedTermBase =  termService.find(rankUuid);
596
            if(definedTermBase instanceof Rank){
597
                rank = (Rank) definedTermBase;
598
            } else {
599
               throw new IllegalArgumentException("DefinedTermBase is not a Rank");
600
            }
601
        }
602
        return rank;
603
    }
604

    
605
}
(55-55/63)