From 57e785ea040d268eb8bcdd776fa2c8b39180f375 Mon Sep 17 00:00:00 2001 From: Paurikova2 Date: Wed, 27 Nov 2024 08:24:03 +0100 Subject: [PATCH] using of res policy end_date and added comments --- .../org/dspace/utils/SpecialItemService.java | 161 ++++++++++++------ .../resources/functions/GetAvailableFn.java | 9 + 2 files changed, 117 insertions(+), 53 deletions(-) diff --git a/dspace-oai/src/main/java/org/dspace/utils/SpecialItemService.java b/dspace-oai/src/main/java/org/dspace/utils/SpecialItemService.java index 3c09a6347c6b..a7f16aeb73ba 100644 --- a/dspace-oai/src/main/java/org/dspace/utils/SpecialItemService.java +++ b/dspace-oai/src/main/java/org/dspace/utils/SpecialItemService.java @@ -281,9 +281,66 @@ public static Node getAuthor(String mdValue) { } } - // Helper method to find the item by its handle - private static Item findItemByHandle(ClarinItemService clarinItemService, - Context context, MetadataField metadataField, String handle) { + /** + * Retrieves the earliest available date for an item identified by the given identifier URI. + * This method checks for any embargo date first and then retrieves the "dc.date.available" + * metadata value as a fallback if no embargo date is found. + * + * @param identifierUri The identifier URI of the item whose available date is to be retrieved. + * @return A string representation of the earliest available date, or null if no date is found or an error occurs. + */ + public static String getAvailable(String identifierUri) { + Context context = new Context(); + // Find the metadata field for "dc.identifier.uri" + String mtdField = "dc.identifier.uri"; + MetadataField metadataField = findMetadataField(context, mtdField); + if (Objects.isNull(metadataField)) { + log.error(String.format("Metadata field for %s not found.", mtdField)); + return null; + } + + // Retrieve the item using the handle + Item item = findItemByHandle(context, metadataField, identifierUri); + if (Objects.isNull(item)) { + log.error(String.format("Item for handle %s doesn't exist!", identifierUri)); + return null; + } + + // Check if there is an embargo or get the earliest available date + Date startDate = getEmbargoDate(context, item); + if (Objects.isNull(startDate)) { + startDate = getAvailableDate(context, item); + } + return (Objects.nonNull(startDate)) ? startDate.toString() : null; + } + + /** + * Finds the metadata field corresponding to the provided string. + * + * @param context The DSpace context + * @param mtd The metadata field string + * @return The MetadataField object, or null if not found. + */ + private static MetadataField findMetadataField(Context context, String mtd){ + MetadataFieldService metadataFieldService = ContentServiceFactory.getInstance().getMetadataFieldService(); + try { + return metadataFieldService.findByString(context, mtd, '.'); + } catch (SQLException e) { + log.error(String.format("Error finding metadata field %s.", mtd), e); + return null; + } + } + + /** + * Finds an item in DSpace using the provided handle and metadata field. + * + * @param context The DSpace context + * @param metadataField The metadata field used for item search + * @param handle The handle (identifier) of the item. + * @return The Item object, or null if no item is found. + */ + private static Item findItemByHandle(Context context, MetadataField metadataField, String handle) { + ClarinItemService clarinItemService = ClarinServiceFactory.getInstance().getClarinItemService(); try { List itemList = clarinItemService.findByHandle(context, metadataField, handle); return (itemList.isEmpty()) ? null : itemList.get(0); @@ -293,16 +350,33 @@ private static Item findItemByHandle(ClarinItemService clarinItemService, } } - // Helper method to get the embargo start date from the resource policies - private static Date getEmbargoStartDate(Context context, Item item) throws SQLException { + /** + * Retrieves the embargo start date for the given item bitstreams. If an embargo has ended, the end date is returned. + * + * @param context The DSpace context + * @param item The item whose embargo date is to be retrieved. + * @return The start or end date of the embargo, or null if no embargo exists. + */ + private static Date getEmbargoDate(Context context, Item item){ ResourcePolicyService resPolicyService = AuthorizeServiceFactory.getInstance().getResourcePolicyService(); Date startDate = null; for (Bundle bundle : item.getBundles()) { for (Bitstream bitstream : bundle.getBitstreams()) { - List resPolList = resPolicyService.find(context, bitstream, Constants.READ); + List resPolList; + try { + resPolList = resPolicyService.find(context, bitstream, Constants.READ); + } catch (SQLException e) { + log.error(String.format("Error during finding resource policies READ for bitstream %s"), + bitstream.getID()); + return null; + } for (ResourcePolicy resPol : resPolList) { Date date = resPol.getStartDate(); - if (startDate == null || (date != null && date.compareTo(startDate) > 0)) { + // If the embargo has already ended, use the date of its end. + if (Objects.nonNull(date) && Objects.nonNull(resPol.getEndDate())) { + date = resPol.getEndDate(); + } + if (Objects.isNull(startDate) || (Objects.nonNull(date) && date.compareTo(startDate) > 0)) { startDate = date; } } @@ -311,54 +385,30 @@ private static Date getEmbargoStartDate(Context context, Item item) throws SQLEx return startDate; } - public static String getAvailable(String identifierUri) { - Context context = new Context(); - ClarinItemService clarinItemService = ClarinServiceFactory.getInstance().getClarinItemService(); - try { - // Find the metadata field for "dc.identifier.uri" - MetadataField metadataField = findMetadataField(context, "dc.identifier.uri"); - if (metadataField == null) { - log.error("Metadata field for 'dc.identifier.uri' not found."); - return null; - } - - // Retrieve the item using the handle - Item item = findItemByHandle(clarinItemService, context, metadataField, identifierUri); - if (item == null) { - log.error(String.format("Item for handle %s doesn't exist!", identifierUri)); - return null; - } - - // Check if there is an embargo or get the earliest available date - Date startDate = getEmbargoStartDate(context, item); - if (startDate == null) { - startDate = getAvailableDate(context, item); - } - return (startDate != null) ? startDate.toString() : null; - } catch (SQLException | InvalidMetadataFieldException ex) { - log.error("Error in getAvailable method: ", ex); - } - return null; - } - - // Helper method to find the metadata field "dc.identifier.uri" - private static MetadataField findMetadataField(Context context, String mtd) throws SQLException { - MetadataFieldService metadataFieldService = ContentServiceFactory.getInstance().getMetadataFieldService(); - return metadataFieldService.findByString(context, mtd, '.'); - } - - // Helper method to get the available date from the metadata values - private static Date getAvailableDate(Context context, Item item) - throws SQLException, InvalidMetadataFieldException { + /** + * Retrieves the available date for the given item by checking the "dc.date.available" metadata. + * + * @param context The DSpace context + * @param item The item whose available date is to be retrieved. + * @return The available date, or null if no available date is found. + */ + private static Date getAvailableDate(Context context, Item item) { DSpaceFieldResolver dSpaceFieldResolver = new DSpaceFieldResolver(); List metadataValueList = item.getMetadata(); - int fieldID = dSpaceFieldResolver.getFieldID(context, "dc.date.available"); + String mtdField = "dc.date.available"; + int fieldID; + try { + fieldID = dSpaceFieldResolver.getFieldID(context, mtdField); + } catch (SQLException | InvalidMetadataFieldException e) { + log.error(String.format("Error during finding ID of metadata field %s.", mtdField)); + return null; + } Date startDate = null; - for (MetadataValue mtd : metadataValueList) { if (mtd.getMetadataField().getID() == fieldID) { Date availableDate = parseDate(mtd.getValue()); - if (startDate == null || (availableDate != null && availableDate.compareTo(startDate) > 0)) { + if (Objects.isNull(startDate) || (Objects.nonNull(availableDate) + && availableDate.compareTo(startDate) > 0)) { startDate = availableDate; } } @@ -366,19 +416,24 @@ private static Date getAvailableDate(Context context, Item item) return startDate; } - // Helper method to parse a date from a string + /** + * Parses a date string in the format "yyyy-MM-dd" into a Date object. + * + * @param dateString The date string to be parsed. + * @return A Date object representing the parsed date, or null if parsing fails. + */ private static Date parseDate(String dateString) { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); // Example format + String format = "yyyy-MM-dd"; + SimpleDateFormat dateFormat = new SimpleDateFormat(format); // Example format dateFormat.setLenient(false); // Set lenient to false to avoid parsing incorrect dates - try { return dateFormat.parse(dateString); // Attempt to parse the date } catch (ParseException e) { + log.warn(String.format("Date %s cannot be parsed using the format %s.", dateString, format)); return null; } } - public static boolean hasOwnMetadata(List metadataValues) { if (metadataValues.size() == 1 && metadataValues.get(0).getValue().equalsIgnoreCase("true")) { return true; diff --git a/dspace-oai/src/main/java/org/dspace/xoai/services/impl/resources/functions/GetAvailableFn.java b/dspace-oai/src/main/java/org/dspace/xoai/services/impl/resources/functions/GetAvailableFn.java index b10c554cce52..f7843abed51c 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/services/impl/resources/functions/GetAvailableFn.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/services/impl/resources/functions/GetAvailableFn.java @@ -9,6 +9,15 @@ import org.dspace.utils.SpecialItemService; +/** + * The GetAvailableFn class extends the StringXSLFunction to provide a custom function + * that retrieves the availability status of an item based on its identifier. + * It uses the SpecialItemService to fetch the available information. + * This function is intended to be used in XSL transformations where the + * "getAvailable" function is called with an item's identifier as a parameter. + * + * @author Michaela Paurikova(michaela.paurikova at dataquest.sk) + */ public class GetAvailableFn extends StringXSLFunction { @Override protected String getFnName() {