diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/DublinCoreBuilder.java b/oaipmh-core/src/main/java/info/textgrid/middleware/DublinCoreBuilder.java index f59edf8af827b9536910eae0c75e2e8aa9dfef78..835d05314fb830968cdab5095aa70d08cd5385ab 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/DublinCoreBuilder.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/DublinCoreBuilder.java @@ -114,7 +114,7 @@ public final class DublinCoreBuilder { for (String dcdate : dates) { ElementType dateElement = new ElementType(); JAXBElement<ElementType> dcCoreDate = oaiDcObj.createDate(dateElement); - dateElement.setValue(OaipmhUtilities.oaiDatestampAsString(dcdate)); + dateElement.setValue(dcdate); this.tgMappedDC.getTitleOrCreatorOrSubject().add(dcCoreDate); } } diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/DublinCoreFieldLoader.java b/oaipmh-core/src/main/java/info/textgrid/middleware/DublinCoreFieldLoader.java index 2d780b859efed754b7f2dcd0d896bd3b6ef27803..6801e39c535d5a46202f2ad5ac34ac337e588c1b 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/DublinCoreFieldLoader.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/DublinCoreFieldLoader.java @@ -15,14 +15,12 @@ import org.elasticsearch.search.SearchHit; * </p> * * <p> - * For each element two functions are necessary because the datatype "SeachHit" could contain more + * For each element two functions are necessary because the data type "SeachHit" could contain more * then one results and the GetResponse just one. * </p> * * @author Maximilian Brodhun, SUB Göttingen * @author Stefan E. Funk, SUB Göttingen - * @version 2019-10-29 - * @since 2014-02-18 */ public class DublinCoreFieldLoader { @@ -49,25 +47,15 @@ public class DublinCoreFieldLoader { */ public static List<String> setDate(GetResponse responseWorkValues, String[] fields) { - // TODO We don't need this here, I suppose? We have to check the dates here! - // return fillList(responseWorkValues, fields); - List<String> dates = new ArrayList<String>(); // Transform to OAI-PMH certificated time stamp if (responseWorkValues.isExists()) { for (String field : fields) { - try { - // TODO Set values in config file! - if (responseWorkValues.getField(field) != null) { - dates.add(OaipmhUtilities - .oaiDatestampAsString(responseWorkValues.getField(field).getValue().toString())); - } - } catch (ParseException e) { - // TODO Do not use invalid dates here! + // TODO Set values in config file! + if (responseWorkValues.getField(field) != null) { + // We need ISO8601 here, take entries as they come from ElasticSearch! dates.add(responseWorkValues.getField(field).getValue().toString()); - log.fine("tried to parse date value: " - + responseWorkValues.getField(field).getValue().toString()); } } } @@ -86,13 +74,8 @@ public class DublinCoreFieldLoader { for (String field : fields) { if (hit.getFields().get(field) != null) { - try { - dates.add(OaipmhUtilities - .oaiDatestampAsString(hit.getFields().get(field).getValues().get(0).toString())); - } catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + // We need ISO8601 here, take entries as they come from ElasticSearch! + dates.add(hit.getFields().get(field).getValues().get(0).toString()); } } diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererAbstract.java b/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererAbstract.java index c6206eba11c01b87e3093605b887ea1e6b2dd20f..f5ab2f45d001c71e1460fde292911d84b41b0fe3 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererAbstract.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererAbstract.java @@ -1,7 +1,5 @@ package info.textgrid.middleware; - -import java.text.ParseException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -18,8 +16,6 @@ import info.textgrid.middleware.oaipmh.ResumptionTokenType; /** * @author Stefan E. Funk, SUB Göttingen - * @version 2023-01-10 - * @since 2014-02-20 */ public abstract class IdentifierListDelivererAbstract implements IdentifierListDelivererInterface { @@ -47,7 +43,6 @@ public abstract class IdentifierListDelivererAbstract implements IdentifierListD protected long resultSize; protected int searchResponseSize; protected ResumptionTokenType resTokenForResponse; - protected String datestamp; protected boolean idExist = true; protected String[] identifierListFields; // Fields for the elasticsearch request protected String rangeField; // Field for the optional range query @@ -128,20 +123,14 @@ public abstract class IdentifierListDelivererAbstract implements IdentifierListD public SearchResponse hitHandling(SearchResponse listFurtherValues, ListIdentifiersType lit, String set, String resumptionToken, Map<String, Integer> cursorCollector) { - int i = 0; long size = listFurtherValues.getHits().totalHits; setResultSize(size); for (SearchHit hit : listFurtherValues.getHits().getHits()) { - i++; // Handle TextGrid. if (this.textgrid) { String datestamp = hit.getSourceAsMap().get(this.dateOfObjectCreation).toString(); - try { - datestamp = OaipmhUtilities.oaiDatestampAsString(datestamp); - } catch (ParseException e) { - log.severe(e.getMessage()); - } + datestamp = OaipmhUtilities.getUTCDateAsString(datestamp); String identifier = hit.getSourceAsMap().get(this.identifierField).toString(); lit = setListIdentifierHeader(datestamp, identifier, lit, set); } @@ -149,26 +138,17 @@ public abstract class IdentifierListDelivererAbstract implements IdentifierListD // Handle DARIAH. else if (this.dariah) { JSONObject json = new JSONObject(hit.getSourceAsMap()); - - // Get modifiedDate field and convert datestamp. - this.datestamp = OaipmhUtilities.firstEnrtryFieldLoader(json, this.dateOfObjectCreation); - try { - this.datestamp = OaipmhUtilities.oaiDatestampAsString(this.datestamp); - } catch (ParseException e) { - log.severe(e.getMessage()); - // TODO Go to ERROR state! - } - - // Get identifier field. - String identifier = OaipmhUtilities.firstEnrtryFieldLoader(json, this.identifierField); - lit = setListIdentifierHeader(this.datestamp, identifier, lit, set); + String datestamp = OaipmhUtilities.firstEntryFieldLoader(json, this.dateOfObjectCreation); + datestamp = OaipmhUtilities.getUTCDateAsString(datestamp); + String identifier = OaipmhUtilities.firstEntryFieldLoader(json, this.identifierField); + lit = setListIdentifierHeader(datestamp, identifier, lit, set); } } // Check the need for a resumption token! ResumptionTokenType responseToken = OaipmhUtilities.getResumptionToken( listFurtherValues.getHits().getTotalHits(), resumptionToken, cursorCollector, - listFurtherValues.getScrollId(), this.searchResponseSize, i); + listFurtherValues.getScrollId(), this.searchResponseSize); if (responseToken != null) { lit.setResumptionToken(responseToken); } diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererDatacite.java b/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererDatacite.java index cbcc39db766e5c8d4ce8ae5c02b6c937687d4bb6..f674977b88d1cff0af09724e48cb4b6ee1352d6f 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererDatacite.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererDatacite.java @@ -21,8 +21,6 @@ import info.textgrid.middleware.oaipmh.ListIdentifiersType; * </p> * * @author Stefan E. Funk, SUB Göttingen - * @version 2022-09-07 - * @since 2014-02-20 */ public class IdentifierListDelivererDatacite extends IdentifierListDelivererAbstract { diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererIdiom.java b/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererIdiom.java index 489a00624e24bf3e7f6523670d737a5e680d5fb2..4b483374e9bedd653d955222f854bec7b2003696 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererIdiom.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererIdiom.java @@ -141,22 +141,19 @@ public class IdentifierListDelivererIdiom extends IdentifierListDelivererAbstrac if (completeListSize > 0) { setFoundItems(true); - int i = 0; for (SearchHit hit : scrollResp.getHits().getHits()) { - i++; String textgridURI = OaipmhUtilities - .firstEnrtryFieldLoader(new JSONObject(hit.getSourceAsMap()), this.identifierField); - String createdDate = OaipmhUtilities.oaiDatestampAsString(OaipmhUtilities - .firstEnrtryFieldLoader(new JSONObject(hit.getSourceAsMap()), this.rangeField)); - + .firstEntryFieldLoader(new JSONObject(hit.getSourceAsMap()), this.identifierField); + String createdDate = OaipmhUtilities.getUTCDateAsString(OaipmhUtilities + .firstEntryFieldLoader(new JSONObject(hit.getSourceAsMap()), this.rangeField)); identifierList.getHeader().add(OaipmhUtilities.computeResponseHeader(createdDate, OaipmhUtilities.getTextGridBaseURI(textgridURI), "")); } // Check the need for a resumption token! ResumptionTokenType responseToken = OaipmhUtilities.getResumptionToken(completeListSize, - resumptionToken, cursorCollector, scrollID, IDIOM_RESPONSE_SIZE, i); + resumptionToken, cursorCollector, scrollID, IDIOM_RESPONSE_SIZE); if (responseToken != null) { identifierList.setResumptionToken(responseToken); } diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/IdiomImages.java b/oaipmh-core/src/main/java/info/textgrid/middleware/IdiomImages.java index de9a118f29a2daeb26113d52d72fe6929e3093fe..76283c910403ea13ec0e489e1ab4a3ddf77273d7 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/IdiomImages.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/IdiomImages.java @@ -220,7 +220,7 @@ public class IdiomImages implements RecordDelivererInterface, RecordListDelivere // Use base URI for IDIOM image delivery! String tgBaseURI = OaipmhUtilities.getTextGridBaseURI(changedID); conedaKorRecord.setHeader(buildOAIPMHRecordHeader( - OaipmhUtilities.oaiDatestampAsString(immByTGObject.getCreationDate()), tgBaseURI)); + OaipmhUtilities.getUTCDateAsString(immByTGObject.getCreationDate()), tgBaseURI)); singleImageMetsMods.setRecord(conedaKorRecord); diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/MetadataFormatListDelivererAbstract.java b/oaipmh-core/src/main/java/info/textgrid/middleware/MetadataFormatListDelivererAbstract.java index 8439befbad719f87786d171bb569e1fbae1e1c74..0e4bce6e3a9910b1664acd82a68b95a1671cec41 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/MetadataFormatListDelivererAbstract.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/MetadataFormatListDelivererAbstract.java @@ -16,16 +16,6 @@ public abstract class MetadataFormatListDelivererAbstract protected OaipmhElasticSearchClient oaiEsClient; - private boolean idExist = true; - - /** - * @param textgrid - * @param dariah - */ - public MetadataFormatListDelivererAbstract() { - // - } - /** * */ @@ -41,7 +31,7 @@ public abstract class MetadataFormatListDelivererAbstract mft.setSchema(OaipmhConstants.OAIDC_SCHEMA_LOCATION); result.getMetadataFormat().add(mft); - // Add metadata format for OPEN AIRE. + // Add metadata format for (oai_datacite). MetadataFormatType mftOpenAire = new MetadataFormatType(); mftOpenAire.setMetadataNamespace(OaipmhConstants.DATACITE_NAMESPACE); mftOpenAire.setMetadataPrefix(OaipmhConstants.METADATA_OPENAIRE_PREFIX); @@ -75,20 +65,6 @@ public abstract class MetadataFormatListDelivererAbstract // GETTERS & SETTERS // - /** - * @return - */ - public boolean isIdExist() { - return this.idExist; - } - - /** - * @param idExist - */ - public void setIdExist(boolean idExist) { - this.idExist = idExist; - } - /** * @return */ diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/MetadataFormatListDelivererDH.java b/oaipmh-core/src/main/java/info/textgrid/middleware/MetadataFormatListDelivererDH.java index 38ac270b2d45cd9715da22c98373cdf7df13d103..c2d361a1f2ef9d9ac2549a391ad7752b8ab0f89d 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/MetadataFormatListDelivererDH.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/MetadataFormatListDelivererDH.java @@ -7,20 +7,13 @@ import info.textgrid.middleware.oaipmh.ListMetadataFormatsType; */ public class MetadataFormatListDelivererDH extends MetadataFormatListDelivererAbstract { - /** - * @param textgrid - * @param dariah - */ - public MetadataFormatListDelivererDH() { - // NOTE We do not have specific metadata formats for DHREP right now. - } - /** * */ @Override public ListMetadataFormatsType setMetadataFormatList(String id) { - // Get things from abstract class. + // Get things from abstract class, we do not have different metadata formats for different + // identifiers! Get the two defaults here. return super.setMetadataFormatList(); } diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/MetadataFormatListDelivererTG.java b/oaipmh-core/src/main/java/info/textgrid/middleware/MetadataFormatListDelivererTG.java index 2ad0e6512d83f937619e8d10ee8f17a5dcc07369..334fe565fbe3827cf7f662fefdab26889f3f5ac2 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/MetadataFormatListDelivererTG.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/MetadataFormatListDelivererTG.java @@ -20,13 +20,6 @@ public class MetadataFormatListDelivererTG extends MetadataFormatListDelivererAb public static final String URI = "textgridUri"; - /** - * - */ - public MetadataFormatListDelivererTG() { - // - } - /** * <p> * Get metadata format list for specific ID. @@ -35,14 +28,12 @@ public class MetadataFormatListDelivererTG extends MetadataFormatListDelivererAb @Override public ListMetadataFormatsType setMetadataFormatList(String id) { + ListMetadataFormatsType result = new ListMetadataFormatsType(); + String[] includes = new String[] {URI}; String[] excludes = Strings.EMPTY_ARRAY; FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes); - ListMetadataFormatsType lmft = new ListMetadataFormatsType(); - MetadataFormatType mft = new MetadataFormatType(); - MetadataFormatType openAireMetadataFormat = new MetadataFormatType(); - GetRequest getRequest = new GetRequest(this.oaiEsClient.getEsIndex(), this.oaiEsClient.getEsType(), id.replace("textgrid:", "")).fetchSourceContext(fetchSourceContext); @@ -51,29 +42,18 @@ public class MetadataFormatListDelivererTG extends MetadataFormatListDelivererAb try { tgObject = this.oaiEsClient.getEsClient().get(getRequest, RequestOptions.DEFAULT); + // Check if object is existing in TG. if (tgObject.isExists()) { - setIdExist(true); - mft.setMetadataPrefix(OaipmhConstants.METADATA_OAIDC_PREFIX); - mft.setMetadataNamespace(OaipmhConstants.OAIDC_NAMESPACE); - mft.setSchema(OaipmhConstants.OAIDC_SCHEMA_LOCATION); - - openAireMetadataFormat.setMetadataPrefix(OaipmhConstants.METADATA_OPENAIRE_PREFIX); - openAireMetadataFormat.setMetadataNamespace(OaipmhConstants.DATACITE_NAMESPACE); - openAireMetadataFormat.setSchema(OaipmhConstants.DATACITE_SCHEMA_LOCATION); + result = setMetadataFormatList(); - lmft.getMetadataFormat().add(mft); - lmft.getMetadataFormat().add(openAireMetadataFormat); - - } else { - setIdExist(false); - lmft = null; + // TODO Check here, if object is existing in IDIOM? } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } - return lmft; + return result; } /** diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/OaipmhConstants.java b/oaipmh-core/src/main/java/info/textgrid/middleware/OaipmhConstants.java index f02e9f374be049a7bf45516900c7aec830745ef4..710d26b77a3d6e0b2713cc6ea13fbdd677e170b6 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/OaipmhConstants.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/OaipmhConstants.java @@ -19,7 +19,7 @@ public final class OaipmhConstants { // Namespaces public static final String OAIPMH_NAMESPACE = "http://www.openarchives.org/OAI/2.0/"; public static final String OAIPMH_SCHEMA_LOCATION = - "https://www.openarchives.org/OAI/2.0/OAI-PMH.xsd"; + "http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd"; public static final String OAIDC_NAMESPACE = "http://www.openarchives.org/OAI/2.0/oai_dc/"; public static final String OAIDC_SCHEMA_LOCATION = @@ -30,14 +30,14 @@ public final class OaipmhConstants { "https://dublincore.org/schemas/xmls/simpledc20021212.xsd"; public static final String METS_NAMESPACE = "http://www.loc.gov/METS/"; - public static final String METS_SCHEMA_LOCATION = "https://www.loc.gov/standards/mets/mets.xsd"; + public static final String METS_SCHEMA_LOCATION = "http://www.loc.gov/standards/mets/mets.xsd"; public static final String IDIOM_IMAGE_NAMESPACE = METS_NAMESPACE; public static final String IDIOM_IMAGE_SCHEMA_LOCATION = METS_SCHEMA_LOCATION; public static final String DATACITE_NAMESPACE = "http://datacite.org/schema/kernel-3"; public static final String DATACITE_SCHEMA_LOCATION = - "https://schema.datacite.org/meta/kernel-3/metadata.xsd"; + "http://schema.datacite.org/meta/kernel-3/metadata.xsd"; // Error String Constants. public static final String OAI_BAD_ARGUMENT = "BadArgument"; diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/OaipmhImpl.java b/oaipmh-core/src/main/java/info/textgrid/middleware/OaipmhImpl.java index a7cad1e61a3e63a1aaa60bd141ab7c6ea631d615..a566ecc7daf07d0fe2675911d038912699a76d3e 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/OaipmhImpl.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/OaipmhImpl.java @@ -30,8 +30,6 @@ import info.textgrid.middleware.oaipmh.VerbType; * * @author Maximilian Brodhun, SUB Göttingen * @author Stefan E. Funk, SUB Göttingen - * @version 2023-01-06 - * @since 2014-01-29 */ public class OaipmhImpl implements OaipmhProducer { @@ -419,6 +417,9 @@ public class OaipmhImpl implements OaipmhProducer { } if (listIdentifiers != null) { + if (listIdentifiers.getHeader() == null || listIdentifiers.getHeader().isEmpty()) { + return oaipmhError(oaipmhRoot, OaipmhConstants.OAI_NO_RECORD_MATCH, ""); + } oaipmhRoot.setListIdentifiers(listIdentifiers); } else { return oaipmhError(oaipmhRoot, OaipmhConstants.OAI_NO_RECORD_MATCH, @@ -481,9 +482,10 @@ public class OaipmhImpl implements OaipmhProducer { public OAIPMHtype listMetadataFormatsRequest(String id, OAIPMHtype oaipmhRoot, RequestType request) { - List<String> errorValues = new ArrayList<String>(); ListMetadataFormatsType listMF = new ListMetadataFormatsType(); + List<String> errorValues = new ArrayList<String>(); + if (this.metadataFormatList.requestChecker(request)) { if (id.isEmpty()) { @@ -492,7 +494,7 @@ public class OaipmhImpl implements OaipmhProducer { listMF = this.metadataFormatList.setMetadataFormatList(request.getIdentifier()); } - if (listMF != null) { + if (listMF != null && !listMF.getMetadataFormat().isEmpty()) { oaipmhRoot.setListMetadataFormats(listMF); } else { return oaipmhError(oaipmhRoot, OaipmhConstants.OAI_NO_RECORD_MATCH, ILLEGAL_ID); @@ -617,6 +619,9 @@ public class OaipmhImpl implements OaipmhProducer { } if (listRecords != null) { + if (listRecords.getRecord() == null || listRecords.getRecord().isEmpty()) { + return oaipmhError(oaipmhRoot, OaipmhConstants.OAI_NO_RECORD_MATCH, ""); + } oaipmhRoot.setListRecords(listRecords); } else { return oaipmhError(oaipmhRoot, OaipmhConstants.OAI_BAD_ARGUMENT, ILLEGAL_OTHER); @@ -778,7 +783,7 @@ public class OaipmhImpl implements OaipmhProducer { // Set the responseDate of today. try { - oaipmhRoot.setResponseDate(OaipmhUtilities.getXMLGregorianCalendarNow()); + oaipmhRoot.setResponseDate(OaipmhUtilities.getCurrentUTCDateAsGregorian()); } catch (DatatypeConfigurationException e) { log.severe("datatype configuration failed"); } diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/OaipmhUtilities.java b/oaipmh-core/src/main/java/info/textgrid/middleware/OaipmhUtilities.java index c4638b946e7d8f874859fdbf60a9992cad11904b..266dd0e4f17e9b268115b861c47de273e062add6 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/OaipmhUtilities.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/OaipmhUtilities.java @@ -1,20 +1,23 @@ package info.textgrid.middleware; import java.io.IOException; +import java.io.StringReader; import java.io.StringWriter; import java.math.BigInteger; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; -import java.util.GregorianCalendar; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; -import java.util.TimeZone; import java.util.logging.Logger; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; @@ -22,6 +25,9 @@ import javax.xml.bind.Marshaller; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.client.RequestOptions; @@ -29,12 +35,13 @@ import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; import info.textgrid.clients.AuthClient; import info.textgrid.clients.tgauth.AuthClientException; import info.textgrid.middleware.oaipmh.GetRecordType; import info.textgrid.middleware.oaipmh.HeaderType; -import info.textgrid.middleware.oaipmh.ListMetadataFormatsType; -import info.textgrid.middleware.oaipmh.MetadataFormatType; import info.textgrid.middleware.oaipmh.MetadataType; import info.textgrid.middleware.oaipmh.RecordType; import info.textgrid.middleware.oaipmh.Resource; @@ -52,6 +59,10 @@ import info.textgrid.namespaces.middleware.tgauth.ProjectInfo; */ public class OaipmhUtilities { + // ** + // STATICS + // ** + private static Logger log = Logger.getLogger(OaipmhUtilities.class.getName()); // ** @@ -64,9 +75,15 @@ public class OaipmhUtilities { public static final String PREFIX_DEVIDER = ":"; public static final String PREFIX_HDL = "hdl"; public static final String PREFIX_TEXTGRID = "textgrid"; - public static final Set<String> IDENTIFIER_PREFIXES_TO_FILTER = new HashSet<String>(Arrays.asList( - PREFIX_HDL, - PREFIX_TEXTGRID)); + public static final Set<String> IDENTIFIER_PREFIXES_TO_FILTER = + new HashSet<String>(Arrays.asList(PREFIX_HDL, PREFIX_TEXTGRID)); + + // Define date formats. + public static final String OAIDC_UTC_TIME_FORMAT_String = "yyyy-MM-dd'T'HH:mm:ss'Z'"; + public static final DateTimeFormatter UTC_FORMATTER = + DateTimeFormatter.ofPattern(OAIDC_UTC_TIME_FORMAT_String).withZone(ZoneId.of("UTC")); + public static final SimpleDateFormat FROM_UNTIL_FORMAT = + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); // ** // CLASS @@ -84,32 +101,6 @@ public class OaipmhUtilities { // STATICS // ** - /** - * @param verb - * @return - */ - public static boolean isOAIPMH_RequestArgument(String verb) { - String allowedArgument = "^[identifier,from,until,set,resumptionToken,metadataPrefix]*$"; - return verb.matches(allowedArgument); - } - - /** - * <p> - * Since TextGrid just supports DC the only returned MetadataFormat is DublinCore. - * </p> - * - * @return - */ - public MetadataFormatType setMetadataFormats() { - - MetadataFormatType tgDublinCore = new MetadataFormatType(); - tgDublinCore.setMetadataNamespace("http://www.openarchives.org/OAI/2.0/oai_dc/"); - tgDublinCore.setMetadataPrefix("oai_dc"); - tgDublinCore.setSchema("http://www.openarchives.org/OAI/2.0/oai_dc.xsd"); - - return tgDublinCore; - } - /** * @return * @throws AuthClientException @@ -135,87 +126,82 @@ public class OaipmhUtilities { /** * <p> - * Producing the list of all metadata formats. + * Get the current UTC date string for OAI-PMH response dates from current system millis. * </p> * - * @return tgRepMetadaFormats + * @return */ - public ListMetadataFormatsType setMetadataFormatList() { - - ListMetadataFormatsType tgRepMetadataFormats = new ListMetadataFormatsType(); - MetadataFormatType tgDublinCore = setMetadataFormats(); - tgRepMetadataFormats.getMetadataFormat().add(tgDublinCore); - - return tgRepMetadataFormats; + public static String getCurrentUTCDateAsString() { + return UTC_FORMATTER.format(Instant.now()); } /** * <p> - * Calculating the current date and give it back as XMLGregorianCalendar. + * Converting a given string representing a date value into the date format required for OAIPMH + * and give it back as string. * </p> * - * @return now - * @throws DatatypeConfigurationException + * @param originalDateTimeString + * @return */ - public static XMLGregorianCalendar getXMLGregorianCalendarNow() - throws DatatypeConfigurationException { - - GregorianCalendar gregorianCalendar = new GregorianCalendar(); - DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); - XMLGregorianCalendar now = datatypeFactory.newXMLGregorianCalendar(gregorianCalendar); - - return now; + public static String getUTCDateAsString(String originalDateTimeString) { + return UTC_FORMATTER.format(Instant.from(OffsetDateTime.parse(originalDateTimeString))); } /** * <p> - * Converting a given string representing a date value into the date format required for OAIPMH - * and give it back as XMLGregorianCalendar. + * Converting a given string representing a date value into XMLGregorianCalendar. * </p> * * @param originalDateTimeString - * @return xmlCal - * @throws ParseException + * @return * @throws DatatypeConfigurationException */ - public static XMLGregorianCalendar oaiDatestampAsGregorian(String originalDateTimeString) - throws ParseException, DatatypeConfigurationException { - - log.fine("original date time string: " + originalDateTimeString); - - SimpleDateFormat tgItemTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S"); - Date date = tgItemTime.parse(originalDateTimeString); - SimpleDateFormat outFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - outFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); - String output2 = outFormatter.format(date); - XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(output2); + public static XMLGregorianCalendar getUTCDateAsGregorian(String originalDateTimeString) + throws DatatypeConfigurationException { + return DatatypeFactory.newInstance() + .newXMLGregorianCalendar(getUTCDateAsString(originalDateTimeString)); + } - return xmlCal; + /** + * @param originalDateTimeString + * @return + * @throws DatatypeConfigurationException + */ + public static XMLGregorianCalendar getCurrentUTCDateAsGregorian() + throws DatatypeConfigurationException { + return getUTCDateAsGregorian(getCurrentUTCDateAsString()); } /** * <p> - * Converting a given string representing a date value into the date format required for OAIPMH - * and give it back as string. + * Parse incoming date for UTS format. * </p> * - * @param originalDateTimeString - * @return dateOutputAsString - * @throws ParseException + * @param incomingDate + * @return */ - public static String oaiDatestampAsString(String originalDateTimeString) throws ParseException { + public static boolean isCorrectFromUntilDate(String incomingDate) { + + boolean result = false; - log.fine("incoming date: " + originalDateTimeString); + log.fine("incoming date: " + incomingDate); - SimpleDateFormat tgItemTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S"); - Date date = tgItemTime.parse(originalDateTimeString); - SimpleDateFormat outFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - outFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); - String dateOutputAsString = outFormatter.format(date); + try { + Date d = FROM_UNTIL_FORMAT.parse(incomingDate); + FROM_UNTIL_FORMAT.format(d); + + log.fine("date used: " + result); + + result = true; + } catch (ParseException e) { + + log.warning("date not usable for from/until: " + incomingDate); - log.fine("outgoing date: " + dateOutputAsString); + result = false; + } - return dateOutputAsString; + return result; } /** @@ -223,140 +209,71 @@ public class OaipmhUtilities { * Returns a resumptionToken for a search, if necessary. * </p> * - * TODO Check if we really must put all these references in! - * * @param completeListSize * @param resumptionToken * @param cursorCollector * @param scrollID * @param searchResponseSize - * @param i * @return A resumption token if applicable, null otherwise. */ public static ResumptionTokenType getResumptionToken(final long completeListSize, final String resumptionToken, Map<String, Integer> cursorCollector, final String scrollID, - final int searchResponseSize, final int i) { + final int searchResponseSize) { - log.fine("Creating a ResumptionToken:\n" + " CompleteListSize: " + completeListSize + "\n" - + " ResumptionToken: " + resumptionToken + "\n" + " CursorCollector: " + cursorCollector - + "\n" + " ScrollID: " + scrollID + "\n" + " SearchResponseSize: " + searchResponseSize - + "\n" + " IterationStep: " + i); + ResumptionTokenType result = null; - int cursor; + log.fine("need a resumption token?\n" + + " completeListSize: " + completeListSize + "\n" + + " searchResponseSize: " + searchResponseSize + "\n" + + " resumptionToken: " + resumptionToken + "\n" + + " scrollID: " + scrollID + "\n" + + " cursorCollector (size:" + cursorCollector.size() + "): " + cursorCollector + "\n"); - // Three cases here: - // 1. Complete list size is > searchResponseSize and a token already is existing: we need to - // check hash map! - // 2. Complete list size is > searchResponseSize and we have no token: we do need one! - // 3. Complete list size is <= searchResponseSize (we do not need a token! do nothing!) if (completeListSize > searchResponseSize) { - ResumptionTokenType resTokenForResponse = new ResumptionTokenType(); + int cursor; + result = new ResumptionTokenType(); - if (resumptionToken != null && cursorCollector.containsKey(resumptionToken)) { - - cursor = cursorCollector.get(resumptionToken).intValue() + i; - if (cursor == searchResponseSize) { - // TODO Why not "cursor += searchResponseSize;" ?? - cursor = 2 * searchResponseSize; - } - resTokenForResponse.setCursor(BigInteger.valueOf((long) cursor)); - cursorCollector.put(scrollID, cursor); - } else { - resTokenForResponse.setCursor(BigInteger.valueOf(searchResponseSize)); - cursorCollector.put(scrollID, searchResponseSize); - cursor = searchResponseSize; - resTokenForResponse.setCursor(BigInteger.valueOf((long) cursor)); + log.fine("yes, we NEED a restok"); - log.fine("New ResumptionToken created from scroll ID: " + cursorCollector.get(scrollID)); - } - - // Set resumption token string if cursor is less then complete list size: More objects can be - // delivered! - if (cursor < completeListSize) { - resTokenForResponse.setValue(scrollID); + // 1. Complete list size is > searchResponseSize and a token already is existing: we need to + // check hash map! + if (resumptionToken != null && cursorCollector.containsKey(resumptionToken)) { + // Get cursor from resumption token map and increase. + cursor = cursorCollector.get(resumptionToken).intValue() + searchResponseSize; } - - // Remove resumption token string if cursor is bigger then or equal complete list size: This - // is the last response, no more objects are available! - if (cursor >= completeListSize) { - resTokenForResponse.setValue(""); + // 2. Complete list size is > searchResponseSize and we have no token: we do need one! + else { + // Cursor must be 0 in first response. + cursor = 0; } + // Set cursor, token value, and complete list size. + result.setCursor(BigInteger.valueOf(cursor)); + result.setValue(scrollID); + result.setCompleteListSize(BigInteger.valueOf(completeListSize)); + // Update token map. + cursorCollector.put(scrollID, cursor); - // Set complete list size. - resTokenForResponse.setCompleteListSize(BigInteger.valueOf(completeListSize)); + log.fine("restok from scroll id (cursor: " + cursor + "): " + result.getValue()); - return resTokenForResponse; - } - - return null; - } - - /** - * @param dateToValidate - * @return - */ - public static boolean isThisDateValid(String dateToValidate) { - - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S"); - - dateFormat.setLenient(false); - try { - dateFormat.parse(dateToValidate.trim()); - } catch (ParseException pe) { - return false; - } - return true; - } - - /** - * @param dateToValidate - * @return - */ - public static boolean isThisDateValidToOtherTimeStamp(String dateToValidate) { + // Last response, no more objects are available! + if ((cursor + searchResponseSize) >= completeListSize) { + // Remove resumption token string from response, and clear token map. + result.setValue(""); + cursorCollector.remove(scrollID); - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + log.fine("last response, restok deleted"); - dateFormat.setLenient(false); - dateFormat.setLenient(false); - try { - dateFormat.parse(dateToValidate.trim()); - } catch (ParseException pe) { - return false; + // FIXME See, how large the map is getting! Add expiration date to response and delete + // expired tokens!! + } } - return true; - } - - /** - * - */ - private static final String[] formats = { - "yyyy-MM-dd'T'HH:mm:ss'Z'", "yyyy-MM-dd'T'HH:mm:ssZ", - "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", - "yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd HH:mm:ss", - "MM/dd/yyyy HH:mm:ss", "MM/dd/yyyy'T'HH:mm:ss.SSS'Z'", - "MM/dd/yyyy'T'HH:mm:ss.SSSZ", "MM/dd/yyyy'T'HH:mm:ss.SSS", - "MM/dd/yyyy'T'HH:mm:ssZ", "MM/dd/yyyy'T'HH:mm:ss", - "yyyy:MM:dd HH:mm:ss", "yyyyMMdd",}; - - /** - * @param d - * @return - */ - public static String getFormatOfDate(String d) { - if (d != null) { - for (String parse : formats) { - SimpleDateFormat sdf = new SimpleDateFormat(parse); - try { - sdf.parse(d); - return parse; - } catch (ParseException e) { - // TODO Handle Exception! - } - } + // 3. Complete list size is <= searchResponseSize (we do not need a token! do nothing!) + else { + log.fine("no, we do NOT need a restok!"); } - return d; + return result; } /** @@ -456,7 +373,7 @@ public class OaipmhUtilities { * @param field * @return Returns only the first String from the result list, or "" if list is empty. */ - public static String firstEnrtryFieldLoader(JSONObject resultFromGetRequestInES, String field) { + public static String firstEntryFieldLoader(JSONObject resultFromGetRequestInES, String field) { String result = ""; @@ -476,7 +393,7 @@ public class OaipmhUtilities { * @return * @throws IOException */ - protected static GetResponse getRcordByIDFromElasticSearch(OaipmhElasticSearchClient theESClient, + protected static GetResponse getRecordByIDFromElasticSearch(OaipmhElasticSearchClient theESClient, String idInElasticSearchIndex, String[] includes, String[] excludes) throws IOException { log.fine("id in es index: " + idInElasticSearchIndex); @@ -500,9 +417,15 @@ public class OaipmhUtilities { log.fine("get request id: " + getRequest.id()); - // Declaration of the result from the get-request + // Declaration of the result from the get-request. GetResponse esResultObject = theESClient.getEsClient().get(getRequest, RequestOptions.DEFAULT); + log.fine("es result object is existing: " + esResultObject.isExists()); + + if (!esResultObject.isExists()) { + throw new IOException("es record with id " + idInElasticSearchIndex + " is not existing!"); + } + return esResultObject; } @@ -537,31 +460,6 @@ public class OaipmhUtilities { return getRecordType; } - /** - * @param propertyName - * @param propFile - * @return - */ - @Deprecated - public static String[][] fetchArrayFromPropFile(String propertyName, Properties propFile) { - - // TODO Why get a 2D array and only use the first element in RecordDelivererDatacite? - // BTW Where does the ";" come from anyway? - - // Get array split up by the semicolon. - String[] a = propFile.getProperty(propertyName).split(";"); - - // Create the two dimensional array with correct size. - String[][] array = new String[a.length][a.length]; - - // Combine the arrays split by semicolon and comma. - for (int i = 0; i < a.length; i++) { - array[i] = a[i].split(","); - } - - return array; - } - /** * @param propertyName * @param propFile @@ -706,6 +604,50 @@ public class OaipmhUtilities { return result.trim(); } + + /** + * @param message + * @return + * @throws IOException + */ + public static MetadataType buildMETSErrorMetadata(String message) throws IOException { + + MetadataType result = new MetadataType(); + + String metsError = + "<mets xsi:schemaLocation=\"http://www.loc.gov/METS/" + + " http://www.loc.gov/standards/mets/mets.xsd\"" + + " xmlns=\"http://www.loc.gov/METS/\"" + + " xmlns:dv=\"http://dfg-viewer.de/\"" + + " xmlns:xlink=\"http://www.w3.org/1999/xlink\"" + + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" + + " <amdSec ID=\"error\" />\n" + + " <structMap TYPE=\"LOGICAL\">\n" + + " <div LABEL=\"error\">\n" + + " <![CDATA[ " + message + " ]]>\n" + + " </div>\n" + + " </structMap>\n" + + "</mets>\n"; + + log.warning(message); + + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder; + builder = factory.newDocumentBuilder(); + Document doc = builder.parse(new InputSource(new StringReader(metsError))); + + result.setAny(doc.getDocumentElement()); + + } catch (ParserConfigurationException | SAXException e1) { + log.severe( + "ERROR BUILDING ERROR METS METADATA PART! PLEASE CONTACT YOUR LOCAL XML BUILDER! SYSTEM MESSAGE: " + + e1.getMessage()); + } + + return result; + } + // ** // PRIVATE METHODS // ** diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordDelivererDC.java b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordDelivererDC.java index c7e41b8d92fff52b859a20a00b98a491e1a895c5..bde9a6d19e4e554e2df5032146b899d3f1ccc661 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordDelivererDC.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordDelivererDC.java @@ -14,8 +14,6 @@ import info.textgrid.middleware.oaipmh.RecordType; /** * @author Maximilian Brodhun, SUB Göttingen * @author Stefan E. Funk, SUB Göttingen - * @version 2023-01-11 - * @since 2014-02-17 */ @Component public class RecordDelivererDC extends RecordDelivererAbstract { @@ -56,7 +54,7 @@ public class RecordDelivererDC extends RecordDelivererAbstract { String[] excludes = Strings.EMPTY_ARRAY; GetResponse esResultObject = - OaipmhUtilities.getRcordByIDFromElasticSearch(this.oaiEsClient, id, includes, excludes); + OaipmhUtilities.getRecordByIDFromElasticSearch(this.oaiEsClient, id, includes, excludes); log.fine("es result id/size: " + (esResultObject != null ? esResultObject.getId() + "/" + esResultObject.getFields().size() @@ -77,20 +75,15 @@ public class RecordDelivererDC extends RecordDelivererAbstract { if (this.dariah == true) { dublinCoreBuilder = putContentIntoDCFieldListsDH(esResultObject); JSONObject json = new JSONObject(esResultObject.getSourceAsMap()); - identifier = OaipmhUtilities.firstEnrtryFieldLoader(json, this.identifierField); + identifier = OaipmhUtilities.firstEntryFieldLoader(json, this.identifierField); String dateOfCreation = "NO_DATE_SET!"; - if (OaipmhUtilities.firstEnrtryFieldLoader(json, this.dateOfObjectCreation) != null) { - try { - dateOfCreation = OaipmhUtilities.oaiDatestampAsString( - OaipmhUtilities.firstEnrtryFieldLoader(json, this.dateOfObjectCreation).toString()); - } catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + if (OaipmhUtilities.firstEntryFieldLoader(json, this.dateOfObjectCreation) != null) { + dateOfCreation = OaipmhUtilities.getUTCDateAsString( + OaipmhUtilities.firstEntryFieldLoader(json, this.dateOfObjectCreation).toString()); } - String setSpec = OaipmhUtilities.firstEnrtryFieldLoader(json, this.specField); + String setSpec = OaipmhUtilities.firstEntryFieldLoader(json, this.specField); String setSpecValue = OaipmhUtilities.getSetSpec(setSpec, this.specFieldPrefix, identifier); @@ -125,13 +118,14 @@ public class RecordDelivererDC extends RecordDelivererAbstract { String dateOfCreation = esResultObject.getSourceAsMap().get(this.dateOfObjectCreation).toString(); + log.fine("date of creation: " + dateOfCreation); + String setSpec = DublinCoreFieldLoader .fillListFromTGWorkValues(esResultObject, this.relationList).get(0); String setSpecValue = OaipmhUtilities.getSetSpec(setSpec, this.specFieldPrefix, identifier); - String convertedCreationDate = - OaipmhUtilities.oaiDatestampAsString(dateOfCreation).toString(); + String convertedCreationDate = OaipmhUtilities.getUTCDateAsString(dateOfCreation).toString(); record.setHeader( OaipmhUtilities.computeResponseHeader(convertedCreationDate, identifier, setSpecValue)); record.setMetadata(dublinCoreBuilder.getDC()); @@ -163,7 +157,7 @@ public class RecordDelivererDC extends RecordDelivererAbstract { String[] excludes = Strings.EMPTY_ARRAY; responseWorkValues = - OaipmhUtilities.getRcordByIDFromElasticSearch(this.oaiEsClient, id, includes, excludes); + OaipmhUtilities.getRecordByIDFromElasticSearch(this.oaiEsClient, id, includes, excludes); } catch (IOException e) { // TODO Auto-generated catch block diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordDelivererDatacite.java b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordDelivererDatacite.java index fcf30a2abb238b78059260a0609a087d978a1193..1722a4aabeb56934d3cce7b8468c4e4d1a538b86 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordDelivererDatacite.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordDelivererDatacite.java @@ -49,8 +49,6 @@ import info.textgrid.middleware.oaipmh.Resource.Titles.Title; /** * @author Maximilian Brodhun, SUB Göttingen * @author Stefan E. Funk, SUB Göttingen - * @version 2023-01-10 - * @since 2020-06-13 */ @Component public class RecordDelivererDatacite extends RecordDelivererAbstract { @@ -138,7 +136,7 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { String replacedID = idInElasticSearchIndex.replace(this.repositoryObjectURIPrefix, ""); GetRecordType getRecordType = new GetRecordType(); - GetResponse esResultObject = OaipmhUtilities.getRcordByIDFromElasticSearch(this.oaiEsClient, + GetResponse esResultObject = OaipmhUtilities.getRecordByIDFromElasticSearch(this.oaiEsClient, replacedID, this.fields, Strings.EMPTY_ARRAY); // ** @@ -161,8 +159,8 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { } // Set response header. - String datestamp = OaipmhUtilities.oaiDatestampAsString( - OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, this.dateOfObjectCreation)); + String datestamp = OaipmhUtilities.getUTCDateAsString( + OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, this.dateOfObjectCreation)); String identifier = ""; if (!idInElasticSearchIndex.startsWith(this.repositoryObjectURIPrefix)) { @@ -170,8 +168,7 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { } else { identifier = idInElasticSearchIndex; } - - String setSpec = OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, this.specField); + String setSpec = OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, this.specField); String setSpecValue = OaipmhUtilities.getSetSpec(setSpec, this.specFieldPrefix, identifier); HeaderType header = OaipmhUtilities.computeResponseHeader(datestamp, identifier, setSpecValue); @@ -282,7 +279,7 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { Sizes sizes = new Sizes(); String size = - OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, this.oarSizeField) + " " + BYTES; + OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, this.oarSizeField) + " " + BYTES; sizes.getSize().add(size); return sizes; @@ -305,17 +302,17 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { if (this.textgrid) { Subject subject = new Subject(); String value = - OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, subjectField + DOT_VALUE); + OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, subjectField + DOT_VALUE); if (!value.isEmpty()) { subject.setValue(value); } String scheme = - OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, subjectField + DOT_ID + DOT_VALUE); + OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, subjectField + DOT_ID + DOT_VALUE); if (!scheme.isEmpty()) { subject.setSubjectScheme(scheme); } String schemeURI = - OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, subjectField + DOT_ID + DOT_TYPE); + OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, subjectField + DOT_ID + DOT_TYPE); if (schemeURI.isEmpty()) { subject.setSchemeURI(schemeURI); } @@ -351,7 +348,7 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { String version = ""; for (String versionField : this.oarVersionFields) { - version = OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, versionField); + version = OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, versionField); } return version; @@ -372,7 +369,7 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { // ** if (this.textgrid) { - String resourceValue = OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, format); + String resourceValue = OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, format); resourceType.setValue(resourceValue); // Set collection for all aggregation types, take also into account: images and text. if (TextGridMimetypes.AGGREGATION_SET.contains(format)) { @@ -400,7 +397,7 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { // ** else if (this.dariah) { - String resourceValue = OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, format); + String resourceValue = OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, format); resourceType.setValue(resourceValue); // Set collection for DARIAH collection type here, data object for everything else. if (TextGridMimetypes.DARIAH_COLLECTION.equals(format)) { @@ -430,7 +427,7 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { for (String geoLocationField : this.oarGeoLocationFields) { GeoLocation geoLocation = new GeoLocation(); - String place = OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, geoLocationField); + String place = OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, geoLocationField); geoLocation.setGeoLocationPlace(place); if (!place.isEmpty()) { geoLocations.getGeoLocation().add(geoLocation); @@ -456,30 +453,32 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { // * if (this.textgrid) { - - // TODO CHECK THIS! - - String[] workFields = {this.handle}; - RelatedIdentifier relatedIdentifier = new RelatedIdentifier(); - relatedIdentifier.setRelatedIdentifierType(RelatedIdentifierType.HANDLE); - // relatedIdentifier.setRelatedMetadataScheme(TGConstants.TEXTGRID_METADATASCHEME); - relatedIdentifier.setRelationType(RelationType.IS_PART_OF); - // relatedIdentifier.setSchemeType("XSD"); - // relatedIdentifier.setSchemeURI(TGConstants.TEXTGRID_METADATASCHEME_URI); - String uriForWork = - OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, relatedIdentifierField) + OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, relatedIdentifierField) .replace(this.repositoryObjectURIPrefix, ""); - relatedIdentifier - .setValue( - OaipmhUtilities - .firstEnrtryFieldLoader( - new JSONObject( - OaipmhUtilities.getRcordByIDFromElasticSearch(this.oaiEsClient, - uriForWork, workFields, Strings.EMPTY_ARRAY).getSource()), - this.handle)); - - relatedIdentifiers.getRelatedIdentifier().add(relatedIdentifier); + if (uriForWork != null && !uriForWork.isEmpty()) { + + log.fine("looking for work with id " + uriForWork); + + try { + JSONObject resultOfFurtherObject = + new JSONObject(OaipmhUtilities.getRecordByIDFromElasticSearch(this.oaiEsClient, + uriForWork, this.workFields, Strings.EMPTY_ARRAY).getSource()); + + RelatedIdentifier relatedIdentifier = new RelatedIdentifier(); + relatedIdentifier.setRelatedIdentifierType(RelatedIdentifierType.HANDLE); + // relatedIdentifier.setRelatedMetadataScheme(TGConstants.TEXTGRID_METADATASCHEME); + relatedIdentifier.setRelationType(RelationType.IS_PART_OF); + // relatedIdentifier.setSchemeType("XSD"); + // relatedIdentifier.setSchemeURI(TGConstants.TEXTGRID_METADATASCHEME_URI); + relatedIdentifier.setValue( + OaipmhUtilities.firstEntryFieldLoader(resultOfFurtherObject, this.handle)); + relatedIdentifiers.getRelatedIdentifier().add(relatedIdentifier); + } catch (IOException e) { + log.warning("work with id " + uriForWork + " does not exist in elasticsearch! " + + e.getMessage()); + } + } } // ** @@ -535,20 +534,32 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { if (this.textgrid) { String idForWorkObject = - OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, this.relationToWorkObject); - if (idForWorkObject != null) { + OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, this.relationToWorkObject); + if (idForWorkObject != null && !idForWorkObject.isEmpty()) { idForWorkObject = idForWorkObject.replace(this.repositoryObjectURIPrefix, ""); - JSONObject resultOfFurtherObject = - new JSONObject(OaipmhUtilities.getRcordByIDFromElasticSearch(this.oaiEsClient, - idForWorkObject, this.workFields, Strings.EMPTY_ARRAY).getSource()); - // Create abstract for every dc:description. - List<String> abstractsFromWork = - OaipmhUtilities.listFieldLoader(resultOfFurtherObject, descriptionField); - for (String d : abstractsFromWork) { - Description description = new Description(); - description.setDescriptionType(OpenaireDescriptionType.ABSTRACT); - description.getContent().add(d); - descriptions.getDescription().add(description); + + log.fine("looking for work with uri " + idForWorkObject); + + try { + JSONObject resultOfFurtherObject = + new JSONObject(OaipmhUtilities.getRecordByIDFromElasticSearch(this.oaiEsClient, + idForWorkObject, this.workFields, Strings.EMPTY_ARRAY).getSource()); + + // Create abstract for every dc:description. + List<String> abstractsFromWork = + OaipmhUtilities.listFieldLoader(resultOfFurtherObject, descriptionField); + + log.fine("found abstracts: " + abstractsFromWork.toString()); + + for (String d : abstractsFromWork) { + Description description = new Description(); + description.setDescriptionType(OpenaireDescriptionType.ABSTRACT); + description.getContent().add(d); + descriptions.getDescription().add(description); + } + } catch (IOException e) { + log.warning("work with id " + idForWorkObject + " does not exist in elasticsearch! " + + e.getMessage()); } } } @@ -590,9 +601,9 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { if (this.textgrid) { Rights rights = new Rights(); rights.setRightsURI( - OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, rightsField + LICENSE_URI)); + OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, rightsField + LICENSE_URI)); rights.setValue( - OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, rightsField + DOT_VALUE)); + OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, rightsField + DOT_VALUE)); rightsResultList.getRights().add(rights); } @@ -658,7 +669,7 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { if (this.textgrid) { AlternateIdentifier alternateIdentifier = new AlternateIdentifier(); alternateIdentifier.setValue( - OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, alternateIdentifierField)); + OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, alternateIdentifierField)); alternateIdentifier.setAlternateIdentifierType(ID_TYPE_URI); alternateIdentifiers.getAlternateIdentifier().add(alternateIdentifier); } @@ -727,7 +738,7 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { Contributor contributor = new Contributor(); if (contributorField.equals("project")) { String fieldContent = - OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, contributorField + DOT_VALUE); + OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, contributorField + DOT_VALUE); if (fieldContent != null && !fieldContent.isEmpty()) { contributor.setContributorName(fieldContent); contributor.setContributorType(ContributorType.OTHER); @@ -735,7 +746,7 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { new info.textgrid.middleware.oaipmh.Resource.Contributors.Contributor.NameIdentifier(); name.setNameIdentifierScheme(TG_PROJECT_CONTRIBUTOR_SCHEME); name.setValue( - OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, contributorField + DOT_ID)); + OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, contributorField + DOT_ID)); name.setSchemeURI(TG_PROJECT_CONTRIBUTOR_SCHEME_URI); if (!name.getValue().isEmpty() && !name.getNameIdentifierScheme().isEmpty() && !name.getSchemeURI().isEmpty()) { @@ -745,7 +756,7 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { } } else { String fieldContent = - OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, contributorField); + OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, contributorField); if (fieldContent != null && !fieldContent.isEmpty()) { contributor.setContributorName(fieldContent); contributor.setContributorType(ContributorType.DATA_MANAGER); @@ -798,34 +809,31 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { for (String dateField : this.oarDateFields) { Date dateInOpenAireRecord = new Date(); - try { - // Only one value per field is needed here (I think). - String dateValue = OaipmhUtilities - .oaiDatestampAsString(OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, dateField)); - dateInOpenAireRecord.setValue(dateValue); - // TODO Use extra created, issued, and updated fields in configuration! + // Only one value per field is needed here (I think). + // We need ISO8601 here, take entries as they come from ElasticSearch! + String dateValue = OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, dateField); + dateInOpenAireRecord.setValue(dateValue); - // Filter TextGrid values for date type. - if (dateField.equals("created")) { - dateInOpenAireRecord.setDateType(DateType.CREATED); - } - if (dateField.equals("issued")) { - dateInOpenAireRecord.setDateType(DateType.ISSUED); - } - if (dateField.equals("lastModified")) { - dateInOpenAireRecord.setDateType(DateType.UPDATED); - } + // TODO Use extra created, issued, and updated fields in configuration! - // Filter DARIAH values for date type. - if (dateField.equals("administrativeMetadata.dcterms:created")) { - dateInOpenAireRecord.setDateType(DateType.CREATED); - } - if (dateField.equals("administrativeMetadata.dcterms:modified")) { - dateInOpenAireRecord.setDateType(DateType.UPDATED); - } - } catch (ParseException e) { - log.severe("could not parse date field: " + e.getMessage()); + // Filter TextGrid values for date type. + if (dateField.equals("created")) { + dateInOpenAireRecord.setDateType(DateType.CREATED); + } + if (dateField.equals("issued")) { + dateInOpenAireRecord.setDateType(DateType.ISSUED); + } + if (dateField.equals("lastModified")) { + dateInOpenAireRecord.setDateType(DateType.UPDATED); + } + + // Filter DARIAH values for date type. + if (dateField.equals("administrativeMetadata.dcterms:created")) { + dateInOpenAireRecord.setDateType(DateType.CREATED); + } + if (dateField.equals("administrativeMetadata.dcterms:modified")) { + dateInOpenAireRecord.setDateType(DateType.UPDATED); } dates.getDate().add(dateInOpenAireRecord); @@ -840,7 +848,7 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { private Identifier addIdentifier() { Identifier identifier = new Identifier(); - String idValue = OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, this.oarIdentifierField); + String idValue = OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, this.oarIdentifierField); // ** // TextGrid @@ -884,10 +892,10 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { if (this.textgrid) { Creator creator = new Creator(); - creator.setCreatorName(OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, creatorField)); + creator.setCreatorName(OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, creatorField)); NameIdentifier nameIdentifier = new NameIdentifier(); // TODO: creatorID Field from config file - String creatorID = OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, + String creatorID = OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, "edition.source.bibliographicCitation.author.id"); if (creatorID != null && creatorID.contains(":")) { nameIdentifier.setValue(creatorID.split(":")[1]); @@ -996,8 +1004,8 @@ public class RecordDelivererDatacite extends RecordDelivererAbstract { */ private String addPublicationYear() throws ParseException, DatatypeConfigurationException { return Integer.toString(OaipmhUtilities - .oaiDatestampAsGregorian( - OaipmhUtilities.firstEnrtryFieldLoader(this.jsonObj, this.dateOfObjectCreation)) + .getUTCDateAsGregorian( + OaipmhUtilities.firstEntryFieldLoader(this.jsonObj, this.dateOfObjectCreation)) .getYear()); } diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordDelivererIdiom.java b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordDelivererIdiom.java index 028538d587a07ad2f0fd77e438e12313a8951be5..20fa5578200b3caccaad18a7ed2e63b8bee0e2ad 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordDelivererIdiom.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordDelivererIdiom.java @@ -3,7 +3,6 @@ package info.textgrid.middleware; import java.io.IOException; import java.io.StringReader; import java.text.ParseException; -import java.util.NoSuchElementException; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -24,8 +23,6 @@ import info.textgrid.middleware.oaipmh.RecordType; /** * @author Maximilian Brodhun, SUB Göttingen * @author Stefan E. Funk, SUB Göttingen - * @version 2023-01-06 - * @since 2019-03-12 */ @Component public class RecordDelivererIdiom extends RecordDelivererAbstract { @@ -87,6 +84,10 @@ public class RecordDelivererIdiom extends RecordDelivererAbstract { String creationDate = getIdiomInfoFromES(textgridRevisionURI, CREATED); String modificationDate = getIdiomInfoFromES(textgridRevisionURI, LAST_MODIFIED); + log.fine("object type: " + objectType); + log.fine("textgrid creationDate: " + creationDate); + log.fine("textgrid modificationDate: " + modificationDate); + // Get TG URI from ID. if (!textgridRevisionURI.startsWith(TEXTGRID_URI_PREFIX)) { textgridRevisionURI = TEXTGRID_URI_PREFIX + textgridRevisionURI; @@ -96,25 +97,30 @@ public class RecordDelivererIdiom extends RecordDelivererAbstract { String textgridBaseURI = OaipmhUtilities.getTextGridBaseURI(textgridRevisionURI); log.fine("textgrid base uri: " + textgridBaseURI); - log.fine("object type is: " + objectType); log.fine(objectType + " doc/dom: " + creationDate + "/" + modificationDate); if (objectType.equals("ARTEFACT")) { try { + + log.fine("calling ClassicMayanMetsMods for: " + textgridRevisionURI); + ClassicMayanMetsMods metsmods = new ClassicMayanMetsMods( textgridBaseURI, creationDate, modificationDate); log.fine("metsmods title: " + metsmods.getArtefactTitle()); + log.fine("setting metsmods metadata"); + + MetadataType metadata = idiomMets(metsmods); + recordType.setMetadata(metadata); - recordType.setMetadata(idiomMets(metsmods)); + log.fine("metsmods metadata set"); - } catch (JSONException | ParserConfigurationException | SAXException | IOException - | ParseException | NoSuchElementException e) { + } catch (ParserConfigurationException | SAXException | ParseException e) { String message = "ERROR getting IDIOM METS record for ID " + textgridRevisionURI + "! " + e.getClass().getName() + ": " + e.getMessage(); - log.warning(message); + recordType.setMetadata(OaipmhUtilities.buildMETSErrorMetadata(message)); } } @@ -129,27 +135,14 @@ public class RecordDelivererIdiom extends RecordDelivererAbstract { recordType = idi.getRecord(); } else { String message = "ERROR getting IDIOM IMAGE record for ID " + textgridRevisionURI + "!"; - log.warning(message); - String metsError = - "<mets xsi:schemaLocation=\"http://www.loc.gov/METS/ http://www.loc.gov/standards/mets/mets.xsd\"\n" - + "xmlns=\"http://www.loc.gov/METS/\" xmlns:dv=\"http://dfg-viewer.de/\"\n" - + "xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n" - + "<amdSec ID=\"error\"/>\n" - + "<structMap TYPE=\"LOGICAL\">\n" - + "<div LABEL=\"" + message + "\"/>\n" - + "</structMap>\n" - + "</mets>"; - MetadataType errorMetadata = new MetadataType(); - errorMetadata.setAny(metsError); - recordType.setMetadata(errorMetadata); + recordType.setMetadata(OaipmhUtilities.buildMETSErrorMetadata(message)); } } // No setSpec needed here! It COULD be the IDIOM project ID, but we do not need it at the // moment. String setSpec = ""; - String convertedModificationDate = - OaipmhUtilities.oaiDatestampAsString(modificationDate).toString(); + String convertedModificationDate = OaipmhUtilities.getUTCDateAsString(modificationDate); // We need to have the base URI here in header (and record), it is used as Record ID of Mayan // artifacts here! HeaderType header = @@ -219,10 +212,11 @@ public class RecordDelivererIdiom extends RecordDelivererAbstract { String[] searchField = {theSearchField}; JSONObject json = new JSONObject(); - json = new JSONObject(OaipmhUtilities.getRcordByIDFromElasticSearch(this.oaiEsClient, changedId, - searchField, Strings.EMPTY_ARRAY).getSource()); + json = + new JSONObject(OaipmhUtilities.getRecordByIDFromElasticSearch(this.oaiEsClient, changedId, + searchField, Strings.EMPTY_ARRAY).getSource()); - result = OaipmhUtilities.firstEnrtryFieldLoader(json, theSearchField); + result = OaipmhUtilities.firstEntryFieldLoader(json, theSearchField); return result; } diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererAbstract.java b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererAbstract.java index e4d7b740c997a8c7a0353539ac58477f7d95bb44..38b81998c7d256a7d63d44853a2f26c8c4e504a9 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererAbstract.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererAbstract.java @@ -9,8 +9,6 @@ import info.textgrid.middleware.oaipmh.ResumptionTokenType; /** * @author Maximilian Brodhun, SUB Göttingen * @author Stefan E. Funk, SUB Göttingen - * @version 2022-09-07 - * @since */ public abstract class RecordListDelivererAbstract implements RecordListDelivererInterface { @@ -85,16 +83,16 @@ public abstract class RecordListDelivererAbstract implements RecordListDeliverer if (request.getIdentifier() != null) { errorValues.add("identifier"); } - /* - * if(request.getFrom()!= null && (!OAIPMHUtilities.isThisDateValid(request.getFrom()) && - * !OAIPMHUtilities.isThisDateValidToOtherTimeStamp(request.getFrom()))) { - * errorValues.add("from"); } if(request.getUntil() != null && - * (!OAIPMHUtilities.isThisDateValid(request.getUntil()) && - * !OAIPMHUtilities.isThisDateValidToOtherTimeStamp(request.getUntil()))) { - * errorValues.add("until"); } if(request.getFrom()!= null && request.getUntil()!=null && - * !OAIPMHUtilities.getFormatOfDate(request.getFrom()).equals(OAIPMHUtilities.getFormatOfDate( - * request.getFrom()))) { errorValues.add("until, from"); } - */ + + // Check from and util. + if (request.getFrom() != null && !OaipmhUtilities.isCorrectFromUntilDate(request.getFrom())) { + errorValues.add("from"); + } + if (request.getUntil() != null && !OaipmhUtilities.isCorrectFromUntilDate(request.getUntil())) { + errorValues.add("until"); + } + + // Set error messages. if (errorValues.size() > 0) { result.setError(OaipmhConstants.OAI_BAD_ARGUMENT, "The request includes illegal arguments " + "or is missing required arguments: " + errorValues); @@ -205,7 +203,6 @@ public abstract class RecordListDelivererAbstract implements RecordListDeliverer this.resTokenForResponse = resTokenForResponse; } - /** * @return */ @@ -220,7 +217,6 @@ public abstract class RecordListDelivererAbstract implements RecordListDeliverer this.modifiedField = modifiedField; } - /** * @return */ @@ -326,7 +322,6 @@ public abstract class RecordListDelivererAbstract implements RecordListDeliverer return this.formatToFilter; } - /** * @return */ diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererDC.java b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererDC.java index 5ca6ce5bcbce300d15db2c001731776ac7892c63..a0ee3a71bbbf990c819dad6d7100ea4257855bb6 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererDC.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererDC.java @@ -138,13 +138,29 @@ public class RecordListDelivererDC extends RecordListDelivererAbstract { QueryBuilder recordFilter; DublinCoreBuilder dublinCoreBuilder = new DublinCoreBuilder(); + // ** + // DARIAH + // ** + if (this.dariah == true) { // All objects! recordFilter = query; - } else { + } + + // ** + // TEXTGRID + // ** + + else { + // No sandbox items. + QueryBuilder tgFilterSandBox = QueryBuilders.matchPhraseQuery("nearlyPublished", "true"); // All editions only! - recordFilter = QueryBuilders.boolQuery().must(query) - .must(QueryBuilders.matchPhraseQuery(this.formatField, this.formatToFilter)); + QueryBuilder tgEditionsOnly = + QueryBuilders.matchPhraseQuery(this.formatField, this.formatToFilter); + + // Compose query. + recordFilter = + QueryBuilders.boolQuery().must(query).must(tgEditionsOnly).mustNot(tgFilterSandBox); } SearchRequest searchRequest = new SearchRequest(this.oaiEsClient.getEsIndex()); @@ -185,13 +201,10 @@ public class RecordListDelivererDC extends RecordListDelivererAbstract { if (completeListSize > 0) { setFoundItems(true); - int i = 0; for (SearchHit hit : scrollResp.getHits().getHits()) { - i++; - if (hit != null && hit.getFields() != null) { JSONObject json = new JSONObject(hit.getSourceAsMap()); - this.modifiedValue = OaipmhUtilities.firstEnrtryFieldLoader(json, this.modifiedField); + this.modifiedValue = OaipmhUtilities.firstEntryFieldLoader(json, this.modifiedField); // ** // TEXTGRID SEARCH @@ -219,7 +232,7 @@ public class RecordListDelivererDC extends RecordListDelivererAbstract { String identifier = hit.getSourceAsMap().get(this.identifierField).toString(); HeaderType header = OaipmhUtilities.computeResponseHeader( - OaipmhUtilities.oaiDatestampAsString(this.modifiedValue).toString(), identifier, + OaipmhUtilities.getUTCDateAsString(this.modifiedValue).toString(), identifier, setSpec); buildRecord(recordList, header, dublinCoreBuilder); @@ -240,14 +253,14 @@ public class RecordListDelivererDC extends RecordListDelivererAbstract { else if (this.dariah) { // Get identifier and setSpec field, add setSpec prefix if not already set. - String identifier = OaipmhUtilities.firstEnrtryFieldLoader(json, this.identifierField); + String identifier = OaipmhUtilities.firstEntryFieldLoader(json, this.identifierField); String setSpec = OaipmhUtilities.getSetSpec(set, this.specFieldPrefix, identifier); try { dublinCoreBuilder = putContentIntoDCFieldListsDH(hit); HeaderType header = OaipmhUtilities.computeResponseHeader( - OaipmhUtilities.oaiDatestampAsString(this.modifiedValue).toString(), identifier, + OaipmhUtilities.getUTCDateAsString(this.modifiedValue).toString(), identifier, setSpec); buildRecord(recordList, header, dublinCoreBuilder); @@ -262,16 +275,8 @@ public class RecordListDelivererDC extends RecordListDelivererAbstract { } } - // Check the need for a resumption token! - - log.fine("completeListSize: " + completeListSize); - log.fine("resumptionToken: " + resumptionToken); - log.fine("scrollid: " + scrollID); - log.fine("searchResponseSize: " + this.searchResponseSize); - ResumptionTokenType resTokenForResponse = OaipmhUtilities.getResumptionToken(completeListSize, - resumptionToken, cursorCollector, scrollID, this.searchResponseSize, i); - + resumptionToken, cursorCollector, scrollID, this.searchResponseSize); if (resTokenForResponse != null) { log.fine("resTokenForResponse: " + resTokenForResponse.getValue()); } diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererDatacite.java b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererDatacite.java index 13ad6559fa06843c6ac0ff489d5a32b19115213c..0e66a0b695a6f351465fa1597923871647f4d27d 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererDatacite.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererDatacite.java @@ -24,8 +24,6 @@ import info.textgrid.middleware.oaipmh.RecordType; /** * @author Maximilian Brodhun, SUB Göttingen * @author Stefan E. Funk, SUB Göttingen - * @version 2022-09-08 - * @since 2020-06-13 */ public class RecordListDelivererDatacite extends RecordListDelivererAbstract { @@ -207,15 +205,21 @@ public class RecordListDelivererDatacite extends RecordListDelivererAbstract { if (completeListSize > 0) { setFoundItems(true); - int i = 0; - for (SearchHit hit : scrollResp.getHits().getHits()) { - i++; if (hit != null && hit.getFields() != null) { String id2add; // TODO Could we not use hit.getId() also for TG hits? Where is the difference? + // TODO See: + // TODO hit.getId(): xj5w.0 + // TODO hit.getSourceAsMap(): textgrid:xj5w.0 if (this.textgrid) { + + System.out.println(" #### hit.getId(): " + hit.getId()); + id2add = hit.getSourceAsMap().get(this.identifierField).toString(); + + System.out.println(" #### hit.getSourceAsMap(): " + id2add); + } else { id2add = hit.getId(); } @@ -232,14 +236,13 @@ public class RecordListDelivererDatacite extends RecordListDelivererAbstract { this.resTokenForResponse.setValue(""); } else { this.resTokenForResponse = OaipmhUtilities.getResumptionToken(completeListSize, - resumptionToken, cursorCollector, scrollID, this.searchResponseSize, i); + resumptionToken, cursorCollector, scrollID, this.searchResponseSize); } } else { setFoundItems(false); } - return uriList; } diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererIdiom.java b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererIdiom.java index 14bbe724680da889860f15adbe90e2a668d1f6de..87a9f872409bdff85edf9c8fdfee5bda860563e3 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererIdiom.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererIdiom.java @@ -141,15 +141,13 @@ public class RecordListDelivererIdiom extends RecordListDelivererAbstract { if (completeListSize > 0) { setFoundItems(true); - int i = 0; for (SearchHit hit : scrollResp.getHits().getHits()) { - i++; - log.fine("hit no." + i + ": id=" + hit.getId()); + log.fine("hit no." + hit.getIndex() + ": id=" + hit.getId()); String textgridURI = OaipmhUtilities - .firstEnrtryFieldLoader(new JSONObject(hit.getSourceAsMap()), this.identifierField); + .firstEntryFieldLoader(new JSONObject(hit.getSourceAsMap()), this.identifierField); log.fine("textgrid uri: " + textgridURI); @@ -173,7 +171,7 @@ public class RecordListDelivererIdiom extends RecordListDelivererAbstract { // Check the need for a resumption token! ResumptionTokenType responseToken = OaipmhUtilities.getResumptionToken(completeListSize, - resumptionToken, cursorCollector, scrollID, IDIOM_RESPONSE_SIZE, i); + resumptionToken, cursorCollector, scrollID, IDIOM_RESPONSE_SIZE); if (responseToken != null) { recordList.setResumptionToken(responseToken); } diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererInterface.java b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererInterface.java index b79343d8158fd6400f52105d8ac9318a9b87231b..c22a2b06ac689e127eec7c5b6e56f2b19ae37e55 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererInterface.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererInterface.java @@ -9,7 +9,6 @@ import info.textgrid.middleware.oaipmh.ListRecordsType; */ public interface RecordListDelivererInterface { - /** * @param from * @param to diff --git a/oaipmh-core/src/main/openaire/include/datacite-contributorType-v3.1.xsd b/oaipmh-core/src/main/openaire/include/datacite-contributorType-v3.1.xsd deleted file mode 100644 index c472076af44c0e2a6c30d8e1f7183d6be6ba5e36..0000000000000000000000000000000000000000 --- a/oaipmh-core/src/main/openaire/include/datacite-contributorType-v3.1.xsd +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Version 1.0 - Created 2011-01-13 - FZ, TIB, Germany - 2013-05 v3.0: Addition of ID to simpleType element, added values "ResearchGroup" & "Other" - 2014-08-20 v3.1: Addition of value "DataCurator" - 2015-05-14 v4.0 dropped value "Funder", use new "funderReference" --> -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://datacite.org/schema/kernel-3" targetNamespace="http://datacite.org/schema/kernel-3" elementFormDefault="qualified"> - <xs:simpleType name="contributorType" id="contributorType"> - <xs:annotation> - <xs:documentation>The type of contributor of the resource.</xs:documentation> - </xs:annotation> - <xs:restriction base="xs:string"> - <xs:enumeration value="ContactPerson"/> - <xs:enumeration value="DataCollector"/> - <xs:enumeration value="DataCurator"/> - <xs:enumeration value="DataManager"/> - <xs:enumeration value="Distributor"/> - <xs:enumeration value="Editor"/> - <xs:enumeration value="HostingInstitution"/> - <xs:enumeration value="Other"/> - <xs:enumeration value="Producer"/> - <xs:enumeration value="ProjectLeader"/> - <xs:enumeration value="ProjectManager"/> - <xs:enumeration value="ProjectMember"/> - <xs:enumeration value="RegistrationAgency"/> - <xs:enumeration value="RegistrationAuthority"/> - <xs:enumeration value="RelatedPerson"/> - <xs:enumeration value="ResearchGroup"/> - <xs:enumeration value="RightsHolder"/> - <xs:enumeration value="Researcher"/> - <xs:enumeration value="Sponsor"/> - <xs:enumeration value="Supervisor"/> - <xs:enumeration value="WorkPackageLeader"/> - </xs:restriction> - </xs:simpleType> -</xs:schema> diff --git a/oaipmh-core/src/main/openaire/include/datacite-dateType-v3.xsd b/oaipmh-core/src/main/openaire/include/datacite-dateType-v3.xsd deleted file mode 100644 index 0455f8ac57344bd75fa5119603293297b33353a5..0000000000000000000000000000000000000000 --- a/oaipmh-core/src/main/openaire/include/datacite-dateType-v3.xsd +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Version 1.0 - Created 2011-01-13 - FZ, TIB, Germany - 2013-05 v3.0: Addition of ID to simpleType element; addition of value "Collected"; deleted "StartDate" & "EndDate"--> -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://datacite.org/schema/kernel-3" targetNamespace="http://datacite.org/schema/kernel-3" elementFormDefault="qualified"> - <xs:simpleType name="dateType" id="dateType"> - <xs:annotation> - <xs:documentation>The type of date. Use RKMS‐ISO8601 standard for depicting date ranges.To indicate the end of an embargo period, use Available. To indicate the start of an embargo period, use Submitted or Accepted, as appropriate.</xs:documentation> - </xs:annotation> - <xs:restriction base="xs:string"> - <xs:enumeration value="Accepted"/> - <xs:enumeration value="Available"/> - <xs:enumeration value="Collected"/> - <xs:enumeration value="Copyrighted"/> - <xs:enumeration value="Created"/> - <xs:enumeration value="Issued"/> - <xs:enumeration value="Submitted"/> - <xs:enumeration value="Updated"/> - <xs:enumeration value="Valid"/> - </xs:restriction> - </xs:simpleType> -</xs:schema> diff --git a/oaipmh-core/src/main/openaire/include/datacite-descriptionType-v3.xsd b/oaipmh-core/src/main/openaire/include/datacite-descriptionType-v3.xsd deleted file mode 100644 index 881a4dfddd66bf3421e93cb4845f17bde757e81b..0000000000000000000000000000000000000000 --- a/oaipmh-core/src/main/openaire/include/datacite-descriptionType-v3.xsd +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Version 1.0 - Created 2011-01-13 - FZ, TIB, Germany - 2013-05 v3.0: Addition of ID to simpleType element, addition of value "Methods" - 2015-02-12 v4.0: Addition of value "TechnicalInfo"--> -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://datacite.org/schema/kernel-3" targetNamespace="http://datacite.org/schema/kernel-3" elementFormDefault="qualified"> - <xs:simpleType name="openaireDescriptionType" id="openaireDescriptionType"> - <xs:annotation> - <xs:documentation>The type of the description.</xs:documentation> - </xs:annotation> - <xs:restriction base="xs:string"> - <xs:enumeration value="Abstract"/> - <xs:enumeration value="Methods"/> - <xs:enumeration value="SeriesInformation"/> - <xs:enumeration value="TableOfContents"/> - <xs:enumeration value="TechnicalInfo"/> - <xs:enumeration value="Other"/> - </xs:restriction> - </xs:simpleType> -</xs:schema> diff --git a/oaipmh-core/src/main/openaire/include/datacite-relatedIdentifierType-v3.1.xsd b/oaipmh-core/src/main/openaire/include/datacite-relatedIdentifierType-v3.1.xsd deleted file mode 100644 index a300456d93c1fad4d5bc96f73d9f526b9270db5e..0000000000000000000000000000000000000000 --- a/oaipmh-core/src/main/openaire/include/datacite-relatedIdentifierType-v3.1.xsd +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Version 1.0 - Created 2011-01-13 - FZ, TIB, Germany - 2013-05 v3.0: Addition of ID to simpleType element; addition of value "PMID" - 2014-08-20 v3.1: Addition of values "arxiv" and "bibcode"--> -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://datacite.org/schema/kernel-3" targetNamespace="http://datacite.org/schema/kernel-3" elementFormDefault="qualified"> - <xs:simpleType name="relatedIdentifierType" id="relatedIdentifierType"> - <xs:annotation> - <xs:documentation>The type of the RelatedIdentifier.</xs:documentation> - </xs:annotation> - <xs:restriction base="xs:string"> - <xs:enumeration value="ARK"/> - <xs:enumeration value="arXiv"/> - <xs:enumeration value="bibcode"/> - <xs:enumeration value="DOI"/> - <xs:enumeration value="EAN13"/> - <xs:enumeration value="EISSN"/> - <xs:enumeration value="Handle"/> - <xs:enumeration value="ISBN"/> - <xs:enumeration value="ISSN"/> - <xs:enumeration value="ISTC"/> - <xs:enumeration value="LISSN"/> - <xs:enumeration value="LSID"/> - <xs:enumeration value="PMID"/> - <xs:enumeration value="PURL"/> - <xs:enumeration value="UPC"/> - <xs:enumeration value="URL"/> - <xs:enumeration value="URN"/> - </xs:restriction> - </xs:simpleType> -</xs:schema> diff --git a/oaipmh-core/src/main/openaire/include/datacite-relationType-v3.1.xsd b/oaipmh-core/src/main/openaire/include/datacite-relationType-v3.1.xsd deleted file mode 100644 index ed8516b52bdd3a92220946e2b22b630de2fa55f3..0000000000000000000000000000000000000000 --- a/oaipmh-core/src/main/openaire/include/datacite-relationType-v3.1.xsd +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Version 1.0 - Created 2011-01-13 - FZ, TIB, Germany - 2013-05 v3.0: Addition of ID to simpleType element, addition of values "IsIdenticalTo", "HasMetadata" & "IsMetadataFor" - 2014-08-20 v3.1: Addition of values "Reviews" & "IsReviewedBy" and "IsDerivedFrom" & "IsSourceOf"--> -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://datacite.org/schema/kernel-3" targetNamespace="http://datacite.org/schema/kernel-3" elementFormDefault="qualified"> - <xs:simpleType name="relationType" id="relationType"> - <xs:annotation> - <xs:documentation>Description of the relationship of the resource being registered (A) and the related resource (B).</xs:documentation> - </xs:annotation> - <xs:restriction base="xs:string"> - <xs:enumeration value="IsCitedBy"/> - <xs:enumeration value="Cites"/> - <xs:enumeration value="IsSupplementTo"/> - <xs:enumeration value="IsSupplementedBy"/> - <xs:enumeration value="IsContinuedBy"/> - <xs:enumeration value="Continues"/> - <xs:enumeration value="IsNewVersionOf"/> - <xs:enumeration value="IsPreviousVersionOf"/> - <xs:enumeration value="IsPartOf"/> - <xs:enumeration value="HasPart"/> - <xs:enumeration value="IsReferencedBy"/> - <xs:enumeration value="References"/> - <xs:enumeration value="IsDocumentedBy"/> - <xs:enumeration value="Documents"/> - <xs:enumeration value="IsCompiledBy"/> - <xs:enumeration value="Compiles"/> - <xs:enumeration value="IsVariantFormOf"/> - <xs:enumeration value="IsOriginalFormOf"/> - <xs:enumeration value="IsIdenticalTo"/> - <xs:enumeration value="HasMetadata"/> - <xs:enumeration value="IsMetadataFor"/> - <xs:enumeration value="Reviews"/> - <xs:enumeration value="IsReviewedBy"/> - <xs:enumeration value="IsDerivedFrom"/> - <xs:enumeration value="IsSourceOf"/> - </xs:restriction> - </xs:simpleType> -</xs:schema> diff --git a/oaipmh-core/src/main/openaire/include/datacite-resourceType-v3.xsd b/oaipmh-core/src/main/openaire/include/datacite-resourceType-v3.xsd deleted file mode 100644 index 3205a0cd3df8975b6b142061d67fe63622cda082..0000000000000000000000000000000000000000 --- a/oaipmh-core/src/main/openaire/include/datacite-resourceType-v3.xsd +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Version 1.0 - Created 2011-01-13 - FZ, TIB, Germany - 2013-05 v3.0: Addition of ID to simpleType element; added values "Audiovisual", "Workflow" & "Other"; deleted value "Film" --> -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://datacite.org/schema/kernel-3" targetNamespace="http://datacite.org/schema/kernel-3" elementFormDefault="qualified"> - <xs:simpleType name="resourceType" id="resourceType"> - <xs:annotation> - <xs:documentation>The general type of a resource.</xs:documentation> - </xs:annotation> - <xs:restriction base="xs:string"> - <xs:enumeration value="Audiovisual"/> - <xs:enumeration value="Collection"/> - <xs:enumeration value="Dataset"/> - <xs:enumeration value="Event"/> - <xs:enumeration value="Image"/> - <xs:enumeration value="InteractiveResource"/> - <xs:enumeration value="Model"/> - <xs:enumeration value="PhysicalObject"/> - <xs:enumeration value="Service"/> - <xs:enumeration value="Software"/> - <xs:enumeration value="Sound"/> - <xs:enumeration value="Text"/> - <xs:enumeration value="Workflow"/> - <xs:enumeration value="Other"/> - </xs:restriction> - </xs:simpleType> -</xs:schema> diff --git a/oaipmh-core/src/main/openaire/include/datacite-titleType-v3.xsd b/oaipmh-core/src/main/openaire/include/datacite-titleType-v3.xsd deleted file mode 100644 index ed2508ad8a9e8da913dbf77ea8763ccff13fe1cf..0000000000000000000000000000000000000000 --- a/oaipmh-core/src/main/openaire/include/datacite-titleType-v3.xsd +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Version 1.0 - Created 2011-01-13 - FZ, TIB, Germany - 2013-05 v3.0: Addition of ID to simpleType element - 2015-02-12 v4.0 Added value "Other" --> -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://datacite.org/schema/kernel-3" targetNamespace="http://datacite.org/schema/kernel-3" elementFormDefault="qualified"> - <xs:simpleType name="titleType" id="titleType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="AlternativeTitle"/> - <xs:enumeration value="Subtitle"/> - <xs:enumeration value="TranslatedTitle"/> - <xs:enumeration value="Other"/> - </xs:restriction> - </xs:simpleType> -</xs:schema> diff --git a/oaipmh-core/src/main/openaire/oaf-1.0.xsd b/oaipmh-core/src/main/openaire/oaf-1.0.xsd deleted file mode 100644 index 952ae31ddbf10d640b11c920f116bb400f07f257..0000000000000000000000000000000000000000 --- a/oaipmh-core/src/main/openaire/oaf-1.0.xsd +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" - xmlns:dri="http://www.driver-repository.eu/namespace/dri" xmlns="http://namespace.openaire.eu/oaf" - targetNamespace="http://namespace.openaire.eu/oaf"> - - <xs:annotation> - <xs:documentation>This schema describes the XML serialization of the OpenAIRE Research Graph. - For an overview of the model, please check the OpenAIRE Research Graph Data Model at https://doi.org/10.5281/zenodo.2643199 - </xs:documentation> - </xs:annotation> - - <xs:include schemaLocation="oaf-result-1.0.xsd"/> - <xs:include schemaLocation="oaf-org-1.0.xsd"/> - <xs:include schemaLocation="oaf-datasource-1.0.xsd"/> - <xs:include schemaLocation="oaf-project-1.0.xsd"/> - - <xs:element name="entity"> - <xs:complexType> - <xs:sequence> - <xs:choice> - <xs:element ref="result"/> - <xs:element ref="organization"/> - <xs:element ref="datasource"/> - <xs:element ref="project"/> - </xs:choice> - </xs:sequence> - </xs:complexType> - </xs:element> - -</xs:schema> diff --git a/oaipmh-core/src/main/openaire/oaf-common-1.0.xsd b/oaipmh-core/src/main/openaire/oaf-common-1.0.xsd deleted file mode 100644 index 8c52e22a3732c42d8f782bb065f7acfd7e525e0a..0000000000000000000000000000000000000000 --- a/oaipmh-core/src/main/openaire/oaf-common-1.0.xsd +++ /dev/null @@ -1,298 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" - xmlns="http://namespace.openaire.eu/oaf" targetNamespace="http://namespace.openaire.eu/oaf"> - - <xs:annotation> - <xs:documentation>This schema defines common types that can be re-used.</xs:documentation> - </xs:annotation> - - <xs:simpleType name="emptyType"> - <xs:restriction base="xs:string"> - <xs:length value="0"/> - </xs:restriction> - </xs:simpleType> - - <xs:simpleType name="boolOrEmptyType"> - <xs:union memberTypes="emptyType xs:boolean"/> - </xs:simpleType> - - <xs:simpleType name="stringOrEmptyType"> - <xs:union memberTypes="emptyType xs:string"/> - </xs:simpleType> - - <xs:attributeGroup name="dataInfoAttributeGroup"> - <xs:attribute name="inferred" use="optional" type="xs:boolean"> - <xs:annotation> - <xs:documentation>True if this information has been inferred by the automatic - inference algorithms run by OpenAIRE. </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute name="trust" use="optional" type="xs:string"> - <xs:annotation> - <xs:documentation>Value of trust of this information in the range [0,1]. More the - value, more trustworthy is the information. </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute name="inferenceprovenance" use="optional" type="xs:string"> - <xs:annotation> - <xs:documentation>Which algorithm inferred the current property. </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attributeGroup ref="qualifierAttributeGroup"></xs:attributeGroup> - </xs:attributeGroup> - - <xs:attributeGroup name="qualifierAttributeGroup"> - <xs:attribute name="classid" use="required" type="xs:string"/> - <xs:attribute name="classname" use="required" type="xs:string"/> - <xs:attribute name="schemeid" use="required" type="xs:string"/> - <xs:attribute name="schemename" use="required" type="xs:string"/> - </xs:attributeGroup> - - <xs:complexType name="fieldType"> - <xs:simpleContent> - <xs:extension base="xs:string"> - <xs:attributeGroup ref="dataInfoAttributeGroup"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - - <xs:complexType name="qualifierType"> - <xs:attributeGroup ref="qualifierAttributeGroup"/> - </xs:complexType> - - <xs:complexType name="dataInfoType"> - <xs:attributeGroup ref="dataInfoAttributeGroup"/> - </xs:complexType> - - <xs:complexType name="structuredPropertyElementType"> - <xs:simpleContent> - <xs:extension base="xs:string"> - <xs:attributeGroup ref="qualifierAttributeGroup"/> - <xs:attributeGroup ref="dataInfoAttributeGroup"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - - <xs:complexType name="labeledIdElementType"> - <xs:attribute name="id" use="required"/> - <xs:attribute name="label" use="required"/> - </xs:complexType> - - <!-- <oaf:context id="egi" label="EGI" type="community"> - <oaf:category id="egi::virtual" label="EGI virtual organizations"> - <oaf:concept id="egi::virtual::2" label="alice"/> - </oaf:category> - </oaf:context> - <oaf:community id="{@id}" label="{@label}"> - <xsl:apply-templates/> - </oaf:community> - --> - <xs:complexType name="contextType"> - <xs:complexContent> - <xs:extension base="labeledIdElementType"> - <xs:sequence maxOccurs="unbounded"> - <xs:element name="category" type="categoryType"/> - </xs:sequence> - <xs:attributeGroup ref="dataInfoAttributeGroup"/> - </xs:extension> - </xs:complexContent> - </xs:complexType> - - <xs:complexType name="categoryType"> - <xs:complexContent> - <xs:extension base="labeledIdElementType"> - <xs:sequence minOccurs="0" maxOccurs="unbounded"> - <xs:element name="concept" type="conceptType"/> - </xs:sequence> - </xs:extension> - </xs:complexContent> - </xs:complexType> - - <xs:complexType name="conceptType"> - <xs:complexContent> - <xs:extension base="labeledIdElementType"> - <xs:sequence maxOccurs="unbounded" minOccurs="0"> - <xs:element name="concept" type="conceptType"/> - </xs:sequence> - </xs:extension> - </xs:complexContent> - </xs:complexType> - - <xs:complexType name="namedIdElementType"> - <xs:attribute name="id" use="required"/> - <xs:attribute name="name" use="required"/> - <xs:attributeGroup ref="dataInfoAttributeGroup"/> - </xs:complexType> - - <xs:complexType name="relsType"> - <xs:annotation> - <xs:documentation>Relationships to other entities.</xs:documentation> - </xs:annotation> - <xs:choice maxOccurs="unbounded" minOccurs="0"> - <xs:element name="rel" type="relType" minOccurs="0"/> - </xs:choice> - </xs:complexType> - - <xs:complexType name="relType"> - <xs:sequence> - <xs:choice maxOccurs="unbounded"> - <xs:element name="to" type="relToType"/> - <xs:element name="title" type="xs:string"/> - <xs:element name="websiteurl"/> - <xs:choice> - <xs:group ref="relDataSourceGroup"/> - <xs:group ref="relResultGroup"/> - <xs:group ref="relProjectGroup"/> - <xs:group ref="relOrganizationGroup"/> - <xs:group ref="fundingGroup"/> - </xs:choice> - </xs:choice> - </xs:sequence> - <xs:attributeGroup ref="dataInfoAttributeGroup"/> - </xs:complexType> - - <xs:group name="relDataSourceGroup"> - <xs:sequence> - <xs:choice minOccurs="0" maxOccurs="unbounded"> - <xs:element name="officialname" type="xs:string"/> - <xs:element name="datasourcetype" type="qualifierType"/> - </xs:choice> - </xs:sequence> - </xs:group> - - <xs:group name="relResultGroup"> - <xs:sequence> - <xs:choice minOccurs="0" maxOccurs="unbounded"> - <xs:element name="collectedfrom" type="namedIdElementType"/> - <xs:element name="url" type="xs:string"/> - <xs:element name="pid" type="structuredPropertyElementType"/> - <xs:element name="dateofacceptance" type="xs:string"/> - <xs:element name="publisher" type="xs:string"/> - <xs:element name="resulttype" type="xs:string"> - <xs:annotation> - <xs:documentation> Tells if the related record is about a publication or a - dataset. </xs:documentation> - </xs:annotation> - </xs:element> - <!-- the following fields are available only for similarity relations --> - <xs:element name="similarity" type="xs:double"> - <xs:annotation> - <xs:documentation>The similarity degree expressed in the range (0,1]. This - field is avaiable only when the to/@class is one of - {hasAmongTopNSimilarDocuments, - isAmongTopNSimilarDocuments}</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="type"> - <xs:annotation> - <xs:documentation>The similarity degree expressed in the range (0,1]. This - field is avaiable only when the to/@class is one of - {hasAmongTopNSimilarDocuments, - isAmongTopNSimilarDocuments}</xs:documentation> - </xs:annotation> - <xs:simpleType> - <xs:restriction base="xs:string"> - <xs:enumeration value="STANDARD"/> - <xs:enumeration value="WEBUSAGE"/> - </xs:restriction> - </xs:simpleType> - </xs:element> - </xs:choice> - </xs:sequence> - </xs:group> - - <xs:group name="relProjectGroup"> - <xs:sequence> - <xs:choice minOccurs="0" maxOccurs="unbounded"> - <xs:element name="code" type="xs:string"/> - <xs:element name="acronym" type="xs:string"/> - </xs:choice> - </xs:sequence> - </xs:group> - - <xs:group name="fundingGroup"> - <xs:sequence> - <xs:choice minOccurs="0" maxOccurs="unbounded"> - <xs:element name="contracttype" type="qualifierType"/> - <xs:element name="funding" type="fundingFlatType"/> - </xs:choice> - </xs:sequence> - </xs:group> - - <xs:group name="relOrganizationGroup"> - <xs:sequence> - <xs:choice minOccurs="0" maxOccurs="unbounded"> - <xs:element name="legalname" type="xs:string"/> - <xs:element name="legalshortname" type="xs:string"/> - <xs:element name="country" type="xs:string"/> - </xs:choice> - </xs:sequence> - </xs:group> - - - <xs:complexType name="relToType"> - <xs:annotation> - <xs:documentation>Information about the related entity. <p>The semantics of the - relationships is expressed by the attributes class and scheme. </p> - </xs:documentation> - </xs:annotation> - <xs:simpleContent> - <xs:extension base="xs:string"> - <xs:attribute name="class" use="required" type="xs:string"/> - <xs:attribute name="type" use="required" type="xs:string"> - <xs:annotation> - <xs:documentation>The type of the related entity. <p>Allowed values are: - project, organization, datasource, result, person.</p> - </xs:documentation> - </xs:annotation> - </xs:attribute> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - - <xs:complexType name="fundingFlatType"> - <xs:sequence> - <xs:element name="funder" type="funderFlatType" minOccurs="1" maxOccurs="1"/> - <xs:element name="funding_level_0" type="namedFundingLevel" minOccurs="0" - maxOccurs="unbounded"/> - <xs:element name="funding_level_1" type="namedFundingLevel" minOccurs="0" - maxOccurs="unbounded"/> - <xs:element name="funding_level_2" type="namedFundingLevel" minOccurs="0" - maxOccurs="unbounded"/> - </xs:sequence> - </xs:complexType> - - <xs:complexType name="funderFlatType"> - <xs:simpleContent> - <xs:extension base="xs:string"> - <xs:attribute name="id" use="required" type="xs:string"/> - <xs:attribute name="shortname" use="required" type="xs:string"/> - <xs:attribute name="name" use="required" type="xs:string"/> - <xs:attribute name="jurisdiction" use="optional" type="xs:string"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - - <xs:complexType name="namedFundingLevel"> - <xs:simpleContent> - <xs:extension base="xs:string"> - <xs:attribute name="name" use="required" type="xs:string"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - - <xs:complexType name="externalreferenceType"> - <xs:sequence> - <xs:element name="sitename" type="xs:string" minOccurs="0" maxOccurs="1"/> - <!--<xs:element name="label" type="xs:string" minOccurs="0" maxOccurs="1"/>--> - <xs:element name="url" type="xs:string" minOccurs="0" maxOccurs="1"/> - <xs:element name="qualifier" type="qualifierType" minOccurs="0" maxOccurs="1"/> - <xs:element name="refidentifier" type="xs:string" minOccurs="0" maxOccurs="1"/> - </xs:sequence> - <xs:attributeGroup ref="dataInfoAttributeGroup"/> - </xs:complexType> - - - <!-- REMOVE FROM HERE TO THE END --> - -</xs:schema> diff --git a/oaipmh-core/src/main/openaire/oaf-datasource-1.0.xsd b/oaipmh-core/src/main/openaire/oaf-datasource-1.0.xsd deleted file mode 100644 index c84ec2531dafd7151cd00ac15f6b15aa1fd579af..0000000000000000000000000000000000000000 --- a/oaipmh-core/src/main/openaire/oaf-datasource-1.0.xsd +++ /dev/null @@ -1,76 +0,0 @@ -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://namespace.openaire.eu/oaf" - targetNamespace="http://namespace.openaire.eu/oaf" elementFormDefault="qualified"> - - <xs:annotation> - <xs:documentation>This schema describes elements and properties of OpenAIRE datasources: https://issue.openaire.research-infrastructures.eu/projects/openaire2020-wiki/wiki/Core_entity_datasource</xs:documentation> - </xs:annotation> - - <xs:include schemaLocation="oaf-common-1.0.xsd"/> - - <xs:element name="datasource"> - <xs:complexType> - <xs:choice maxOccurs="unbounded"> - <xs:element name="namespaceprefix" type="xs:string" /> - <xs:element name="officialname" type="xs:string" /> - <xs:element name="englishname" type="xs:string" /> - <xs:element name="websiteurl" type="xs:string" /> - <xs:element name="logourl" type="xs:string" /> - <xs:element name="contactemail" type="xs:string" /> - <xs:element name="datasourcetype" type="qualifierType"> - <xs:annotation> - <xs:documentation>For allowed values check terms in:http://api.openaire.eu/vocabularies/dnet:datasource_typologies</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="openairecompatibility" type="qualifierType"> - <xs:annotation> - <xs:documentation> - Level of compatibility of this datasource with regards to the - guidelines. - <p>For allowed values check: - http://api.openaire.eu/vocabularies/dnet:datasourceCompatibilityLevel - </p> - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="dateofvalidation" type="xs:string"> - <xs:annotation> - <xs:documentation>When this datasource has been validated by the - OpenAire - Validator. - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="latitude" type="xs:string" /> - <xs:element name="longitude" type="xs:string" /> - <xs:element name="description" type="xs:string" /> - <xs:element name="subjects" type="structuredPropertyElementType"> - <xs:annotation> - <xs:documentation> - Subjects and keywords. - <p>For allowed values check: - http://api.openaire.eu/vocabularies/dnet:result_subjects - </p> - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="originalId" type="xs:string" /> - <xs:element name="collectedfrom" type="namedIdElementType"> - <xs:annotation> - <xs:documentation>Identifier and name of the datasource from which - this datasource has - been collected from. - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="pid" type="structuredPropertyElementType" /> - <xs:element name="rels" type="relsType"> - <xs:annotation> - <xs:documentation>Relationships to other entities. - </xs:documentation> - </xs:annotation> - </xs:element> - - </xs:choice> - </xs:complexType> - </xs:element> -</xs:schema> diff --git a/oaipmh-core/src/main/openaire/oaf-org-1.0.xsd b/oaipmh-core/src/main/openaire/oaf-org-1.0.xsd deleted file mode 100644 index 3c46fca44b6462be5fb51d116555cac23ea9d016..0000000000000000000000000000000000000000 --- a/oaipmh-core/src/main/openaire/oaf-org-1.0.xsd +++ /dev/null @@ -1,41 +0,0 @@ -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://namespace.openaire.eu/oaf" - targetNamespace="http://namespace.openaire.eu/oaf" elementFormDefault="qualified"> - - <xs:annotation> - <xs:documentation>This schema describes elements and properties of OpenAIRE entities of type organization: https://issue.openaire.research-infrastructures.eu/projects/openaire2020-wiki/wiki/Core_entity_organization</xs:documentation> - </xs:annotation> - - <xs:include schemaLocation="oaf-common-1.0.xsd"/> - - <xs:element name="organization"> - <xs:complexType> - <xs:choice maxOccurs="unbounded"> - <xs:element name="legalname" type="xs:string"/> - <xs:element name="legalshortname" type="xs:string"/> - <xs:element name="logourl" type="xs:string"/> - <xs:element name="originalId" type="xs:string"/> - <xs:element name="websiteurl" type="xs:string"/> - <xs:element name="country" type="qualifierType"> - <xs:annotation> - <xs:documentation>Countries in ISO 3166-1 alpha-2. </xs:documentation> - </xs:annotation> - </xs:element> - - <xs:element name="collectedfrom" type="namedIdElementType"> - <xs:annotation> - <xs:documentation>Identifier and name of the datasource from which this - organization has been collected from. </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="pid" type="structuredPropertyElementType"/> - <xs:element name="rels" type="relsType"> - <xs:annotation> - <xs:documentation>Relationships to other entities. </xs:documentation> - </xs:annotation> - </xs:element> - <!-- If we decide not to show deduplicated org, then we have to remove this field --> - <!-- <xs:element name="duplicates" type="mergedOrgs"/> --> - </xs:choice> - </xs:complexType> - </xs:element> -</xs:schema> diff --git a/oaipmh-core/src/main/openaire/oaf-project-1.0.xsd b/oaipmh-core/src/main/openaire/oaf-project-1.0.xsd deleted file mode 100644 index abcba4d9f63f31996226f01a18ab575541e32827..0000000000000000000000000000000000000000 --- a/oaipmh-core/src/main/openaire/oaf-project-1.0.xsd +++ /dev/null @@ -1,111 +0,0 @@ -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://namespace.openaire.eu/oaf" - targetNamespace="http://namespace.openaire.eu/oaf" elementFormDefault="qualified"> - - <xs:annotation> - <xs:documentation>This schema describes elements and properties of OpenAIRE project entity: https://issue.openaire.research-infrastructures.eu/projects/openaire2020-wiki/wiki/Core_entity_project</xs:documentation> - </xs:annotation> - - <xs:include schemaLocation="oaf-common-1.0.xsd"/> - - <xs:element name="project"> - <xs:complexType> - <xs:choice maxOccurs="unbounded"> - <xs:element name="code" type="xs:string"> - <xs:annotation> - <xs:documentation>Project code as assigned by the project's funder.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="title" type="xs:string"/> - <xs:element name="acronym" type="xs:string"/> - <xs:element name="callidentifier" type="xs:string"> - <xs:annotation> - <xs:documentation> Identifier of the call for proposal.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="contactfullname" type="xs:string"/> - <xs:element name="contactfax" type="xs:string"/> - <xs:element name="contactphone" type="xs:string"/> - <xs:element name="contactemail" type="xs:string"/> - <xs:element name="contracttype" type="qualifierType"/> - <xs:element name="keywords" type="xs:string"/> - <xs:element name="websiteurl" type="xs:string"/> - <xs:element name="startdate" type="xs:string"/> - <xs:element name="enddate" type="xs:string"/> - <xs:element name="duration" type="xs:string"/> - <xs:element name="ecsc39" type="boolOrEmptyType"> - <xs:annotation> - <xs:documentation>True if the project has the special clause 39. Available - only for EC FP7 funded projects. </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="oamandatepublications" type="xs:boolean"> - <xs:annotation> - <xs:documentation>True if the project's funding mandates the availability of project's publications in Open Access.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="ecarticle29_3" type="boolOrEmptyType"> - <xs:annotation> - <xs:documentation>True if the project is under the EC Open Data Pilot. Available only for EC H2020 funded projects. </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="subjects" type="qualifierType"/> - - <xs:element name="fundingtree" type="fundingTreeType"/> - <xs:element name="originalId" type="xs:string"/> - <xs:element name="collectedfrom" type="namedIdElementType"> - <xs:annotation> - <xs:documentation>Identifier and name of the datasource from which this - project has been collected from. </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="pid" type="qualifierType"/> - <xs:element name="rels" type="relsType"> - <xs:annotation> - <xs:documentation>Relationships to other entities. </xs:documentation> - </xs:annotation> - </xs:element> - </xs:choice> - </xs:complexType> - </xs:element> - - <!-- to be removed, and replaced by ContextType --> - <xs:complexType name="fundingTreeType"> - <xs:sequence> - <xs:element name="funder" type="funderType"/> - <xs:choice maxOccurs="unbounded"> - <!-- Three-tier funding hierarchies --> - <xs:element name="funding_level_2" type="fundingType"/> - <!-- Two-tier funding hierarchies --> - <xs:element name="funding_level_1" type="fundingType"/> - <!-- No funding hierarchy --> - <xs:element name="funding_level_0" type="fundingType"/> - </xs:choice> - </xs:sequence> - </xs:complexType> - - <xs:complexType name="fundingType"> - <xs:all> - <xs:element name="id" type="xs:string"/> - <xs:element name="description" type="xs:string"/> - <xs:element name="name" type="xs:string"/> - <xs:element name="class" type="xs:string"/> - <xs:element name="parent" type="fundingParentType"/> - </xs:all> - </xs:complexType> - - <xs:complexType name="fundingParentType"> - <xs:choice minOccurs="0"> - <xs:element name="funding_level_1" type="fundingType"/> - <xs:element name="funding_level_0" type="fundingType"/> - </xs:choice> - </xs:complexType> - - <xs:complexType name="funderType"> - <xs:all> - <xs:element name="id" type="xs:string"/> - <xs:element name="shortname" type="xs:string"/> - <xs:element name="name" type="xs:string"/> - <xs:element name="jurisdiction" type="xs:string"/> - </xs:all> - </xs:complexType> -</xs:schema> diff --git a/oaipmh-core/src/main/openaire/oaf-result-1.0.xsd b/oaipmh-core/src/main/openaire/oaf-result-1.0.xsd deleted file mode 100644 index 2ffd39849cbb1f5da2ebfa5d7cba94ae8d21185f..0000000000000000000000000000000000000000 --- a/oaipmh-core/src/main/openaire/oaf-result-1.0.xsd +++ /dev/null @@ -1,242 +0,0 @@ -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" - xmlns="http://namespace.openaire.eu/oaf" targetNamespace="http://namespace.openaire.eu/oaf"> - - <xs:annotation> - <xs:documentation>This schema describes elements and properties of the OpenAIRE Result entity. For an overview of the model, please check the OpenAIRE Research Graph Data Model at https://doi.org/10.5281/zenodo.2643199</xs:documentation> - </xs:annotation> - - <xs:include schemaLocation="oaf-common-1.0.xsd"/> - - <xs:element name="result"> - <xs:complexType> - <xs:choice maxOccurs="unbounded"> - <xs:element name="creator"> - <xs:complexType> - <xs:simpleContent> - <xs:extension base="xs:string"> - <xs:attribute name="name" type="xs:string"/> - <xs:attribute name="surname" type="xs:string"/> - <xs:attribute name="ORCID" type="xs:string"/> - <xs:attribute name="rank" type="xs:int"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - </xs:element> - <xs:element name="resulttype" type="qualifierType"> - <xs:annotation> - <xs:documentation> Tells if this record is about a publication or a dataset. - <p>For allowed values check: - http://api.openaire.eu/vocabularies/dnet:result_typologies </p> - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="language" type="qualifierType"/> - <xs:element name="country" type="dataInfoType"/> - <xs:element name="subject" type="structuredPropertyElementType"/> - <xs:element name="title" type="structuredPropertyElementType"> - <xs:annotation> - <xs:documentation> Title of this research result. <p>Different types of - titles are allowed: see http://api.openaire.eu/vocabularies/dnet:dataCite_title</p> - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="relevantdate" type="structuredPropertyElementType"/> - <xs:element name="description" type="xs:string"/> - <xs:element name="dateofacceptance" type="xs:string"/> - <xs:element name="publisher" type="xs:string"/> - <xs:element name="embargoenddate" type="xs:string"/> - <xs:element name="source" type="xs:string"> - <xs:annotation> - <xs:documentation>The semantics of this field is inherited from dc:source in - Dublin Core. </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="format" type="xs:string"/> - <xs:element name="contributor" type="xs:string"/> - <xs:element name="resourcetype" type="qualifierType"> - <xs:annotation> - <xs:documentation> This field is valid only if resulttype is "dataset". It - expresses the nature of the dataset. <p>For allowed values check: - http://api.openaire.eu/vocabularies/dnet:publication_resource </p> - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="coverage" type="xs:string"/> - <xs:element name="bestaccessright" type="qualifierType"> - <xs:annotation> - <xs:documentation> The best access right available for this result among the - available licenses of its children elements. <p>For allowed values - check: http://api.openaire.eu/vocabularies/dnet:access_modes </p> - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="journal" type="journalType"/> - <xs:element name="pid" type="structuredPropertyElementType"> - <xs:annotation> - <xs:documentation> Persistent identifier. <p>For allowed pid systems check: - http://api.openaire.eu/vocabularies/dnet:pid_types </p> - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="device" type="xs:string"> - <xs:annotation> - <xs:documentation> This field is valid only if resulttype is "dataset". It - contains information about the device used to generate the dataset. - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="size" type="xs:string"> - <xs:annotation> - <xs:documentation> This field is valid only if resulttype is "dataset". It - contains information about the size of the dataset. </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="version" type="xs:string"> - <xs:annotation> - <xs:documentation> This field is valid only if resulttype is "dataset". It - contains information about the version of the dataset. - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="lastmetadataupdate" type="xs:string"> - <xs:annotation> - <xs:documentation> This field is valid only if resulttype is "dataset". It - is the last update date of the metadata of the dataset. - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="metadataversionnumber" type="xs:string"> - <xs:annotation> - <xs:documentation> This field is valid only if resulttype is "dataset". It - contains information about the version of the metadata of the dataset. - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="originalId" type="xs:string" maxOccurs="unbounded"/> - <xs:element name="collectedfrom" type="namedIdElementType" maxOccurs="unbounded"> - <xs:annotation> - <xs:documentation>Identifier and name of the datasource from which this - result has been collected from (e.g., "OpenDOAR"). </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="context" type="contextType"> - <xs:annotation> - <xs:documentation>Research community, initiative, infrastructure or funding agency related to this result.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="rels" type="relsType"> - <xs:annotation> - <xs:documentation>Relationships to other entities. </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="instances" type="instancesType" minOccurs="1" maxOccurs="1"/> - <xs:element name="citations" type="citationsType" maxOccurs="1" minOccurs="0"/> - </xs:choice> - </xs:complexType> - </xs:element> - - <xs:complexType name="citationsType"> - <xs:sequence> - <xs:element name="citation" maxOccurs="unbounded" minOccurs="0"> - <xs:complexType> - <xs:sequence> - <xs:element name="rawText"/> - <xs:element name="id" minOccurs="0" maxOccurs="unbounded"> - <xs:complexType> - <xs:attribute name="value"/> - <xs:attribute name="type"/> - <xs:attribute name="confidenceLevel"/> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - </xs:sequence> - <xs:attribute name="provenance" type="xs:string"/> - <xs:attribute name="trust" type="xs:string"/> - </xs:complexType> - - <xs:complexType name="journalType"> - <xs:simpleContent> - <xs:extension base="xs:string"> - <xs:attribute name="eissn" use="optional"/> - <xs:attribute name="issn" use="optional"/> - <xs:attribute name="lissn" use="optional"/> - <xs:attribute name="ep" use="optional"/> - <xs:attribute name="iss" use="optional"/> - <xs:attribute name="sp" use="optional"/> - <xs:attribute name="vol" use="optional"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - <xs:complexType name="instancesType"> - <xs:sequence> - <xs:element name="instance" type="instanceType" minOccurs="1" maxOccurs="unbounded"> - <xs:annotation> - <xs:documentation>Actual digital representation of the publication or dataset. - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="externalreference" type="externalreferenceType" minOccurs="0" - maxOccurs="unbounded"/> - </xs:sequence> - </xs:complexType> - - <xs:complexType name="instanceType"> - <xs:choice maxOccurs="unbounded"> - <xs:element name="license" type="fieldType"> - <xs:annotation> - <xs:documentation> License to access this actual manifestation of the - result. Typically it is a URL. OpenAIRE does not yet attempt any harmonization and reflect the original values that are available in the collected metadata records. - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="accessright" type="qualifierType"/> - <xs:element name="instancetype" type="qualifierType"> - <xs:annotation> - <xs:documentation> Type of the instance, for example: article, thesis, etc. - <p>For allowed values check: http://api.openaire.eu/vocabularies/dnet:publication_resource - </p> - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="collectedfrom" type="namedIdElementType" maxOccurs="1"> - <xs:annotation> - <xs:documentation>Datasource from which OpenAIRE collected the description of this instance.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="hostedby" type="namedIdElementType" maxOccurs="1"> - <xs:annotation> - <xs:documentation>Datasource hosting this file. </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="webresource" type="webresourceType" minOccurs="1" - maxOccurs="unbounded"/> - <xs:element name="distributionlocation" type="xs:string" minOccurs="0"/> - <xs:element name="dateofacceptance" type="xs:string" minOccurs="0"/> - <xs:element name="processingchargeamount" type="fieldType"> - <xs:annotation> - <xs:documentation> Article/Book Processing Charge </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="processingchargecurrency" type="fieldType"> - <xs:annotation> - <xs:documentation>Currency for the value in processingchargeamount </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="refereed" type="fieldType"> - <xs:annotation> - <xs:documentation>Peer-review status</xs:documentation> - </xs:annotation> - </xs:element> - </xs:choice> - <xs:attribute name="id" use="required"/> - </xs:complexType> - - <xs:complexType name="webresourceType"> - <xs:sequence> - <xs:element name="url" type="xs:string" minOccurs="1" maxOccurs="1"/> - </xs:sequence> - </xs:complexType> - -</xs:schema> diff --git a/oaipmh-core/src/main/openaire/openaire.xsd b/oaipmh-core/src/main/openaire/openaire.xsd deleted file mode 100644 index a88a5f0456d1bbad63edf7eef754d1362d41f11d..0000000000000000000000000000000000000000 --- a/oaipmh-core/src/main/openaire/openaire.xsd +++ /dev/null @@ -1,380 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Revision history - 2010-08-26 Complete revision according to new common specification by the metadata work group after review. AJH, DTIC - 2010-11-17 Revised to current state of kernel review, FZ, TIB - 2011-01-17 Complete revsion after community review. FZ, TIB - 2011-03-17 Release of v2.1: added a namespace; mandatory properties got minLength; changes in the definitions of relationTypes - IsDocumentedBy/Documents and isCompiledBy/Compiles; changes type of property "Date" from xs:date to xs:string. FZ, TIB - 2011-06-27 v2.2: namespace: kernel-2.2, additions to controlled lists "resourceType", "contributorType", "relatedIdentifierType", and "descriptionType". Removal of intermediate include-files. - 2013-05 v3.0: namespace: kernel-3.0; delete LastMetadataUpdate & MetadateVersionNumber; additions to controlled lists "contributorType", "dateType", "descriptionType", "relationType", "relatedIdentifierType" & "resourceType"; deletion of "StartDate" & "EndDate" from list "dateType" and "Film" from "resourceType"; allow arbitrary order of elements; allow optional wrapper elements to be empty; include openaire:lang attribute for title, subject & description; include attribute schemeURI for nameIdentifier of creator, contributor & subject; added new attributes "relatedMetadataScheme", "schemeURI" & "schemeType" to relatedIdentifier; included new property "geoLocation" - 2014-08-20 v3.1: additions to controlled lists "relationType", contributorType" and "relatedIdentifierType"; introduction of new child element "affiliation" to "creator" and "contributor"--> -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://datacite.org/schema/kernel-3" targetNamespace="http://datacite.org/schema/kernel-3" elementFormDefault="qualified" > - - <xs:include schemaLocation="include/datacite-titleType-v3.xsd"/> - <xs:include schemaLocation="include/datacite-contributorType-v3.1.xsd"/> - <xs:include schemaLocation="include/datacite-dateType-v3.xsd"/> - <xs:include schemaLocation="include/datacite-resourceType-v3.xsd"/> - <xs:include schemaLocation="include/datacite-relationType-v3.1.xsd"/> - <xs:include schemaLocation="include/datacite-relatedIdentifierType-v3.1.xsd"/> - <xs:include schemaLocation="include/datacite-descriptionType-v3.xsd"/> - <xs:element name="resource"> - <xs:annotation> - <xs:documentation> - Root element of a single record. This wrapper element is for XML implementation only and is not defined in the DataCite DOI standard. - Note: This is the case for all wrapper elements within this schema!</xs:documentation> - <xs:documentation>No content in this wrapper element.</xs:documentation> - </xs:annotation> - <xs:complexType> - <xs:all> - <!--REQUIRED FIELDS--> - <xs:element name="identifier"> - <xs:annotation> - <xs:documentation>A persistent identifier that identifies a resource.</xs:documentation> - <xs:documentation>Currently, only DOI is allowed.</xs:documentation> - </xs:annotation> - <xs:complexType> - <xs:simpleContent> - <xs:extension base="doiType"> - <xs:attribute name="identifierType" use="required" fixed="DOI"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - </xs:element> - <xs:element name="creators"> - <xs:complexType> - <xs:sequence> - <xs:element name="creator" maxOccurs="unbounded"> - <xs:annotation> - <xs:documentation>The main researchers involved working on the data, or the authors of the publication in priority order. May be a corporate/institutional or personal name.</xs:documentation> - <xs:documentation>Format: Family, Given.</xs:documentation> - </xs:annotation> - <xs:complexType> - <xs:sequence> - <xs:element name="creatorName"> - <xs:simpleType> - <xs:restriction base="nonemptycontentStringType"/> - </xs:simpleType> - </xs:element> - <xs:element name="nameIdentifier" minOccurs="0"> - <xs:complexType> - <xs:simpleContent> - <xs:extension base="nonemptycontentStringType"> - <xs:attribute name="nameIdentifierScheme" use="required"/> - <xs:attribute name="schemeURI" type="xs:anyURI" use="optional"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - </xs:element> - <xs:element name="affiliation" minOccurs="0" maxOccurs="unbounded"/> - </xs:sequence> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - <xs:element name="titles"> - <xs:complexType> - <xs:sequence> - <xs:element name="title" maxOccurs="unbounded"> - <xs:annotation> - <xs:documentation>A name or title by which a resource is known.</xs:documentation> - </xs:annotation> - <xs:complexType> - <xs:simpleContent> - <xs:extension base="nonemptycontentStringType"> - <xs:attribute name="titleType" type="titleType" use="optional"/> - <xs:attribute name="lang"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - <xs:element name="publisher"> - <xs:annotation> - <xs:documentation>The name of the entity that holds, archives, publishes prints, distributes, releases, issues, or produces the resource. This property will be used to formulate the citation, so consider the prominence of the role.</xs:documentation> - <xs:documentation>In the case of datasets, "publish" is understood to mean making the data available to the community of researchers.</xs:documentation> - </xs:annotation> - <xs:simpleType> - <xs:restriction base="nonemptycontentStringType"/> - </xs:simpleType> - </xs:element> - <xs:element name="publicationYear"> - <xs:annotation> - <xs:documentation>Year when the data is made publicly available. If an embargo period has been in effect, use the date when the embargo period ends.</xs:documentation> - <xs:documentation>In the case of datasets, "publish" is understood to mean making the data available on a specific date to the community of researchers. If there is no standard publication year value, use the date that would be preferred from a citation perspective.</xs:documentation> - <xs:documentation>YYYY</xs:documentation> - </xs:annotation> - <xs:simpleType> - <xs:restriction base="yearType"/> - </xs:simpleType> - </xs:element> - <!--OPTIONAL FIELDS--> - <xs:element name="subjects" minOccurs="0"> - <xs:complexType> - <xs:sequence> - <xs:element name="subject" minOccurs="0" maxOccurs="unbounded"> - <xs:annotation> - <xs:documentation>Subject, keywords, classification codes, or key phrases describing the resource.</xs:documentation> - </xs:annotation> - <xs:complexType> - <xs:simpleContent> - <xs:extension base="xs:string"> - <xs:attribute name="subjectScheme" use="optional"/> - <xs:attribute name="schemeURI" type="xs:anyURI" use="optional"/> - <xs:attribute name="lang"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - <xs:element name="contributors" minOccurs="0"> - <xs:complexType> - <xs:sequence> - <xs:element name="contributor" minOccurs="0" maxOccurs="unbounded"> - <xs:annotation> - <xs:documentation>The institution or person responsible for collecting, creating, or otherwise contributing to the developement of the dataset.</xs:documentation> - <xs:documentation>The personal name format should be: Family, Given.</xs:documentation> - </xs:annotation> - <xs:complexType> - <xs:sequence> - <xs:element name="contributorName"> - <xs:simpleType> - <xs:restriction base="xs:string"> - <xs:minLength value="1"/> - </xs:restriction> - </xs:simpleType> - </xs:element> - <xs:element name="nameIdentifier" minOccurs="0"> - <xs:complexType> - <xs:simpleContent> - <xs:extension base="xs:string"> - <xs:attribute name="nameIdentifierScheme" use="required"/> - <xs:attribute name="schemeURI" type="xs:anyURI" use="optional"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - </xs:element> - <xs:element name="affiliation" minOccurs="0" maxOccurs="unbounded"/> - </xs:sequence> - <xs:attribute name="contributorType" type="contributorType" use="required"/> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - <xs:element name="dates" minOccurs="0"> - <xs:complexType> - <xs:sequence> - <xs:element name="date" minOccurs="0" maxOccurs="unbounded"> - <xs:annotation> - <xs:documentation>Different dates relevant to the work.</xs:documentation> - <xs:documentation>YYYY,YYYY-MM-DD, YYYY-MM-DDThh:mm:ssTZD or any other format or level of granularity described in W3CDTF. Use RKMS-ISO8601 standard for depicting date ranges.</xs:documentation> - </xs:annotation> - <xs:complexType> - <xs:simpleContent> - <xs:extension base="xs:string"> - <xs:attribute name="dateType" type="dateType" use="required"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - <xs:element name="language" type="xs:language" minOccurs="0"> - <xs:annotation> - <xs:documentation>Primary language of the resource. Allowed values are taken from IETF BCP 47, ISO 639-1 language codes.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="resourceType" minOccurs="0"> - <xs:annotation> - <xs:documentation>The type of a resource. You may enter an additional free text description.</xs:documentation> - <xs:documentation>The format is open, but the preferred format is a single term of some detail so that a pair can be formed with the sub-property.</xs:documentation> - </xs:annotation> - <xs:complexType> - <xs:simpleContent> - <xs:extension base="xs:string"> - <xs:attribute name="resourceTypeGeneral" type="resourceType" use="required"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - </xs:element> - <xs:element name="alternateIdentifiers" minOccurs="0"> - <xs:complexType> - <xs:sequence> - <xs:element name="alternateIdentifier" minOccurs="0" maxOccurs="unbounded"> - <xs:annotation> - <xs:documentation>An identifier or identifiers other than the primary Identifier applied to the resource being registered. This may be any alphanumeric string which is unique within its domain of issue. May be used for local identifiers. AlternateIdentifier should be used for another identifier of the same instance (same location, same file).</xs:documentation> - </xs:annotation> - <xs:complexType> - <xs:simpleContent> - <xs:extension base="xs:string"> - <xs:attribute name="alternateIdentifierType" use="required"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - <xs:element name="relatedIdentifiers" minOccurs="0"> - <xs:complexType> - <xs:sequence> - <xs:element name="relatedIdentifier" minOccurs="0" maxOccurs="unbounded"> - <xs:annotation> - <xs:documentation>Identifiers of related resources. Use this property to indicate subsets of properties, as appropriate.</xs:documentation> - </xs:annotation> - <xs:complexType> - <xs:simpleContent> - <xs:extension base="xs:string"> - <xs:attribute name="relatedIdentifierType" type="relatedIdentifierType" use="required"/> - <xs:attribute name="relationType" type="relationType" use="required"/> - <xs:attribute name="relatedMetadataScheme" use="optional"/> - <xs:attribute name="schemeURI" type="xs:anyURI" use="optional"/> - <xs:attribute name="schemeType" use="optional"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - <xs:element name="sizes" minOccurs="0"> - <xs:complexType> - <xs:sequence> - <xs:element name="size" type="xs:string" minOccurs="0" maxOccurs="unbounded"> - <xs:annotation> - <xs:documentation>Unstructures size information about the resource.</xs:documentation> - </xs:annotation> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - <xs:element name="formats" minOccurs="0"> - <xs:complexType> - <xs:sequence> - <xs:element name="format" type="xs:string" minOccurs="0" maxOccurs="unbounded"> - <xs:annotation> - <xs:documentation>Technical format of the resource.</xs:documentation> - <xs:documentation>Use file extension or MIME type where possible.</xs:documentation> - </xs:annotation> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - <xs:element name="version" type="xs:string" minOccurs="0"> - <xs:annotation> - <xs:documentation>Version number of the resource. If the primary resource has changed the version number increases.</xs:documentation> - <xs:documentation>Register a new identifier for a major version change. Individual stewards need to determine which are major vs. minor versions. May be used in conjunction with properties 11 and 12 (AlternateIdentifier and RelatedIdentifier) to indicate various information updates. May be used in conjunction with property 17 (Description) to indicate the nature and file/record range of version.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="rightsList" minOccurs="0"> - <xs:complexType> - <xs:sequence> - <xs:element name="rights" minOccurs="0" maxOccurs="unbounded"> - <xs:annotation> - <xs:documentation>Any rights information for this resource. Provide a rights management statement for the resource or reference a service providing such information. Include embargo information if applicable. -Use the complete title of a license and include version information if applicable.</xs:documentation> - </xs:annotation> - <xs:complexType> - <xs:simpleContent> - <xs:extension base="xs:string"> - <xs:attribute name="rightsURI" type="xs:anyURI" use="optional"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - <xs:element name="descriptions" minOccurs="0"> - <xs:complexType> - <xs:sequence> - <xs:element name="description" minOccurs="0" maxOccurs="unbounded"> - <xs:annotation> - <xs:documentation>All additional information that does not fit in any of the other categories. May be used for technical information. It is a best practice to supply a description.</xs:documentation> - </xs:annotation> - <xs:complexType mixed="true"> - <xs:choice> - <xs:element name="br" minOccurs="0" maxOccurs="unbounded"> - <xs:simpleType> - <xs:restriction base="xs:string"> - <xs:length value="0"/> - </xs:restriction> - </xs:simpleType> - </xs:element> - </xs:choice> - <xs:attribute name="openaireDescriptionType" type="openaireDescriptionType" use="required"/> - <xs:attribute name="lang"/> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - <xs:element name="geoLocations" minOccurs="0"> - <xs:complexType> - <xs:sequence> - <xs:element name="geoLocation" minOccurs="0" maxOccurs="unbounded"> - <xs:annotation> - <xs:documentation>Spatial region or named place where the data was gathered or about which the data is focused.</xs:documentation> - <xs:documentation>A point contains a single latitude-longitude pair, separated by whitespace.</xs:documentation> - <xs:documentation>A box contains two white space separated latitude-longitude pairs, with each pair separated by whitespace. The first pair is the lower corner, the second is the upper corner.</xs:documentation> - </xs:annotation> - <xs:complexType> - <xs:sequence> - <xs:element name="geoLocationPoint" type="point" minOccurs="0"/> - <xs:element name="geoLocationBox" type="box" minOccurs="0"/> - <xs:element name="geoLocationPlace" minOccurs="0"/> - </xs:sequence> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - </xs:all> - </xs:complexType> - </xs:element> - <!-- TYPE DECLARATIONS --> - <!-- defines the value for a DOI: DOI must start with "10." --> - <xs:simpleType name="doiType"> - <xs:restriction base="xs:token"> - <xs:pattern value="10\..+/.+"/> - </xs:restriction> - </xs:simpleType> - <!-- defines value for mandatory fields --> - <xs:simpleType name="nonemptycontentStringType"> - <xs:restriction base="xs:string"> - <xs:minLength value="1"/> - </xs:restriction> - </xs:simpleType> - <xs:attributeGroup name="nameId"> - <xs:attribute name="nameIdentifier" type="xs:string" use="optional"/> - <xs:attribute name="nameIdentifierScheme" type="xs:string" use="optional"/> - </xs:attributeGroup> - <!-- defines the value for a year --> - <xs:simpleType name="yearType"> - <xs:restriction base="xs:token"> - <xs:pattern value="[\d]{4}"/> - </xs:restriction> - <!-- definitions for geoLocation --> - </xs:simpleType> - <xs:simpleType name="point"> - <xs:restriction base="listOfDoubles"> - <xs:minLength value="2"/> - <xs:maxLength value="2"/> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="box"> - <xs:restriction base="listOfDoubles"> - <xs:minLength value="4"/> - <xs:maxLength value="4"/> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="listOfDoubles"> - <xs:list itemType="xs:double"/> - </xs:simpleType> -</xs:schema> diff --git a/oaipmh-core/src/main/resources/simpledc20021212.xsd b/oaipmh-core/src/main/resources/simpledc20021212.xsd index c4bd03d537d361c7d65ee16133baf25efbcb455a..f0ad14be8c0c4f7731a7f485082e857033d13832 100644 --- a/oaipmh-core/src/main/resources/simpledc20021212.xsd +++ b/oaipmh-core/src/main/resources/simpledc20021212.xsd @@ -1,76 +1,79 @@ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" - xmlns="http://purl.org/dc/elements/1.1/" - targetNamespace="http://purl.org/dc/elements/1.1/" - elementFormDefault="qualified" - attributeFormDefault="unqualified"> + xmlns="http://purl.org/dc/elements/1.1/" + targetNamespace="http://purl.org/dc/elements/1.1/" + elementFormDefault="qualified" attributeFormDefault="unqualified"> - <xs:annotation> - <xs:documentation xml:lang="en"> - Simple DC XML Schema, 2002-10-09 - by Pete Johnston (p.johnston@ukoln.ac.uk), - Carl Lagoze (lagoze@cs.cornell.edu), Andy Powell (a.powell@ukoln.ac.uk), - Herbert Van de Sompel (hvdsomp@yahoo.com). - This schema defines terms for Simple Dublin Core, i.e. the 15 - elements from the http://purl.org/dc/elements/1.1/ namespace, with - no use of encoding schemes or element refinements. - Default content type for all elements is xs:string with xml:lang - attribute available. + <xs:annotation> + <xs:documentation xml:lang="en"> + Simple DC XML Schema, 2002-10-09 + by Pete Johnston (p.johnston@ukoln.ac.uk), + Carl Lagoze (lagoze@cs.cornell.edu), Andy Powell (a.powell@ukoln.ac.uk), + Herbert Van de Sompel (hvdsomp@yahoo.com). + This schema defines terms for Simple Dublin Core, i.e. the 15 + elements from the http://purl.org/dc/elements/1.1/ namespace, with + no use of encoding schemes or element refinements. + Default content type for all elements is xs:string with xml:lang + attribute available. - Supercedes version of 2002-03-12. - Amended to remove namespace declaration for http://www.w3.org/XML/1998/namespace namespace, - and to reference lang attribute via built-in xml: namespace prefix. - xs:appinfo also removed. - </xs:documentation> - </xs:annotation> + Supercedes version of 2002-03-12. + Amended to remove namespace declaration for + http://www.w3.org/XML/1998/namespace namespace, + and to reference lang attribute via built-in xml: namespace prefix. + xs:appinfo also removed. + </xs:documentation> + </xs:annotation> - <xs:import namespace="http://www.w3.org/XML/1998/namespace" - schemaLocation="https://www.w3.org/2001/03/xml.xsd"> - </xs:import> + <!-- In case of an error such as "Server returned HTTP response code: 429 + for URL: https://www.w3.org/2001/03/XMLSchema.dtd" try using VPN, downloading + all needed files for offline could be another solution... --> + <xs:import namespace="http://www.w3.org/XML/1998/namespace" + schemaLocation="https://www.w3.org/2001/03/xml.xsd"> + </xs:import> - <xs:element name="title" type="elementType"/> - <xs:element name="creator" type="elementType"/> - <xs:element name="subject" type="elementType"/> - <xs:element name="description" type="elementType"/> - <xs:element name="publisher" type="elementType"/> - <xs:element name="contributor" type="elementType"/> - <xs:element name="date" type="elementType"/> - <xs:element name="type" type="elementType"/> - <xs:element name="format" type="elementType"/> - <xs:element name="identifier" type="elementType"/> - <xs:element name="source" type="elementType"/> - <xs:element name="language" type="elementType"/> - <xs:element name="relation" type="elementType"/> - <xs:element name="coverage" type="elementType"/> - <xs:element name="rights" type="elementType"/> + <xs:element name="title" type="elementType" /> + <xs:element name="creator" type="elementType" /> + <xs:element name="subject" type="elementType" /> + <xs:element name="description" type="elementType" /> + <xs:element name="publisher" type="elementType" /> + <xs:element name="contributor" type="elementType" /> + <xs:element name="date" type="elementType" /> + <xs:element name="type" type="elementType" /> + <xs:element name="format" type="elementType" /> + <xs:element name="identifier" type="elementType" /> + <xs:element name="source" type="elementType" /> + <xs:element name="language" type="elementType" /> + <xs:element name="relation" type="elementType" /> + <xs:element name="coverage" type="elementType" /> + <xs:element name="rights" type="elementType" /> - <xs:group name="elementsGroup"> - <xs:sequence> - <xs:choice minOccurs="0" maxOccurs="unbounded"> - <xs:element ref="title"/> - <xs:element ref="creator"/> - <xs:element ref="subject"/> - <xs:element ref="description"/> - <xs:element ref="publisher"/> - <xs:element ref="contributor"/> - <xs:element ref="date"/> - <xs:element ref="type"/> - <xs:element ref="format"/> - <xs:element ref="identifier"/> - <xs:element ref="source"/> - <xs:element ref="language"/> - <xs:element ref="relation"/> - <xs:element ref="coverage"/> - <xs:element ref="rights"/> - </xs:choice> - </xs:sequence> - </xs:group> + <xs:group name="elementsGroup"> + <xs:sequence> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="title" /> + <xs:element ref="creator" /> + <xs:element ref="subject" /> + <xs:element ref="description" /> + <xs:element ref="publisher" /> + <xs:element ref="contributor" /> + <xs:element ref="date" /> + <xs:element ref="type" /> + <xs:element ref="format" /> + <xs:element ref="identifier" /> + <xs:element ref="source" /> + <xs:element ref="language" /> + <xs:element ref="relation" /> + <xs:element ref="coverage" /> + <xs:element ref="rights" /> + </xs:choice> + </xs:sequence> + </xs:group> - <xs:complexType name="elementType"> - <xs:simpleContent> - <xs:extension base="xs:string"> - <xs:attribute ref="xml:lang" use="optional"/> - </xs:extension> - </xs:simpleContent> - </xs:complexType> + <xs:complexType name="elementType"> + <xs:simpleContent> + <xs:extension base="xs:string"> + <xs:attribute ref="xml:lang" use="optional" /> + </xs:extension> + </xs:simpleContent> + </xs:complexType> </xs:schema> diff --git a/oaipmh-core/src/test/java/info/textgrid/middleware/test/TestDHOaipmhLocally.java b/oaipmh-core/src/test/java/info/textgrid/middleware/test/TestDHOaipmhLocally.java index 9d18a65b00bf38c5b17ca1a0bf88ad400585acf0..fa8f5a8af7bfbd8a2053dd25b7542231127d5168 100644 --- a/oaipmh-core/src/test/java/info/textgrid/middleware/test/TestDHOaipmhLocally.java +++ b/oaipmh-core/src/test/java/info/textgrid/middleware/test/TestDHOaipmhLocally.java @@ -281,7 +281,7 @@ public class TestDHOaipmhLocally { // System.out.println(json); DublinCoreBuilder result = new DublinCoreBuilder(); List<String> identifier = new ArrayList<String>(); - System.out.println(OaipmhUtilities.firstEnrtryFieldLoader(json, TEST_DARIAH_IDENTIFIER)); + System.out.println(OaipmhUtilities.firstEntryFieldLoader(json, TEST_DARIAH_IDENTIFIER)); identifier = OaipmhUtilities.listFieldLoader(json, "descriptiveMetadata.dc:identifier"); for (String id : identifier) { System.out.println(id); @@ -330,7 +330,7 @@ public class TestDHOaipmhLocally { JSONObject json = new JSONObject(jsonAsString); DublinCoreBuilder result = new DublinCoreBuilder(); List<String> identifier = new ArrayList<String>(); - System.out.println(OaipmhUtilities.firstEnrtryFieldLoader(json, TEST_DARIAH_IDENTIFIER)); + System.out.println(OaipmhUtilities.firstEntryFieldLoader(json, TEST_DARIAH_IDENTIFIER)); identifier = OaipmhUtilities.listFieldLoader(json, "descriptiveMetadata.dc:identifier"); for (String id : identifier) { System.out.println(id); diff --git a/oaipmh-core/src/test/java/info/textgrid/middleware/test/TestOaipmhUtilities.java b/oaipmh-core/src/test/java/info/textgrid/middleware/test/TestOaipmhUtilities.java index f941fa50c5c1a97b3b39233920705e22f86656e6..f1168648d88880882aa266b7629bff7f6fff53cb 100644 --- a/oaipmh-core/src/test/java/info/textgrid/middleware/test/TestOaipmhUtilities.java +++ b/oaipmh-core/src/test/java/info/textgrid/middleware/test/TestOaipmhUtilities.java @@ -1,6 +1,11 @@ package info.textgrid.middleware.test; import static org.junit.Assert.assertTrue; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.XMLGregorianCalendar; import org.junit.Test; import info.textgrid.middleware.OaipmhUtilities; @@ -178,4 +183,106 @@ public class TestOaipmhUtilities { } } + /** + * @throws DatatypeConfigurationException + */ + @Test + public void testGetUTCDateAsString() throws DatatypeConfigurationException { + + String tgDateStamp = "2012-02-10T23:45:00.507+01:00"; + String expectedUTCDate = "2012-02-10T22:45:00Z"; + String utcDate = OaipmhUtilities.getUTCDateAsString(tgDateStamp); + + if (!utcDate.equals(expectedUTCDate)) { + assertTrue(utcDate + " != " + expectedUTCDate, false); + } + } + + /** + * @throws ParseException + * @throws DatatypeConfigurationException + */ + @Test + public void testGetUTCDateAsGregorian() throws DatatypeConfigurationException { + + String tgDateStamp = "2022-07-22T14:28:13.139+02:00"; + String expectedUTCDate = "2022-07-22T12:28:13Z"; + XMLGregorianCalendar utcDate = OaipmhUtilities.getUTCDateAsGregorian(tgDateStamp); + + if (!utcDate.toString().equals(expectedUTCDate)) { + assertTrue(utcDate + " != " + expectedUTCDate, false); + } + } + + /** + * @throws DatatypeConfigurationException + * @throws ParseException + */ + @Test + public void testIsCorrectFromUntilDate() throws DatatypeConfigurationException, ParseException { + + String date = "1970-12-10T18:30:00"; + List<String> result = new ArrayList<String>(); + if (!OaipmhUtilities.isCorrectFromUntilDate(date)) { + result.add(date); + } + date = "1970-12-10T18:30"; + if (OaipmhUtilities.isCorrectFromUntilDate(date)) { + result.add(date); + } + date = "1970-12-10T18"; + if (OaipmhUtilities.isCorrectFromUntilDate(date)) { + result.add(date); + } + date = "1970-12-10"; + if (OaipmhUtilities.isCorrectFromUntilDate(date)) { + result.add(date); + } + date = "1970-12"; + if (OaipmhUtilities.isCorrectFromUntilDate(date)) { + result.add(date); + } + date = "1970"; + if (OaipmhUtilities.isCorrectFromUntilDate(date)) { + result.add(date); + } + date = "kakki"; + if (OaipmhUtilities.isCorrectFromUntilDate(date)) { + result.add(date); + } + date = "kakki-fakki"; + if (OaipmhUtilities.isCorrectFromUntilDate(date)) { + result.add(date); + } + + if (!result.isEmpty()) { + assertTrue(result.toString() + ": not ISO8691!", false); + } + } + + /** + * @throws DatatypeConfigurationException + * @throws ParseException + */ + @Test + public void testGetCurrentUTCDateAsString() + throws DatatypeConfigurationException, ParseException { + + String currentUTCDate = OaipmhUtilities.getCurrentUTCDateAsString(); + + System.out.println("UTC from current millies: " + currentUTCDate); + } + + /** + * @throws DatatypeConfigurationException + * @throws ParseException + */ + @Test + public void testGetCurrentUTCg() throws DatatypeConfigurationException, ParseException { + + XMLGregorianCalendar currentUTCDate = OaipmhUtilities.getCurrentUTCDateAsGregorian(); + + System.out.println("UTC from current millies: " + currentUTCDate); + } + } diff --git a/oaipmh-core/src/test/java/info/textgrid/middleware/test/TestTGOaipmhLocally.java b/oaipmh-core/src/test/java/info/textgrid/middleware/test/TestTGOaipmhLocally.java index fac84975f4128d595773debb9079c0a3d32a12d7..bb826ba8ba24d1318b844cdbf2b317af221e97c2 100644 --- a/oaipmh-core/src/test/java/info/textgrid/middleware/test/TestTGOaipmhLocally.java +++ b/oaipmh-core/src/test/java/info/textgrid/middleware/test/TestTGOaipmhLocally.java @@ -218,7 +218,7 @@ public class TestTGOaipmhLocally { public void testDateNow() throws DatatypeConfigurationException { System.out.println("---------------Test Datestamp Parsing with now date -----------------"); - XMLGregorianCalendar nowTest = OaipmhUtilities.getXMLGregorianCalendarNow(); + String nowTest = OaipmhUtilities.getCurrentUTCDateAsString(); System.out.println(nowTest); System.out.println("-------------------------------------------"); } @@ -233,7 +233,7 @@ public class TestTGOaipmhLocally { String dateformatbefore = "2012-02-06T20:48:39.614+01:00"; System.out.println("--------- Test Datestamp Parsing with a given date ---------------"); System.out.println("Original date: " + dateformatbefore); - XMLGregorianCalendar testDate = OaipmhUtilities.oaiDatestampAsGregorian(dateformatbefore); + XMLGregorianCalendar testDate = OaipmhUtilities.getUTCDateAsGregorian(dateformatbefore); System.out.println("Date after conversion: " + testDate); System.out.println("---------------------------------------------"); } @@ -248,7 +248,7 @@ public class TestTGOaipmhLocally { String dateformatbefore = "2012-02-06T20:48:39.614+01:00"; System.out.println("------------String Version-------------------"); System.out.println("Original date: " + dateformatbefore); - String testDate = OaipmhUtilities.oaiDatestampAsString(dateformatbefore); + String testDate = OaipmhUtilities.getUTCDateAsString(dateformatbefore); System.out.println("Date after conversion: " + testDate); System.out.println("---------------------------------------------"); } @@ -289,17 +289,6 @@ public class TestTGOaipmhLocally { System.out.println("-----------------------------------\n"); } - /** - * @throws ParseException - */ - @Test - public void testGetDateFormat() throws ParseException { - - System.out.println("Test get time format"); - System.out.println(OaipmhUtilities.getFormatOfDate("2019-12-02T15:36:13Z")); - System.out.println("-----------------------------------\n"); - } - /** * @throws ParseException */ diff --git a/oaipmh-core/src/test/java/info/textgrid/middleware/test/online/OaipmhUtilitiesOnline.java b/oaipmh-core/src/test/java/info/textgrid/middleware/test/online/OaipmhUtilitiesOnline.java index 470c4be16e9b4b61e2db6d147d4d63afe10b7738..41fd21481c2701907f1b349961237f94e4d72e80 100644 --- a/oaipmh-core/src/test/java/info/textgrid/middleware/test/online/OaipmhUtilitiesOnline.java +++ b/oaipmh-core/src/test/java/info/textgrid/middleware/test/online/OaipmhUtilitiesOnline.java @@ -46,8 +46,8 @@ public class OaipmhUtilitiesOnline { // ## CHANGE SETTINGS BELOW FOR SETTING TEST SCOPE --------------------------------------------- - // public static final String PROPERTIES_FILE = "oaipmh.test.textgridlab-org.properties"; - public static final String PROPERTIES_FILE = "oaipmh.test.dev-textgridlab-org.properties"; + public static final String PROPERTIES_FILE = "oaipmh.test.textgridlab-org.properties"; + // public static final String PROPERTIES_FILE = "oaipmh.test.dev-textgridlab-org.properties"; public static final boolean TEST_ALL_PAGES = false; // public static final boolean TEST_ALL_PAGES = true; @@ -77,12 +77,12 @@ public class OaipmhUtilitiesOnline { public static final String NOT_TESTED = " >>> NOT_TESTED"; public static final String NO_TOKEN = "-1"; - public static final String NO_SET = null; - public static final String NO_THREAD_NAME = ""; public static final boolean NO_METADATA_FORMAT_WITH_RESTOK = false; public static final boolean METADATA_FORMAT_WITH_RESTOK = true; public static final boolean NO_ERROR_EXPECTED = false; public static final boolean ERROR_EXPECTED = true; + public static final String NO_SET = null; + public static final String NO_THREAD_NAME = "MAIN"; public static final String NO_FROM = null; public static final String NO_UNTIL = null; public static final String NO_QUERY = ""; @@ -142,7 +142,7 @@ public class OaipmhUtilitiesOnline { Response result; - System.out.println("\twaiting: " + TIME + " millies"); + System.out.println("\t" + theThreadName + "waiting: " + TIME + " millies"); try { Thread.sleep(TIME); @@ -335,7 +335,7 @@ public class OaipmhUtilitiesOnline { // Test if the header identifiers are sound. if (theVerb.equals(VERB_LIST_RECORDS) || theVerb.equals(VERB_LIST_IDENTIFIERS)) { - examineTGHeaderIDs(responseString, theMetadataPrefix); + examineTGHeaderIDs(responseString, theMetadataPrefix, theThreadName); } // Test if the header dates and record (modification) dates are equal. @@ -379,7 +379,7 @@ public class OaipmhUtilitiesOnline { // Test if the header identifiers are sound. if (theVerb.equals(VERB_LIST_RECORDS)) { - examineTGHeaderIDs(responseString, theMetadataPrefix); + examineTGHeaderIDs(responseString, theMetadataPrefix, theThreadName); } // Test general metadata content (if verb is listRecords!), must go conform with the @@ -479,7 +479,8 @@ public class OaipmhUtilitiesOnline { int size = Integer.parseInt(sizeStr.substring(0, sizeStr.indexOf("\""))); String cursorStr = toktag.substring(toktag.indexOf("cursor=\"") + 8); int cursor = Integer.parseInt(cursorStr.substring(0, cursorStr.indexOf("\""))); - System.out.println("\t" + theThreadName + "size: " + size + " / " + cursor); + System.out.println("\t" + theThreadName + "complete list size: " + size); + System.out.println("\t" + theThreadName + "delivered with last response: " + cursor); // If token is provided, test cursor and element count! if (!restok.isEmpty()) { @@ -495,7 +496,7 @@ public class OaipmhUtilitiesOnline { + recordsExpectedPerRequest + " if token is provided, but is " + size; assertTrue(message, false); } - if (cursor != recordsExpectedPerRequest * loopCount) { + if (cursor != recordsExpectedPerRequest * (loopCount - 1)) { String message = "cursor must be " + (loopCount * recordsExpectedPerRequest) + " in loop " + loopCount + ", but is " + cursor; assertTrue(message, false); @@ -506,9 +507,12 @@ public class OaipmhUtilitiesOnline { // If no token is provided, stop querying. else { // Check <record> count, must be completeListSize % recordsExpectedPerRequest. - if (recordCount != size % recordsExpectedPerRequest) { + // NOTE In case we have exactly recordsExpectedPerRequest records, we have to use moduloCount! + int moduloCount = recordCount % recordsExpectedPerRequest; + int moduloExpected = size % recordsExpectedPerRequest; + if (moduloCount != moduloExpected) { String message = theThreadName + ": " + recordOrHeader + " count mismatch, should be " - + size % recordsExpectedPerRequest + ", but is " + recordCount; + + moduloExpected + ", but is " + recordCount; assertTrue(message, false); } @@ -556,8 +560,29 @@ public class OaipmhUtilitiesOnline { String message = OAI_DATACITE_PREFIX + " needs to deliver content with schema: " + EXPECTED_DATACITE_FORMAT_CONTENT + "!"; assertTrue(message, false); - } + + // DEBUG OUTPUT Trace empty record tags without metadata. + // try { + // File f = new File("kaputt.log"); + // if (!f.exists()) { + // f.createNewFile(); + // } + // FileWriter kaputt = new FileWriter(f, true); + // String mustNOTcontain = "</header>\n" + " </record>"; + // if (theResponseString.contains(mustNOTcontain)) { + // int loc = theResponseString.indexOf(mustNOTcontain); + // kaputt.append("#########################################\n"); + // kaputt.append(loc + "\n"); + // kaputt.append("#########################################\n"); + // kaputt.append(theResponseString.substring(loc - 200, loc + 200) + "\n"); + // kaputt.append("#########################################\n"); + // } + // kaputt.close(); + // } catch (IOException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } } /** @@ -569,8 +594,10 @@ public class OaipmhUtilitiesOnline { * * @param theResponseString * @param theMetadataPrefix + * @param theThreadName */ - public static void examineTGHeaderIDs(String theResponseString, String theMetadataPrefix) { + public static void examineTGHeaderIDs(String theResponseString, String theMetadataPrefix, + String theThreadName) { HashSet<String> idHash = new HashSet<String>(); @@ -589,7 +616,7 @@ public class OaipmhUtilitiesOnline { } } - System.out.println("\tID hash (" + idHash.size() + "): " + idHash); + System.out.println("\t[" + theThreadName + "] ID hash (" + idHash.size() + "): " + idHash); // Check for ID count: Hash size (unique IDs!) must be equal to the count of ID headers! if (count != idHash.size()) { @@ -629,13 +656,10 @@ public class OaipmhUtilitiesOnline { String headerDate = theResponseString.substring(theResponseString.indexOf(datestampTag) + datestampTag.length(), theResponseString.indexOf("</datestamp>")).trim(); - - System.out.println(headerDate); - - String recordChangeDate = theResponseString + String recordChangeDate = OaipmhUtilities.getUTCDateAsString(theResponseString .substring(theResponseString.indexOf(recordChangeTag) + recordChangeTag.length(), theResponseString.indexOf("</recordChangeDate>")) - .trim(); + .trim()); if (!headerDate.equals(recordChangeDate)) { assertTrue(headerDate + " != " + recordChangeDate, false); diff --git a/oaipmh-core/src/test/java/info/textgrid/middleware/test/online/tg/TestTGGetRecordOnline.java b/oaipmh-core/src/test/java/info/textgrid/middleware/test/online/tg/TestTGGetRecordOnline.java index 8c91a2c0eb74b97a0d1dc62cf16f9718d8f6156d..8c2831ddde2f66a37645d66faf119859329c4cbe 100644 --- a/oaipmh-core/src/test/java/info/textgrid/middleware/test/online/tg/TestTGGetRecordOnline.java +++ b/oaipmh-core/src/test/java/info/textgrid/middleware/test/online/tg/TestTGGetRecordOnline.java @@ -35,8 +35,6 @@ import info.textgrid.middleware.test.online.OaipmhUtilitiesOnline; * </p> * * @author Stefan E. Funk, SUB Göttingen - * @version 2023-01-11 - * @since 2022-09-08 */ @Ignore public class TestTGGetRecordOnline { @@ -188,9 +186,10 @@ public class TestTGGetRecordOnline { } /** + * @param theThreadName * @throws IOException - * @throws DatatypeConfigurationException * @throws ParseException + * @throws DatatypeConfigurationException */ @Test public void testGetRecordIdiomMETS() @@ -213,7 +212,8 @@ public class TestTGGetRecordOnline { } // Test OAI header. - OaipmhUtilitiesOnline.examineTGHeaderIDs(response, OaipmhUtilitiesOnline.OAI_IDIOMMETS_PREFIX); + OaipmhUtilitiesOnline.examineTGHeaderIDs(response, OaipmhUtilitiesOnline.OAI_IDIOMMETS_PREFIX, + OaipmhUtilitiesOnline.NO_THREAD_NAME); OaipmhUtilitiesOnline.examineTGModificationDates(response); System.out.println("\tresponse: " + response); @@ -221,9 +221,10 @@ public class TestTGGetRecordOnline { } /** + * @param theThreadName * @throws IOException - * @throws DatatypeConfigurationException * @throws ParseException + * @throws DatatypeConfigurationException */ @Test public void testGetRecordIDIOMMETSImage() @@ -248,7 +249,8 @@ public class TestTGGetRecordOnline { } // Test OAI header. - OaipmhUtilitiesOnline.examineTGHeaderIDs(response, OaipmhUtilitiesOnline.OAI_IDIOMMETS_PREFIX); + OaipmhUtilitiesOnline.examineTGHeaderIDs(response, OaipmhUtilitiesOnline.OAI_IDIOMMETS_PREFIX, + OaipmhUtilitiesOnline.NO_THREAD_NAME); OaipmhUtilitiesOnline.examineTGModificationDates(response); System.out.println("\tresponse: " + response); diff --git a/oaipmh-core/src/test/java/info/textgrid/middleware/test/online/tg/TestTGListIdentifiersOnline.java b/oaipmh-core/src/test/java/info/textgrid/middleware/test/online/tg/TestTGListIdentifiersOnline.java index 52d488e5983b8dfa97219ee0a3d54e2763aa52fe..3a373f61077851782feecad0ced0600693584051 100644 --- a/oaipmh-core/src/test/java/info/textgrid/middleware/test/online/tg/TestTGListIdentifiersOnline.java +++ b/oaipmh-core/src/test/java/info/textgrid/middleware/test/online/tg/TestTGListIdentifiersOnline.java @@ -25,8 +25,6 @@ import info.textgrid.middleware.test.online.OaipmhUtilitiesOnline; * </p> * * @author Stefan E. Funk, SUB Göttingen - * @version 2022-09-23 - * @since 2022-09-12 */ @Ignore public class TestTGListIdentifiersOnline { diff --git a/oaipmh-core/src/test/java/info/textgrid/middleware/test/online/tg/TestTGListRecordsOnline.java b/oaipmh-core/src/test/java/info/textgrid/middleware/test/online/tg/TestTGListRecordsOnline.java index 20431afaf5aa719eea036811c2df4dff4c396a96..500dae534dfabdc131b22c39537f444b63b780a8 100644 --- a/oaipmh-core/src/test/java/info/textgrid/middleware/test/online/tg/TestTGListRecordsOnline.java +++ b/oaipmh-core/src/test/java/info/textgrid/middleware/test/online/tg/TestTGListRecordsOnline.java @@ -25,8 +25,6 @@ import info.textgrid.middleware.test.online.OaipmhUtilitiesOnline; * </p> * * @author Stefan E. Funk, SUB Göttingen - * @version 2022-09-28 - * @since 2022-09-12 */ @Ignore public class TestTGListRecordsOnline { diff --git a/oaipmh-webapp/src/main/webapp/WEB-INF/beans.xml b/oaipmh-webapp/src/main/webapp/WEB-INF/beans.xml index 1a468037a5e32c55d4015d5ffe8ad72ab3560e4c..d098e2f02f4b1a7de4b302bef2d0d97c5be3dc74 100644 --- a/oaipmh-webapp/src/main/webapp/WEB-INF/beans.xml +++ b/oaipmh-webapp/src/main/webapp/WEB-INF/beans.xml @@ -93,6 +93,7 @@ <bean id="MetadataFormatListDelivererTG" class="info.textgrid.middleware.MetadataFormatListDelivererTG"> + <property name="oaiEsClient" ref="ElasticSearchClient" /> </bean> <!-- Bean for verb=Identify --> diff --git a/pom.xml b/pom.xml index ad93c4cef716c9cbf1dd17ee74e7170db33f62a4..48bc2913bdefe158df47d17a99c131b5563483ab 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ <maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version> <maven-eclipse-plugin.version>2.10</maven-eclipse-plugin.version> <maven-jaxb2-plugin.version>0.15.2</maven-jaxb2-plugin.version> - <mets-mods-mapping.version>2.1.4</mets-mods-mapping.version> + <mets-mods-mapping.version>2.3.1</mets-mods-mapping.version> <package-info-maven-plugin.version>1.4.5</package-info-maven-plugin.version> <properties-maven-plugin.version>1.0-alpha-2</properties-maven-plugin.version> <rdf4j-repository-api.version>3.0.2</rdf4j-repository-api.version>