diff --git a/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java b/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java index 57136d6143b..bd5791481e9 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java +++ b/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java @@ -8,13 +8,14 @@ package org.dspace.identifier.doi; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URISyntaxException; import java.sql.SQLException; -import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; @@ -35,13 +36,14 @@ import org.apache.http.util.EntityUtils; import org.dspace.authorize.AuthorizeException; import org.dspace.content.DSpaceObject; +import org.dspace.content.Item; import org.dspace.content.crosswalk.CrosswalkException; -import org.dspace.content.crosswalk.DisseminationCrosswalk; -import org.dspace.content.crosswalk.ParameterizedDisseminationCrosswalk; +import org.dspace.content.crosswalk.StreamDisseminationCrosswalk; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.DSpaceObjectService; +import org.dspace.content.service.ItemService; +import org.dspace.core.Constants; import org.dspace.core.Context; -import org.dspace.core.factory.CoreServiceFactory; import org.dspace.handle.service.HandleService; import org.dspace.identifier.DOI; import org.dspace.services.ConfigurationService; @@ -99,18 +101,6 @@ public class DataCiteConnector * dependency injection. */ protected String METADATA_PATH; - /** - * Name of crosswalk to convert metadata into DataCite Metadata Scheme. Set - * by spring dependency injection. - */ - protected String CROSSWALK_NAME; - /** - * DisseminationCrosswalk to map local metadata into DataCite metadata. - * The name of the crosswalk is set by spring dependency injection using - * {@link #setDisseminationCrosswalkName(String) setDisseminationCrosswalkName} which - * instantiates the crosswalk. - */ - protected ParameterizedDisseminationCrosswalk xwalk; protected ConfigurationService configurationService; @@ -119,8 +109,12 @@ public class DataCiteConnector @Autowired protected HandleService handleService; + @Autowired + private ItemService itemService; + + private Map disseminationCrosswalkByEntityType; + public DataCiteConnector() { - this.xwalk = null; this.USERNAME = null; this.PASSWORD = null; } @@ -189,34 +183,6 @@ public void setConfigurationService(ConfigurationService configurationService) { this.configurationService = configurationService; } - /** - * Set the name of the dissemination crosswalk used to convert the metadata - * into DataCite Metadata Schema. Used by spring dependency injection. - * - * @param CROSSWALK_NAME The name of the dissemination crosswalk to use. This - * crosswalk must be configured in dspace.cfg. - */ - @Autowired(required = true) - public void setDisseminationCrosswalkName(String CROSSWALK_NAME) { - this.CROSSWALK_NAME = CROSSWALK_NAME; - } - - protected void prepareXwalk() { - if (null != this.xwalk) { - return; - } - - this.xwalk = (ParameterizedDisseminationCrosswalk) CoreServiceFactory.getInstance().getPluginService() - .getNamedPlugin( - DisseminationCrosswalk.class, - this.CROSSWALK_NAME); - - if (this.xwalk == null) { - throw new RuntimeException("Can't find crosswalk '" - + CROSSWALK_NAME + "'!"); - } - } - protected String getUsername() { if (null == this.USERNAME) { this.USERNAME = this.configurationService.getProperty(CFG_USER); @@ -350,64 +316,43 @@ public void deleteDOI(Context context, String doi) @Override public void reserveDOI(Context context, DSpaceObject dso, String doi) throws DOIIdentifierException { - this.prepareXwalk(); DSpaceObjectService dSpaceObjectService = ContentServiceFactory.getInstance() .getDSpaceObjectService(dso); - if (!this.xwalk.canDisseminate(dso)) { - log.error("Crosswalk " + this.CROSSWALK_NAME - + " cannot disseminate DSO with type " + dso.getType() - + " and ID " + dso.getID() + ". Giving up reserving the DOI " - + doi + "."); - throw new DOIIdentifierException("Cannot disseminate " - + dSpaceObjectService.getTypeText(dso) + "/" + dso.getID() - + " using crosswalk " + this.CROSSWALK_NAME + ".", - DOIIdentifierException.CONVERSION_ERROR); - } + StreamDisseminationCrosswalk xwalk = getStreamDisseminationCrosswalkByDso(dso); - // Set the transform's parameters. - // XXX Should the actual list be configurable? - Map parameters = new HashMap<>(); - if (configurationService.hasProperty(CFG_PREFIX)) { - parameters.put("prefix", - configurationService.getProperty(CFG_PREFIX)); - } - if (configurationService.hasProperty(CFG_PUBLISHER)) { - parameters.put("publisher", - configurationService.getProperty(CFG_PUBLISHER)); - } - if (configurationService.hasProperty(CFG_DATAMANAGER)) { - parameters.put("datamanager", - configurationService.getProperty(CFG_DATAMANAGER)); - } - if (configurationService.hasProperty(CFG_HOSTINGINSTITUTION)) { - parameters.put("hostinginstitution", - configurationService.getProperty(CFG_HOSTINGINSTITUTION)); + if (xwalk == null) { + log.error("No crosswalk found for DSO with type " + dso.getType() + + " and ID " + dso.getID() + ". Giving up reserving the DOI " + + doi + "."); + throw new DOIIdentifierException("Cannot disseminate " + + dSpaceObjectService.getTypeText(dso) + "/" + dso.getID() + ".", + DOIIdentifierException.CONVERSION_ERROR); } Element root = null; try { - root = xwalk.disseminateElement(context, dso, parameters); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + xwalk.disseminate(context, dso, baos); + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(new ByteArrayInputStream(baos.toByteArray())); + root = document.getRootElement(); } catch (AuthorizeException ae) { log.error("Caught an AuthorizeException while disseminating DSO " + "with type " + dso.getType() + " and ID " + dso.getID() + ". Giving up to reserve DOI " + doi + ".", ae); throw new DOIIdentifierException("AuthorizeException occured while " - + "converting " + dSpaceObjectService.getTypeText(dso) + "/" + dso - .getID() - + " using crosswalk " + this.CROSSWALK_NAME + ".", ae, + + "converting " + dSpaceObjectService.getTypeText(dso) + "/" + dso + ".", ae, DOIIdentifierException.CONVERSION_ERROR); } catch (CrosswalkException ce) { log.error("Caught an CrosswalkException while reserving a DOI (" + doi + ") for DSO with type " + dso.getType() + " and ID " + dso.getID() + ". Won't reserve the doi.", ce); throw new DOIIdentifierException("CrosswalkException occured while " - + "converting " + dSpaceObjectService.getTypeText(dso) + "/" + dso - .getID() - + " using crosswalk " + this.CROSSWALK_NAME + ".", ce, + + "converting " + dSpaceObjectService.getTypeText(dso) + "/" + dso + ".", ce, DOIIdentifierException.CONVERSION_ERROR); - } catch (IOException | SQLException ex) { + } catch (IOException | SQLException | JDOMException ex) { throw new RuntimeException(ex); } @@ -462,6 +407,21 @@ public void reserveDOI(Context context, DSpaceObject dso, String doi) } } + private StreamDisseminationCrosswalk getStreamDisseminationCrosswalkByDso(DSpaceObject dso) { + + if (dso.getType() != Constants.ITEM) { + return null; + } + + String entityType = itemService.getEntityType((Item) dso); + if (StringUtils.isBlank(entityType)) { + entityType = "Publication"; + } + + return disseminationCrosswalkByEntityType.get(entityType); + + } + @Override public void registerDOI(Context context, DSpaceObject dso, String doi) throws DOIIdentifierException { @@ -631,7 +591,7 @@ protected DataCiteResponse sendMetadataPostRequest(String doi, Element metadataR Format format = Format.getCompactFormat(); format.setEncoding("UTF-8"); XMLOutputter xout = new XMLOutputter(format); - return sendMetadataPostRequest(doi, xout.outputString(new Document(metadataRoot))); + return sendMetadataPostRequest(doi, xout.outputString(metadataRoot.getDocument())); } protected DataCiteResponse sendMetadataPostRequest(String doi, String metadata) @@ -848,6 +808,15 @@ protected Element addDOI(String doi, Element root) { return root.addContent(0, identifier); } + public Map getDisseminationCrosswalkByEntityType() { + return disseminationCrosswalkByEntityType; + } + + public void setDisseminationCrosswalkByEntityType( + Map disseminationCrosswalkByEntityType) { + this.disseminationCrosswalkByEntityType = disseminationCrosswalkByEntityType; + } + protected class DataCiteResponse { private final int statusCode; private final String content; diff --git a/dspace/config/crosswalks/mapConverter-datacitePublicationLicense.properties b/dspace/config/crosswalks/mapConverter-datacitePublicationLicense.properties new file mode 100644 index 00000000000..05bcf86c28d --- /dev/null +++ b/dspace/config/crosswalks/mapConverter-datacitePublicationLicense.properties @@ -0,0 +1,8 @@ +CC\ BY = https://creativecommons.org/licenses/by/4.0/legalcode +CC\ BY\-SA = https://creativecommons.org/licenses/by-sa/4.0/legalcode +CC\ BY\-ND = https://creativecommons.org/licenses/by-nd/4.0/legalcode +CC\ BY\-NC = https://creativecommons.org/licenses/by-nc/4.0/legalcode +CC\ BY\-NC\-SA = https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode +CC\ BY\-NC\-ND = https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode +CC0 = https://creativecommons.org/share-your-work/public-domain/cc0/ +PDM = https://creativecommons.org/publicdomain/mark/1.0/ \ No newline at end of file diff --git a/dspace/config/crosswalks/mapConverter-datacitePublicationRights.properties b/dspace/config/crosswalks/mapConverter-datacitePublicationRights.properties new file mode 100644 index 00000000000..049024f7dc5 --- /dev/null +++ b/dspace/config/crosswalks/mapConverter-datacitePublicationRights.properties @@ -0,0 +1,4 @@ +openaccess = http://purl.org/coar/access_right/c_abf2 +embargoed = http://purl.org/coar/access_right/c_f1cf +restricted = http://purl.org/coar/access_right/c_16ec +metadata\ only = http://purl.org/coar/access_right/c_14cb \ No newline at end of file diff --git a/dspace/config/crosswalks/mapConverter-datacitePublicationTypes.properties b/dspace/config/crosswalks/mapConverter-datacitePublicationTypes.properties new file mode 100644 index 00000000000..0ef150d6f8f --- /dev/null +++ b/dspace/config/crosswalks/mapConverter-datacitePublicationTypes.properties @@ -0,0 +1,50 @@ +Resource\ Types\:\:text = Text +Resource\ Types\:\:text\:\:annotation = Text +Resource\ Types\:\:text\:\:bibliography = Text +Resource\ Types\:\:text\:\:blog\ post = Text +Resource\ Types\:\:text\:\:book = Book +Resource\ Types\:\:text\:\:book\:\:book\ part = BookChapter +Resource\ Types\:\:text\:\:conference\ output = ConferencePaper +Resource\ Types\:\:text\:\:conference\ output\:\:conference paper not in proceedings = ConferencePaper +Resource\ Types\:\:text\:\:conference\ output\:\:conference poster not in proceedings = ConferencePaper +Resource\ Types\:\:text\:\:conference\ output\:\:conference presentation = ConferenceProceeding +Resource\ Types\:\:text\:\:conference\ output\:\:conference proceedings = ConferenceProceeding +Resource\ Types\:\:text\:\:journal = Journal +Resource\ Types\:\:text\:\:journal\:\:editorial = Journal +Resource\ Types\:\:text\:\:journal\:\:journal\ article = JournalArticle +Resource\ Types\:\:text\:\:journal\:\:journal\ article\:\:corrigendum = JournalArticle +Resource\ Types\:\:text\:\:journal\:\:journal\ article\:\:data\ paper = JournalArticle +Resource\ Types\:\:text\:\:journal\:\:journal\ article\:\:research\ article = JournalArticle +Resource\ Types\:\:text\:\:journal\:\:journal\ article\:\:review\ article = JournalArticle +Resource\ Types\:\:text\:\:journal\:\:journal\ article\:\:software\ paper = JournalArticle +Resource\ Types\:\:text\:\:journal\:\:letter\ to\ the\ editor = Journal +Resource\ Types\:\:text\:\:lecture = Text +Resource\ Types\:\:text\:\:letter = Text +Resource\ Types\:\:text\:\:magazine = Text +Resource\ Types\:\:text\:\:manuscript = Text +Resource\ Types\:\:text\:\:musical\ notation = Sound +Resource\ Types\:\:text\:\:newspaper = Text +Resource\ Types\:\:text\:\:newspaper\:\:newspaper\ article = Text +Resource\ Types\:\:text\:\:other\ periodical = Text +Resource\ Types\:\:text\:\:preprint = Preprint +Resource\ Types\:\:text\:\:report = Report +Resource\ Types\:\:text\:\:report\:\:clinical\ study = Report +Resource\ Types\:\:text\:\:report\:\:data\ management\ plan = OutputManagementPlan +Resource\ Types\:\:text\:\:report\:\:memorandum = Report +Resource\ Types\:\:text\:\:report\:\:policy\ report = Report +Resource\ Types\:\:text\:\:report\:\:project\ deliverable = Report +Resource\ Types\:\:text\:\:report\:\:research\ protocol = Report +Resource\ Types\:\:text\:\:report\:\:research\ report = Report +Resource\ Types\:\:text\:\:report\:\:technical\ report = Report +Resource\ Types\:\:text\:\:research\ proposal = Text +Resource\ Types\:\:text\:\:review = PeerReview +Resource\ Types\:\:text\:\:review\:\:book\ review = PeerReview +Resource\ Types\:\:text\:\:review\:\:commentary = PeerReview +Resource\ Types\:\:text\:\:review\:\:peer\ review = PeerReview +Resource\ Types\:\:text\:\:technical\ documentation = Text +Resource\ Types\:\:text\:\:thesis = Dissertation +Resource\ Types\:\:text\:\:thesis\:\:bachelor\ thesis = Dissertation +Resource\ Types\:\:text\:\:thesis\:\:doctoral\ thesis = Dissertation +Resource\ Types\:\:text\:\:thesis\:\:master\ thesis = Dissertation +Resource\ Types\:\:text\:\:transcription = Text +Resource\ Types\:\:text\:\:working\ paper = Preprint diff --git a/dspace/config/crosswalks/template/patent-datacite-xml.template b/dspace/config/crosswalks/template/patent-datacite-xml.template new file mode 100644 index 00000000000..22b400e9692 --- /dev/null +++ b/dspace/config/crosswalks/template/patent-datacite-xml.template @@ -0,0 +1,43 @@ + + + @dc.identifier.doi@ + + @group.dc-contributor-author.start@ + + @dc.contributor.author@ + @relation.dc-contributor-author.start@ + @person.identifier.orcid@ + @relation.dc-contributor-author.end@ + @oairecerif.author.affiliation@ + + @group.dc-contributor-author.end@ + + + @dc.title@ + + @dc.publisher@ + @virtual.date.dc-date-issued.YYYY@ + + @dc.subject@ + + + @dc.date.issued@ + @datacite.available@ + + @dc.language.iso@ + + + @dc.identifier.uri@ + + @dc.description.version@ + + + @oaire.licenseCondition@ + + @datacite.rights@ + + + @dc.description.abstract@ + @dc.description@ + + \ No newline at end of file diff --git a/dspace/config/crosswalks/template/product-datacite-xml.template b/dspace/config/crosswalks/template/product-datacite-xml.template new file mode 100644 index 00000000000..50224aa35cc --- /dev/null +++ b/dspace/config/crosswalks/template/product-datacite-xml.template @@ -0,0 +1,42 @@ + + + @dc.identifier.doi@ + + @group.dc-contributor-author.start@ + + @dc.contributor.author@ + @relation.dc-contributor-author.start@ + @person.identifier.orcid@ + @relation.dc-contributor-author.end@ + @oairecerif.author.affiliation@ + + @group.dc-contributor-author.end@ + + + @dc.title@ + + @dc.publisher@ + @virtual.date.dc-date-issued.YYYY@ + + @dc.subject@ + + + @dc.date.issued@ + + @dc.language.iso@ + + + @dc.identifier.uri@ + + @dc.description.version@ + + + @oaire.licenseCondition@ + + @datacite.rights@ + + + @dc.description.abstract@ + @dc.description@ + + \ No newline at end of file diff --git a/dspace/config/crosswalks/template/publication-datacite-xml.template b/dspace/config/crosswalks/template/publication-datacite-xml.template new file mode 100644 index 00000000000..22b400e9692 --- /dev/null +++ b/dspace/config/crosswalks/template/publication-datacite-xml.template @@ -0,0 +1,43 @@ + + + @dc.identifier.doi@ + + @group.dc-contributor-author.start@ + + @dc.contributor.author@ + @relation.dc-contributor-author.start@ + @person.identifier.orcid@ + @relation.dc-contributor-author.end@ + @oairecerif.author.affiliation@ + + @group.dc-contributor-author.end@ + + + @dc.title@ + + @dc.publisher@ + @virtual.date.dc-date-issued.YYYY@ + + @dc.subject@ + + + @dc.date.issued@ + @datacite.available@ + + @dc.language.iso@ + + + @dc.identifier.uri@ + + @dc.description.version@ + + + @oaire.licenseCondition@ + + @datacite.rights@ + + + @dc.description.abstract@ + @dc.description@ + + \ No newline at end of file diff --git a/dspace/config/spring/api/crosswalks.xml b/dspace/config/spring/api/crosswalks.xml index 8af3936f480..504645bd83b 100644 --- a/dspace/config/spring/api/crosswalks.xml +++ b/dspace/config/spring/api/crosswalks.xml @@ -19,6 +19,7 @@ + @@ -59,8 +60,10 @@ + + @@ -283,6 +286,15 @@ + + + + + + + + + @@ -332,6 +344,24 @@ + + + + + + + + + + + + + + + + + + @@ -568,6 +598,9 @@ + + + @@ -644,6 +677,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/dspace/config/spring/api/identifier-service.xml b/dspace/config/spring/api/identifier-service.xml index dbcd49df0e9..39754edce46 100644 --- a/dspace/config/spring/api/identifier-service.xml +++ b/dspace/config/spring/api/identifier-service.xml @@ -1,8 +1,11 @@ + http://www.springframework.org/schema/beans/spring-beans-2.5.xsd + http://www.springframework.org/schema/util + http://www.springframework.org/schema/util/spring-util.xsd">