merge-update from trunk
[cdmlib.git] / cdmlib-ext / src / main / java / eu / etaxonomy / cdm / ext / ipni / IpniService.java
index b712c2e7d5a53219b97ed52a984fa824bbb47f49..37d00782356ec19a0577892cb57f3293e25bf7ea 100644 (file)
@@ -15,6 +15,8 @@ import java.io.InputStream;
 import java.io.InputStreamReader;\r
 import java.net.HttpURLConnection;\r
 import java.net.MalformedURLException;\r
+import java.net.URI;\r
+import java.net.URISyntaxException;\r
 import java.net.URL;\r
 import java.text.ParseException;\r
 import java.util.ArrayList;\r
@@ -23,13 +25,14 @@ import java.util.List;
 import java.util.Map;\r
 \r
 import org.apache.commons.lang.StringUtils;\r
+import org.apache.http.HttpResponse;\r
 import org.apache.log4j.Logger;\r
 import org.springframework.stereotype.Component;\r
 \r
 import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration;\r
 import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;\r
-import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade.DerivedUnitType;\r
 import eu.etaxonomy.cdm.common.CdmUtils;\r
+import eu.etaxonomy.cdm.common.UriUtils;\r
 import eu.etaxonomy.cdm.model.agent.Person;\r
 import eu.etaxonomy.cdm.model.agent.Team;\r
 import eu.etaxonomy.cdm.model.common.Annotation;\r
@@ -38,25 +41,30 @@ import eu.etaxonomy.cdm.model.common.Extension;
 import eu.etaxonomy.cdm.model.common.ExtensionType;\r
 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;\r
 import eu.etaxonomy.cdm.model.common.Language;\r
+import eu.etaxonomy.cdm.model.common.OriginalSourceType;\r
 import eu.etaxonomy.cdm.model.common.TimePeriod;\r
 import eu.etaxonomy.cdm.model.name.BotanicalName;\r
 import eu.etaxonomy.cdm.model.name.NomenclaturalCode;\r
 import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;\r
 import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;\r
 import eu.etaxonomy.cdm.model.name.Rank;\r
-import eu.etaxonomy.cdm.model.reference.ReferenceBase;\r
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;\r
+import eu.etaxonomy.cdm.model.reference.Reference;\r
 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;\r
 import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;\r
-\r
+import eu.etaxonomy.cdm.strategy.parser.TimePeriodParser;\r
 \r
 /**\r
 * @author a.mueller\r
 * @created Aug 16, 2010\r
 * @version 1.0\r
+ *\r
+ * TODO the whole ipni service should be refactored to use UriUtils. I did this for the queryService method only because we ran into timeout\r
+ * problems in tests. UriUtils handles these problems already.\r
  *\r
  */\r
 @Component\r
-public class IpniService implements IIpniService{\r
+public class IpniService  implements IIpniService{\r
        private static final String EAST_OR_WEST = "East or west";\r
 \r
        private static final String NORTH_OR_SOUTH = "North or south";\r
@@ -158,6 +166,7 @@ public class IpniService implements IIpniService{
                 AUTHOR,\r
                 NAME,\r
                 PUBLICATION,\r
+                ID\r
        }\r
        \r
        public enum IpniRank{\r
@@ -232,6 +241,8 @@ public class IpniService implements IIpniService{
               \r
 \r
        /**\r
+        *      FIXME rewrote this method to rely on {@link UriUtils}. The whole class should be adjusted to reflect this change.\r
+        *      Also see comments in the class' documentation block.\r
         *\r
         * @param restRequest\r
         * @return\r
@@ -241,32 +252,32 @@ public class IpniService implements IIpniService{
                        throw new NullPointerException("Ipni service configurator should not be null");\r
                }\r
                try {\r
+                       \r
             // create the request url\r
             URL newUrl = new URL(serviceUrl.getProtocol(),\r
                                                      serviceUrl.getHost(),\r
                                                      serviceUrl.getPort(),\r
                                                      serviceUrl.getPath() \r
                                                      + "?" + request);\r
-            // open a connection\r
-            HttpURLConnection connection = (HttpURLConnection) newUrl.openConnection();\r
-            // set the accept property to XML so we can use jdom to handle the content\r
-            //connection.setRequestProperty("Accept", "text/xml");\r
-   \r
-           \r
-            logger.info("Firing request for URL: " + newUrl);\r
-                   \r
-            int responseCode = connection.getResponseCode();\r
-           \r
+            \r
+            \r
+            URI newUri = newUrl.toURI();\r
+                       \r
+            logger.info("Firing request for URI: " + newUri);\r
+                \r
+            HttpResponse response = UriUtils.getResponse(newUri, null);\r
+            \r
+            int responseCode = response.getStatusLine().getStatusCode();\r
+            \r
             // get the content at the resource\r
-            InputStream content = (InputStream) connection.getContent();\r
-           \r
+            InputStream content = response.getEntity().getContent();\r
             // build the result\r
             List<? extends IdentifiableEntity> result;\r
             if (serviceType.equals(ServiceType.AUTHOR)){\r
                result = buildAuthorList(content, services, config);\r
             }else if (serviceType.equals(ServiceType.NAME)){\r
                result = buildNameList(content, services, config);\r
-            }else{\r
+            }else {\r
                result = buildPublicationList(content, services, config);\r
             }\r
             if(responseCode == HttpURLConnection.HTTP_OK){\r
@@ -277,17 +288,56 @@ public class IpniService implements IIpniService{
             }\r
                \r
         } catch (IOException e) {\r
-                logger.error("No content for request: " + request);\r
-        }\r
+            logger.error("No content for request: " + request);\r
+        } catch (URISyntaxException e) {\r
+                       logger.error("Given URL could not be transformed into URI", e);\r
+               }\r
        \r
         // error\r
         return null;\r
     }\r
+       \r
+       public InputStream queryServiceForID (String request, URL serviceUrl){\r
+               \r
+               try {\r
+                       \r
+            // create the request url\r
+            URL newUrl = new URL(serviceUrl.getProtocol(),\r
+                                                     serviceUrl.getHost(),\r
+                                                     serviceUrl.getPort(),\r
+                                                     serviceUrl.getPath() \r
+                                                     + "?" + request);\r
+            \r
+            \r
+            URI newUri = newUrl.toURI();\r
+                       \r
+            logger.info("Firing request for URI: " + newUri);\r
+                \r
+            HttpResponse response = UriUtils.getResponse(newUri, null);\r
+            \r
+            int responseCode = response.getStatusLine().getStatusCode();\r
+            \r
+            // get the content at the resource\r
+            InputStream content = response.getEntity().getContent();\r
+            return content;\r
+           \r
+                  } catch (IOException e) {\r
+                   logger.error("No content for request: " + request);\r
+               } catch (URISyntaxException e) {\r
+                               logger.error("Given URL could not be transformed into URI", e);\r
+                       }\r
+         \r
+               return null;\r
+       \r
+       }\r
+\r
+       \r
+\r
 \r
-       private List<ReferenceBase> buildPublicationList( InputStream content, ICdmApplicationConfiguration services, IIpniServiceConfigurator iConfig) throws IOException {\r
+       private List<Reference> buildPublicationList( InputStream content, ICdmApplicationConfiguration services, IIpniServiceConfigurator iConfig) throws IOException {\r
                IpniServicePublicationConfigurator config = (IpniServicePublicationConfigurator)iConfig;\r
                \r
-               List<ReferenceBase> result = new ArrayList<ReferenceBase>(); \r
+               List<Reference> result = new ArrayList<Reference>(); \r
                BufferedReader reader = new BufferedReader (new InputStreamReader(content));\r
                \r
                String headerLine = reader.readLine();\r
@@ -295,7 +345,7 @@ public class IpniService implements IIpniService{
                \r
                String line = reader.readLine();\r
                while (StringUtils.isNotBlank(line)){\r
-                       ReferenceBase reference = getPublicationFromLine(line, parameterMap, services, config);\r
+                       Reference reference = getPublicationFromLine(line, parameterMap, services, config);\r
                        result.add(reference);\r
                        line = reader.readLine();\r
                }\r
@@ -304,7 +354,14 @@ public class IpniService implements IIpniService{
        }\r
 \r
 \r
-       private ReferenceBase getPublicationFromLine(String line, Map<Integer, String> parameterMap, ICdmApplicationConfiguration appConfig, IpniServicePublicationConfigurator config) {\r
+       /**\r
+        * @param line\r
+        * @param parameterMap\r
+        * @param appConfig\r
+        * @param config\r
+        * @return\r
+        */\r
+       private Reference getPublicationFromLine(String line, Map<Integer, String> parameterMap, ICdmApplicationConfiguration appConfig, IpniServicePublicationConfigurator config) {\r
                //fill value map\r
                String[] splits = line.split("%");\r
                \r
@@ -314,7 +371,7 @@ public class IpniService implements IIpniService{
                }\r
                \r
                //create reference object\r
-               ReferenceBase ref = ReferenceFactory.newGeneric();\r
+               Reference ref = ReferenceFactory.newGeneric();\r
                \r
                //reference\r
                if (config.isUseAbbreviationAsTitle() == true){\r
@@ -330,30 +387,45 @@ public class IpniService implements IIpniService{
                ref.setPlacePublished(valueMap.get(PLACE));\r
 \r
                String author = valueMap.get(PUBLICATION_AUTHOR_TEAM);\r
-               Team team = Team.NewTitledInstance(author, author);\r
-               ref.setAuthorTeam(team);\r
+               if (StringUtils.isNotBlank(author)){\r
+                       Team team = Team.NewTitledInstance(author, author);\r
+                       ref.setAuthorship(team);\r
+               }\r
                \r
                //remarks\r
                String remarks = valueMap.get(REMARKS);\r
                Annotation annotation = Annotation.NewInstance(remarks, AnnotationType.EDITORIAL(), Language.ENGLISH());\r
                ref.addAnnotation(annotation);\r
 \r
+\r
+               String tl2AuthorString = valueMap.get(TL2_AUTHOR);\r
+               if (ref.getAuthorship() == null){\r
+                       Team tl2Author = Team.NewTitledInstance(tl2AuthorString, null);\r
+                       ref.setAuthorship(tl2Author);\r
+               }else{\r
+                       //TODO parse name, \r
+                       ref.getAuthorship().setTitleCache(tl2AuthorString, true);\r
+                       ref.addAnnotation(Annotation.NewInstance(tl2AuthorString, AnnotationType.EDITORIAL(), Language.ENGLISH()));\r
+               }\r
+\r
+               \r
                //dates\r
-               TimePeriod date = TimePeriod.parseString(valueMap.get(DATE));\r
+               TimePeriod date = TimePeriodParser.parseString(valueMap.get(DATE));\r
                ref.setDatePublished(date);\r
 \r
+\r
                //source\r
-               ReferenceBase citation = getIpniCitation(appConfig);\r
-               ref.addSource(valueMap.get(ID), "Publication", citation, valueMap.get(VERSION));\r
+               Reference citation = getIpniCitation(appConfig);\r
+               ref.addSource(OriginalSourceType.Lineage, valueMap.get(ID), "Publication", citation, valueMap.get(VERSION));\r
 \r
                \r
+               \r
 /*             TODO\r
                BPH number\r
                Authors role\r
                In publication facade\r
                LC number\r
                Preceded by\r
-               TL2 author\r
                TL2 number\r
                TDWG abbreviation\r
        */\r
@@ -372,9 +444,11 @@ public class IpniService implements IIpniService{
                \r
                String line = reader.readLine();\r
                while (StringUtils.isNotBlank(line)){\r
+                       \r
                        BotanicalName name = getNameFromLine(line,parameterMap, appConfig);\r
                        result.add(name);\r
                        line = reader.readLine();\r
+                       \r
                }\r
 \r
                \r
@@ -406,7 +480,7 @@ public class IpniService implements IIpniService{
                //rank\r
                try {\r
                        String rankStr = nomalizeRank(valueMap.get(RANK));\r
-                       name.setRank(Rank.getRankByNameOrAbbreviation(rankStr, NomenclaturalCode.ICBN, true));\r
+                       name.setRank(Rank.getRankByNameOrIdInVoc(rankStr, NomenclaturalCode.ICNAFP, true));\r
                } catch (UnknownCdmTypeException e) {\r
                        logger.warn("Rank was unknown");\r
                }\r
@@ -416,9 +490,9 @@ public class IpniService implements IIpniService{
                name.setCombinationAuthorTeam(Team.NewTitledInstance(valueMap.get(PUBLISHING_AUTHOR), valueMap.get(PUBLISHING_AUTHOR)));\r
                \r
                //publication\r
-               ReferenceBase ref = ReferenceFactory.newGeneric();\r
-               ref.setTitleCache(valueMap.get(PUBLICATION));\r
-               TimePeriod datePublished = TimePeriod.parseString(valueMap.get(PUBLICATION_YEAR_FULL));\r
+               Reference<?> ref = ReferenceFactory.newGeneric();\r
+               ref.setTitleCache(valueMap.get(PUBLICATION), true);\r
+               TimePeriod datePublished = TimePeriodParser.parseString(valueMap.get(PUBLICATION_YEAR_FULL));\r
                name.setNomenclaturalReference(ref);\r
                \r
                //name status\r
@@ -426,7 +500,7 @@ public class IpniService implements IIpniService{
                String statusString = valueMap.get(NAME_STATUS);\r
                if (StringUtils.isNotBlank(statusString)){\r
                        try {\r
-                               statusType = NomenclaturalStatusType.getNomenclaturalStatusTypeByAbbreviation(statusString);\r
+                               statusType = NomenclaturalStatusType.getNomenclaturalStatusTypeByAbbreviation(statusString, name);\r
                                NomenclaturalStatus nomStatus = NomenclaturalStatus.NewInstance(statusType);\r
                                name.addStatus(nomStatus);\r
                        } catch (UnknownCdmTypeException e) {\r
@@ -450,12 +524,12 @@ public class IpniService implements IIpniService{
                name.addReplacedSynonym(replacedSynoynm, null, null, null);\r
 \r
                //type information\r
-               DerivedUnitFacade specimen = DerivedUnitFacade.NewInstance(DerivedUnitType.Specimen);\r
+               DerivedUnitFacade specimen = DerivedUnitFacade.NewInstance(SpecimenOrObservationType.PreservedSpecimen);\r
                \r
                \r
                //gathering period\r
                String collectionDateAsText = valueMap.get(COLLECTION_DATE_AS_TEXT);\r
-               TimePeriod gatheringPeriod = TimePeriod.parseString(collectionDateAsText);\r
+               TimePeriod gatheringPeriod = TimePeriodParser.parseString(collectionDateAsText);\r
                \r
                try {\r
                        gatheringPeriod.setStartDay(getIntegerDateValueOrNull(valueMap, COLLECTION_DAY1));\r
@@ -483,13 +557,13 @@ public class IpniService implements IIpniService{
                        String latMinutes = CdmUtils.Nz(valueMap.get(LATITUDE_MINUTES));\r
                        String latSeconds = CdmUtils.Nz(valueMap.get(LATITUDE_SECONDS));\r
                        String direction = CdmUtils.Nz(valueMap.get(NORTH_OR_SOUTH));\r
-                       String latitude = latDegrees + "°" + latMinutes + "'" + latSeconds + "\"" + direction;\r
+                       String latitude = latDegrees + "°" + latMinutes + "'" + latSeconds + "\"" + direction;\r
                        \r
                        String lonDegrees = CdmUtils.Nz(valueMap.get(LATITUDE_DEGREES));\r
                        String lonMinutes = CdmUtils.Nz(valueMap.get(LATITUDE_MINUTES));\r
                        String lonSeconds = CdmUtils.Nz(valueMap.get(LATITUDE_SECONDS));\r
                        direction = CdmUtils.Nz(valueMap.get(EAST_OR_WEST));\r
-                       String longitude = lonDegrees + "°" + lonMinutes + "'" + lonSeconds + "\"" + direction;\r
+                       String longitude = lonDegrees + "°" + lonMinutes + "'" + lonSeconds + "\"" + direction;\r
 \r
                        \r
                        specimen.setExactLocationByParsing(longitude, latitude, null, null);\r
@@ -515,8 +589,8 @@ public class IpniService implements IIpniService{
                \r
                \r
                //source\r
-               ReferenceBase citation = getIpniCitation(appConfig);\r
-               name.addSource(valueMap.get(ID), "Name", citation, valueMap.get(VERSION));\r
+               Reference citation = getIpniCitation(appConfig);\r
+               name.addSource(OriginalSourceType.Lineage, valueMap.get(ID), "Name", citation, valueMap.get(VERSION));\r
                \r
                \r
 //             //TODO\r
@@ -613,9 +687,11 @@ public class IpniService implements IIpniService{
 \r
        private Map<Integer, String> getParameterMap(String headerLine) {\r
                Map<Integer, String> result = new HashMap<Integer, String>();\r
-               String[] splits = headerLine.split("%");\r
-               for (int i = 0; i < splits.length ; i ++){\r
-                       result.put(i, splits[i]);\r
+               if ( headerLine != null ){\r
+                       String[] splits = headerLine.split("%");\r
+                       for (int i = 0; i < splits.length ; i ++){\r
+                               result.put(i, splits[i]);\r
+                       }\r
                }\r
                return result;\r
        }\r
@@ -636,13 +712,13 @@ public class IpniService implements IIpniService{
                person.setFirstname(valueMap.get(DEFAULT_AUTHOR_FORENAME));\r
                person.setLastname(valueMap.get(DEFAULT_AUTHOR_SURNAME));\r
                \r
-               ReferenceBase citation = getIpniCitation(appConfig);\r
+               Reference<?> citation = getIpniCitation(appConfig);\r
                \r
                //id, version\r
-               person.addSource(valueMap.get(ID), "Author", citation, valueMap.get(VERSION));\r
+               person.addSource(OriginalSourceType.Lineage, valueMap.get(ID), "Author", citation, valueMap.get(VERSION));\r
                \r
                //dates\r
-               TimePeriod lifespan = TimePeriod.parseString(valueMap.get(DATES));\r
+               TimePeriod lifespan = TimePeriodParser.parseString(valueMap.get(DATES));\r
                person.setLifespan(lifespan);\r
                \r
                //alternative_names\r
@@ -663,8 +739,8 @@ public class IpniService implements IIpniService{
        }\r
 \r
        \r
-       private ReferenceBase getIpniCitation(ICdmApplicationConfiguration appConfig) {\r
-               ReferenceBase ipniReference;\r
+       private Reference getIpniCitation(ICdmApplicationConfiguration appConfig) {\r
+               Reference<?> ipniReference;\r
                if (appConfig != null){\r
                        ipniReference = appConfig.getReferenceService().find(uuidIpni);\r
                        if (ipniReference == null){\r
@@ -681,8 +757,8 @@ public class IpniService implements IIpniService{
        /**\r
         * @return\r
         */\r
-       private ReferenceBase getNewIpniReference() {\r
-               ReferenceBase ipniReference;\r
+       private Reference getNewIpniReference() {\r
+               Reference<?> ipniReference;\r
                ipniReference = ReferenceFactory.newDatabase();\r
                ipniReference.setTitleCache("The International Plant Names Index (IPNI)");\r
                return ipniReference;\r
@@ -803,7 +879,7 @@ public class IpniService implements IIpniService{
        /* (non-Javadoc)\r
         * @see eu.etaxonomy.cdm.ext.IIpniService#getPublications(java.lang.String, java.lang.String, boolean, eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration)\r
         */\r
-       public List<ReferenceBase> getPublications(String title, String abbreviation, ICdmApplicationConfiguration services, IpniServicePublicationConfigurator config){\r
+       public List<Reference> getPublications(String title, String abbreviation, ICdmApplicationConfiguration services, IpniServicePublicationConfigurator config){\r
 //             http://www.uk.ipni.org/ipni/advPublicationSearch.do?find_title=Spe*plant*&find_abbreviation=&output_format=normal&query_type=by_query&back_page=publicationsearch\r
 //             http://www.uk.ipni.org/ipni/advPublicationSearch.do?find_title=*Hortus+Britannicus*&find_abbreviation=&output_format=delimited-classic&output_format=delimited\r
                \r
@@ -818,7 +894,7 @@ public class IpniService implements IIpniService{
                                                "&find_abbreviation=" + abbreviation +\r
                                                "&output_format=" + DelimitedFormat.CLASSIC.parameter;\r
                \r
-               List<ReferenceBase> result = (List)queryService(request, services, getServiceUrl(IIpniService.PUBLICATION_SERVICE_URL), config, ServiceType.PUBLICATION);\r
+               List<Reference> result = (List)queryService(request, services, getServiceUrl(IIpniService.PUBLICATION_SERVICE_URL), config, ServiceType.PUBLICATION);\r
                return result;\r
        }\r
 \r
@@ -847,6 +923,25 @@ public class IpniService implements IIpniService{
                return serviceUrl;\r
        }\r
 \r
+\r
+       @Override\r
+       public InputStream getNamesById(String id) {\r
+               \r
+       \r
+               String request = "id="+id + "&output_format=lsid-metadata";\r
+               return queryServiceForID(request, getServiceUrl(IIpniService.ID_NAMESEARCH_SERVICE_URL));\r
+               \r
+       }\r
+       \r
+       @Override\r
+       public InputStream getPublicationsById(String id) {\r
+               \r
+       \r
+               String request = "id="+id ;\r
+               return queryServiceForID(request, getServiceUrl(IIpniService.ID_PUBLICATION_SERVICE_URL));\r
+               \r
+       }\r
+\r
                \r
        \r
 }\r