3 * Copyright (C) 2009 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.ext
.ipni
;
12 import java
.io
.BufferedReader
;
13 import java
.io
.IOException
;
14 import java
.io
.InputStream
;
15 import java
.io
.InputStreamReader
;
16 import java
.net
.HttpURLConnection
;
17 import java
.net
.MalformedURLException
;
19 import java
.net
.URISyntaxException
;
21 import java
.text
.ParseException
;
22 import java
.util
.ArrayList
;
23 import java
.util
.HashMap
;
24 import java
.util
.List
;
27 import org
.apache
.commons
.lang
.StringUtils
;
28 import org
.apache
.http
.HttpResponse
;
29 import org
.apache
.log4j
.Logger
;
30 import org
.springframework
.stereotype
.Component
;
32 import eu
.etaxonomy
.cdm
.api
.application
.ICdmApplicationConfiguration
;
33 import eu
.etaxonomy
.cdm
.api
.facade
.DerivedUnitFacade
;
34 import eu
.etaxonomy
.cdm
.api
.facade
.DerivedUnitFacade
.DerivedUnitType
;
35 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
36 import eu
.etaxonomy
.cdm
.common
.UriUtils
;
37 import eu
.etaxonomy
.cdm
.model
.agent
.Person
;
38 import eu
.etaxonomy
.cdm
.model
.agent
.Team
;
39 import eu
.etaxonomy
.cdm
.model
.common
.Annotation
;
40 import eu
.etaxonomy
.cdm
.model
.common
.AnnotationType
;
41 import eu
.etaxonomy
.cdm
.model
.common
.Extension
;
42 import eu
.etaxonomy
.cdm
.model
.common
.ExtensionType
;
43 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
44 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
45 import eu
.etaxonomy
.cdm
.model
.common
.OriginalSourceType
;
46 import eu
.etaxonomy
.cdm
.model
.common
.TimePeriod
;
47 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
48 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalCode
;
49 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
50 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
51 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
52 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
53 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceFactory
;
54 import eu
.etaxonomy
.cdm
.strategy
.exceptions
.UnknownCdmTypeException
;
59 * @created Aug 16, 2010
62 * TODO the whole ipni service should be refactored to use UriUtils. I did this for the queryService method only because we ran into timeout
63 * problems in tests. UriUtils handles these problems already.
67 public class IpniService
implements IIpniService
{
68 private static final String EAST_OR_WEST
= "East or west";
70 private static final String NORTH_OR_SOUTH
= "North or south";
72 private static final String LATITUDE_SECONDS
= "Latitude seconds";
74 private static final String LATITUDE_MINUTES
= "Latitude minutes";
76 private static final String LATITUDE_DEGREES
= "Latitude degrees";
78 private static final String COLLECTION_DATE_AS_TEXT
= "Collection date as text";
80 private static final String COLLECTION_DAY1
= "Collection day1";
82 private static final String COLLECTION_MONTH1
= "Collection month1";
84 private static final String COLLECTION_YEAR1
= "Collection year1";
86 private static final String COLLECTION_DAY2
= "Collection day2";
88 private static final String COLLECTION_MONTH2
= "Collection month2";
90 private static final String COLLECTION_YEAR2
= "Collection year2";
92 private static final String COLLECTION_NUMBER
= "Collection number";
94 private static final String COLLECTOR_TEAM_AS_TEXT
= "Collector team as text";
96 private static final String LOCALITY
= "Locality";
98 private static final String TYPE_REMARKS
= "Type remarks";
100 private static final Logger logger
= Logger
.getLogger(IpniService
.class);
103 public static String ID
= "Id";
104 public static String VERSION
= "Version";
105 public static final String REMARKS
= "Remarks";
108 public static final String FULL_NAME_WITHOUT_FAMILY_AND_AUTHORS
= "Full name without family and authors";
109 public static final String AUTHORS
= "Authors";
110 public static final String FAMILY
= "Family";
111 public static final String GENUS
= "Genus";
112 public static final String INFRA_GENUS
= "Infra genus";
113 public static final String SPECIES
= "Species";
114 public static final String INFRA_SPECIFIC
= "Infra species";
115 public static final String RANK
= "Rank";
116 public static final String BASIONYM_AUTHOR
= "Basionym author";
117 public static final String PUBLISHING_AUTHOR
= "Publishing author";
118 public static final String PUBLICATION
= "Publication";
119 public static final String PUBLICATION_YEAR_FULL
= "Publication year full";
120 public static final String NAME_STATUS
= "Name status";
121 public static final String BASIONYM
= "Basionym";
122 public static final String REPLACED_SYNONYM
= "Replaced synonym";
127 public static final String STANDARD_FORM
= "Standard Form";
129 public static final String DEFAULT_AUTHOR_FORENAME
= "Default author forename";
130 public static final String DEFAULT_AUTHOR_SURNAME
= "Default author surname";
131 public static final String TAXON_GROUPS
= "Taxon groups";
132 public static final String DATES
= "Dates";
133 public static final String ALTERNATIVE_NAMES
= "Alternative names";
135 public static final String DEFAULT_AUTHOR_NAME
= "Default author name";
137 public static final String NAME_NOTES
= "Name notes";
138 public static final String NAME_SOURCE
= "Name source";
139 public static final String DATE_TYPE_CODE
= "Date type code";
140 public static final String DATE_TYPE_STRING
= "Date type string";
142 public static final String ALTERNATIVE_ABBREVIATIONS
= "Alternative abbreviations";
143 public static final String EXAMPLE_OF_NAME_PUBLISHED
= "Example of name published";
148 public static final String ABBREVIATION
= "Abbreviation";
149 public static final String TITLE
= "Title";
150 public static final String BPH_NUMBER
= "BPH number";
151 public static final String ISBN
= "ISBN";
152 public static final String ISSN
= "ISSN";
153 public static final String AUTHORS_ROLE
= "Authors role";
154 public static final String EDITION
= "Edition";
155 public static final String DATE
= "Date";
156 public static final String IN_PUBLICATION_FACADE
= "In publication facade";
157 public static final String LC_NUMBER
= "LC number";
158 public static final String PLACE
= "Place";
159 public static final String PUBLICATION_AUTHOR_TEAM
= "Publication author team";
160 public static final String PRECEDED_BY
= "Preceded";
161 public static final String TL2_AUTHOR
= "TL2 author";
162 public static final String TL2_NUMBER
= "TL2 number";
163 public static final String TDWG_ABBREVIATION
= "TDWG abbreviation";
165 private enum ServiceType
{
171 public enum IpniRank
{
173 FAMILIAL ("Familial"),
174 INFRA_FAMILIAL ("Infrafamilial"),
176 INFRA_GENERIC("Infrageneric"),
177 SPECIFIC ("Specific"),
178 INFRA_SPECIFIC("InfraSpecific");
181 IpniRank(String strRank
){
182 this.strRank
= strRank
;
185 public static IpniRank
valueOf(Rank rank
){
188 }else if (rank
.isInfraSpecific()){
189 return INFRA_SPECIFIC
;
190 }else if (rank
.isSpecies()){
192 }else if (rank
.isInfraGeneric()){
193 return INFRA_GENERIC
;
194 }else if (rank
.isGenus()){
196 }else if (rank
.isLower(Rank
.FAMILY())){
197 return INFRA_FAMILIAL
;
198 }else if (rank
.isHigher(Rank
.SUBFAMILY())){
201 logger
.warn("Rank could not be transformed to ipni rank. Use ALL instead");
208 // private URL serviceUrl;
210 // ******************************** CONSTRUCTOR **************************************
212 // ****************************** METHODS ****************************************************/
216 * @see eu.etaxonomy.cdm.ext.ipni.IIpniService#getAuthors(java.lang.String, java.lang.String, java.lang.String, java.lang.String, eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration, eu.etaxonomy.cdm.ext.ipni.IpniServiceAuthorConfigurator)
218 public List
<Person
> getAuthors(String abbreviation
, String surname
, String forename
, String isoCountry
, ICdmApplicationConfiguration services
, IpniServiceAuthorConfigurator config
){
221 config
= new IpniServiceAuthorConfigurator();
225 abbreviation
= normalizeParameter(abbreviation
);
226 surname
= normalizeParameter(surname
);
227 isoCountry
= normalizeParameter(isoCountry
);
228 forename
= normalizeParameter(forename
);
230 DelimitedFormat format
= config
.getFormat();
232 String request
= "find_abbreviation=" + abbreviation
+
233 "&find_surname=" + surname
+
234 "&find_isoCountry=" + isoCountry
+
235 "&find_forename=" + forename
+
236 "&output_format=" + format
.parameter
;
238 return (List
)queryService(request
, services
, getServiceUrl(IIpniService
.AUTHOR_SERVICE_URL
), config
, ServiceType
.AUTHOR
);
243 * FIXME rewrote this method to rely on {@link UriUtils}. The whole class should be adjusted to reflect this change.
244 * Also see comments in the class' documentation block.
249 private List
<?
extends IdentifiableEntity
> queryService(String request
, ICdmApplicationConfiguration services
, URL serviceUrl
, IIpniServiceConfigurator config
, ServiceType serviceType
){
251 throw new NullPointerException("Ipni service configurator should not be null");
255 // create the request url
256 URL newUrl
= new URL(serviceUrl
.getProtocol(),
257 serviceUrl
.getHost(),
258 serviceUrl
.getPort(),
263 URI newUri
= newUrl
.toURI();
265 logger
.info("Firing request for URI: " + newUri
);
267 HttpResponse response
= UriUtils
.getResponse(newUri
, null);
269 int responseCode
= response
.getStatusLine().getStatusCode();
271 // get the content at the resource
272 InputStream content
= response
.getEntity().getContent();
274 List
<?
extends IdentifiableEntity
> result
;
275 if (serviceType
.equals(ServiceType
.AUTHOR
)){
276 result
= buildAuthorList(content
, services
, config
);
277 }else if (serviceType
.equals(ServiceType
.NAME
)){
278 result
= buildNameList(content
, services
, config
);
280 result
= buildPublicationList(content
, services
, config
);
282 if(responseCode
== HttpURLConnection
.HTTP_OK
){
285 //TODO error handling
286 logger
.error("No Http_OK");
289 } catch (IOException e
) {
290 logger
.error("No content for request: " + request
);
291 } catch (URISyntaxException e
) {
292 logger
.error("Given URL could not be transformed into URI", e
);
299 private List
<Reference
> buildPublicationList( InputStream content
, ICdmApplicationConfiguration services
, IIpniServiceConfigurator iConfig
) throws IOException
{
300 IpniServicePublicationConfigurator config
= (IpniServicePublicationConfigurator
)iConfig
;
302 List
<Reference
> result
= new ArrayList
<Reference
>();
303 BufferedReader reader
= new BufferedReader (new InputStreamReader(content
));
305 String headerLine
= reader
.readLine();
306 Map
<Integer
, String
> parameterMap
= getParameterMap(headerLine
);
308 String line
= reader
.readLine();
309 while (StringUtils
.isNotBlank(line
)){
310 Reference reference
= getPublicationFromLine(line
, parameterMap
, services
, config
);
311 result
.add(reference
);
312 line
= reader
.readLine();
321 * @param parameterMap
326 private Reference
getPublicationFromLine(String line
, Map
<Integer
, String
> parameterMap
, ICdmApplicationConfiguration appConfig
, IpniServicePublicationConfigurator config
) {
328 String
[] splits
= line
.split("%");
330 Map
<String
, String
> valueMap
= new HashMap
<String
, String
>();
331 for (int i
= 0; i
< splits
.length
; i
++){
332 valueMap
.put(parameterMap
.get(i
), splits
[i
]);
335 //create reference object
336 Reference ref
= ReferenceFactory
.newGeneric();
339 if (config
.isUseAbbreviationAsTitle() == true){
340 ref
.setTitle(valueMap
.get(ABBREVIATION
));
341 //TODO handle title as extension
343 ref
.setTitle(valueMap
.get(TITLE
));
344 //TODO handle abbreviation as extension
346 ref
.setIsbn(valueMap
.get(ISBN
));
347 ref
.setIssn(valueMap
.get(ISSN
));
348 ref
.setEdition(valueMap
.get(EDITION
));
349 ref
.setPlacePublished(valueMap
.get(PLACE
));
351 String author
= valueMap
.get(PUBLICATION_AUTHOR_TEAM
);
352 if (StringUtils
.isNotBlank(author
)){
353 Team team
= Team
.NewTitledInstance(author
, author
);
354 ref
.setAuthorTeam(team
);
358 String remarks
= valueMap
.get(REMARKS
);
359 Annotation annotation
= Annotation
.NewInstance(remarks
, AnnotationType
.EDITORIAL(), Language
.ENGLISH());
360 ref
.addAnnotation(annotation
);
363 String tl2AuthorString
= valueMap
.get(TL2_AUTHOR
);
364 if (ref
.getAuthorTeam() == null){
365 Team tl2Author
= Team
.NewTitledInstance(tl2AuthorString
, null);
366 ref
.setAuthorTeam(tl2Author
);
369 ref
.getAuthorTeam().setTitleCache(tl2AuthorString
, true);
370 ref
.addAnnotation(Annotation
.NewInstance(tl2AuthorString
, AnnotationType
.EDITORIAL(), Language
.ENGLISH()));
375 TimePeriod date
= TimePeriod
.parseString(valueMap
.get(DATE
));
376 ref
.setDatePublished(date
);
380 Reference citation
= getIpniCitation(appConfig
);
381 ref
.addSource(OriginalSourceType
.Lineage
, valueMap
.get(ID
), "Publication", citation
, valueMap
.get(VERSION
));
388 In publication facade
399 private List
<BotanicalName
> buildNameList( InputStream content
, ICdmApplicationConfiguration appConfig
, IIpniServiceConfigurator iConfig
) throws IOException
{
400 IpniServiceNamesConfigurator config
= (IpniServiceNamesConfigurator
)iConfig
;
401 List
<BotanicalName
> result
= new ArrayList
<BotanicalName
>();
402 BufferedReader reader
= new BufferedReader (new InputStreamReader(content
));
404 String headerLine
= reader
.readLine();
405 Map
<Integer
, String
> parameterMap
= getParameterMap(headerLine
);
407 String line
= reader
.readLine();
408 while (StringUtils
.isNotBlank(line
)){
409 BotanicalName name
= getNameFromLine(line
,parameterMap
, appConfig
);
411 line
= reader
.readLine();
419 private BotanicalName
getNameFromLine(String line
, Map
<Integer
, String
> parameterMap
, ICdmApplicationConfiguration appConfig
) {
420 //Id%Version%Standard form%Default author forename%Default author surname%Taxon groups%Dates%Alternative names
421 String
[] splits
= line
.split("%");
422 Map
<String
, String
> valueMap
= new HashMap
<String
, String
>();
424 for (int i
= 0; i
< splits
.length
; i
++){
425 valueMap
.put(parameterMap
.get(i
), splits
[i
]);
428 BotanicalName name
= BotanicalName
.NewInstance(null);
431 name
.setNameCache(valueMap
.get(FULL_NAME_WITHOUT_FAMILY_AND_AUTHORS
), true);
432 name
.setAuthorshipCache(valueMap
.get(AUTHORS
), true);
435 name
.setGenusOrUninomial(valueMap
.get(GENUS
));
436 name
.setInfraGenericEpithet(valueMap
.get(INFRA_GENUS
));
437 name
.setSpecificEpithet(valueMap
.get(SPECIES
));
438 name
.setInfraSpecificEpithet(valueMap
.get(INFRA_SPECIFIC
));
442 String rankStr
= nomalizeRank(valueMap
.get(RANK
));
443 name
.setRank(Rank
.getRankByNameOrAbbreviation(rankStr
, NomenclaturalCode
.ICNAFP
, true));
444 } catch (UnknownCdmTypeException e
) {
445 logger
.warn("Rank was unknown");
449 name
.setBasionymAuthorTeam(Team
.NewTitledInstance(valueMap
.get(BASIONYM_AUTHOR
), valueMap
.get(BASIONYM_AUTHOR
)));
450 name
.setCombinationAuthorTeam(Team
.NewTitledInstance(valueMap
.get(PUBLISHING_AUTHOR
), valueMap
.get(PUBLISHING_AUTHOR
)));
453 Reference ref
= ReferenceFactory
.newGeneric();
454 ref
.setTitleCache(valueMap
.get(PUBLICATION
));
455 TimePeriod datePublished
= TimePeriod
.parseString(valueMap
.get(PUBLICATION_YEAR_FULL
));
456 name
.setNomenclaturalReference(ref
);
459 NomenclaturalStatusType statusType
= null;
460 String statusString
= valueMap
.get(NAME_STATUS
);
461 if (StringUtils
.isNotBlank(statusString
)){
463 statusType
= NomenclaturalStatusType
.getNomenclaturalStatusTypeByAbbreviation(statusString
);
464 NomenclaturalStatus nomStatus
= NomenclaturalStatus
.NewInstance(statusType
);
465 name
.addStatus(nomStatus
);
466 } catch (UnknownCdmTypeException e
) {
467 logger
.warn("Name status not recognized: " + statusString
);
472 String remarks
= valueMap
.get(REMARKS
);
473 Annotation annotation
= Annotation
.NewInstance(remarks
, AnnotationType
.EDITORIAL(), Language
.ENGLISH());
474 name
.addAnnotation(annotation
);
477 BotanicalName basionym
= BotanicalName
.NewInstance(null);
478 basionym
.setTitleCache(valueMap
.get(BASIONYM
), true);
479 name
.addBasionym(basionym
);
482 BotanicalName replacedSynoynm
= BotanicalName
.NewInstance(null);
483 replacedSynoynm
.setTitleCache(valueMap
.get(REPLACED_SYNONYM
), true);
484 name
.addReplacedSynonym(replacedSynoynm
, null, null, null);
487 DerivedUnitFacade specimen
= DerivedUnitFacade
.NewInstance(DerivedUnitType
.Specimen
);
491 String collectionDateAsText
= valueMap
.get(COLLECTION_DATE_AS_TEXT
);
492 TimePeriod gatheringPeriod
= TimePeriod
.parseString(collectionDateAsText
);
495 gatheringPeriod
.setStartDay(getIntegerDateValueOrNull(valueMap
, COLLECTION_DAY1
));
496 gatheringPeriod
.setStartMonth(getIntegerDateValueOrNull(valueMap
, COLLECTION_MONTH1
));
497 gatheringPeriod
.setStartYear(getIntegerDateValueOrNull(valueMap
, COLLECTION_YEAR1
));
498 gatheringPeriod
.setEndDay(getIntegerDateValueOrNull(valueMap
, COLLECTION_DAY2
));
499 gatheringPeriod
.setEndMonth(getIntegerDateValueOrNull(valueMap
, COLLECTION_MONTH2
));
500 gatheringPeriod
.setEndYear(getIntegerDateValueOrNull(valueMap
, COLLECTION_YEAR2
));
501 } catch (IndexOutOfBoundsException e
) {
502 logger
.info("Exception occurred when trying to fill gathering period");
504 specimen
.setGatheringPeriod(gatheringPeriod
);
506 specimen
.setFieldNumber(valueMap
.get(COLLECTION_NUMBER
));
509 String team
= valueMap
.get(COLLECTOR_TEAM_AS_TEXT
);
510 Team collectorTeam
= Team
.NewTitledInstance(team
, team
);
511 specimen
.setCollector(collectorTeam
);
513 specimen
.setLocality(valueMap
.get(LOCALITY
));
516 String latDegrees
= CdmUtils
.Nz(valueMap
.get(LATITUDE_DEGREES
));
517 String latMinutes
= CdmUtils
.Nz(valueMap
.get(LATITUDE_MINUTES
));
518 String latSeconds
= CdmUtils
.Nz(valueMap
.get(LATITUDE_SECONDS
));
519 String direction
= CdmUtils
.Nz(valueMap
.get(NORTH_OR_SOUTH
));
520 String latitude
= latDegrees
+ "°" + latMinutes
+ "'" + latSeconds
+ "\"" + direction
;
522 String lonDegrees
= CdmUtils
.Nz(valueMap
.get(LATITUDE_DEGREES
));
523 String lonMinutes
= CdmUtils
.Nz(valueMap
.get(LATITUDE_MINUTES
));
524 String lonSeconds
= CdmUtils
.Nz(valueMap
.get(LATITUDE_SECONDS
));
525 direction
= CdmUtils
.Nz(valueMap
.get(EAST_OR_WEST
));
526 String longitude
= lonDegrees
+ "°" + lonMinutes
+ "'" + lonSeconds
+ "\"" + direction
;
529 specimen
.setExactLocationByParsing(longitude
, latitude
, null, null);
530 } catch (ParseException e
) {
531 logger
.info("Parsing exception occurred when trying to parse type exact location." + e
.getMessage());
532 } catch (Exception e
) {
533 logger
.info("Exception occurred when trying to read type exact location." + e
.getMessage());
538 Annotation typeAnnotation
= Annotation
.NewInstance(TYPE_REMARKS
, AnnotationType
.EDITORIAL(), Language
.DEFAULT());
539 specimen
.addAnnotation(typeAnnotation
);
543 //TODO "Type locations" , eg. holotype CAT ,isotype CAT ,isotype FI
545 //TODO Geographic unit as text
552 Reference citation
= getIpniCitation(appConfig
);
553 name
.addSource(OriginalSourceType
.Lineage
, valueMap
.get(ID
), "Name", citation
, valueMap
.get(VERSION
));
557 //SHORT Family, Infra family, Hybrid genus, Hybrid, Collation, Nomenclatural synonym, Distribution, Citation type
560 * Standardised basionym author flag,
561 * Standardised publishing author flag
563 Full name without family
564 Full name without authors
567 Standardised publication flag
569 publication year note
570 Publication year text
578 Replaced synonym Author team
581 Bibliographic reference
582 Bibliographic type info
585 Original taxon name author team
586 Original replaced synonym
587 Original replaced synonym author team
589 Original basionym author team
590 Original parent citation taxon name author team
591 Original taxon distribution
592 Original hybrid parentage
604 private Integer
getIntegerDateValueOrNull(Map
<String
, String
> valueMap
, String key
) {
606 Integer result
= Integer
.valueOf(valueMap
.get(key
));
611 } catch (NumberFormatException e
) {
612 if (logger
.isDebugEnabled()){
613 logger
.debug("Number Format exception for " + valueMap
.get(key
));
620 private String
nomalizeRank(String string
) {
621 String result
= string
.replace("spec.", "sp.");
626 private List
<Person
> buildAuthorList(InputStream content
, ICdmApplicationConfiguration services
, IIpniServiceConfigurator iConfig
) throws IOException
{
627 IpniServiceAuthorConfigurator config
= (IpniServiceAuthorConfigurator
)iConfig
;
628 List
<Person
> result
= new ArrayList
<Person
>();
629 BufferedReader reader
= new BufferedReader (new InputStreamReader(content
));
631 String headerLine
= reader
.readLine();
632 if (headerLine
!= null){
633 Map
<Integer
, String
> parameterMap
= getParameterMap(headerLine
);
635 String line
= reader
.readLine();
636 while (StringUtils
.isNotBlank(line
)){
637 Person author
= getAuthorFromLine(line
,parameterMap
, services
, config
);
639 line
= reader
.readLine();
648 private Map
<Integer
, String
> getParameterMap(String headerLine
) {
649 Map
<Integer
, String
> result
= new HashMap
<Integer
, String
>();
650 if ( headerLine
!= null ){
651 String
[] splits
= headerLine
.split("%");
652 for (int i
= 0; i
< splits
.length
; i
++){
653 result
.put(i
, splits
[i
]);
660 private Person
getAuthorFromLine(String line
, Map
<Integer
, String
> categoryMap
, ICdmApplicationConfiguration appConfig
, IpniServiceAuthorConfigurator config
) {
661 //Id%Version%Standard form%Default author forename%Default author surname%Taxon groups%Dates%Alternative names
662 String
[] splits
= line
.split("%");
663 Map
<String
, String
> valueMap
= new HashMap
<String
, String
>();
665 for (int i
= 0; i
< splits
.length
; i
++){
666 valueMap
.put(categoryMap
.get(i
), splits
[i
]);
669 Person person
= Person
.NewInstance();
671 person
.setNomenclaturalTitle(valueMap
.get(STANDARD_FORM
));
672 person
.setFirstname(valueMap
.get(DEFAULT_AUTHOR_FORENAME
));
673 person
.setLastname(valueMap
.get(DEFAULT_AUTHOR_SURNAME
));
675 Reference
<?
> citation
= getIpniCitation(appConfig
);
678 person
.addSource(OriginalSourceType
.Lineage
, valueMap
.get(ID
), "Author", citation
, valueMap
.get(VERSION
));
681 TimePeriod lifespan
= TimePeriod
.parseString(valueMap
.get(DATES
));
682 person
.setLifespan(lifespan
);
685 String alternativeNames
= valueMap
.get(ALTERNATIVE_NAMES
);
686 if (StringUtils
.isNotBlank(alternativeNames
)){
687 String
[] alternativeNameSplits
= alternativeNames
.split("%");
688 for (String alternativeName
: alternativeNameSplits
){
689 if (alternativeName
.startsWith(">")){
690 alternativeName
= alternativeName
.substring(1);
692 Extension
.NewInstance(person
, alternativeName
, ExtensionType
.INFORMAL_CATEGORY());
702 private Reference
getIpniCitation(ICdmApplicationConfiguration appConfig
) {
703 Reference
<?
> ipniReference
;
704 if (appConfig
!= null){
705 ipniReference
= appConfig
.getReferenceService().find(uuidIpni
);
706 if (ipniReference
== null){
707 ipniReference
= getNewIpniReference();
708 ipniReference
.setUuid(uuidIpni
);
709 appConfig
.getReferenceService().save(ipniReference
);
712 ipniReference
= getNewIpniReference();
714 return ipniReference
;
720 private Reference
getNewIpniReference() {
721 Reference
<?
> ipniReference
;
722 ipniReference
= ReferenceFactory
.newDatabase();
723 ipniReference
.setTitleCache("The International Plant Names Index (IPNI)");
724 return ipniReference
;
731 private String
normalizeParameter(String parameter
) {
732 String result
= CdmUtils
.Nz(parameter
).replace(" ", "+");
736 public List
<BotanicalName
> getNamesAdvanced(String family
, String genus
, String species
, String infraFamily
,
737 String infraGenus
, String infraSpecies
, String authorAbbrev
, Boolean includePublicationAuthors
,
738 Boolean includeBasionymAuthors
,
739 String publicationTitle
,
740 Boolean isAPNIRecord
,
743 Rank rankInRangeToReturn
,
744 Boolean sortByFamily
,
745 IpniServiceNamesConfigurator config
,
746 ICdmApplicationConfiguration services
){
747 IpniRank ipniRank
= IpniRank
.valueOf(rankInRangeToReturn
);
748 return getNamesAdvanced(family
, genus
, species
, infraFamily
, infraGenus
, infraSpecies
, authorAbbrev
, includePublicationAuthors
, includeBasionymAuthors
, publicationTitle
, isAPNIRecord
, isGCIRecord
, isIKRecord
, ipniRank
, sortByFamily
, config
, services
);
751 public List
<BotanicalName
> getNamesAdvanced(String family
, String genus
, String species
, String infraFamily
,
752 String infraGenus
, String infraSpecies
, String authorAbbrev
, Boolean includePublicationAuthors
,
753 Boolean includeBasionymAuthors
,
754 String publicationTitle
,
755 Boolean isAPNIRecord
,
758 IpniRank rankToReturn
,
759 Boolean sortByFamily
,
760 IpniServiceNamesConfigurator config
,
761 ICdmApplicationConfiguration services
) {
763 // find_rankToReturn=all&output_format=normal&find_sortByFamily=on&find_sortByFamily=off&query_type=by_query&back_page=plantsearch
767 config
= new IpniServiceNamesConfigurator();
771 family
= normalizeParameter(family
);
772 genus
= normalizeParameter(genus
);
773 species
= normalizeParameter(species
);
774 infraFamily
= normalizeParameter(infraFamily
);
775 infraGenus
= normalizeParameter(infraGenus
);
776 infraSpecies
= normalizeParameter(infraSpecies
);
777 authorAbbrev
= normalizeParameter(authorAbbrev
);
779 publicationTitle
= normalizeParameter(publicationTitle
);
781 DelimitedFormat format
= config
.getFormat();
784 "find_family=" + family
+
785 "&find_genus=" + genus
+
786 "&find_species=" + species
+
787 "&find_infrafamily=" + infraFamily
+
788 "&find_infragenus=" + infraGenus
+
789 "&find_infraspecies=" + infraSpecies
+
790 "&find_authorAbbrev=" + authorAbbrev
+
791 getBooleanParameter("&find_includePublicationAuthors=", includePublicationAuthors
, "on", "off") +
792 getBooleanParameter("&find_includeBasionymAuthors=", includePublicationAuthors
, "on", "off") +
793 getBooleanParameter("&find_find_isAPNIRecord=", includePublicationAuthors
, "on", "false") +
794 getBooleanParameter("&find_isGCIRecord=", includePublicationAuthors
, "on", "false") +
795 getBooleanParameter("&find_isIKRecord=", includePublicationAuthors
, "on", "false") +
798 "&find_publicationTitle=" + publicationTitle
+
799 "&output_format=" + format
.parameter
;
801 return (List
)queryService(request
, services
, getServiceUrl(IIpniService
.ADVANCED_NAME_SERVICE_URL
), config
, ServiceType
.NAME
);
805 private String
getBooleanParameter(String urlParamString
, Boolean booleanParameter
, String trueString
, String falseString
) {
807 if (booleanParameter
== null){
808 result
= getBooleanParameter(urlParamString
, true, trueString
, falseString
) + getBooleanParameter(urlParamString
, false, trueString
, falseString
);
809 }else if (booleanParameter
== true){
810 result
= urlParamString
+ trueString
;
812 result
= urlParamString
+ falseString
;
819 * @see eu.etaxonomy.cdm.ext.IIpniService#getNamesSimple(java.lang.String, eu.etaxonomy.cdm.ext.IIpniService.DelimitedFormat, eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration)
821 public List
<BotanicalName
> getNamesSimple(String wholeName
, ICdmApplicationConfiguration services
, IpniServiceNamesConfigurator config
){
823 config
= new IpniServiceNamesConfigurator();
827 // query_type=by_query&back_page=query_ipni.html
829 wholeName
= normalizeParameter(wholeName
);
831 DelimitedFormat format
= config
.getFormat();
833 String request
= "find_wholeName=" + wholeName
+
834 "&output_format=" + format
.parameter
;
836 return (List
)queryService(request
, services
, getServiceUrl(IIpniService
.SIMPLE_NAME_SERVICE_URL
), config
, ServiceType
.NAME
);
840 * @see eu.etaxonomy.cdm.ext.IIpniService#getPublications(java.lang.String, java.lang.String, boolean, eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration)
842 public List
<Reference
> getPublications(String title
, String abbreviation
, ICdmApplicationConfiguration services
, IpniServicePublicationConfigurator config
){
843 // http://www.uk.ipni.org/ipni/advPublicationSearch.do?find_title=Spe*plant*&find_abbreviation=&output_format=normal&query_type=by_query&back_page=publicationsearch
844 // http://www.uk.ipni.org/ipni/advPublicationSearch.do?find_title=*Hortus+Britannicus*&find_abbreviation=&output_format=delimited-classic&output_format=delimited
847 config
= new IpniServicePublicationConfigurator();
850 title
= normalizeParameter(title
);
851 abbreviation
= normalizeParameter(abbreviation
);
853 String request
= "find_title=" + title
+
854 "&find_abbreviation=" + abbreviation
+
855 "&output_format=" + DelimitedFormat
.CLASSIC
.parameter
;
857 List
<Reference
> result
= (List
)queryService(request
, services
, getServiceUrl(IIpniService
.PUBLICATION_SERVICE_URL
), config
, ServiceType
.PUBLICATION
);
866 private DelimitedFormat
getDefaultFormat() {
867 return DelimitedFormat
.SHORT
;
874 * @return the serviceUrl
876 public URL
getServiceUrl(String url
) {
879 serviceUrl
= new URL(url
);
880 } catch (MalformedURLException e
) {
881 throw new RuntimeException("This should not happen", e
);