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
.text
.ParseException
;
20 import java
.util
.ArrayList
;
21 import java
.util
.HashMap
;
22 import java
.util
.List
;
25 import org
.apache
.commons
.lang
.StringUtils
;
26 import org
.apache
.log4j
.Logger
;
27 import org
.springframework
.stereotype
.Component
;
29 import eu
.etaxonomy
.cdm
.api
.application
.ICdmApplicationConfiguration
;
30 import eu
.etaxonomy
.cdm
.api
.facade
.DerivedUnitFacade
;
31 import eu
.etaxonomy
.cdm
.api
.facade
.DerivedUnitFacade
.DerivedUnitType
;
32 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
33 import eu
.etaxonomy
.cdm
.model
.agent
.Person
;
34 import eu
.etaxonomy
.cdm
.model
.agent
.Team
;
35 import eu
.etaxonomy
.cdm
.model
.common
.Annotation
;
36 import eu
.etaxonomy
.cdm
.model
.common
.AnnotationType
;
37 import eu
.etaxonomy
.cdm
.model
.common
.Extension
;
38 import eu
.etaxonomy
.cdm
.model
.common
.ExtensionType
;
39 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
40 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
41 import eu
.etaxonomy
.cdm
.model
.common
.TimePeriod
;
42 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
43 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalCode
;
44 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
45 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
46 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
47 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
48 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceFactory
;
49 import eu
.etaxonomy
.cdm
.strategy
.exceptions
.UnknownCdmTypeException
;
54 * @created Aug 16, 2010
59 public class IpniService
implements IIpniService
{
60 private static final String EAST_OR_WEST
= "East or west";
62 private static final String NORTH_OR_SOUTH
= "North or south";
64 private static final String LATITUDE_SECONDS
= "Latitude seconds";
66 private static final String LATITUDE_MINUTES
= "Latitude minutes";
68 private static final String LATITUDE_DEGREES
= "Latitude degrees";
70 private static final String COLLECTION_DATE_AS_TEXT
= "Collection date as text";
72 private static final String COLLECTION_DAY1
= "Collection day1";
74 private static final String COLLECTION_MONTH1
= "Collection month1";
76 private static final String COLLECTION_YEAR1
= "Collection year1";
78 private static final String COLLECTION_DAY2
= "Collection day2";
80 private static final String COLLECTION_MONTH2
= "Collection month2";
82 private static final String COLLECTION_YEAR2
= "Collection year2";
84 private static final String COLLECTION_NUMBER
= "Collection number";
86 private static final String COLLECTOR_TEAM_AS_TEXT
= "Collector team as text";
88 private static final String LOCALITY
= "Locality";
90 private static final String TYPE_REMARKS
= "Type remarks";
92 private static final Logger logger
= Logger
.getLogger(IpniService
.class);
95 public static String ID
= "Id";
96 public static String VERSION
= "Version";
97 public static final String REMARKS
= "Remarks";
100 public static final String FULL_NAME_WITHOUT_FAMILY_AND_AUTHORS
= "Full name without family and authors";
101 public static final String AUTHORS
= "Authors";
102 public static final String FAMILY
= "Family";
103 public static final String GENUS
= "Genus";
104 public static final String INFRA_GENUS
= "Infra genus";
105 public static final String SPECIES
= "Species";
106 public static final String INFRA_SPECIFIC
= "Infra species";
107 public static final String RANK
= "Rank";
108 public static final String BASIONYM_AUTHOR
= "Basionym author";
109 public static final String PUBLISHING_AUTHOR
= "Publishing author";
110 public static final String PUBLICATION
= "Publication";
111 public static final String PUBLICATION_YEAR_FULL
= "Publication year full";
112 public static final String NAME_STATUS
= "Name status";
113 public static final String BASIONYM
= "Basionym";
114 public static final String REPLACED_SYNONYM
= "Replaced synonym";
119 public static final String STANDARD_FORM
= "Standard Form";
121 public static final String DEFAULT_AUTHOR_FORENAME
= "Default author forename";
122 public static final String DEFAULT_AUTHOR_SURNAME
= "Default author surname";
123 public static final String TAXON_GROUPS
= "Taxon groups";
124 public static final String DATES
= "Dates";
125 public static final String ALTERNATIVE_NAMES
= "Alternative names";
127 public static final String DEFAULT_AUTHOR_NAME
= "Default author name";
129 public static final String NAME_NOTES
= "Name notes";
130 public static final String NAME_SOURCE
= "Name source";
131 public static final String DATE_TYPE_CODE
= "Date type code";
132 public static final String DATE_TYPE_STRING
= "Date type string";
134 public static final String ALTERNATIVE_ABBREVIATIONS
= "Alternative abbreviations";
135 public static final String EXAMPLE_OF_NAME_PUBLISHED
= "Example of name published";
140 public static final String ABBREVIATION
= "Abbreviation";
141 public static final String TITLE
= "Title";
142 public static final String BPH_NUMBER
= "BPH number";
143 public static final String ISBN
= "ISBN";
144 public static final String ISSN
= "ISSN";
145 public static final String AUTHORS_ROLE
= "Authors role";
146 public static final String EDITION
= "Edition";
147 public static final String DATE
= "Date";
148 public static final String IN_PUBLICATION_FACADE
= "In publication facade";
149 public static final String LC_NUMBER
= "LC number";
150 public static final String PLACE
= "Place";
151 public static final String PUBLICATION_AUTHOR_TEAM
= "Publication author team";
152 public static final String PRECEDED_BY
= "Preceded";
153 public static final String TL2_AUTHOR
= "TL2 author";
154 public static final String TL2_NUMBER
= "TL2 number";
155 public static final String TDWG_ABBREVIATION
= "TDWG abbreviation";
157 private enum ServiceType
{
163 public enum IpniRank
{
165 FAMILIAL ("Familial"),
166 INFRA_FAMILIAL ("Infrafamilial"),
168 INFRA_GENERIC("Infrageneric"),
169 SPECIFIC ("Specific"),
170 INFRA_SPECIFIC("InfraSpecific");
173 IpniRank(String strRank
){
174 this.strRank
= strRank
;
177 public static IpniRank
valueOf(Rank rank
){
180 }else if (rank
.isInfraSpecific()){
181 return INFRA_SPECIFIC
;
182 }else if (rank
.isSpecies()){
184 }else if (rank
.isInfraGeneric()){
185 return INFRA_GENERIC
;
186 }else if (rank
.isGenus()){
188 }else if (rank
.isLower(Rank
.FAMILY())){
189 return INFRA_FAMILIAL
;
190 }else if (rank
.isHigher(Rank
.SUBFAMILY())){
193 logger
.warn("Rank could not be transformed to ipni rank. Use ALL instead");
200 // private URL serviceUrl;
202 // ******************************** CONSTRUCTOR **************************************
204 // ****************************** METHODS ****************************************************/
208 * @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)
210 public List
<Person
> getAuthors(String abbreviation
, String surname
, String forename
, String isoCountry
, ICdmApplicationConfiguration services
, IpniServiceAuthorConfigurator config
){
213 config
= new IpniServiceAuthorConfigurator();
217 abbreviation
= normalizeParameter(abbreviation
);
218 surname
= normalizeParameter(surname
);
219 isoCountry
= normalizeParameter(isoCountry
);
220 forename
= normalizeParameter(forename
);
222 DelimitedFormat format
= config
.getFormat();
224 String request
= "find_abbreviation=" + abbreviation
+
225 "&find_surname=" + surname
+
226 "&find_isoCountry=" + isoCountry
+
227 "&find_forename=" + forename
+
228 "&output_format=" + format
.parameter
;
230 return (List
)queryService(request
, services
, getServiceUrl(IIpniService
.AUTHOR_SERVICE_URL
), config
, ServiceType
.AUTHOR
);
239 private List
<?
extends IdentifiableEntity
> queryService(String request
, ICdmApplicationConfiguration services
, URL serviceUrl
, IIpniServiceConfigurator config
, ServiceType serviceType
){
241 throw new NullPointerException("Ipni service configurator should not be null");
244 // create the request url
245 URL newUrl
= new URL(serviceUrl
.getProtocol(),
246 serviceUrl
.getHost(),
247 serviceUrl
.getPort(),
251 HttpURLConnection connection
= (HttpURLConnection
) newUrl
.openConnection();
252 // set the accept property to XML so we can use jdom to handle the content
253 //connection.setRequestProperty("Accept", "text/xml");
256 logger
.info("Firing request for URL: " + newUrl
);
258 int responseCode
= connection
.getResponseCode();
260 // get the content at the resource
261 InputStream content
= (InputStream
) connection
.getContent();
264 List
<?
extends IdentifiableEntity
> result
;
265 if (serviceType
.equals(ServiceType
.AUTHOR
)){
266 result
= buildAuthorList(content
, services
, config
);
267 }else if (serviceType
.equals(ServiceType
.NAME
)){
268 result
= buildNameList(content
, services
, config
);
270 result
= buildPublicationList(content
, services
, config
);
272 if(responseCode
== HttpURLConnection
.HTTP_OK
){
275 //TODO error handling
276 logger
.error("No Http_OK");
279 } catch (IOException e
) {
280 logger
.error("No content for request: " + request
);
287 private List
<ReferenceBase
> buildPublicationList( InputStream content
, ICdmApplicationConfiguration services
, IIpniServiceConfigurator iConfig
) throws IOException
{
288 IpniServicePublicationConfigurator config
= (IpniServicePublicationConfigurator
)iConfig
;
290 List
<ReferenceBase
> result
= new ArrayList
<ReferenceBase
>();
291 BufferedReader reader
= new BufferedReader (new InputStreamReader(content
));
293 String headerLine
= reader
.readLine();
294 Map
<Integer
, String
> parameterMap
= getParameterMap(headerLine
);
296 String line
= reader
.readLine();
297 while (StringUtils
.isNotBlank(line
)){
298 ReferenceBase reference
= getPublicationFromLine(line
, parameterMap
, services
, config
);
299 result
.add(reference
);
300 line
= reader
.readLine();
307 private ReferenceBase
getPublicationFromLine(String line
, Map
<Integer
, String
> parameterMap
, ICdmApplicationConfiguration appConfig
, IpniServicePublicationConfigurator config
) {
309 String
[] splits
= line
.split("%");
311 Map
<String
, String
> valueMap
= new HashMap
<String
, String
>();
312 for (int i
= 0; i
< splits
.length
; i
++){
313 valueMap
.put(parameterMap
.get(i
), splits
[i
]);
316 //create reference object
317 ReferenceBase ref
= ReferenceFactory
.newGeneric();
320 if (config
.isUseAbbreviationAsTitle() == true){
321 ref
.setTitle(valueMap
.get(ABBREVIATION
));
322 //TODO handle title as extension
324 ref
.setTitle(valueMap
.get(TITLE
));
325 //TODO handle abbreviation as extension
327 ref
.setIsbn(valueMap
.get(ISBN
));
328 ref
.setIssn(valueMap
.get(ISSN
));
329 ref
.setEdition(valueMap
.get(EDITION
));
330 ref
.setPlacePublished(valueMap
.get(PLACE
));
332 String author
= valueMap
.get(PUBLICATION_AUTHOR_TEAM
);
333 Team team
= Team
.NewTitledInstance(author
, author
);
334 ref
.setAuthorTeam(team
);
337 String remarks
= valueMap
.get(REMARKS
);
338 Annotation annotation
= Annotation
.NewInstance(remarks
, AnnotationType
.EDITORIAL(), Language
.ENGLISH());
339 ref
.addAnnotation(annotation
);
342 TimePeriod date
= TimePeriod
.parseString(valueMap
.get(DATE
));
343 ref
.setDatePublished(date
);
346 ReferenceBase citation
= getIpniCitation(appConfig
);
347 ref
.addSource(valueMap
.get(ID
), "Publication", citation
, valueMap
.get(VERSION
));
353 In publication facade
365 private List
<BotanicalName
> buildNameList( InputStream content
, ICdmApplicationConfiguration appConfig
, IIpniServiceConfigurator iConfig
) throws IOException
{
366 IpniServiceNamesConfigurator config
= (IpniServiceNamesConfigurator
)iConfig
;
367 List
<BotanicalName
> result
= new ArrayList
<BotanicalName
>();
368 BufferedReader reader
= new BufferedReader (new InputStreamReader(content
));
370 String headerLine
= reader
.readLine();
371 Map
<Integer
, String
> parameterMap
= getParameterMap(headerLine
);
373 String line
= reader
.readLine();
374 while (StringUtils
.isNotBlank(line
)){
375 BotanicalName name
= getNameFromLine(line
,parameterMap
, appConfig
);
377 line
= reader
.readLine();
385 private BotanicalName
getNameFromLine(String line
, Map
<Integer
, String
> parameterMap
, ICdmApplicationConfiguration appConfig
) {
386 //Id%Version%Standard form%Default author forename%Default author surname%Taxon groups%Dates%Alternative names
387 String
[] splits
= line
.split("%");
388 Map
<String
, String
> valueMap
= new HashMap
<String
, String
>();
390 for (int i
= 0; i
< splits
.length
; i
++){
391 valueMap
.put(parameterMap
.get(i
), splits
[i
]);
394 BotanicalName name
= BotanicalName
.NewInstance(null);
397 name
.setNameCache(valueMap
.get(FULL_NAME_WITHOUT_FAMILY_AND_AUTHORS
), true);
398 name
.setAuthorshipCache(valueMap
.get(AUTHORS
), true);
401 name
.setGenusOrUninomial(valueMap
.get(GENUS
));
402 name
.setInfraGenericEpithet(valueMap
.get(INFRA_GENUS
));
403 name
.setSpecificEpithet(valueMap
.get(SPECIES
));
404 name
.setInfraSpecificEpithet(valueMap
.get(INFRA_SPECIFIC
));
408 String rankStr
= nomalizeRank(valueMap
.get(RANK
));
409 name
.setRank(Rank
.getRankByNameOrAbbreviation(rankStr
, NomenclaturalCode
.ICBN
, true));
410 } catch (UnknownCdmTypeException e
) {
411 logger
.warn("Rank was unknown");
415 name
.setBasionymAuthorTeam(Team
.NewTitledInstance(valueMap
.get(BASIONYM_AUTHOR
), valueMap
.get(BASIONYM_AUTHOR
)));
416 name
.setCombinationAuthorTeam(Team
.NewTitledInstance(valueMap
.get(PUBLISHING_AUTHOR
), valueMap
.get(PUBLISHING_AUTHOR
)));
419 ReferenceBase ref
= ReferenceFactory
.newGeneric();
420 ref
.setTitleCache(valueMap
.get(PUBLICATION
));
421 TimePeriod datePublished
= TimePeriod
.parseString(valueMap
.get(PUBLICATION_YEAR_FULL
));
422 name
.setNomenclaturalReference(ref
);
425 NomenclaturalStatusType statusType
= null;
426 String statusString
= valueMap
.get(NAME_STATUS
);
427 if (StringUtils
.isNotBlank(statusString
)){
429 statusType
= NomenclaturalStatusType
.getNomenclaturalStatusTypeByAbbreviation(statusString
);
430 NomenclaturalStatus nomStatus
= NomenclaturalStatus
.NewInstance(statusType
);
431 name
.addStatus(nomStatus
);
432 } catch (UnknownCdmTypeException e
) {
433 logger
.warn("Name status not recognized: " + statusString
);
438 String remarks
= valueMap
.get(REMARKS
);
439 Annotation annotation
= Annotation
.NewInstance(remarks
, AnnotationType
.EDITORIAL(), Language
.ENGLISH());
440 name
.addAnnotation(annotation
);
443 BotanicalName basionym
= BotanicalName
.NewInstance(null);
444 basionym
.setTitleCache(valueMap
.get(BASIONYM
), true);
445 name
.addBasionym(basionym
);
448 BotanicalName replacedSynoynm
= BotanicalName
.NewInstance(null);
449 replacedSynoynm
.setTitleCache(valueMap
.get(REPLACED_SYNONYM
), true);
450 name
.addReplacedSynonym(replacedSynoynm
, null, null, null);
453 DerivedUnitFacade specimen
= DerivedUnitFacade
.NewInstance(DerivedUnitType
.Specimen
);
457 String collectionDateAsText
= valueMap
.get(COLLECTION_DATE_AS_TEXT
);
458 TimePeriod gatheringPeriod
= TimePeriod
.parseString(collectionDateAsText
);
461 gatheringPeriod
.setStartDay(getIntegerDateValueOrNull(valueMap
, COLLECTION_DAY1
));
462 gatheringPeriod
.setStartMonth(getIntegerDateValueOrNull(valueMap
, COLLECTION_MONTH1
));
463 gatheringPeriod
.setStartYear(getIntegerDateValueOrNull(valueMap
, COLLECTION_YEAR1
));
464 gatheringPeriod
.setEndDay(getIntegerDateValueOrNull(valueMap
, COLLECTION_DAY2
));
465 gatheringPeriod
.setEndMonth(getIntegerDateValueOrNull(valueMap
, COLLECTION_MONTH2
));
466 gatheringPeriod
.setEndYear(getIntegerDateValueOrNull(valueMap
, COLLECTION_YEAR2
));
467 } catch (IndexOutOfBoundsException e
) {
468 logger
.info("Exception occurred when trying to fill gathering period");
470 specimen
.setGatheringPeriod(gatheringPeriod
);
472 specimen
.setFieldNumber(valueMap
.get(COLLECTION_NUMBER
));
475 String team
= valueMap
.get(COLLECTOR_TEAM_AS_TEXT
);
476 Team collectorTeam
= Team
.NewTitledInstance(team
, team
);
477 specimen
.setCollector(collectorTeam
);
479 specimen
.setLocality(valueMap
.get(LOCALITY
));
482 String latDegrees
= CdmUtils
.Nz(valueMap
.get(LATITUDE_DEGREES
));
483 String latMinutes
= CdmUtils
.Nz(valueMap
.get(LATITUDE_MINUTES
));
484 String latSeconds
= CdmUtils
.Nz(valueMap
.get(LATITUDE_SECONDS
));
485 String direction
= CdmUtils
.Nz(valueMap
.get(NORTH_OR_SOUTH
));
486 String latitude
= latDegrees
+ "°" + latMinutes
+ "'" + latSeconds
+ "\"" + direction
;
488 String lonDegrees
= CdmUtils
.Nz(valueMap
.get(LATITUDE_DEGREES
));
489 String lonMinutes
= CdmUtils
.Nz(valueMap
.get(LATITUDE_MINUTES
));
490 String lonSeconds
= CdmUtils
.Nz(valueMap
.get(LATITUDE_SECONDS
));
491 direction
= CdmUtils
.Nz(valueMap
.get(EAST_OR_WEST
));
492 String longitude
= lonDegrees
+ "°" + lonMinutes
+ "'" + lonSeconds
+ "\"" + direction
;
495 specimen
.setExactLocationByParsing(longitude
, latitude
, null, null);
496 } catch (ParseException e
) {
497 logger
.info("Parsing exception occurred when trying to parse type exact location." + e
.getMessage());
498 } catch (Exception e
) {
499 logger
.info("Exception occurred when trying to read type exact location." + e
.getMessage());
504 Annotation typeAnnotation
= Annotation
.NewInstance(TYPE_REMARKS
, AnnotationType
.EDITORIAL(), Language
.DEFAULT());
505 specimen
.addAnnotation(typeAnnotation
);
509 //TODO "Type locations" , eg. holotype CAT ,isotype CAT ,isotype FI
511 //TODO Geographic unit as text
518 ReferenceBase citation
= getIpniCitation(appConfig
);
519 name
.addSource(valueMap
.get(ID
), "Name", citation
, valueMap
.get(VERSION
));
523 //SHORT Family, Infra family, Hybrid genus, Hybrid, Collation, Nomenclatural synonym, Distribution, Citation type
526 * Standardised basionym author flag,
527 * Standardised publishing author flag
529 Full name without family
530 Full name without authors
533 Standardised publication flag
535 publication year note
536 Publication year text
544 Replaced synonym Author team
547 Bibliographic reference
548 Bibliographic type info
551 Original taxon name author team
552 Original replaced synonym
553 Original replaced synonym author team
555 Original basionym author team
556 Original parent citation taxon name author team
557 Original taxon distribution
558 Original hybrid parentage
570 private Integer
getIntegerDateValueOrNull(Map
<String
, String
> valueMap
, String key
) {
572 Integer result
= Integer
.valueOf(valueMap
.get(key
));
577 } catch (NumberFormatException e
) {
578 if (logger
.isDebugEnabled()){
579 logger
.debug("Number Format exception for " + valueMap
.get(key
));
586 private String
nomalizeRank(String string
) {
587 String result
= string
.replace("spec.", "sp.");
592 private List
<Person
> buildAuthorList(InputStream content
, ICdmApplicationConfiguration services
, IIpniServiceConfigurator iConfig
) throws IOException
{
593 IpniServiceAuthorConfigurator config
= (IpniServiceAuthorConfigurator
)iConfig
;
594 List
<Person
> result
= new ArrayList
<Person
>();
595 BufferedReader reader
= new BufferedReader (new InputStreamReader(content
));
597 String headerLine
= reader
.readLine();
598 if (headerLine
!= null){
599 Map
<Integer
, String
> parameterMap
= getParameterMap(headerLine
);
601 String line
= reader
.readLine();
602 while (StringUtils
.isNotBlank(line
)){
603 Person author
= getAuthorFromLine(line
,parameterMap
, services
, config
);
605 line
= reader
.readLine();
614 private Map
<Integer
, String
> getParameterMap(String headerLine
) {
615 Map
<Integer
, String
> result
= new HashMap
<Integer
, String
>();
616 if ( headerLine
!= null ){
617 String
[] splits
= headerLine
.split("%");
618 for (int i
= 0; i
< splits
.length
; i
++){
619 result
.put(i
, splits
[i
]);
626 private Person
getAuthorFromLine(String line
, Map
<Integer
, String
> categoryMap
, ICdmApplicationConfiguration appConfig
, IpniServiceAuthorConfigurator config
) {
627 //Id%Version%Standard form%Default author forename%Default author surname%Taxon groups%Dates%Alternative names
628 String
[] splits
= line
.split("%");
629 Map
<String
, String
> valueMap
= new HashMap
<String
, String
>();
631 for (int i
= 0; i
< splits
.length
; i
++){
632 valueMap
.put(categoryMap
.get(i
), splits
[i
]);
635 Person person
= Person
.NewInstance();
637 person
.setNomenclaturalTitle(valueMap
.get(STANDARD_FORM
));
638 person
.setFirstname(valueMap
.get(DEFAULT_AUTHOR_FORENAME
));
639 person
.setLastname(valueMap
.get(DEFAULT_AUTHOR_SURNAME
));
641 ReferenceBase citation
= getIpniCitation(appConfig
);
644 person
.addSource(valueMap
.get(ID
), "Author", citation
, valueMap
.get(VERSION
));
647 TimePeriod lifespan
= TimePeriod
.parseString(valueMap
.get(DATES
));
648 person
.setLifespan(lifespan
);
651 String alternativeNames
= valueMap
.get(ALTERNATIVE_NAMES
);
652 if (StringUtils
.isNotBlank(alternativeNames
)){
653 String
[] alternativeNameSplits
= alternativeNames
.split("%");
654 for (String alternativeName
: alternativeNameSplits
){
655 if (alternativeName
.startsWith(">")){
656 alternativeName
= alternativeName
.substring(1);
658 Extension
.NewInstance(person
, alternativeName
, ExtensionType
.INFORMAL_CATEGORY());
668 private ReferenceBase
getIpniCitation(ICdmApplicationConfiguration appConfig
) {
669 ReferenceBase ipniReference
;
670 if (appConfig
!= null){
671 ipniReference
= appConfig
.getReferenceService().find(uuidIpni
);
672 if (ipniReference
== null){
673 ipniReference
= getNewIpniReference();
674 ipniReference
.setUuid(uuidIpni
);
675 appConfig
.getReferenceService().save(ipniReference
);
678 ipniReference
= getNewIpniReference();
680 return ipniReference
;
686 private ReferenceBase
getNewIpniReference() {
687 ReferenceBase ipniReference
;
688 ipniReference
= ReferenceFactory
.newDatabase();
689 ipniReference
.setTitleCache("The International Plant Names Index (IPNI)");
690 return ipniReference
;
697 private String
normalizeParameter(String parameter
) {
698 String result
= CdmUtils
.Nz(parameter
).replace(" ", "+");
702 public List
<BotanicalName
> getNamesAdvanced(String family
, String genus
, String species
, String infraFamily
,
703 String infraGenus
, String infraSpecies
, String authorAbbrev
, Boolean includePublicationAuthors
,
704 Boolean includeBasionymAuthors
,
705 String publicationTitle
,
706 Boolean isAPNIRecord
,
709 Rank rankInRangeToReturn
,
710 Boolean sortByFamily
,
711 IpniServiceNamesConfigurator config
,
712 ICdmApplicationConfiguration services
){
713 IpniRank ipniRank
= IpniRank
.valueOf(rankInRangeToReturn
);
714 return getNamesAdvanced(family
, genus
, species
, infraFamily
, infraGenus
, infraSpecies
, authorAbbrev
, includePublicationAuthors
, includeBasionymAuthors
, publicationTitle
, isAPNIRecord
, isGCIRecord
, isIKRecord
, ipniRank
, sortByFamily
, config
, services
);
717 public List
<BotanicalName
> getNamesAdvanced(String family
, String genus
, String species
, String infraFamily
,
718 String infraGenus
, String infraSpecies
, String authorAbbrev
, Boolean includePublicationAuthors
,
719 Boolean includeBasionymAuthors
,
720 String publicationTitle
,
721 Boolean isAPNIRecord
,
724 IpniRank rankToReturn
,
725 Boolean sortByFamily
,
726 IpniServiceNamesConfigurator config
,
727 ICdmApplicationConfiguration services
) {
729 // find_rankToReturn=all&output_format=normal&find_sortByFamily=on&find_sortByFamily=off&query_type=by_query&back_page=plantsearch
733 config
= new IpniServiceNamesConfigurator();
737 family
= normalizeParameter(family
);
738 genus
= normalizeParameter(genus
);
739 species
= normalizeParameter(species
);
740 infraFamily
= normalizeParameter(infraFamily
);
741 infraGenus
= normalizeParameter(infraGenus
);
742 infraSpecies
= normalizeParameter(infraSpecies
);
743 authorAbbrev
= normalizeParameter(authorAbbrev
);
745 publicationTitle
= normalizeParameter(publicationTitle
);
747 DelimitedFormat format
= config
.getFormat();
750 "find_family=" + family
+
751 "&find_genus=" + genus
+
752 "&find_species=" + species
+
753 "&find_infrafamily=" + infraFamily
+
754 "&find_infragenus=" + infraGenus
+
755 "&find_infraspecies=" + infraSpecies
+
756 "&find_authorAbbrev=" + authorAbbrev
+
757 getBooleanParameter("&find_includePublicationAuthors=", includePublicationAuthors
, "on", "off") +
758 getBooleanParameter("&find_includeBasionymAuthors=", includePublicationAuthors
, "on", "off") +
759 getBooleanParameter("&find_find_isAPNIRecord=", includePublicationAuthors
, "on", "false") +
760 getBooleanParameter("&find_isGCIRecord=", includePublicationAuthors
, "on", "false") +
761 getBooleanParameter("&find_isIKRecord=", includePublicationAuthors
, "on", "false") +
764 "&find_publicationTitle=" + publicationTitle
+
765 "&output_format=" + format
.parameter
;
767 return (List
)queryService(request
, services
, getServiceUrl(IIpniService
.ADVANCED_NAME_SERVICE_URL
), config
, ServiceType
.NAME
);
771 private String
getBooleanParameter(String urlParamString
, Boolean booleanParameter
, String trueString
, String falseString
) {
773 if (booleanParameter
== null){
774 result
= getBooleanParameter(urlParamString
, true, trueString
, falseString
) + getBooleanParameter(urlParamString
, false, trueString
, falseString
);
775 }else if (booleanParameter
== true){
776 result
= urlParamString
+ trueString
;
778 result
= urlParamString
+ falseString
;
785 * @see eu.etaxonomy.cdm.ext.IIpniService#getNamesSimple(java.lang.String, eu.etaxonomy.cdm.ext.IIpniService.DelimitedFormat, eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration)
787 public List
<BotanicalName
> getNamesSimple(String wholeName
, ICdmApplicationConfiguration services
, IpniServiceNamesConfigurator config
){
789 config
= new IpniServiceNamesConfigurator();
793 // query_type=by_query&back_page=query_ipni.html
795 wholeName
= normalizeParameter(wholeName
);
797 DelimitedFormat format
= config
.getFormat();
799 String request
= "find_wholeName=" + wholeName
+
800 "&output_format=" + format
.parameter
;
802 return (List
)queryService(request
, services
, getServiceUrl(IIpniService
.SIMPLE_NAME_SERVICE_URL
), config
, ServiceType
.NAME
);
806 * @see eu.etaxonomy.cdm.ext.IIpniService#getPublications(java.lang.String, java.lang.String, boolean, eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration)
808 public List
<ReferenceBase
> getPublications(String title
, String abbreviation
, ICdmApplicationConfiguration services
, IpniServicePublicationConfigurator config
){
809 // http://www.uk.ipni.org/ipni/advPublicationSearch.do?find_title=Spe*plant*&find_abbreviation=&output_format=normal&query_type=by_query&back_page=publicationsearch
810 // http://www.uk.ipni.org/ipni/advPublicationSearch.do?find_title=*Hortus+Britannicus*&find_abbreviation=&output_format=delimited-classic&output_format=delimited
813 config
= new IpniServicePublicationConfigurator();
816 title
= normalizeParameter(title
);
817 abbreviation
= normalizeParameter(abbreviation
);
819 String request
= "find_title=" + title
+
820 "&find_abbreviation=" + abbreviation
+
821 "&output_format=" + DelimitedFormat
.CLASSIC
.parameter
;
823 List
<ReferenceBase
> result
= (List
)queryService(request
, services
, getServiceUrl(IIpniService
.PUBLICATION_SERVICE_URL
), config
, ServiceType
.PUBLICATION
);
832 private DelimitedFormat
getDefaultFormat() {
833 return DelimitedFormat
.SHORT
;
840 * @return the serviceUrl
842 public URL
getServiceUrl(String url
) {
845 serviceUrl
= new URL(url
);
846 } catch (MalformedURLException e
) {
847 throw new RuntimeException("This should not happen", e
);