Project

General

Profile

Download (24.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.FindByIdentifierDTO;
43
import eu.etaxonomy.cdm.api.service.pager.Pager;
44
import eu.etaxonomy.cdm.api.service.search.LuceneMultiSearchException;
45
import eu.etaxonomy.cdm.api.service.search.SearchResult;
46
import eu.etaxonomy.cdm.model.common.CdmBase;
47
import eu.etaxonomy.cdm.model.common.DefinedTerm;
48
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
49
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
50
import eu.etaxonomy.cdm.model.common.Language;
51
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
52
import eu.etaxonomy.cdm.model.description.Feature;
53
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
54
import eu.etaxonomy.cdm.model.location.NamedArea;
55
import eu.etaxonomy.cdm.model.name.Rank;
56
import eu.etaxonomy.cdm.model.taxon.Classification;
57
import eu.etaxonomy.cdm.model.taxon.Synonym;
58
import eu.etaxonomy.cdm.model.taxon.Taxon;
59
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
60
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
61
import eu.etaxonomy.cdm.persistence.query.MatchMode;
62
import eu.etaxonomy.cdm.persistence.query.OrderHint;
63
import eu.etaxonomy.cdm.remote.controller.util.PagerParameters;
64
import eu.etaxonomy.cdm.remote.editor.DefinedTermBaseList;
65
import eu.etaxonomy.cdm.remote.editor.MatchModePropertyEditor;
66
import eu.etaxonomy.cdm.remote.editor.RankPropertyEditor;
67
import eu.etaxonomy.cdm.remote.editor.TermBaseListPropertyEditor;
68
import eu.etaxonomy.cdm.remote.editor.UuidList;
69
import io.swagger.annotations.Api;
70

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

    
82

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

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

    
97
    @Override
98
    @Autowired
99
    public void setService(ITaxonService service) {
100
        this.service = service;
101
    }
102

    
103
    @Autowired
104
    private IClassificationService classificationService;
105

    
106
    @Autowired
107
    private ITaxonNodeService taxonNodeService;
108

    
109

    
110
    @Autowired
111
    private ITermService termService;
112

    
113
    @InitBinder
114
    @Override
115
    public void initBinder(WebDataBinder binder) {
116
        super.initBinder(binder);
117
        binder.registerCustomEditor(DefinedTermBaseList.class, new TermBaseListPropertyEditor<NamedArea>(termService));
118
        binder.registerCustomEditor(MatchMode.class, new MatchModePropertyEditor());
119
        binder.registerCustomEditor(Rank.class, new RankPropertyEditor());
120

    
121
    }
122

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

    
175

    
176
        logger.info("search : " + requestPathAndQuery(request) );
177

    
178
        Set<NamedArea> areaSet = null;
179
        if(areaList != null){
180
            areaSet = new HashSet<NamedArea>(areaList.size());
181
            areaSet.addAll(areaList);
182
            TaxonListController.includeAllSubAreas(areaSet, termService);
183
        }
184

    
185
        PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
186
        pagerParams.normalizeAndValidate(response);
187

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

    
203
        Classification classification = null;
204
        if(treeUuid != null){
205
            classification = classificationService.find(treeUuid);
206
        }
207

    
208
        return service.findTaxaAndNamesByFullText(searchModes, query,
209
                classification, areaSet, status, null,
210
                false, pagerParams.getPageSize(), pagerParams.getPageIndex(),
211
                OrderHint.NOMENCLATURAL_SORT_ORDER.asList(), getSimpleTaxonInitStrategy());
212
    }
213

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

    
266

    
267
        logger.info("find : " + request.getRequestURI() + "?" + request.getQueryString() );
268

    
269
        PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
270
        pagerParams.normalizeAndValidate(response);
271

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

    
288
        return service.findTaxaAndNames(config);
289

    
290
    }
291

    
292

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

    
321
         logger.info("findByDescriptionElementFullText : " + requestPathAndQuery(request) );
322

    
323
         PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
324
         pagerParams.normalizeAndValidate(response);
325

    
326
         if(highlighting == null){
327
             highlighting = false;
328
         }
329

    
330
         Classification classification = null;
331
        if(treeUuid != null){
332
            classification = classificationService.find(treeUuid);
333
        }
334

    
335
        List<Feature> features = null;
336
        if(featureUuids != null){
337
            features = new ArrayList<Feature>(featureUuids.size());
338
            for(UUID uuid : featureUuids){
339
                features.add((Feature) termService.find(uuid));
340
            }
341
        }
342

    
343
        Pager<SearchResult<TaxonBase>> pager = service.findByDescriptionElementFullText(
344
                clazz, queryString, classification, features, languages, highlighting,
345
                pagerParams.getPageSize(), pagerParams.getPageIndex(),
346
                ((List<OrderHint>)null), getSimpleTaxonInitStrategy());
347
        return pager;
348
    }
349

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

    
364
         logger.info("findByFullText : " + requestPathAndQuery(request)  );
365

    
366
         PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
367
         pagerParams.normalizeAndValidate(response);
368

    
369
         if(highlighting == null){
370
             highlighting = false;
371
         }
372

    
373
         Classification classification = null;
374
        if(treeUuid != null){
375
            classification = classificationService.find(treeUuid);
376
        }
377

    
378
        Pager<SearchResult<TaxonBase>> pager = service.findByFullText(clazz, queryString, classification, languages,
379
                highlighting, pagerParams.getPageSize(), pagerParams.getPageIndex(), ((List<OrderHint>)  null),
380
                initializationStrategy);
381
        return pager;
382
    }
383

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

    
398
         logger.info("findByEverythingFullText : " + requestPathAndQuery(request) );
399

    
400
         PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
401
         pagerParams.normalizeAndValidate(response);
402

    
403
         if(highlighting == null){
404
             highlighting = false;
405
         }
406

    
407
         Classification classification = null;
408
        if(treeUuid != null){
409
            classification = classificationService.find(treeUuid);
410
        }
411

    
412
        Pager<SearchResult<TaxonBase>> pager = service.findByEverythingFullText(
413
                queryString, classification, languages, highlighting,
414
                pagerParams.getPageSize(), pagerParams.getPageIndex(),
415
                ((List<OrderHint>)null), initializationStrategy);
416
        return pager;
417
    }
418

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

    
437
    @RequestMapping(value = "findBestMatchingTaxon", method = RequestMethod.GET)
438
    public TaxonBase doFindBestMatchingTaxon(
439
            @RequestParam(value = "query", required = true) String taxonName,
440
            HttpServletRequest request,
441
            HttpServletResponse response)throws IOException {
442

    
443
        logger.info("doFindBestMatchingTaxon : " + requestPathAndQuery(request) );
444

    
445
        Taxon bestMatchingTaxon =  service.findBestMatchingTaxon(taxonName);
446

    
447
        return bestMatchingTaxon;
448
    }
449

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

    
480
        DefinedTerm definedTerm = null;
481
        if(identifierType != null){
482
            definedTerm = CdmBase.deproxy(termService.find(identifierType), DefinedTerm.class);
483
        }
484

    
485
        TaxonNode subTree;
486
        Classification cl = classificationService.load(subtreeUuid);
487
        if (cl != null){
488
            subTree = cl.getRootNode();
489
        }else{
490
            subTree = taxonNodeService.find(subtreeUuid);
491
        }
492

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

    
495

    
496
        PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber).normalizeAndValidate(response);
497

    
498
        matchMode = matchMode != null ? matchMode : MatchMode.EXACT;
499
        return service.findByIdentifier(type, identifier, definedTerm , subTree, matchMode, includeEntity, pagerParams.getPageSize(), pagerParams.getPageIndex(), initializationStrategy);
500
    }
501

    
502
    @RequestMapping(value = "doFindByNameParts", method = RequestMethod.GET)
503
    public Pager<TaxonBase> doFindByNameParts(
504
            @RequestParam(value = "genusOrUninomial", required = false) String genusOrUninomial,
505
            @RequestParam(value = "infragenericEpithet", required = false) String infragenericEpithet,
506
            @RequestParam(value = "specificEpithet", required = false) String specificEpithet,
507
            @RequestParam(value = "infraspecificEpithet", required = false) String infraspecificEpithet,
508
            @RequestParam(value = "authorship", required = false) String authorship,
509
            @RequestParam(value = "rankUuid", required = false) UUID rankUuid,
510
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
511
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
512
            HttpServletRequest request,
513
            HttpServletResponse response)throws IOException {
514

    
515
        logger.info("doFindByNameParts : " + requestPathAndQuery(request) );
516

    
517
        if (genusOrUninomial == null && infragenericEpithet == null && specificEpithet == null && infraspecificEpithet == null){
518
            response.sendError(404 , "At least 1 name part must be defined " );
519
            return null;
520
        }
521

    
522
        Rank rank = null;
523
        if (rankUuid != null){
524
             rank = findRank(rankUuid);
525
        }
526

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

    
529
        return result;
530
    }
531

    
532

    
533
    private Rank findRank(UUID rankUuid) {
534
        Rank rank = null;
535
        if(rankUuid != null){
536
            DefinedTermBase<?> definedTermBase =  termService.find(rankUuid);
537
            if(definedTermBase instanceof Rank){
538
                rank = (Rank) definedTermBase;
539
            } else {
540
               throw new IllegalArgumentException("DefinedTermBase is not a Rank");
541
            }
542
        }
543
        return rank;
544
    }
545

    
546
}
(55-55/63)