/** * Licensed to The Apereo Foundation under one or more contributor license * agreements. See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * * The Apereo Foundation licenses this file to you under the Educational * Community License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License * at: * * http://opensource.org/licenses/ecl2.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * */ package org.opencastproject.schema; import static org.opencastproject.util.data.Option.option; import org.opencastproject.mediapackage.EName; import org.opencastproject.metadata.dublincore.DublinCore; import org.opencastproject.metadata.dublincore.DublinCoreCatalog; import org.opencastproject.metadata.dublincore.DublinCoreValue; import org.opencastproject.metadata.dublincore.DublinCores; import org.opencastproject.metadata.dublincore.EncodingSchemeUtils; import org.opencastproject.metadata.dublincore.Precision; import org.opencastproject.util.data.Function; import org.opencastproject.util.data.Option; import org.opencastproject.util.data.functions.Functions; import org.opencastproject.util.data.functions.Strings; import java.util.ArrayList; import java.util.Date; import java.util.List; /** Constructor, converter and encoder functions for {@link org.opencastproject.schema.OcDublinCore}. */ public final class OcDublinCoreUtil { private OcDublinCoreUtil() { } private static final Function<DublinCoreValue, String> value = new Function<DublinCoreValue, String>() { @Override public String apply(DublinCoreValue dublinCoreValue) { return dublinCoreValue.getValue(); } }; private static Function<String, Date> decodeDate = new Function<String, Date>() { @Override public Date apply(String s) { final Date d = EncodingSchemeUtils.decodeDate(s); if (d != null) return d; else throw new Error(s + " is not a W3C-DTF encoded date"); } }; public static DublinCoreValue encodeCreated(Date a) { return EncodingSchemeUtils.encodeDate(a, Precision.Second); } public static final Function<Date, DublinCoreValue> encodeCreated = new Function<Date, DublinCoreValue>() { @Override public DublinCoreValue apply(Date a) { return encodeCreated(a); } }; public static DublinCoreValue encodeDate(Date a) { return EncodingSchemeUtils.encodeDate(a, Precision.Second); } public static final Function<Date, DublinCoreValue> encodeDate = new Function<Date, DublinCoreValue>() { @Override public DublinCoreValue apply(Date a) { return encodeDate(a); } }; public static DublinCoreValue encodeDateAccepted(Date a) { return EncodingSchemeUtils.encodeDate(a, Precision.Second); } public static final Function<Date, DublinCoreValue> encodeDateAccepted = new Function<Date, DublinCoreValue>() { @Override public DublinCoreValue apply(Date a) { return encodeDateAccepted(a); } }; public static DublinCoreValue encodeDateCopyrighted(Date a) { return EncodingSchemeUtils.encodeDate(a, Precision.Second); } public static final Function<Date, DublinCoreValue> encodeDateCopyrighted = new Function<Date, DublinCoreValue>() { @Override public DublinCoreValue apply(Date a) { return encodeDateCopyrighted(a); } }; public static DublinCoreValue encodeDateSubmitted(Date a) { return EncodingSchemeUtils.encodeDate(a, Precision.Second); } public static final Function<Date, DublinCoreValue> encodeDateSubmitted = new Function<Date, DublinCoreValue>() { @Override public DublinCoreValue apply(Date a) { return encodeDateSubmitted(a); } }; public static DublinCoreValue encodeExtent(Long a) { return DublinCoreValue.mk(a.toString()); } public static final Function<Long, DublinCoreValue> encodeExtent = new Function<Long, DublinCoreValue>() { @Override public DublinCoreValue apply(Long a) { return encodeExtent(a); } }; /** * Create a generic DublinCoreCatalog from an OcDublinCore. * Fields are encoded according to the Opencast rules. This class provides functions for each DublinCore * property that needs special encoding. */ public static DublinCoreCatalog toCatalog(final OcDublinCore source) { // completeness assured by unit test final DublinCoreCatalog target = DublinCores.mkOpencastEpisode().getCatalog(); for (String a : source.getAbstract()) target.set(DublinCore.PROPERTY_ABSTRACT, a); for (String a : source.getAccessRights()) target.set(DublinCore.PROPERTY_ACCESS_RIGHTS, a); for (String a : source.getAccrualMethod()) target.set(DublinCore.PROPERTY_ACCRUAL_METHOD, a); for (String a : source.getAccrualPeriodicity()) target.set(DublinCore.PROPERTY_ACCRUAL_PERIODICITY, a); for (String a : source.getAccrualPolicy()) target.set(DublinCore.PROPERTY_ACCRUAL_POLICY, a); for (String a : source.getAlternative()) target.set(DublinCore.PROPERTY_ALTERNATIVE, a); for (String a : source.getAudience()) target.set(DublinCore.PROPERTY_AUDIENCE, a); for (String a : source.getAvailable()) target.set(DublinCore.PROPERTY_AVAILABLE, a); for (String a : source.getBibliographicCitation()) target.set(DublinCore.PROPERTY_BIBLIOGRAPHIC_CITATION, a); for (String a : source.getConformsTo()) target.set(DublinCore.PROPERTY_CONFORMS_TO, a); for (String a : source.getContributor()) target.set(DublinCore.PROPERTY_CONTRIBUTOR, a); for (String a : source.getCoverage()) target.set(DublinCore.PROPERTY_COVERAGE, a); target.set(DublinCore.PROPERTY_CREATED, encodeCreated(source.getCreated())); for (String a : source.getCreator()) target.set(DublinCore.PROPERTY_CREATOR, a); for (Date a : source.getDate()) target.set(DublinCore.PROPERTY_DATE, encodeDate(a)); for (Date a : source.getDateAccepted()) target.set(DublinCore.PROPERTY_DATE_ACCEPTED, encodeDateAccepted(a)); for (Date a : source.getDateCopyrighted()) target.set(DublinCore.PROPERTY_DATE_COPYRIGHTED, encodeDateCopyrighted(a)); for (Date a : source.getDateSubmitted()) target.set(DublinCore.PROPERTY_DATE_SUBMITTED, encodeDateSubmitted(a)); for (String a : source.getDescription()) target.set(DublinCore.PROPERTY_DESCRIPTION, a); for (String a : source.getEducationLevel()) target.set(DublinCore.PROPERTY_EDUCATION_LEVEL, a); for (Long a : source.getExtent()) target.set(DublinCore.PROPERTY_EXTENT, encodeExtent(a)); for (String a : source.getFormat()) target.set(DublinCore.PROPERTY_FORMAT, a); for (String a : source.getHasFormat()) target.set(DublinCore.PROPERTY_HAS_FORMAT, a); for (String a : source.getHasPart()) target.set(DublinCore.PROPERTY_HAS_PART, a); for (String a : source.getHasVersion()) target.set(DublinCore.PROPERTY_HAS_VERSION, a); for (String a : source.getIdentifier()) target.set(DublinCore.PROPERTY_IDENTIFIER, a); for (String a : source.getInstructionalMethod()) target.set(DublinCore.PROPERTY_INSTRUCTIONAL_METHOD, a); for (String a : source.getIsFormatOf()) target.set(DublinCore.PROPERTY_IS_FORMAT_OF, a); for (String a : source.getIsPartOf()) target.set(DublinCore.PROPERTY_IS_PART_OF, a); for (String a : source.getIsReferencedBy()) target.set(DublinCore.PROPERTY_IS_REFERENCED_BY, a); for (String a : source.getIsReplacedBy()) target.set(DublinCore.PROPERTY_IS_REPLACED_BY, a); for (String a : source.getIsRequiredBy()) target.set(DublinCore.PROPERTY_IS_REQUIRED_BY, a); for (String a : source.getIssued()) target.set(DublinCore.PROPERTY_ISSUED, a); for (String a : source.getIsVersionOf()) target.set(DublinCore.PROPERTY_IS_VERSION_OF, a); for (String a : source.getLanguage()) target.set(DublinCore.PROPERTY_LANGUAGE, a); for (String a : source.getLicense()) target.set(DublinCore.PROPERTY_LICENSE, a); for (String a : source.getMediator()) target.set(DublinCore.PROPERTY_MEDIATOR, a); for (String a : source.getMedium()) target.set(DublinCore.PROPERTY_MEDIUM, a); for (String a : source.getModified()) target.set(DublinCore.PROPERTY_MODIFIED, a); for (String a : source.getProvenance()) target.set(DublinCore.PROPERTY_PROVENANCE, a); for (String a : source.getPublisher()) target.set(DublinCore.PROPERTY_PUBLISHER, a); for (String a : source.getReferences()) target.set(DublinCore.PROPERTY_REFERENCES, a); for (String a : source.getRelation()) target.set(DublinCore.PROPERTY_RELATION, a); for (String a : source.getReplaces()) target.set(DublinCore.PROPERTY_REPLACES, a); for (String a : source.getRequires()) target.set(DublinCore.PROPERTY_REQUIRES, a); for (String a : source.getRights()) target.set(DublinCore.PROPERTY_RIGHTS, a); for (String a : source.getRightsHolder()) target.set(DublinCore.PROPERTY_RIGHTS_HOLDER, a); for (String a : source.getSource()) target.set(DublinCore.PROPERTY_SOURCE, a); for (String a : source.getSpatial()) target.set(DublinCore.PROPERTY_SPATIAL, a); for (String a : source.getSubject()) target.set(DublinCore.PROPERTY_SUBJECT, a); for (String a : source.getTableOfContents()) target.set(DublinCore.PROPERTY_TABLE_OF_CONTENTS, a); for (String a : source.getTemporal()) target.set(DublinCore.PROPERTY_TEMPORAL, a); target.set(DublinCore.PROPERTY_TITLE, source.getTitle()); for (String a : source.getType()) target.set(DublinCore.PROPERTY_TYPE, a); for (String a : source.getValid()) target.set(DublinCore.PROPERTY_VALID, a); return target; } public static class OcDublinCoreConversion { private final OcDublinCore dublinCore; private final List<String> conversionErrors; public OcDublinCoreConversion(OcDublinCore dublinCore, List<String> conversionErrors) { this.dublinCore = dublinCore; this.conversionErrors = conversionErrors; } public OcDublinCore getDublinCore() { return dublinCore; } public List<String> getConversionErrors() { return conversionErrors; } } /** * Create an OcDublinCore from a generic DublinCoreCatalog enforcing schema rules. * If mandatory properties are missing default values will be used and the error is recorded. */ public static OcDublinCoreConversion create(DublinCoreCatalog src) { final List<String> errors = new ArrayList<String>(); final Option<String> abstrakt = option(src.getFirst(DublinCore.PROPERTY_ABSTRACT)); final Option<String> accessRights = option(src.getFirst(DublinCore.PROPERTY_ACCESS_RIGHTS)); final Option<String> accrualMethod = option(src.getFirst(DublinCore.PROPERTY_ACCRUAL_METHOD)); final Option<String> accrualPeriodicity = option(src.getFirst(DublinCore.PROPERTY_ACCRUAL_PERIODICITY)); final Option<String> accrualPolicy = option(src.getFirst(DublinCore.PROPERTY_ACCRUAL_POLICY)); final Option<String> alternative = option(src.getFirst(DublinCore.PROPERTY_ALTERNATIVE)); final Option<String> audience = option(src.getFirst(DublinCore.PROPERTY_AUDIENCE)); final Option<String> available = option(src.getFirst(DublinCore.PROPERTY_AVAILABLE)); final Option<String> bibliographicCitation = option(src.getFirst(DublinCore.PROPERTY_BIBLIOGRAPHIC_CITATION)); final Option<String> conformsTo = option(src.getFirst(DublinCore.PROPERTY_CONFORMS_TO)); final Option<String> contributor = option(src.getFirst(DublinCore.PROPERTY_CONTRIBUTOR)); final Option<String> coverage = option(src.getFirst(DublinCore.PROPERTY_COVERAGE)); final Date created = getMandatoryProperty(src, DublinCore.PROPERTY_CREATED, decodeDate, new Date(0), errors); final Option<String> creator = option(src.getFirst(DublinCore.PROPERTY_CREATOR)); final Option<Date> date = option(src.getFirst(DublinCore.PROPERTY_DATE)).map(decodeDate); final Option<Date> dateAccepted = option(src.getFirst(DublinCore.PROPERTY_DATE_ACCEPTED)).map(decodeDate); final Option<Date> dateCopyrighted = option(src.getFirst(DublinCore.PROPERTY_DATE_COPYRIGHTED)).map(decodeDate); final Option<Date> dateSubmitted = option(src.getFirst(DublinCore.PROPERTY_DATE_SUBMITTED)).map(decodeDate); final Option<String> description = option(src.getFirst(DublinCore.PROPERTY_DESCRIPTION)); final Option<String> educationLevel = option(src.getFirst(DublinCore.PROPERTY_EDUCATION_LEVEL)); final Option<Long> extent = option(src.getFirst(DublinCore.PROPERTY_EXTENT)).bind(Strings.toLong); final Option<String> format = option(src.getFirst(DublinCore.PROPERTY_FORMAT)); final Option<String> hasFormat = option(src.getFirst(DublinCore.PROPERTY_HAS_FORMAT)); final Option<String> hasPart = option(src.getFirst(DublinCore.PROPERTY_HAS_PART)); final Option<String> hasVersion = option(src.getFirst(DublinCore.PROPERTY_HAS_VERSION)); final Option<String> identifier = option(src.getFirst(DublinCore.PROPERTY_IDENTIFIER)); final Option<String> instructionalMethod = option(src.getFirst(DublinCore.PROPERTY_INSTRUCTIONAL_METHOD)); final Option<String> isFormatOf = option(src.getFirst(DublinCore.PROPERTY_IS_FORMAT_OF)); final Option<String> isPartOf = option(src.getFirst(DublinCore.PROPERTY_IS_PART_OF)); final Option<String> isReferencedBy = option(src.getFirst(DublinCore.PROPERTY_IS_REFERENCED_BY)); final Option<String> isReplacedBy = option(src.getFirst(DublinCore.PROPERTY_IS_REPLACED_BY)); final Option<String> isRequiredBy = option(src.getFirst(DublinCore.PROPERTY_IS_REQUIRED_BY)); final Option<String> issued = option(src.getFirst(DublinCore.PROPERTY_ISSUED)); final Option<String> isVersionOf = option(src.getFirst(DublinCore.PROPERTY_IS_VERSION_OF)); final Option<String> language = option(src.getFirst(DublinCore.PROPERTY_LANGUAGE)); final Option<String> license = option(src.getFirst(DublinCore.PROPERTY_LICENSE)); final Option<String> mediator = option(src.getFirst(DublinCore.PROPERTY_MEDIATOR)); final Option<String> medium = option(src.getFirst(DublinCore.PROPERTY_MEDIUM)); final Option<String> modified = option(src.getFirst(DublinCore.PROPERTY_MODIFIED)); final Option<String> provenance = option(src.getFirst(DublinCore.PROPERTY_PROVENANCE)); final Option<String> publisher = option(src.getFirst(DublinCore.PROPERTY_PUBLISHER)); final Option<String> references = option(src.getFirst(DublinCore.PROPERTY_REFERENCES)); final Option<String> relation = option(src.getFirst(DublinCore.PROPERTY_RELATION)); final Option<String> replaces = option(src.getFirst(DublinCore.PROPERTY_REPLACES)); final Option<String> requires = option(src.getFirst(DublinCore.PROPERTY_REQUIRES)); final Option<String> rights = option(src.getFirst(DublinCore.PROPERTY_RIGHTS)); final Option<String> rightsHolder = option(src.getFirst(DublinCore.PROPERTY_RIGHTS_HOLDER)); final Option<String> source = option(src.getFirst(DublinCore.PROPERTY_SOURCE)); final Option<String> spatial = option(src.getFirst(DublinCore.PROPERTY_SPATIAL)); final Option<String> subject = option(src.getFirst(DublinCore.PROPERTY_SUBJECT)); final Option<String> tableOfContents = option(src.getFirst(DublinCore.PROPERTY_TABLE_OF_CONTENTS)); final Option<String> temporal = option(src.getFirst(DublinCore.PROPERTY_TEMPORAL)); final String title = getMandatoryProperty(src, DublinCore.PROPERTY_TITLE, Functions.<String>identity(), "?", errors); final Option<String> type = option(src.getFirst(DublinCore.PROPERTY_TYPE)); final Option<String> valid = option(src.getFirst(DublinCore.PROPERTY_VALID)); final OcDublinCore dc = new OcDublinCore() { @Override public Option<String> getAbstract() { return abstrakt; } @Override public Option<String> getAccessRights() { return accessRights; } @Override public Option<String> getAccrualMethod() { return accrualMethod; } @Override public Option<String> getAccrualPeriodicity() { return accrualPeriodicity; } @Override public Option<String> getAccrualPolicy() { return accrualPolicy; } @Override public Option<String> getAlternative() { return alternative; } @Override public Option<String> getAudience() { return audience; } @Override public Option<String> getAvailable() { return available; } @Override public Option<String> getBibliographicCitation() { return bibliographicCitation; } @Override public Option<String> getConformsTo() { return conformsTo; } @Override public Option<String> getContributor() { return contributor; } @Override public Option<String> getCoverage() { return coverage; } @Override public Date getCreated() { return created; } @Override public Option<String> getCreator() { return creator; } @Override public Option<Date> getDate() { return date; } @Override public Option<Date> getDateAccepted() { return dateAccepted; } @Override public Option<Date> getDateCopyrighted() { return dateCopyrighted; } @Override public Option<Date> getDateSubmitted() { return dateSubmitted; } @Override public Option<String> getDescription() { return description; } @Override public Option<String> getEducationLevel() { return educationLevel; } @Override public Option<Long> getExtent() { return extent; } @Override public Option<String> getFormat() { return format; } @Override public Option<String> getHasFormat() { return hasFormat; } @Override public Option<String> getHasPart() { return hasPart; } @Override public Option<String> getHasVersion() { return hasVersion; } @Override public Option<String> getIdentifier() { return identifier; } @Override public Option<String> getInstructionalMethod() { return instructionalMethod; } @Override public Option<String> getIsFormatOf() { return isFormatOf; } @Override public Option<String> getIsPartOf() { return isPartOf; } @Override public Option<String> getIsReferencedBy() { return isReferencedBy; } @Override public Option<String> getIsReplacedBy() { return isReplacedBy; } @Override public Option<String> getIsRequiredBy() { return isRequiredBy; } @Override public Option<String> getIssued() { return issued; } @Override public Option<String> getIsVersionOf() { return isVersionOf; } @Override public Option<String> getLanguage() { return language; } @Override public Option<String> getLicense() { return license; } @Override public Option<String> getMediator() { return mediator; } @Override public Option<String> getMedium() { return medium; } @Override public Option<String> getModified() { return modified; } @Override public Option<String> getProvenance() { return provenance; } @Override public Option<String> getPublisher() { return publisher; } @Override public Option<String> getReferences() { return references; } @Override public Option<String> getRelation() { return relation; } @Override public Option<String> getReplaces() { return replaces; } @Override public Option<String> getRequires() { return requires; } @Override public Option<String> getRights() { return rights; } @Override public Option<String> getRightsHolder() { return rightsHolder; } @Override public Option<String> getSource() { return source; } @Override public Option<String> getSpatial() { return spatial; } @Override public Option<String> getSubject() { return subject; } @Override public Option<String> getTableOfContents() { return tableOfContents; } @Override public Option<String> getTemporal() { return temporal; } @Override public String getTitle() { return title; } @Override public Option<String> getType() { return type; } @Override public Option<String> getValid() { return valid; } }; return new OcDublinCoreConversion(dc, errors); } private static <A> A getMandatoryProperty(DublinCoreCatalog c, EName property, Function<String, A> convert, A dflt, List<String> errors) { for (A value : option(c.getFirst(property)).map(convert)) { return value; } errors.add(property.getLocalName() + " is missing"); return dflt; } /** Create a JAXB transfer object from an OcDublinCore. */ public static JaxbOcDublinCore toJaxb(final OcDublinCore source) { // completeness assured by unit test final JaxbOcDublinCore target = new JaxbOcDublinCore(); target.abstrakt = source.getAbstract().getOrElseNull(); target.accessRights = source.getAccessRights().getOrElseNull(); target.accrualMethod = source.getAccrualMethod().getOrElseNull(); target.accrualPeriodicity = source.getAccrualPeriodicity().getOrElseNull(); target.accrualPolicy = source.getAccrualPolicy().getOrElseNull(); target.alternative = source.getAlternative().getOrElseNull(); target.audience = source.getAudience().getOrElseNull(); target.available = source.getAvailable().getOrElseNull(); target.bibliographicCitation = source.getBibliographicCitation().getOrElseNull(); target.conformsTo = source.getConformsTo().getOrElseNull(); target.contributor = source.getContributor().getOrElseNull(); target.coverage = source.getCoverage().getOrElseNull(); target.created = source.getCreated(); target.creator = source.getCreator().getOrElseNull(); target.date = source.getDate().getOrElseNull(); target.dateAccepted = source.getDateAccepted().getOrElseNull(); target.dateCopyrighted = source.getDateCopyrighted().getOrElseNull(); target.dateSubmitted = source.getDateSubmitted().getOrElseNull(); target.description = source.getDescription().getOrElseNull(); target.educationLevel = source.getEducationLevel().getOrElseNull(); target.extent = source.getExtent().getOrElseNull(); target.format = source.getFormat().getOrElseNull(); target.hasFormat = source.getHasFormat().getOrElseNull(); target.hasPart = source.getHasPart().getOrElseNull(); target.hasVersion = source.getHasVersion().getOrElseNull(); target.identifier = source.getIdentifier().getOrElseNull(); target.instructionalMethod = source.getInstructionalMethod().getOrElseNull(); target.isFormatOf = source.getIsFormatOf().getOrElseNull(); target.isPartOf = source.getIsPartOf().getOrElseNull(); target.isReferencedBy = source.getIsReferencedBy().getOrElseNull(); target.isReplacedBy = source.getIsReplacedBy().getOrElseNull(); target.isRequiredBy = source.getIsRequiredBy().getOrElseNull(); target.issued = source.getIssued().getOrElseNull(); target.isVersionOf = source.getIsVersionOf().getOrElseNull(); target.language = source.getLanguage().getOrElseNull(); target.license = source.getLicense().getOrElseNull(); target.mediator = source.getMediator().getOrElseNull(); target.medium = source.getMedium().getOrElseNull(); target.modified = source.getModified().getOrElseNull(); target.provenance = source.getProvenance().getOrElseNull(); target.publisher = source.getPublisher().getOrElseNull(); target.references = source.getReferences().getOrElseNull(); target.relation = source.getRelation().getOrElseNull(); target.replaces = source.getReplaces().getOrElseNull(); target.requires = source.getRequires().getOrElseNull(); target.rights = source.getRights().getOrElseNull(); target.rightsHolder = source.getRightsHolder().getOrElseNull(); target.source = source.getSource().getOrElseNull(); target.spatial = source.getSpatial().getOrElseNull(); target.subject = source.getSubject().getOrElseNull(); target.tableOfContents = source.getTableOfContents().getOrElseNull(); target.temporal = source.getTemporal().getOrElseNull(); target.title = source.getTitle(); target.type = source.getType().getOrElseNull(); target.valid = source.getValid().getOrElseNull(); return target; } }