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 String
[] splits
= headerLine
.split("%");
617 for (int i
= 0; i
< splits
.length
; i
++){
618 result
.put(i
, splits
[i
]);
624 private Person
getAuthorFromLine(String line
, Map
<Integer
, String
> categoryMap
, ICdmApplicationConfiguration appConfig
, IpniServiceAuthorConfigurator config
) {
625 //Id%Version%Standard form%Default author forename%Default author surname%Taxon groups%Dates%Alternative names
626 String
[] splits
= line
.split("%");
627 Map
<String
, String
> valueMap
= new HashMap
<String
, String
>();
629 for (int i
= 0; i
< splits
.length
; i
++){
630 valueMap
.put(categoryMap
.get(i
), splits
[i
]);
633 Person person
= Person
.NewInstance();
635 person
.setNomenclaturalTitle(valueMap
.get(STANDARD_FORM
));
636 person
.setFirstname(valueMap
.get(DEFAULT_AUTHOR_FORENAME
));
637 person
.setLastname(valueMap
.get(DEFAULT_AUTHOR_SURNAME
));
639 ReferenceBase citation
= getIpniCitation(appConfig
);
642 person
.addSource(valueMap
.get(ID
), "Author", citation
, valueMap
.get(VERSION
));
645 TimePeriod lifespan
= TimePeriod
.parseString(valueMap
.get(DATES
));
646 person
.setLifespan(lifespan
);
649 String alternativeNames
= valueMap
.get(ALTERNATIVE_NAMES
);
650 if (StringUtils
.isNotBlank(alternativeNames
)){
651 String
[] alternativeNameSplits
= alternativeNames
.split("%");
652 for (String alternativeName
: alternativeNameSplits
){
653 if (alternativeName
.startsWith(">")){
654 alternativeName
= alternativeName
.substring(1);
656 Extension
.NewInstance(person
, alternativeName
, ExtensionType
.INFORMAL_CATEGORY());
666 private ReferenceBase
getIpniCitation(ICdmApplicationConfiguration appConfig
) {
667 ReferenceBase ipniReference
;
668 if (appConfig
!= null){
669 ipniReference
= appConfig
.getReferenceService().find(uuidIpni
);
670 if (ipniReference
== null){
671 ipniReference
= getNewIpniReference();
672 ipniReference
.setUuid(uuidIpni
);
673 appConfig
.getReferenceService().save(ipniReference
);
676 ipniReference
= getNewIpniReference();
678 return ipniReference
;
684 private ReferenceBase
getNewIpniReference() {
685 ReferenceBase ipniReference
;
686 ipniReference
= ReferenceFactory
.newDatabase();
687 ipniReference
.setTitleCache("The International Plant Names Index (IPNI)");
688 return ipniReference
;
695 private String
normalizeParameter(String parameter
) {
696 String result
= CdmUtils
.Nz(parameter
).replace(" ", "+");
700 public List
<BotanicalName
> getNamesAdvanced(String family
, String genus
, String species
, String infraFamily
,
701 String infraGenus
, String infraSpecies
, String authorAbbrev
, Boolean includePublicationAuthors
,
702 Boolean includeBasionymAuthors
,
703 String publicationTitle
,
704 Boolean isAPNIRecord
,
707 Rank rankInRangeToReturn
,
708 Boolean sortByFamily
,
709 IpniServiceNamesConfigurator config
,
710 ICdmApplicationConfiguration services
){
711 IpniRank ipniRank
= IpniRank
.valueOf(rankInRangeToReturn
);
712 return getNamesAdvanced(family
, genus
, species
, infraFamily
, infraGenus
, infraSpecies
, authorAbbrev
, includePublicationAuthors
, includeBasionymAuthors
, publicationTitle
, isAPNIRecord
, isGCIRecord
, isIKRecord
, ipniRank
, sortByFamily
, config
, services
);
715 public List
<BotanicalName
> getNamesAdvanced(String family
, String genus
, String species
, String infraFamily
,
716 String infraGenus
, String infraSpecies
, String authorAbbrev
, Boolean includePublicationAuthors
,
717 Boolean includeBasionymAuthors
,
718 String publicationTitle
,
719 Boolean isAPNIRecord
,
722 IpniRank rankToReturn
,
723 Boolean sortByFamily
,
724 IpniServiceNamesConfigurator config
,
725 ICdmApplicationConfiguration services
) {
727 // find_rankToReturn=all&output_format=normal&find_sortByFamily=on&find_sortByFamily=off&query_type=by_query&back_page=plantsearch
731 config
= new IpniServiceNamesConfigurator();
735 family
= normalizeParameter(family
);
736 genus
= normalizeParameter(genus
);
737 species
= normalizeParameter(species
);
738 infraFamily
= normalizeParameter(infraFamily
);
739 infraGenus
= normalizeParameter(infraGenus
);
740 infraSpecies
= normalizeParameter(infraSpecies
);
741 authorAbbrev
= normalizeParameter(authorAbbrev
);
743 publicationTitle
= normalizeParameter(publicationTitle
);
745 DelimitedFormat format
= config
.getFormat();
748 "find_family=" + family
+
749 "&find_genus=" + genus
+
750 "&find_species=" + species
+
751 "&find_infrafamily=" + infraFamily
+
752 "&find_infragenus=" + infraGenus
+
753 "&find_infraspecies=" + infraSpecies
+
754 "&find_authorAbbrev=" + authorAbbrev
+
755 getBooleanParameter("&find_includePublicationAuthors=", includePublicationAuthors
, "on", "off") +
756 getBooleanParameter("&find_includeBasionymAuthors=", includePublicationAuthors
, "on", "off") +
757 getBooleanParameter("&find_find_isAPNIRecord=", includePublicationAuthors
, "on", "false") +
758 getBooleanParameter("&find_isGCIRecord=", includePublicationAuthors
, "on", "false") +
759 getBooleanParameter("&find_isIKRecord=", includePublicationAuthors
, "on", "false") +
762 "&find_publicationTitle=" + publicationTitle
+
763 "&output_format=" + format
.parameter
;
765 return (List
)queryService(request
, services
, getServiceUrl(IIpniService
.ADVANCED_NAME_SERVICE_URL
), config
, ServiceType
.NAME
);
769 private String
getBooleanParameter(String urlParamString
, Boolean booleanParameter
, String trueString
, String falseString
) {
771 if (booleanParameter
== null){
772 result
= getBooleanParameter(urlParamString
, true, trueString
, falseString
) + getBooleanParameter(urlParamString
, false, trueString
, falseString
);
773 }else if (booleanParameter
== true){
774 result
= urlParamString
+ trueString
;
776 result
= urlParamString
+ falseString
;
783 * @see eu.etaxonomy.cdm.ext.IIpniService#getNamesSimple(java.lang.String, eu.etaxonomy.cdm.ext.IIpniService.DelimitedFormat, eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration)
785 public List
<BotanicalName
> getNamesSimple(String wholeName
, ICdmApplicationConfiguration services
, IpniServiceNamesConfigurator config
){
787 config
= new IpniServiceNamesConfigurator();
791 // query_type=by_query&back_page=query_ipni.html
793 wholeName
= normalizeParameter(wholeName
);
795 DelimitedFormat format
= config
.getFormat();
797 String request
= "find_wholeName=" + wholeName
+
798 "&output_format=" + format
.parameter
;
800 return (List
)queryService(request
, services
, getServiceUrl(IIpniService
.SIMPLE_NAME_SERVICE_URL
), config
, ServiceType
.NAME
);
804 * @see eu.etaxonomy.cdm.ext.IIpniService#getPublications(java.lang.String, java.lang.String, boolean, eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration)
806 public List
<ReferenceBase
> getPublications(String title
, String abbreviation
, ICdmApplicationConfiguration services
, IpniServicePublicationConfigurator config
){
807 // http://www.uk.ipni.org/ipni/advPublicationSearch.do?find_title=Spe*plant*&find_abbreviation=&output_format=normal&query_type=by_query&back_page=publicationsearch
808 // http://www.uk.ipni.org/ipni/advPublicationSearch.do?find_title=*Hortus+Britannicus*&find_abbreviation=&output_format=delimited-classic&output_format=delimited
811 config
= new IpniServicePublicationConfigurator();
814 title
= normalizeParameter(title
);
815 abbreviation
= normalizeParameter(abbreviation
);
817 String request
= "find_title=" + title
+
818 "&find_abbreviation=" + abbreviation
+
819 "&output_format=" + DelimitedFormat
.CLASSIC
.parameter
;
821 List
<ReferenceBase
> result
= (List
)queryService(request
, services
, getServiceUrl(IIpniService
.PUBLICATION_SERVICE_URL
), config
, ServiceType
.PUBLICATION
);
830 private DelimitedFormat
getDefaultFormat() {
831 return DelimitedFormat
.SHORT
;
838 * @return the serviceUrl
840 public URL
getServiceUrl(String url
) {
843 serviceUrl
= new URL(url
);
844 } catch (MalformedURLException e
) {
845 throw new RuntimeException("This should not happen", e
);