/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package edu.harvard.iq.dataverse.export.dublincore; import com.google.gson.Gson; import edu.harvard.iq.dataverse.DatasetFieldConstant; import edu.harvard.iq.dataverse.api.dto.DatasetDTO; import edu.harvard.iq.dataverse.api.dto.DatasetVersionDTO; import edu.harvard.iq.dataverse.api.dto.FieldDTO; import edu.harvard.iq.dataverse.api.dto.MetadataBlockDTO; import edu.harvard.iq.dataverse.export.ddi.DdiExportUtil; import edu.harvard.iq.dataverse.util.json.JsonUtil; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.json.JsonObject; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; /** * * @author skraffmi */ public class DublinCoreExportUtil { private static final Logger logger = Logger.getLogger(DdiExportUtil.class.getCanonicalName()); public static String OAI_DC_XML_NAMESPACE = "http://www.openarchives.org/OAI/2.0/oai_dc/"; public static String OAI_DC_XML_SCHEMALOCATION = "http://www.openarchives.org/OAI/2.0/oai_dc.xsd"; public static String DC_XML_NAMESPACE = "http://purl.org/dc/elements/1.1/"; public static String DCTERMS_XML_NAMESPACE = "http://purl.org/dc/terms/"; public static String DCTERMS_DEFAULT_NAMESPACE="http://dublincore.org/documents/dcmi-terms/"; public static String DCTERMS_XML_SCHEMALOCATION="http://dublincore.org/schemas/xmls/qdc/dcterms.xsd"; public static String DEFAULT_XML_VERSION = "2.0"; public static String DC_FLAVOR_OAI = "dc"; public static String DC_FLAVOR_DCTERMS = "dcterms"; public static String DEFAULT_DC_FLAVOR = DC_FLAVOR_DCTERMS; public static void datasetJson2dublincore(JsonObject datasetDtoAsJson, OutputStream outputStream, String dcFlavor) throws XMLStreamException { logger.fine(JsonUtil.prettyPrint(datasetDtoAsJson.toString())); Gson gson = new Gson(); DatasetDTO datasetDto = gson.fromJson(datasetDtoAsJson.toString(), DatasetDTO.class); //try { dto2dublincore(datasetDto, outputStream, dcFlavor); //} catch (XMLStreamException ex) { // Logger.getLogger(DdiExportUtil.class.getName()).log(Level.SEVERE, null, ex); //} } private static void dto2dublincore(DatasetDTO datasetDto, OutputStream outputStream, String dcFlavor) throws XMLStreamException { XMLStreamWriter xmlw = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream); if (DC_FLAVOR_DCTERMS.equals(dcFlavor)) { xmlw.writeStartElement("metadata"); xmlw.writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); xmlw.writeAttribute("xmlns:dc", DC_XML_NAMESPACE); xmlw.writeAttribute("xmlns:dcterms", DCTERMS_XML_NAMESPACE); xmlw.writeDefaultNamespace(DCTERMS_DEFAULT_NAMESPACE); //xmlw.writeAttribute("xsi:schemaLocation", DCTERMS_DEFAULT_NAMESPACE+" "+DCTERMS_XML_SCHEMALOCATION); createDC(xmlw, datasetDto, dcFlavor); } else if (DC_FLAVOR_OAI.equals(dcFlavor)) { xmlw.writeStartElement("oai_dc:dc"); xmlw.writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); xmlw.writeAttribute("xmlns:oai_dc", OAI_DC_XML_NAMESPACE); xmlw.writeAttribute("xmlns:dc", DC_XML_NAMESPACE); xmlw.writeAttribute("xsi:schemaLocation", OAI_DC_XML_NAMESPACE+" "+OAI_DC_XML_SCHEMALOCATION); //writeAttribute(xmlw, "version", DEFAULT_XML_VERSION); createOAIDC(xmlw, datasetDto, dcFlavor); } xmlw.writeEndElement(); // <metadata> or <oai_dc:dc> xmlw.flush(); } //UPDATED by rmo-cdsp: // If the requested flavor is "OAI_DC" (the minimal, original 15 field format), // we shuld NOT be exporting the extended, DCTERMS fields (aka not createDC) // - such as, for example, "dateSubmitted" ... (4.5.1?) // -- L.A. // but use createOAIDC instead (the minimal, original 15 field format) private static void createDC(XMLStreamWriter xmlw, DatasetDTO datasetDto, String dcFlavor) throws XMLStreamException { DatasetVersionDTO version = datasetDto.getDatasetVersion(); String persistentAgency = datasetDto.getProtocol(); String persistentAuthority = datasetDto.getAuthority(); String persistentId = datasetDto.getIdentifier(); writeFullElement(xmlw, dcFlavor+":"+"title", dto2Primitive(version, DatasetFieldConstant.title)); xmlw.writeStartElement(dcFlavor+":"+"identifier"); xmlw.writeCharacters(persistentAgency + ":" + persistentAuthority + "/" + persistentId); xmlw.writeEndElement(); // decterms:identifier writeAuthorsElement(xmlw, version, dcFlavor); writeFullElement(xmlw, dcFlavor+":"+"publisher", datasetDto.getPublisher()); writeFullElement(xmlw, dcFlavor+":"+"issued", datasetDto.getPublicationDate()); writeFullElement(xmlw, dcFlavor+":"+"modified", datasetDto.getDatasetVersion().getLastUpdateTime()); writeAbstractElement(xmlw, version, dcFlavor); // Description writeSubjectElement(xmlw, version, dcFlavor); //Subjects and Key Words writeFullElementList(xmlw, dcFlavor+":"+"language", dto2PrimitiveList(version, DatasetFieldConstant.language)); writeRelPublElement(xmlw, version, dcFlavor); writeFullElement(xmlw, dcFlavor+":"+"date", dto2Primitive(version, DatasetFieldConstant.productionDate)); writeFullElement(xmlw, dcFlavor+":"+"contributor", dto2Primitive(version, DatasetFieldConstant.depositor)); writeContributorElement(xmlw, version, dcFlavor); writeFullElement(xmlw, dcFlavor+":"+"dateSubmitted", dto2Primitive(version, DatasetFieldConstant.dateOfDeposit)); writeTimeElements(xmlw, version, dcFlavor); writeFullElementList(xmlw, dcFlavor+":"+"relation", dto2PrimitiveList(version, DatasetFieldConstant.relatedDatasets)); writeFullElementList(xmlw, dcFlavor+":"+"type", dto2PrimitiveList(version, DatasetFieldConstant.kindOfData)); writeFullElementList(xmlw, dcFlavor+":"+"source", dto2PrimitiveList(version, DatasetFieldConstant.dataSources)); //Geo Elements writeSpatialElements(xmlw, version, dcFlavor); //License and Terms writeFullElement(xmlw, dcFlavor+":"+"license", version.getLicense()); writeFullElement(xmlw, dcFlavor+":"+"rights", version.getTermsOfUse()); writeFullElement(xmlw, dcFlavor+":"+"rights", version.getRestrictions()); } private static void createOAIDC(XMLStreamWriter xmlw, DatasetDTO datasetDto, String dcFlavor) throws XMLStreamException { DatasetVersionDTO version = datasetDto.getDatasetVersion(); String persistentAgency = datasetDto.getProtocol(); String persistentAuthority = datasetDto.getAuthority(); String persistentId = datasetDto.getIdentifier(); writeFullElement(xmlw, dcFlavor+":"+"title", dto2Primitive(version, DatasetFieldConstant.title)); xmlw.writeStartElement(dcFlavor+":"+"identifier"); xmlw.writeCharacters(persistentAgency + ":" + persistentAuthority + "/" + persistentId); xmlw.writeEndElement(); // decterms:identifier writeAuthorsElement(xmlw, version, dcFlavor); //creator writeFullElement(xmlw, dcFlavor+":"+"publisher", datasetDto.getPublisher()); writeAbstractElement(xmlw, version, dcFlavor); // Description writeSubjectElement(xmlw, version, dcFlavor); //Subjects and Key Words writeFullElementList(xmlw, dcFlavor+":"+"language", dto2PrimitiveList(version, DatasetFieldConstant.language)); writeFullElement(xmlw, dcFlavor+":"+"date", dto2Primitive(version, DatasetFieldConstant.productionDate)); writeFullElement(xmlw, dcFlavor+":"+"contributor", dto2Primitive(version, DatasetFieldConstant.depositor)); writeContributorElement(xmlw, version, dcFlavor); writeFullElementList(xmlw, dcFlavor+":"+"relation", dto2PrimitiveList(version, DatasetFieldConstant.relatedDatasets)); writeFullElementList(xmlw, dcFlavor+":"+"type", dto2PrimitiveList(version, DatasetFieldConstant.kindOfData)); writeFullElementList(xmlw, dcFlavor+":"+"source", dto2PrimitiveList(version, DatasetFieldConstant.dataSources)); } private static void writeAuthorsElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO, String dcFlavor) throws XMLStreamException { for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) { String key = entry.getKey(); MetadataBlockDTO value = entry.getValue(); if ("citation".equals(key)) { for (FieldDTO fieldDTO : value.getFields()) { if (DatasetFieldConstant.author.equals(fieldDTO.getTypeName())) { String authorName = ""; for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) { for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) { FieldDTO next = iterator.next(); if (DatasetFieldConstant.authorName.equals(next.getTypeName())) { authorName = next.getSinglePrimitive(); } } if (!authorName.isEmpty()) { xmlw.writeStartElement(dcFlavor+":"+"creator"); xmlw.writeCharacters(authorName); xmlw.writeEndElement(); //AuthEnty } } } } } } } private static void writeAbstractElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO, String dcFlavor) throws XMLStreamException { for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) { String key = entry.getKey(); MetadataBlockDTO value = entry.getValue(); if ("citation".equals(key)) { for (FieldDTO fieldDTO : value.getFields()) { if (DatasetFieldConstant.description.equals(fieldDTO.getTypeName())) { String descriptionText = ""; for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) { for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) { FieldDTO next = iterator.next(); if (DatasetFieldConstant.descriptionText.equals(next.getTypeName())) { descriptionText = next.getSinglePrimitive(); } } if (!descriptionText.isEmpty()){ xmlw.writeStartElement(dcFlavor+":"+"description"); xmlw.writeCharacters(descriptionText); xmlw.writeEndElement(); //abstract } } } } } } } private static void writeSubjectElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO, String dcFlavor) throws XMLStreamException{ //Key Words and Subject for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) { String key = entry.getKey(); MetadataBlockDTO value = entry.getValue(); if ("citation".equals(key)) { for (FieldDTO fieldDTO : value.getFields()) { if (DatasetFieldConstant.subject.equals(fieldDTO.getTypeName())){ for ( String subject : fieldDTO.getMultipleVocab()){ xmlw.writeStartElement(dcFlavor+":"+"subject"); xmlw.writeCharacters(subject); xmlw.writeEndElement(); //Keyword } } if (DatasetFieldConstant.keyword.equals(fieldDTO.getTypeName())) { for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) { String keywordValue = ""; for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) { FieldDTO next = iterator.next(); if (DatasetFieldConstant.keywordValue.equals(next.getTypeName())) { keywordValue = next.getSinglePrimitive(); } } if (!keywordValue.isEmpty()){ xmlw.writeStartElement(dcFlavor+":"+"subject"); xmlw.writeCharacters(keywordValue); xmlw.writeEndElement(); //Keyword } } } } } } } private static void writeRelPublElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO, String dcFlavor) throws XMLStreamException { for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) { String key = entry.getKey(); MetadataBlockDTO value = entry.getValue(); if ("citation".equals(key)) { for (FieldDTO fieldDTO : value.getFields()) { if (DatasetFieldConstant.publication.equals(fieldDTO.getTypeName())) { for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) { String pubString = ""; String citation = ""; String IDType = ""; String IDNo = ""; String url = ""; for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) { FieldDTO next = iterator.next(); if (DatasetFieldConstant.publicationCitation.equals(next.getTypeName())) { citation = next.getSinglePrimitive(); } if (DatasetFieldConstant.publicationIDType.equals(next.getTypeName())) { IDType = next.getSinglePrimitive(); } if (DatasetFieldConstant.publicationIDNumber.equals(next.getTypeName())) { IDNo = next.getSinglePrimitive(); } if (DatasetFieldConstant.publicationURL.equals(next.getTypeName())) { url = next.getSinglePrimitive(); } } pubString = appendCommaSeparatedValue(citation, IDType); pubString = appendCommaSeparatedValue(pubString, IDNo); pubString = appendCommaSeparatedValue(pubString, url); if (!pubString.isEmpty()){ xmlw.writeStartElement(dcFlavor+":"+"isReferencedBy"); xmlw.writeCharacters(pubString); xmlw.writeEndElement(); //relPubl } } } } } } } private static void writeContributorElement(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO, String dcFlavor) throws XMLStreamException { for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) { String key = entry.getKey(); MetadataBlockDTO value = entry.getValue(); if ("citation".equals(key)) { for (FieldDTO fieldDTO : value.getFields()) { if (DatasetFieldConstant.contributor.equals(fieldDTO.getTypeName())) { String contributorName = ""; for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) { for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) { FieldDTO next = iterator.next(); if (DatasetFieldConstant.contributorName.equals(next.getTypeName())) { contributorName = next.getSinglePrimitive(); } } if (!contributorName.isEmpty()){ xmlw.writeStartElement(dcFlavor+":"+"contributor"); xmlw.writeCharacters(contributorName); xmlw.writeEndElement(); //abstract } } } } } } } private static void writeTimeElements(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO, String dcFlavor) throws XMLStreamException { for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) { String key = entry.getKey(); MetadataBlockDTO value = entry.getValue(); if ("citation".equals(key)) { for (FieldDTO fieldDTO : value.getFields()) { if (DatasetFieldConstant.timePeriodCovered.equals(fieldDTO.getTypeName())) { String dateValStart = ""; String dateValEnd = ""; for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) { for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) { FieldDTO next = iterator.next(); if (DatasetFieldConstant.timePeriodCoveredStart.equals(next.getTypeName())) { dateValStart = next.getSinglePrimitive(); } if (DatasetFieldConstant.timePeriodCoveredEnd.equals(next.getTypeName())) { dateValEnd = next.getSinglePrimitive(); } } if (!dateValStart.isEmpty()) { writeFullElement(xmlw, dcFlavor+":"+"temporal", dateValStart); } if (!dateValEnd.isEmpty()) { writeFullElement(xmlw, dcFlavor+":"+"temporal", dateValEnd); } } } if (DatasetFieldConstant.dateOfCollection.equals(fieldDTO.getTypeName())) { String dateValStart = ""; String dateValEnd = ""; for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) { for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) { FieldDTO next = iterator.next(); if (DatasetFieldConstant.dateOfCollectionStart.equals(next.getTypeName())) { dateValStart = next.getSinglePrimitive(); } if (DatasetFieldConstant.dateOfCollectionEnd.equals(next.getTypeName())) { dateValEnd = next.getSinglePrimitive(); } } if (!dateValStart.isEmpty()) { writeFullElement(xmlw, dcFlavor+":"+"temporal", dateValStart); } if (!dateValEnd.isEmpty()) { writeFullElement(xmlw, dcFlavor+":"+"temporal", dateValEnd); } } } } } } } private static void writeSpatialElements(XMLStreamWriter xmlw, DatasetVersionDTO datasetVersionDTO, String dcFlavor) throws XMLStreamException { for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) { String key = entry.getKey(); MetadataBlockDTO value = entry.getValue(); if("geospatial".equals(key)){ for (FieldDTO fieldDTO : value.getFields()) { if (DatasetFieldConstant.geographicCoverage.equals(fieldDTO.getTypeName())) { for (HashSet<FieldDTO> foo : fieldDTO.getMultipleCompound()) { for (Iterator<FieldDTO> iterator = foo.iterator(); iterator.hasNext();) { FieldDTO next = iterator.next(); if (DatasetFieldConstant.country.equals(next.getTypeName())) { writeFullElement(xmlw, dcFlavor+":"+"spatial", next.getSinglePrimitive()); } if (DatasetFieldConstant.city.equals(next.getTypeName())) { writeFullElement(xmlw, dcFlavor+":"+"spatial", next.getSinglePrimitive()); } if (DatasetFieldConstant.state.equals(next.getTypeName())) { writeFullElement(xmlw, dcFlavor+":"+"spatial", next.getSinglePrimitive()); } if (DatasetFieldConstant.otherGeographicCoverage.equals(next.getTypeName())) { writeFullElement(xmlw, dcFlavor+":"+"spatial", next.getSinglePrimitive()); } } } } } } } } private static String appendCommaSeparatedValue(String inVal, String next) { if (!next.isEmpty()) { if (!inVal.isEmpty()) { return inVal + ", " + next; } else { return next; } } return inVal; } private static String dto2Primitive(DatasetVersionDTO datasetVersionDTO, String datasetFieldTypeName) { for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) { MetadataBlockDTO value = entry.getValue(); for (FieldDTO fieldDTO : value.getFields()) { if (datasetFieldTypeName.equals(fieldDTO.getTypeName())) { return fieldDTO.getSinglePrimitive(); } } } return null; } private static List<String> dto2PrimitiveList(DatasetVersionDTO datasetVersionDTO, String datasetFieldTypeName) { for (Map.Entry<String, MetadataBlockDTO> entry : datasetVersionDTO.getMetadataBlocks().entrySet()) { MetadataBlockDTO value = entry.getValue(); for (FieldDTO fieldDTO : value.getFields()) { if (datasetFieldTypeName.equals(fieldDTO.getTypeName())) { return fieldDTO.getMultiplePrimitive(); } } } return null; } private static void writeFullElementList(XMLStreamWriter xmlw, String name, List<String> values) throws XMLStreamException { //For the simplest Elements we can if (values != null && !values.isEmpty()) { for (String value : values) { xmlw.writeStartElement(name); xmlw.writeCharacters(value); xmlw.writeEndElement(); // labl } } } private static void writeFullElement (XMLStreamWriter xmlw, String name, String value) throws XMLStreamException { //For the simplest Elements we can if (!StringUtilisEmpty(value)) { xmlw.writeStartElement(name); xmlw.writeCharacters(value); xmlw.writeEndElement(); // labl } } private static void writeAttribute(XMLStreamWriter xmlw, String name, String value) throws XMLStreamException { if (!StringUtilisEmpty(value)) { xmlw.writeAttribute(name, value); } } private static boolean StringUtilisEmpty(String str) { if (str == null || str.trim().equals("")) { return true; } return false; } }