/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE and NOTICE files at the root of the source * tree and available online at * * http://www.dspace.org/license/ */ package org.dspace.importer.external.pubmed.metadatamapping.contributor; import org.apache.log4j.Logger; import org.dspace.content.DCDate; import org.dspace.importer.external.metadatamapping.MetadataFieldConfig; import org.dspace.importer.external.metadatamapping.MetadataFieldMapping; import org.dspace.importer.external.metadatamapping.MetadatumDTO; import org.dspace.importer.external.metadatamapping.contributor.MetadataContributor; import org.springframework.beans.factory.annotation.Required; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Date; import java.util.LinkedList; import java.util.List; /** * Pubmed specific implementation of {@link MetadataContributor} * Responsible for generating a set of Date metadata from the retrieved document. * * @author Philip Vissenaekens (philip at atmire dot com) */ public class PubmedDateMetadatumContributor<T> implements MetadataContributor<T> { Logger log = Logger.getLogger(PubmedDateMetadatumContributor.class); private MetadataFieldMapping<T, MetadataContributor<T>> metadataFieldMapping; /* A list of all the dateFormats to attempt. These should be configured to have the most specific first and the more lenient at the back. */ private List<String> dateFormatsToAttempt; public List<String> getDateFormatsToAttempt() { return dateFormatsToAttempt; } @Required public void setDateFormatsToAttempt(List<String> dateFormatsToAttempt) { this.dateFormatsToAttempt = dateFormatsToAttempt; } private MetadataFieldConfig field; private MetadataContributor day; private MetadataContributor month; private MetadataContributor year; /** * Set the metadatafieldMapping used in the transforming of a record to actual metadata. * @param metadataFieldMapping the new mapping. */ @Override public void setMetadataFieldMapping(MetadataFieldMapping<T, MetadataContributor<T>> metadataFieldMapping) { this.metadataFieldMapping = metadataFieldMapping; day.setMetadataFieldMapping(metadataFieldMapping); month.setMetadataFieldMapping(metadataFieldMapping); year.setMetadataFieldMapping(metadataFieldMapping); } /** * Initialize an empty PubmedDateMetadatumContributor object */ public PubmedDateMetadatumContributor() { } /** * * @param field {@link org.dspace.importer.external.metadatamapping.MetadataFieldConfig} used in mapping * @param day a MetadataContributor, representing a day * @param month a {@link MetadataContributor}, representing a month * @param year a {@link MetadataContributor}, representing a year */ public PubmedDateMetadatumContributor(MetadataFieldConfig field, MetadataContributor day, MetadataContributor month, MetadataContributor year) { this.field = field; this.day = day; this.month = month; this.year = year; } /** * Retrieve the metadata associated with the given object. * The code will loop over the different dates and attempt to format them using the configured dateFormats to attempt. * For each date, once a format is successful, this result is used. Make sure that dateFormatsToAttempt is configured from most restrictive to most lenient to try and get the most precise result * @param t A class to retrieve metadata from. * @return a collection of import records. Only the identifier of the found records may be put in the record. */ @Override public Collection<MetadatumDTO> contributeMetadata(T t) { List<MetadatumDTO> values = new LinkedList<>(); try { LinkedList<MetadatumDTO> yearList = (LinkedList<MetadatumDTO>) year.contributeMetadata(t); LinkedList<MetadatumDTO> monthList = (LinkedList<MetadatumDTO>) month.contributeMetadata(t); LinkedList<MetadatumDTO> dayList = (LinkedList<MetadatumDTO>) day.contributeMetadata(t); for (int i = 0; i < yearList.size(); i++) { DCDate dcDate = null; String dateString = ""; if (monthList.size() > i && dayList.size() > i) { dateString = yearList.get(i).getValue() + "-" + monthList.get(i).getValue() + "-" + dayList.get(i).getValue(); } else if (monthList.size() > i) { dateString = yearList.get(i).getValue() + "-" + monthList.get(i).getValue(); } else { dateString = yearList.get(i).getValue(); } int j = 0 ; // Use the first dcDate that has been formatted (Config should go from most specific to most lenient) while (j<dateFormatsToAttempt.size() && dcDate==null){ String dateFormat = dateFormatsToAttempt.get(j); try { SimpleDateFormat formatter = new SimpleDateFormat(dateFormat); Date date = formatter.parse(dateString); dcDate = new DCDate(date); } catch (ParseException e) { // Multiple dateformats can be configured, we don't want to print the entire stacktrace every time one of those formats fails. log.info("Failed parsing "+dateString+" using the following format: "+dateFormat+ ", check the configured dataformats in config/spring/api/pubmed-integration.xml"); } j++; } if (dcDate != null) { values.add(metadataFieldMapping.toDCValue(field, dcDate.toString())); } } } catch (Exception e) { log.error("Error", e); } return values; } /** * Return the MetadataFieldConfig used while retrieving MetadatumDTO * @return MetadataFieldConfig */ public MetadataFieldConfig getField() { return field; } /** * Setting the MetadataFieldConfig * @param field MetadataFieldConfig used while retrieving MetadatumDTO */ public void setField(MetadataFieldConfig field) { this.field = field; } /** * Retrieve the day from the object * @return {@link MetadataContributor}, representing a day */ public MetadataContributor getDay() { return day; } /** * Set a day ({@link MetadataContributor}) to this object * @param day a {@link MetadataContributor}, representing a day */ public void setDay(MetadataContributor day) { this.day = day; } /** * Retrieve the month from the object * @return {@link MetadataContributor}, representing a month */ public MetadataContributor getMonth() { return month; } /** * Set a month ({@link MetadataContributor}) to this object * @param month a {@link MetadataContributor}, representing a month */ public void setMonth(MetadataContributor month) { this.month = month; } /** * Retrieve the year from the object * @return {@link MetadataContributor}, representing a year */ public MetadataContributor getYear() { return year; } /** * Set a year ({@link MetadataContributor}) to this object * @param year a {@link MetadataContributor}, representing a year */ public void setYear(MetadataContributor year) { this.year = year; } }