Il seguente frammento di schema specifica il contenuto previsto contenuto in questa classe.
+ *
+ *
> nameOrNamespace;
+
+ /**
+ * Gets the value of the nameOrNamespace property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the nameOrNamespace property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getNameOrNamespace().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link JAXBElement }{@code <}{@link String }{@code >}
+ * {@link JAXBElement }{@code <}{@link String }{@code >}
+ */
+ public List> getNameOrNamespace() {
+ if (nameOrNamespace == null) {
+ nameOrNamespace = new ArrayList>();
+ }
+ return this.nameOrNamespace;
+ }
+
+}
diff --git a/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DcSchemaBuilder.java b/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DcSchemaBuilder.java
new file mode 100644
index 000000000000..fe7144bda854
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DcSchemaBuilder.java
@@ -0,0 +1,39 @@
+/**
+ * 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.app.metadata.export.model;
+
+import javax.xml.bind.JAXBElement;
+
+/**
+ * @author Vincenzo Mecca (vins01-4science - vincenzo.mecca at 4science.com)
+ **/
+public class DcSchemaBuilder extends AbstractJaxbBuilder {
+
+ protected DcSchemaBuilder() {
+ super(DcSchema.class);
+ }
+
+ public static DcSchemaBuilder createBuilder() {
+ return new DcSchemaBuilder();
+ }
+
+ public DcSchemaBuilder withName(String name) {
+ this.addChildElement(name, objectFactory::createName);
+ return this;
+ }
+
+ public DcSchemaBuilder withNamespace(String namespace) {
+ this.addChildElement(namespace, objectFactory::createNamespace);
+ return this;
+ }
+
+ @Override
+ protected void addChildElement(JAXBElement v) {
+ getObejct().getNameOrNamespace().add(v);
+ }
+}
diff --git a/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DcType.java b/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DcType.java
new file mode 100644
index 000000000000..bff2fc77978a
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DcType.java
@@ -0,0 +1,86 @@
+/**
+ * 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.app.metadata.export.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlElementRefs;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * Classe Java per anonymous complex type.
+ *
+ *
Il seguente frammento di schema specifica il contenuto previsto contenuto in questa classe.
+ *
+ *
+ * <complexType>
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <choice maxOccurs="unbounded" minOccurs="0">
+ * <element ref="{}schema"/>
+ * <element ref="{}element"/>
+ * <element ref="{}qualifier"/>
+ * <element ref="{}scope_note"/>
+ * </choice>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {
+ "schemaOrElementOrQualifier"
+})
+@XmlRootElement(name = "dc-type")
+public class DcType {
+
+ @XmlElementRefs({
+ @XmlElementRef(name = "schema", type = JAXBElement.class, required = false),
+ @XmlElementRef(name = "element", type = JAXBElement.class, required = false),
+ @XmlElementRef(name = "qualifier", type = JAXBElement.class, required = false),
+ @XmlElementRef(name = "scope_note", type = JAXBElement.class, required = false)
+ })
+ protected List> schemaOrElementOrQualifier;
+
+ /**
+ * Gets the value of the schemaOrElementOrQualifier property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the schemaOrElementOrQualifier property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getSchemaOrElementOrQualifier().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link JAXBElement }{@code <}{@link String }{@code >}
+ * {@link JAXBElement }{@code <}{@link String }{@code >}
+ * {@link JAXBElement }{@code <}{@link String }{@code >}
+ * {@link JAXBElement }{@code <}{@link String }{@code >}
+ */
+ public List> getSchemaOrElementOrQualifier() {
+ if (schemaOrElementOrQualifier == null) {
+ schemaOrElementOrQualifier = new ArrayList>();
+ }
+ return this.schemaOrElementOrQualifier;
+ }
+
+}
diff --git a/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DcTypeBuilder.java b/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DcTypeBuilder.java
new file mode 100644
index 000000000000..47fd64763ead
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DcTypeBuilder.java
@@ -0,0 +1,49 @@
+/**
+ * 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.app.metadata.export.model;
+
+import javax.xml.bind.JAXBElement;
+
+/**
+ * @author Vincenzo Mecca (vins01-4science - vincenzo.mecca at 4science.com)
+ **/
+public class DcTypeBuilder extends AbstractJaxbBuilder {
+
+ protected DcTypeBuilder() {
+ super(DcType.class);
+ }
+
+ public static DcTypeBuilder createBuilder() {
+ return new DcTypeBuilder();
+ }
+
+ public DcTypeBuilder withSchema(String schema) {
+ addChildElement(schema, objectFactory::createSchema);
+ return this;
+ }
+
+ public DcTypeBuilder withElement(String element) {
+ addChildElement(element, objectFactory::createElement);
+ return this;
+ }
+
+ public DcTypeBuilder withQualifier(String qualifier) {
+ addChildElement(qualifier, objectFactory::createQualifier);
+ return this;
+ }
+
+ public DcTypeBuilder withScopeNote(String scopeNote) {
+ addChildElement(scopeNote, objectFactory::createScopeNote);
+ return this;
+ }
+
+ @Override
+ protected void addChildElement(JAXBElement v) {
+ getObejct().getSchemaOrElementOrQualifier().add(v);
+ }
+}
diff --git a/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DspaceDcTypes.java b/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DspaceDcTypes.java
new file mode 100644
index 000000000000..4cba081a8a30
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DspaceDcTypes.java
@@ -0,0 +1,82 @@
+/**
+ * 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.app.metadata.export.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElements;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * Classe Java per anonymous complex type.
+ *
+ *
Il seguente frammento di schema specifica il contenuto previsto contenuto in questa classe.
+ *
+ *
+ * <complexType>
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <choice maxOccurs="unbounded" minOccurs="0">
+ * <element ref="{}dspace-header"/>
+ * <element ref="{}dc-schema"/>
+ * <element ref="{}dc-type"/>
+ * </choice>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {
+ "dspaceHeaderOrDcSchemaOrDcType"
+})
+@XmlRootElement(name = "dspace-dc-types")
+public class DspaceDcTypes {
+
+ @XmlElements({
+ @XmlElement(name = "dspace-header", type = DspaceHeader.class),
+ @XmlElement(name = "dc-schema", type = DcSchema.class),
+ @XmlElement(name = "dc-type", type = DcType.class)
+ })
+ protected List dspaceHeaderOrDcSchemaOrDcType;
+
+ /**
+ * Gets the value of the dspaceHeaderOrDcSchemaOrDcType property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the dspaceHeaderOrDcSchemaOrDcType property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getDspaceHeaderOrDcSchemaOrDcType().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link DspaceHeader }
+ * {@link DcSchema }
+ * {@link DcType }
+ */
+ public List getDspaceHeaderOrDcSchemaOrDcType() {
+ if (dspaceHeaderOrDcSchemaOrDcType == null) {
+ dspaceHeaderOrDcSchemaOrDcType = new ArrayList();
+ }
+ return this.dspaceHeaderOrDcSchemaOrDcType;
+ }
+
+}
diff --git a/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DspaceDcTypesBuilder.java b/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DspaceDcTypesBuilder.java
new file mode 100644
index 000000000000..1e4cdb83393c
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DspaceDcTypesBuilder.java
@@ -0,0 +1,59 @@
+/**
+ * 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.app.metadata.export.model;
+
+import java.util.Collection;
+
+/**
+ * @author Vincenzo Mecca (vins01-4science - vincenzo.mecca at 4science.com)
+ **/
+public class DspaceDcTypesBuilder {
+
+ private DspaceDcTypes dcTypes;
+
+ private final ObjectFactory objectFactory = new ObjectFactory();
+
+ private DspaceDcTypes getDcTypes() {
+ if (dcTypes == null) {
+ dcTypes = new DspaceDcTypes();
+ }
+ return dcTypes;
+ }
+
+ private DspaceDcTypesBuilder() {
+ }
+
+ public static DspaceDcTypesBuilder createBuilder() {
+ return new DspaceDcTypesBuilder();
+ }
+
+ public DspaceDcTypesBuilder witheader(DspaceHeader header) {
+ this.getDcTypes().getDspaceHeaderOrDcSchemaOrDcType().add(header);
+ return this;
+ }
+
+ public DspaceDcTypesBuilder withSchema(DcSchema schema) {
+ this.getDcTypes().getDspaceHeaderOrDcSchemaOrDcType().add(schema);
+ return this;
+ }
+
+ public DspaceDcTypesBuilder withDcType(DcType dcType) {
+ this.getDcTypes().getDspaceHeaderOrDcSchemaOrDcType().add(dcType);
+ return this;
+ }
+
+ public DspaceDcTypesBuilder withDcTypes(Collection dcTypes) {
+ this.getDcTypes().getDspaceHeaderOrDcSchemaOrDcType().addAll(dcTypes);
+ return this;
+ }
+
+ public DspaceDcTypes build() {
+ return dcTypes;
+ }
+
+}
diff --git a/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DspaceHeader.java b/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DspaceHeader.java
new file mode 100644
index 000000000000..151c8b28292d
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DspaceHeader.java
@@ -0,0 +1,92 @@
+/**
+ * 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.app.metadata.export.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlElementRefs;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * Classe Java per anonymous complex type.
+ *
+ *
Il seguente frammento di schema specifica il contenuto previsto contenuto in questa classe.
+ *
+ *
+ * <complexType>
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <choice maxOccurs="unbounded" minOccurs="0">
+ * <element ref="{}title"/>
+ * <element ref="{}contributor.author"/>
+ * <element ref="{}contributor.editor"/>
+ * <element ref="{}date.created"/>
+ * <element ref="{}description"/>
+ * <element ref="{}description.version"/>
+ * </choice>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {
+ "titleOrContributorAuthorOrContributorEditor"
+})
+@XmlRootElement(name = "dspace-header")
+public class DspaceHeader {
+
+ @XmlElementRefs({
+ @XmlElementRef(name = "title", type = JAXBElement.class, required = false),
+ @XmlElementRef(name = "contributor.author", type = JAXBElement.class, required = false),
+ @XmlElementRef(name = "contributor.editor", type = JAXBElement.class, required = false),
+ @XmlElementRef(name = "date.created", type = JAXBElement.class, required = false),
+ @XmlElementRef(name = "description", type = JAXBElement.class, required = false),
+ @XmlElementRef(name = "description.version", type = JAXBElement.class, required = false)
+ })
+ protected List> titleOrContributorAuthorOrContributorEditor;
+
+ /**
+ * Gets the value of the titleOrContributorAuthorOrContributorEditor property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set
method for the titleOrContributorAuthorOrContributorEditor property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getTitleOrContributorAuthorOrContributorEditor().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link JAXBElement }{@code <}{@link String }{@code >}
+ * {@link JAXBElement }{@code <}{@link String }{@code >}
+ * {@link JAXBElement }{@code <}{@link String }{@code >}
+ * {@link JAXBElement }{@code <}{@link String }{@code >}
+ * {@link JAXBElement }{@code <}{@link String }{@code >}
+ * {@link JAXBElement }{@code <}{@link String }{@code >}
+ */
+ public List> getTitleOrContributorAuthorOrContributorEditor() {
+ if (titleOrContributorAuthorOrContributorEditor == null) {
+ titleOrContributorAuthorOrContributorEditor = new ArrayList>();
+ }
+ return this.titleOrContributorAuthorOrContributorEditor;
+ }
+
+}
diff --git a/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DspaceHeaderBuilder.java b/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DspaceHeaderBuilder.java
new file mode 100644
index 000000000000..fb4028a2057b
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/app/metadata/export/model/DspaceHeaderBuilder.java
@@ -0,0 +1,59 @@
+/**
+ * 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.app.metadata.export.model;
+
+import javax.xml.bind.JAXBElement;
+
+/**
+ * @author Vincenzo Mecca (vins01-4science - vincenzo.mecca at 4science.com)
+ **/
+public class DspaceHeaderBuilder extends AbstractJaxbBuilder {
+
+ protected DspaceHeaderBuilder() {
+ super(DspaceHeader.class);
+ }
+
+ public static DspaceHeaderBuilder createBuilder() {
+ return new DspaceHeaderBuilder();
+ }
+
+ public DspaceHeaderBuilder withTitle(String title) {
+ addChildElement(title, objectFactory::createTitle);
+ return this;
+ }
+
+ public DspaceHeaderBuilder withContributorAuthor(String contributorAuthor) {
+ addChildElement(contributorAuthor, objectFactory::createContributorAuthor);
+ return this;
+ }
+
+ public DspaceHeaderBuilder withContributorEditor(String contributorEditor) {
+ addChildElement(contributorEditor, objectFactory::createContributorEditor);
+ return this;
+ }
+
+ public DspaceHeaderBuilder withDateCreated(String dateCreated) {
+ addChildElement(dateCreated, objectFactory::createDateCreated);
+ return this;
+ }
+
+ public DspaceHeaderBuilder withDescription(String description) {
+ addChildElement(description, objectFactory::createDescription);
+ return this;
+ }
+
+ public DspaceHeaderBuilder withDescriptionVersion(String descriptionVersion) {
+ addChildElement(descriptionVersion, objectFactory::createDescriptionVersion);
+ return this;
+ }
+
+ @Override
+ protected void addChildElement(JAXBElement v) {
+ getObejct().getTitleOrContributorAuthorOrContributorEditor().add(v);
+ }
+}
diff --git a/dspace-api/src/main/java/org/dspace/app/metadata/export/model/ObjectFactory.java b/dspace-api/src/main/java/org/dspace/app/metadata/export/model/ObjectFactory.java
new file mode 100644
index 000000000000..085e8af5f81b
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/app/metadata/export/model/ObjectFactory.java
@@ -0,0 +1,212 @@
+/**
+ * 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.app.metadata.export.model;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.annotation.XmlElementDecl;
+import javax.xml.bind.annotation.XmlRegistry;
+import javax.xml.namespace.QName;
+
+
+/**
+ * This object contains factory methods for each
+ * Java content interface and Java element interface
+ * generated in the org.dspace.app.metadata.export.model package.
+ * An ObjectFactory allows you to programatically
+ * construct new instances of the Java representation
+ * for XML content. The Java representation of XML
+ * content can consist of schema derived interfaces
+ * and classes representing the binding of schema
+ * type definitions, element declarations and model
+ * groups. Factory methods for each of these are
+ * provided in this class.
+ */
+@XmlRegistry
+public class ObjectFactory {
+
+ private final static QName _Title_QNAME = new QName("", "title");
+ private final static QName _ContributorAuthor_QNAME = new QName("", "contributor.author");
+ private final static QName _ContributorEditor_QNAME = new QName("", "contributor.editor");
+ private final static QName _DateCreated_QNAME = new QName("", "date.created");
+ private final static QName _Description_QNAME = new QName("", "description");
+ private final static QName _DescriptionVersion_QNAME = new QName("", "description.version");
+ private final static QName _Name_QNAME = new QName("", "name");
+ private final static QName _Namespace_QNAME = new QName("", "namespace");
+ private final static QName _Schema_QNAME = new QName("", "schema");
+ private final static QName _Element_QNAME = new QName("", "element");
+ private final static QName _Qualifier_QNAME = new QName("", "qualifier");
+ private final static QName _ScopeNote_QNAME = new QName("", "scope_note");
+
+ /**
+ * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org
+ * .dspace.app.metadata.export.model
+ */
+ public ObjectFactory() {
+ }
+
+ /**
+ * Create an instance of {@link DspaceDcTypes }
+ */
+ public DspaceDcTypes createDspaceDcTypes() {
+ return new DspaceDcTypes();
+ }
+
+ /**
+ * Create an instance of {@link DspaceHeader }
+ */
+ public DspaceHeader createDspaceHeader() {
+ return new DspaceHeader();
+ }
+
+ /**
+ * Create an instance of {@link DcSchema }
+ */
+ public DcSchema createDcSchema() {
+ return new DcSchema();
+ }
+
+ /**
+ * Create an instance of {@link DcType }
+ */
+ public DcType createDcType() {
+ return new DcType();
+ }
+
+ /**
+ * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ *
+ * @param value Java instance representing xml element's value.
+ * @return the new instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ */
+ @XmlElementDecl(namespace = "", name = "title")
+ public JAXBElement createTitle(String value) {
+ return new JAXBElement(_Title_QNAME, String.class, null, value);
+ }
+
+ /**
+ * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ *
+ * @param value Java instance representing xml element's value.
+ * @return the new instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ */
+ @XmlElementDecl(namespace = "", name = "contributor.author")
+ public JAXBElement createContributorAuthor(String value) {
+ return new JAXBElement(_ContributorAuthor_QNAME, String.class, null, value);
+ }
+
+ /**
+ * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ *
+ * @param value Java instance representing xml element's value.
+ * @return the new instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ */
+ @XmlElementDecl(namespace = "", name = "contributor.editor")
+ public JAXBElement createContributorEditor(String value) {
+ return new JAXBElement(_ContributorEditor_QNAME, String.class, null, value);
+ }
+
+ /**
+ * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ *
+ * @param value Java instance representing xml element's value.
+ * @return the new instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ */
+ @XmlElementDecl(namespace = "", name = "date.created")
+ public JAXBElement createDateCreated(String value) {
+ return new JAXBElement(_DateCreated_QNAME, String.class, null, value);
+ }
+
+ /**
+ * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ *
+ * @param value Java instance representing xml element's value.
+ * @return the new instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ */
+ @XmlElementDecl(namespace = "", name = "description")
+ public JAXBElement createDescription(String value) {
+ return new JAXBElement(_Description_QNAME, String.class, null, value);
+ }
+
+ /**
+ * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ *
+ * @param value Java instance representing xml element's value.
+ * @return the new instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ */
+ @XmlElementDecl(namespace = "", name = "description.version")
+ public JAXBElement createDescriptionVersion(String value) {
+ return new JAXBElement(_DescriptionVersion_QNAME, String.class, null, value);
+ }
+
+ /**
+ * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ *
+ * @param value Java instance representing xml element's value.
+ * @return the new instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ */
+ @XmlElementDecl(namespace = "", name = "name")
+ public JAXBElement createName(String value) {
+ return new JAXBElement(_Name_QNAME, String.class, null, value);
+ }
+
+ /**
+ * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ *
+ * @param value Java instance representing xml element's value.
+ * @return the new instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ */
+ @XmlElementDecl(namespace = "", name = "namespace")
+ public JAXBElement createNamespace(String value) {
+ return new JAXBElement(_Namespace_QNAME, String.class, null, value);
+ }
+
+ /**
+ * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ *
+ * @param value Java instance representing xml element's value.
+ * @return the new instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ */
+ @XmlElementDecl(namespace = "", name = "schema")
+ public JAXBElement createSchema(String value) {
+ return new JAXBElement(_Schema_QNAME, String.class, null, value);
+ }
+
+ /**
+ * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ *
+ * @param value Java instance representing xml element's value.
+ * @return the new instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ */
+ @XmlElementDecl(namespace = "", name = "element")
+ public JAXBElement createElement(String value) {
+ return new JAXBElement(_Element_QNAME, String.class, null, value);
+ }
+
+ /**
+ * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ *
+ * @param value Java instance representing xml element's value.
+ * @return the new instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ */
+ @XmlElementDecl(namespace = "", name = "qualifier")
+ public JAXBElement createQualifier(String value) {
+ return new JAXBElement(_Qualifier_QNAME, String.class, null, value);
+ }
+
+ /**
+ * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ *
+ * @param value Java instance representing xml element's value.
+ * @return the new instance of {@link JAXBElement }{@code <}{@link String }{@code >}
+ */
+ @XmlElementDecl(namespace = "", name = "scope_note")
+ public JAXBElement createScopeNote(String value) {
+ return new JAXBElement(_ScopeNote_QNAME, String.class, null, value);
+ }
+
+}
diff --git a/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataExportServiceFactory.java b/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataExportServiceFactory.java
new file mode 100644
index 000000000000..3553cbcba2fd
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataExportServiceFactory.java
@@ -0,0 +1,28 @@
+/**
+ * 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.app.metadata.export.service;
+
+import org.dspace.services.factory.DSpaceServicesFactory;
+
+/**
+ * Factory for the export services related to metadata-schema and metadata-fields.
+ *
+ * @author Vincenzo Mecca (vins01-4science - vincenzo.mecca at 4science.com)
+ **/
+public abstract class MetadataExportServiceFactory {
+
+ public static MetadataExportServiceFactory getInstance() {
+ return DSpaceServicesFactory
+ .getInstance().getServiceManager()
+ .getServiceByName("metadataExportServiceFactory", MetadataExportServiceFactory.class);
+ }
+
+ public abstract MetadataSchemaExportService getMetadataSchemaExportService();
+ public abstract MetadataFieldExportService getMetadataFieldExportService();
+
+}
diff --git a/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataExportServiceFactoryImpl.java b/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataExportServiceFactoryImpl.java
new file mode 100644
index 000000000000..a69d5dfd0fde
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataExportServiceFactoryImpl.java
@@ -0,0 +1,31 @@
+/**
+ * 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.app.metadata.export.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author Vincenzo Mecca (vins01-4science - vincenzo.mecca at 4science.com)
+ **/
+public class MetadataExportServiceFactoryImpl extends MetadataExportServiceFactory {
+
+ @Autowired
+ private MetadataSchemaExportService metadataSchemaExportService;
+ @Autowired
+ private MetadataFieldExportService metadataFieldExportService;
+
+ @Override
+ public MetadataSchemaExportService getMetadataSchemaExportService() {
+ return metadataSchemaExportService;
+ }
+
+ @Override
+ public MetadataFieldExportService getMetadataFieldExportService() {
+ return metadataFieldExportService;
+ }
+}
diff --git a/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataFieldExportService.java b/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataFieldExportService.java
new file mode 100644
index 000000000000..ace312885230
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataFieldExportService.java
@@ -0,0 +1,35 @@
+/**
+ * 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.app.metadata.export.service;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import org.dspace.app.metadata.export.model.DcType;
+import org.dspace.content.MetadataField;
+import org.dspace.content.MetadataSchema;
+import org.dspace.core.Context;
+
+/**
+ * Exports {@code MetadataField} into {@code DcType}
+ *
+ * @author Vincenzo Mecca (vins01-4science - vincenzo.mecca at 4science.com)
+ **/
+public interface MetadataFieldExportService {
+
+ /**
+ * Creates a one {@link DCType} for each {@link MetadataField}
+ * in the given {@link MetadataSchema}, and returns them in a list
+ *
+ * @param context
+ * @param metadataSchema
+ * @return
+ * @throws SQLException
+ */
+ List exportMetadataFieldsBy(Context context, MetadataSchema metadataSchema) throws SQLException;
+}
diff --git a/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataFieldExportServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataFieldExportServiceImpl.java
new file mode 100644
index 000000000000..1ace35f4e45d
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataFieldExportServiceImpl.java
@@ -0,0 +1,49 @@
+/**
+ * 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.app.metadata.export.service;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.dspace.app.metadata.export.model.DcType;
+import org.dspace.app.metadata.export.model.DcTypeBuilder;
+import org.dspace.content.MetadataField;
+import org.dspace.content.MetadataSchema;
+import org.dspace.content.factory.ContentServiceFactory;
+import org.dspace.content.service.MetadataFieldService;
+import org.dspace.core.Context;
+
+/**
+ * @author Vincenzo Mecca (vins01-4science - vincenzo.mecca at 4science.com)
+ **/
+public class MetadataFieldExportServiceImpl implements MetadataFieldExportService {
+
+ private MetadataFieldService metadataFieldService =
+ ContentServiceFactory.getInstance().getMetadataFieldService();
+
+ public List exportMetadataFieldsBy(Context context, MetadataSchema metadataSchema) throws SQLException {
+ return metadataFieldService
+ .findAllInSchema(context, metadataSchema)
+ .stream()
+ .map(this::toDcType)
+ .collect(Collectors.toList());
+ }
+
+ private DcType toDcType(MetadataField metadataField) {
+ return DcTypeBuilder
+ .createBuilder()
+ .withSchema(metadataField.getMetadataSchema().getName())
+ .withElement(metadataField.getElement())
+ .withQualifier(metadataField.getQualifier())
+ .withScopeNote(metadataField.getScopeNote())
+ .build();
+ }
+
+}
+
diff --git a/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataSchemaExportService.java b/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataSchemaExportService.java
new file mode 100644
index 000000000000..cd1f35e2ef9b
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataSchemaExportService.java
@@ -0,0 +1,68 @@
+/**
+ * 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.app.metadata.export.service;
+
+import java.io.File;
+import java.sql.SQLException;
+
+import org.dspace.app.metadata.export.DspaceExportMetadataSchemaException;
+import org.dspace.app.metadata.export.model.DspaceDcTypes;
+import org.dspace.content.MetadataSchema;
+import org.dspace.core.Context;
+
+/**
+ * @author Vincenzo Mecca (vins01-4science - vincenzo.mecca at 4science.com)
+ **/
+public interface MetadataSchemaExportService {
+
+ /**
+ * Exports the given {@code schemaId} into a {@link DspaceDcTypes} entity
+ *
+ * @param context
+ * @param schemaId
+ * @return
+ * @throws SQLException
+ */
+ DspaceDcTypes exportMetadataSchema(Context context, int schemaId) throws SQLException;
+
+ /**
+ * Exports the given {@code metadataSchema} into a {@link DspaceDcTypes} entity
+ *
+ * @param context
+ * @param metadataSchema
+ * @return
+ * @throws SQLException
+ */
+ DspaceDcTypes exportMetadataSchema(Context context, MetadataSchema metadataSchema) throws SQLException;
+
+ /**
+ * Exports the given {@code metadataSchema} to a temporary {@code File},
+ * that will respect the {@code registry} xml format of dspace
+ *
+ * @param context
+ * @param metadataSchema
+ * @return
+ * @throws DspaceExportMetadataSchemaException
+ */
+ File exportMetadataSchemaToFile(Context context, MetadataSchema metadataSchema)
+ throws DspaceExportMetadataSchemaException;
+
+ /**
+ * Exports the given {@code metadataSchema} to a target {@code File},
+ * that will respect the {@code registry} xml format of dspace
+ *
+ * @param context
+ * @param metadataSchema
+ * @param file
+ * @return
+ * @throws DspaceExportMetadataSchemaException
+ */
+ File exportMetadataSchemaToFile(Context context, MetadataSchema metadataSchema, File file)
+ throws DspaceExportMetadataSchemaException;
+
+}
diff --git a/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataSchemaExportServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataSchemaExportServiceImpl.java
new file mode 100644
index 000000000000..eea9a09f7970
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/app/metadata/export/service/MetadataSchemaExportServiceImpl.java
@@ -0,0 +1,107 @@
+/**
+ * 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.app.metadata.export.service;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.SQLException;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+
+import org.dspace.app.metadata.export.DspaceExportMetadataSchemaException;
+import org.dspace.app.metadata.export.model.DcSchema;
+import org.dspace.app.metadata.export.model.DcSchemaBuilder;
+import org.dspace.app.metadata.export.model.DspaceDcTypes;
+import org.dspace.app.metadata.export.model.DspaceDcTypesBuilder;
+import org.dspace.content.MetadataSchema;
+import org.dspace.content.factory.ContentServiceFactory;
+import org.dspace.content.service.MetadataSchemaService;
+import org.dspace.core.Context;
+
+/**
+ * This service can be used to export a target schema into a registry-file
+ *
+ * @author Vincenzo Mecca (vins01-4science - vincenzo.mecca at 4science.com)
+ **/
+public class MetadataSchemaExportServiceImpl implements MetadataSchemaExportService {
+
+ private MetadataSchemaService metadataSchemaService =
+ ContentServiceFactory.getInstance().getMetadataSchemaService();
+
+ @Override
+ public DspaceDcTypes exportMetadataSchema(Context context, int schemaId) throws SQLException {
+ return this.exportMetadataSchema(context, metadataSchemaService.find(context, schemaId));
+ }
+
+ @Override
+ public DspaceDcTypes exportMetadataSchema(Context context, MetadataSchema metadataSchema) throws SQLException {
+ return DspaceDcTypesBuilder
+ .createBuilder()
+ .withSchema(this.mapToDcSchema(metadataSchema))
+ .withDcTypes(
+ MetadataExportServiceFactory.getInstance()
+ .getMetadataFieldExportService()
+ .exportMetadataFieldsBy(context, metadataSchema)
+ )
+ .build();
+ }
+
+ @Override
+ public File exportMetadataSchemaToFile(Context context, MetadataSchema metadataSchema)
+ throws DspaceExportMetadataSchemaException {
+ File tempFile;
+ try {
+ tempFile =
+ File.createTempFile(
+ metadataSchema.getName() + "-" + metadataSchema.getID(),
+ ".xml"
+ );
+ tempFile.deleteOnExit();
+ return this.exportMetadataSchemaToFile(context, metadataSchema, tempFile);
+ } catch (IOException e) {
+ throw new DspaceExportMetadataSchemaException(
+ "Probelm occured during while exporting to temporary file!",
+ e
+ );
+ }
+ }
+
+ @Override
+ public File exportMetadataSchemaToFile(Context context, MetadataSchema metadataSchema, File file)
+ throws DspaceExportMetadataSchemaException {
+ try {
+ DspaceDcTypes dspaceDcTypes = this.exportMetadataSchema(context, metadataSchema);
+
+ JAXBContext jaxb = JAXBContext.newInstance(DspaceDcTypes.class);
+ Marshaller jaxbMarshaller = jaxb.createMarshaller();
+ jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+ jaxbMarshaller.marshal(dspaceDcTypes, file);
+ } catch (SQLException e) {
+ throw new DspaceExportMetadataSchemaException(
+ "Problem occured while retrieving data from DB!",
+ e
+ );
+ } catch (JAXBException e) {
+ throw new DspaceExportMetadataSchemaException(
+ "Problem occured during the export to XML file!",
+ e
+ );
+ }
+ return file;
+ }
+
+ private DcSchema mapToDcSchema(MetadataSchema metadataSchema) {
+ return DcSchemaBuilder
+ .createBuilder()
+ .withName(metadataSchema.getName())
+ .withNamespace(metadataSchema.getNamespace())
+ .build();
+ }
+
+}
diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java
index 4df11b054e67..e07fb16c72ca 100644
--- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java
+++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java
@@ -8,14 +8,17 @@
package org.dspace.app.nbevent.service.impl;
import java.io.IOException;
+import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
+import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
+import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.solr.client.solrj.SolrClient;
@@ -33,6 +36,7 @@
import org.dspace.app.nbevent.NBTopic;
import org.dspace.app.nbevent.dao.impl.NBEventsDaoImpl;
import org.dspace.app.nbevent.service.NBEventService;
+import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Item;
import org.dspace.content.NBEvent;
import org.dspace.content.service.ItemService;
@@ -316,18 +320,38 @@ private String getResourceUUID(Context context, String originalId) throws Except
String id = getHandleFromOriginalId(originalId);
if (id != null) {
Item item = (Item) handleService.resolveToObject(context, id);
+
if (item != null) {
final String itemUuid = item.getID().toString();
context.uncacheEntity(item);
return itemUuid;
} else {
- return null;
+ item = fromLegacyIdentifier(context, originalId);
+ return item == null ? null : item.getID().toString();
}
} else {
throw new RuntimeException("Malformed originalId " + originalId);
}
}
+ private Item fromLegacyIdentifier(Context context, String legacyIdentifier) {
+ if (StringUtils.isBlank(legacyIdentifier)) {
+ return null;
+ }
+ try {
+ Iterator-
+ iterator = itemService.findUnfilteredByMetadataField(
+ context, "dspace", "legacy", "oai-identifier",
+ legacyIdentifier);
+ if (!iterator.hasNext()) {
+ return null;
+ }
+ return iterator.next();
+ } catch (AuthorizeException | SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
// oai:www.openstarts.units.it:10077/21486
private String getHandleFromOriginalId(String originalId) {
Integer startPosition = originalId.lastIndexOf(':');
diff --git a/dspace-api/src/main/java/org/dspace/app/util/SubmissionStepConfig.java b/dspace-api/src/main/java/org/dspace/app/util/SubmissionStepConfig.java
index 7f29e6d79e52..03d5dc6b7657 100644
--- a/dspace-api/src/main/java/org/dspace/app/util/SubmissionStepConfig.java
+++ b/dspace-api/src/main/java/org/dspace/app/util/SubmissionStepConfig.java
@@ -11,6 +11,9 @@
import java.util.Map;
import org.apache.commons.lang3.BooleanUtils;
+import org.dspace.content.InProgressSubmission;
+import org.dspace.content.WorkspaceItem;
+import org.hibernate.proxy.HibernateProxyHelper;
/**
* Class representing configuration for a single step within an Item Submission
@@ -179,6 +182,45 @@ public String getVisibilityOutside() {
return visibilityOutside;
}
+ public boolean isHiddenForInProgressSubmission(InProgressSubmission> obj) {
+
+ String scopeToCheck = getScope(obj);
+
+ if (scope == null || scopeToCheck == null) {
+ return false;
+ }
+
+ String visibility = getVisibility();
+ String visibilityOutside = getVisibilityOutside();
+
+ if (scope.equalsIgnoreCase(scopeToCheck)) {
+ return "hidden".equalsIgnoreCase(visibility);
+ } else {
+ return visibilityOutside == null || "hidden".equalsIgnoreCase(visibilityOutside);
+ }
+
+ }
+
+ public boolean isReadOnlyForInProgressSubmission(InProgressSubmission> obj) {
+
+ String scopeToCheck = getScope(obj);
+
+ if (scope == null || scopeToCheck == null) {
+ return false;
+ }
+
+ String visibility = scope.equalsIgnoreCase(scopeToCheck) ? getVisibility() : getVisibilityOutside();
+ return "read-only".equalsIgnoreCase(visibility);
+
+ }
+
+ private String getScope(InProgressSubmission> obj) {
+ if (HibernateProxyHelper.getClassWithoutInitializingProxy(obj).equals(WorkspaceItem.class)) {
+ return "submission";
+ }
+ return "workflow";
+ }
+
/**
* Get the number of this step in the current Submission process config.
* Step numbers start with #0 (although step #0 is ALWAYS the special
diff --git a/dspace-api/src/main/java/org/dspace/app/util/TypeBindUtils.java b/dspace-api/src/main/java/org/dspace/app/util/TypeBindUtils.java
new file mode 100644
index 000000000000..97104bbb63fe
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/app/util/TypeBindUtils.java
@@ -0,0 +1,73 @@
+/**
+ * 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.app.util;
+
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.dspace.content.InProgressSubmission;
+import org.dspace.content.MetadataValue;
+import org.dspace.content.authority.factory.ContentAuthorityServiceFactory;
+import org.dspace.content.authority.service.MetadataAuthorityService;
+import org.dspace.content.factory.ContentServiceFactory;
+import org.dspace.content.service.ItemService;
+import org.dspace.core.Constants;
+import org.dspace.services.ConfigurationService;
+import org.dspace.services.factory.DSpaceServicesFactory;
+
+/**
+ * Utility methods for the type bind functionality.
+ *
+ * @author Francesco Pio Scognamiglio (francescopio.scognamiglio at 4science.com)
+ *
+ */
+public class TypeBindUtils {
+
+ private static final ConfigurationService configurationService = DSpaceServicesFactory
+ .getInstance().getConfigurationService();
+ private static final ItemService itemService = ContentServiceFactory
+ .getInstance().getItemService();
+ private static final MetadataAuthorityService metadataAuthorityService = ContentAuthorityServiceFactory
+ .getInstance().getMetadataAuthorityService();
+
+ private TypeBindUtils() {}
+
+ /**
+ * This method gets the field used for type-bind.
+ * @return the field used for type-bind.
+ */
+ public static String getTypeBindField() {
+ return configurationService.getProperty("submit.type-bind.field", "dc.type");
+ }
+
+ /**
+ * This method gets the value of the type-bind field from the current item.
+ * @return the value of the type-bind field from the current item.
+ */
+ public static String getTypeBindValue(InProgressSubmission> obj) {
+ List
documentType = itemService.getMetadataByMetadataString(
+ obj.getItem(), getTypeBindField());
+
+ // check empty type-bind field
+ if (documentType == null || documentType.isEmpty()
+ || StringUtils.isBlank(documentType.get(0).getValue())) {
+ return null;
+ }
+
+ MetadataValue typeBindValue = documentType.get(0);
+
+ boolean isAuthorityAllowed = metadataAuthorityService.isAuthorityAllowed(
+ getTypeBindField().replace(".","_"), Constants.ITEM, obj.getCollection());
+ if (isAuthorityAllowed && typeBindValue.getAuthority() != null) {
+ return typeBindValue.getAuthority();
+ }
+
+ return typeBindValue.getValue();
+ }
+
+}
diff --git a/dspace-api/src/main/java/org/dspace/authenticate/OrcidAuthenticationBean.java b/dspace-api/src/main/java/org/dspace/authenticate/OrcidAuthenticationBean.java
index f77d7e57119a..88797e9b1a79 100644
--- a/dspace-api/src/main/java/org/dspace/authenticate/OrcidAuthenticationBean.java
+++ b/dspace-api/src/main/java/org/dspace/authenticate/OrcidAuthenticationBean.java
@@ -27,7 +27,10 @@
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
+import org.dspace.eperson.RegistrationData;
+import org.dspace.eperson.RegistrationTypeEnum;
import org.dspace.eperson.service.EPersonService;
+import org.dspace.eperson.service.RegistrationDataService;
import org.dspace.orcid.OrcidToken;
import org.dspace.orcid.client.OrcidClient;
import org.dspace.orcid.client.OrcidConfiguration;
@@ -47,11 +50,15 @@
* ORCID authentication for DSpace.
*
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
- *
*/
public class OrcidAuthenticationBean implements AuthenticationMethod {
+
+ public static final String ORCID_DEFAULT_FIRSTNAME = "Unnamed";
+ public static final String ORCID_DEFAULT_LASTNAME = ORCID_DEFAULT_FIRSTNAME;
public static final String ORCID_AUTH_ATTRIBUTE = "orcid-authentication";
+ public static final String ORCID_REGISTRATION_TOKEN = "orcid-registration-token";
+ public static final String ORCID_DEFAULT_REGISTRATION_URL = "/external-login/{0}";
private final static Logger LOGGER = LoggerFactory.getLogger(OrcidAuthenticationBean.class);
@@ -78,6 +85,9 @@ public class OrcidAuthenticationBean implements AuthenticationMethod {
@Autowired
private OrcidTokenService orcidTokenService;
+ @Autowired
+ private RegistrationDataService registrationDataService;
+
@Override
public int authenticate(Context context, String username, String password, String realm, HttpServletRequest request)
throws SQLException {
@@ -184,7 +194,7 @@ private int authenticateWithOrcid(Context context, String code, HttpServletReque
return ePerson.canLogIn() ? logInEPerson(context, token, ePerson) : BAD_ARGS;
}
- return canSelfRegister() ? registerNewEPerson(context, person, token) : NO_SUCH_USER;
+ return canSelfRegister() ? createRegistrationData(context, request, person, token) : NO_SUCH_USER;
}
@@ -212,48 +222,59 @@ private ResearcherProfile findProfile(Context context, EPerson ePerson) throws S
}
}
- private int registerNewEPerson(Context context, Person person, OrcidTokenResponseDTO token) throws SQLException {
+ private int createRegistrationData(
+ Context context, HttpServletRequest request, Person person, OrcidTokenResponseDTO token
+ ) throws SQLException {
try {
context.turnOffAuthorisationSystem();
- String email = getEmail(person)
- .orElseThrow(() -> new IllegalStateException("The email is configured private on orcid"));
-
- String orcid = token.getOrcid();
-
- EPerson eperson = ePersonService.create(context);
+ RegistrationData registrationData =
+ this.registrationDataService.create(context, token.getOrcid(), RegistrationTypeEnum.ORCID);
- eperson.setNetid(orcid);
+ registrationData.setEmail(getEmail(person).orElse(null));
+ setOrcidMetadataOnRegistration(context, registrationData, person, token);
- eperson.setEmail(email);
+ registrationDataService.update(context, registrationData);
- Optional firstName = getFirstName(person);
- if (firstName.isPresent()) {
- eperson.setFirstName(context, firstName.get());
- }
-
- Optional lastName = getLastName(person);
- if (lastName.isPresent()) {
- eperson.setLastName(context, lastName.get());
- }
- eperson.setCanLogIn(true);
- eperson.setSelfRegistered(true);
-
- setOrcidMetadataOnEPerson(context, eperson, token);
-
- ePersonService.update(context, eperson);
- context.setCurrentUser(eperson);
+ request.setAttribute(ORCID_REGISTRATION_TOKEN, registrationData.getToken());
+ context.commit();
context.dispatchEvents();
- return SUCCESS;
-
} catch (Exception ex) {
LOGGER.error("An error occurs registering a new EPerson from ORCID", ex);
context.rollback();
- return NO_SUCH_USER;
} finally {
context.restoreAuthSystemState();
+ return NO_SUCH_USER;
+ }
+ }
+
+ private void setOrcidMetadataOnRegistration(
+ Context context, RegistrationData registration, Person person, OrcidTokenResponseDTO token
+ ) throws SQLException, AuthorizeException {
+ String orcid = token.getOrcid();
+
+ setRegistrationMetadata(context, registration, "eperson.firstname", getFirstName(person));
+ setRegistrationMetadata(context, registration, "eperson.lastname", getLastName(person));
+ registrationDataService.setRegistrationMetadataValue(context, registration, "eperson", "orcid", null, orcid);
+
+ for (String scope : token.getScopeAsArray()) {
+ registrationDataService.addMetadata(context, registration, "eperson", "orcid", "scope", scope);
+ }
+ }
+
+ private void setRegistrationMetadata(
+ Context context, RegistrationData registration, String metadataString, String value) {
+ String[] split = metadataString.split("\\.");
+ String qualifier = split.length > 2 ? split[2] : null;
+ try {
+ registrationDataService.setRegistrationMetadataValue(
+ context, registration, split[0], split[1], qualifier, value
+ );
+ } catch (SQLException | AuthorizeException ex) {
+ LOGGER.error("An error occurs setting metadata", ex);
+ throw new RuntimeException(ex);
}
}
@@ -296,16 +317,20 @@ private Optional getEmail(Person person) {
return Optional.ofNullable(emails.get(0).getEmail());
}
- private Optional getFirstName(Person person) {
+ private String getFirstName(Person person) {
return Optional.ofNullable(person.getName())
- .map(name -> name.getGivenNames())
- .map(givenNames -> givenNames.getContent());
+ .map(name -> name.getGivenNames())
+ .map(givenNames -> givenNames.getContent())
+ .filter(StringUtils::isNotBlank)
+ .orElse(ORCID_DEFAULT_FIRSTNAME);
}
- private Optional getLastName(Person person) {
+ private String getLastName(Person person) {
return Optional.ofNullable(person.getName())
- .map(name -> name.getFamilyName())
- .map(givenNames -> givenNames.getContent());
+ .map(name -> name.getFamilyName())
+ .map(givenNames -> givenNames.getContent())
+ .filter(StringUtils::isNotBlank)
+ .orElse(ORCID_DEFAULT_LASTNAME);
}
private boolean canSelfRegister() {
diff --git a/dspace-api/src/main/java/org/dspace/content/BitstreamServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/BitstreamServiceImpl.java
index f2a8680ee58d..b07f23ee23ff 100644
--- a/dspace-api/src/main/java/org/dspace/content/BitstreamServiceImpl.java
+++ b/dspace-api/src/main/java/org/dspace/content/BitstreamServiceImpl.java
@@ -7,12 +7,15 @@
*/
package org.dspace.content;
+import static org.apache.commons.lang.StringUtils.startsWith;
+
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Spliterators;
import java.util.UUID;
import java.util.regex.Pattern;
@@ -606,4 +609,63 @@ private Stream streamOf(Iterator iterator) {
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
}
+ @Override
+ public boolean isOriginalBitstream(DSpaceObject dso) throws SQLException {
+
+ if (dso.getType() != Constants.BITSTREAM) {
+ return false;
+ }
+
+ Bitstream bitstream = (Bitstream) dso;
+
+ return bitstream.getBundles().stream()
+ .anyMatch(bundle -> "ORIGINAL".equals(bundle.getName()));
+
+ }
+
+ @Override
+ public void updateThumbnailResourcePolicies(Context context, Bitstream bitstream) throws SQLException {
+ getThumbnail(bitstream)
+ .ifPresent(thumbnail -> replacePolicies(context, bitstream, thumbnail));
+ }
+
+ private void replacePolicies(Context context, Bitstream bitstream, Bitstream thumbnail) {
+ try {
+ authorizeService.replaceAllPolicies(context, bitstream, thumbnail);
+ } catch (SQLException | AuthorizeException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private Optional getThumbnail(Bitstream bitstream) throws SQLException {
+ return getItem(bitstream)
+ .flatMap(item -> getThumbnail(item, bitstream.getName()));
+ }
+
+ private Optional- getItem(Bitstream bitstream) throws SQLException {
+ return bitstream.getBundles().stream()
+ .flatMap(bundle -> bundle.getItems().stream())
+ .findFirst();
+ }
+
+ private Optional
getThumbnail(Item item, String name) {
+ List bundles = getThumbnailBundles(item);
+ if (CollectionUtils.isEmpty(bundles)) {
+ return Optional.empty();
+ }
+
+ return bundles.stream()
+ .flatMap(bundle -> bundle.getBitstreams().stream())
+ .filter(bitstream -> startsWith(bitstream.getName(), name))
+ .findFirst();
+ }
+
+ private List getThumbnailBundles(Item item) {
+ try {
+ return itemService.getBundles(item, "THUMBNAIL");
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
}
diff --git a/dspace-api/src/main/java/org/dspace/content/authority/ItemAuthority.java b/dspace-api/src/main/java/org/dspace/content/authority/ItemAuthority.java
index 6ec39db9764f..173ea83f62ad 100644
--- a/dspace-api/src/main/java/org/dspace/content/authority/ItemAuthority.java
+++ b/dspace-api/src/main/java/org/dspace/content/authority/ItemAuthority.java
@@ -42,6 +42,7 @@
import org.dspace.util.ItemAuthorityUtils;
import org.dspace.util.UUIDUtils;
import org.dspace.utils.DSpace;
+import org.dspace.web.ContextUtil;
/**
* Sample authority to link a dspace item with another (i.e a publication with
@@ -58,7 +59,7 @@ public class ItemAuthority implements ChoiceAuthority, LinkableEntityAuthority {
/** the name assigned to the specific instance by the PluginService, @see {@link NameAwarePlugin} **/
private String authorityName;
- private DSpace dspace = new DSpace();
+ protected DSpace dspace = new DSpace();
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
@@ -181,9 +182,8 @@ private List getChoiceListFromQueryResults(SolrDocumentList results, Str
public String getLabel(String key, String locale) {
String title = key;
if (key != null) {
- Context context = null;
+ Context context = getContext();
try {
- context = new Context();
DSpaceObject dso = itemService.find(context, UUIDUtils.fromString(key));
if (dso != null) {
title = dso.getName();
@@ -292,4 +292,9 @@ private boolean hasValidExternalSource(String sourceIdentifier) {
return false;
}
+ private Context getContext() {
+ Context context = ContextUtil.obtainCurrentRequestContext();
+ return context != null ? context : new Context();
+ }
+
}
diff --git a/dspace-api/src/main/java/org/dspace/content/authority/RorOrgUnitAuthority.java b/dspace-api/src/main/java/org/dspace/content/authority/RorOrgUnitAuthority.java
new file mode 100644
index 000000000000..09f7330b62fe
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/content/authority/RorOrgUnitAuthority.java
@@ -0,0 +1,86 @@
+/**
+ * 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.content.authority;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.dspace.content.authority.factory.ItemAuthorityServiceFactory;
+import org.dspace.ror.ROROrgUnitDTO;
+import org.dspace.ror.service.RORApiService;
+import org.dspace.ror.service.RORApiServiceImpl;
+import org.dspace.services.ConfigurationService;
+import org.dspace.services.factory.DSpaceServicesFactory;
+
+public class RorOrgUnitAuthority extends ItemAuthority {
+
+ private final RORApiService rorApiService = dspace.getSingletonService(RORApiServiceImpl.class);
+ private final ItemAuthorityServiceFactory itemAuthorityServiceFactory =
+ dspace.getServiceManager().getServiceByName("itemAuthorityServiceFactory", ItemAuthorityServiceFactory.class);
+ private final ConfigurationService configurationService =
+ DSpaceServicesFactory.getInstance().getConfigurationService();
+
+ private String authorityName;
+
+ @Override
+ public Choices getMatches(String text, int start, int limit, String locale) {
+ super.setPluginInstanceName(authorityName);
+ Choices solrChoices = super.getMatches(text, start, limit, locale);
+
+ return solrChoices.values.length == 0 ? getRORApiMatches(text, start, limit) : solrChoices;
+ }
+
+ private Choices getRORApiMatches(String text, int start, int limit) {
+ Choice[] rorApiChoices = getChoiceFromRORQueryResults(
+ rorApiService.getOrgUnits(text).stream()
+ .filter(ou -> "active".equals(ou.getStatus()))
+ .collect(Collectors.toList())
+ ).toArray(new Choice[0]);
+
+ int confidenceValue = itemAuthorityServiceFactory.getInstance(authorityName)
+ .getConfidenceForChoices(rorApiChoices);
+
+ return new Choices(rorApiChoices, start, rorApiChoices.length, confidenceValue,
+ rorApiChoices.length > (start + limit), 0);
+ }
+
+ private List getChoiceFromRORQueryResults(List orgUnits) {
+ return orgUnits
+ .stream()
+ .map(orgUnit -> new Choice(composeAuthorityValue(orgUnit.getIdentifier()), orgUnit.getName(),
+ orgUnit.getName(), buildExtras(orgUnit)))
+ .collect(Collectors.toList());
+ }
+
+ private Map buildExtras(ROROrgUnitDTO orgUnit) {
+ return new HashMap<>();
+ }
+
+ private String composeAuthorityValue(String rorId) {
+ String prefix = configurationService.getProperty("ror.authority.prefix", "will be referenced::ROR-ID::");
+ return prefix + rorId;
+ }
+
+ @Override
+ public String getLinkedEntityType() {
+ return configurationService.getProperty("cris.ItemAuthority." + authorityName + ".entityType");
+ }
+
+ @Override
+ public void setPluginInstanceName(String name) {
+ authorityName = name;
+ }
+
+ @Override
+ public String getPluginInstanceName() {
+ return authorityName;
+ }
+}
diff --git a/dspace-api/src/main/java/org/dspace/content/dto/MetadataValueDTO.java b/dspace-api/src/main/java/org/dspace/content/dto/MetadataValueDTO.java
index 630efd5b0284..7bfa8504f902 100644
--- a/dspace-api/src/main/java/org/dspace/content/dto/MetadataValueDTO.java
+++ b/dspace-api/src/main/java/org/dspace/content/dto/MetadataValueDTO.java
@@ -69,6 +69,14 @@ public MetadataValueDTO(String schema, String element, String qualifier, String
this.confidence = confidence;
}
+ public MetadataValueDTO(String metadataField, String value) {
+ MetadataFieldName fieldName = new MetadataFieldName(metadataField);
+ this.schema = fieldName.schema;
+ this.element = fieldName.element;
+ this.qualifier = fieldName.qualifier;
+ this.value = value;
+ }
+
/**
* Constructor for the MetadataValueDTO class
* @param schema The schema to be assigned to this MetadataValueDTO object
diff --git a/dspace-api/src/main/java/org/dspace/content/edit/CorrectItemMode.java b/dspace-api/src/main/java/org/dspace/content/edit/CorrectItemMode.java
index b374861db9a3..2945065db4ea 100644
--- a/dspace-api/src/main/java/org/dspace/content/edit/CorrectItemMode.java
+++ b/dspace-api/src/main/java/org/dspace/content/edit/CorrectItemMode.java
@@ -10,6 +10,7 @@
import java.util.ArrayList;
import java.util.List;
+import org.dspace.content.logic.Filter;
import org.dspace.content.security.AccessItemMode;
import org.dspace.content.security.CrisSecurity;
@@ -42,6 +43,7 @@ public class CorrectItemMode implements AccessItemMode {
* Contains the list of users metadata for CUSTOM security
*/
private List items = new ArrayList();
+ private Filter additionalFilter;
@Override
public List getSecurities() {
@@ -87,4 +89,13 @@ public void setItems(List items) {
public List getGroups() {
return groups;
}
+
+ public void setAdditionalFilter(Filter additionalFilter) {
+ this.additionalFilter = additionalFilter;
+ }
+
+ @Override
+ public Filter getAdditionalFilter() {
+ return additionalFilter;
+ }
}
diff --git a/dspace-api/src/main/java/org/dspace/content/edit/EditItemMode.java b/dspace-api/src/main/java/org/dspace/content/edit/EditItemMode.java
index 4d56ddafe731..6f6b33ecaa28 100644
--- a/dspace-api/src/main/java/org/dspace/content/edit/EditItemMode.java
+++ b/dspace-api/src/main/java/org/dspace/content/edit/EditItemMode.java
@@ -9,6 +9,7 @@
import java.util.List;
+import org.dspace.content.logic.Filter;
import org.dspace.content.security.AccessItemMode;
import org.dspace.content.security.CrisSecurity;
@@ -49,6 +50,7 @@ public class EditItemMode implements AccessItemMode {
* Contains the list of items metadata for CUSTOM security
*/
private List items;
+ private Filter additionalFilter;
@Override
public List getSecurities() {
@@ -100,6 +102,15 @@ public void setItems(List items) {
this.items = items;
}
+ public void setAdditionalFilter(Filter additionalFilter) {
+ this.additionalFilter = additionalFilter;
+ }
+
+ @Override
+ public Filter getAdditionalFilter() {
+ return additionalFilter;
+ }
+
@Override
public List getGroups() {
return groups;
diff --git a/dspace-api/src/main/java/org/dspace/content/enhancer/impl/RelatedEntityItemEnhancer.java b/dspace-api/src/main/java/org/dspace/content/enhancer/impl/RelatedEntityItemEnhancer.java
index a5d95582e41d..a6c97cc84e65 100644
--- a/dspace-api/src/main/java/org/dspace/content/enhancer/impl/RelatedEntityItemEnhancer.java
+++ b/dspace-api/src/main/java/org/dspace/content/enhancer/impl/RelatedEntityItemEnhancer.java
@@ -78,7 +78,7 @@ private void cleanObsoleteVirtualFields(Context context, Item item) throws SQLEx
}
private void updateVirtualFieldsPlaces(Context context, Item item) {
- List virtualSourceFields = getMetadataValues(item, getVirtualSourceMetadataField());
+ List virtualSourceFields = getVirtualSourceFields(item);
for (MetadataValue virtualSourceField : virtualSourceFields) {
metadataWithPlaceToUpdate(item, virtualSourceField)
.ifPresent(updatePlaces(item, virtualSourceField));
@@ -113,9 +113,9 @@ private List getObsoleteVirtualFields(Item item) {
List obsoleteVirtualFields = new ArrayList<>();
- List virtualSourceFields = getMetadataValues(item, getVirtualSourceMetadataField());
+ List virtualSourceFields = getVirtualSourceFields(item);
for (MetadataValue virtualSourceField : virtualSourceFields) {
- if (isRelatedSourceNoMorePresent(item, virtualSourceField)) {
+ if (!isPlaceholder(virtualSourceField) && isRelatedSourceNoMorePresent(item, virtualSourceField)) {
obsoleteVirtualFields.add(virtualSourceField);
getRelatedVirtualField(item, virtualSourceField).ifPresent(obsoleteVirtualFields::add);
}
@@ -131,7 +131,7 @@ private boolean isRelatedSourceNoMorePresent(Item item, MetadataValue virtualSou
}
private Optional getRelatedVirtualField(Item item, MetadataValue virtualSourceField) {
- return getMetadataValues(item, getVirtualMetadataField()).stream()
+ return getVirtualFields(item).stream()
.filter(metadataValue -> metadataValue.getPlace() == virtualSourceField.getPlace())
.findFirst();
}
@@ -141,6 +141,7 @@ private void performEnhancement(Context context, Item item) throws SQLException
if (noEnhanceableMetadata(context, item)) {
return;
}
+
for (MetadataValue metadataValue : getEnhanceableMetadataValue(item)) {
if (wasValueAlreadyUsedForEnhancement(item, metadataValue)) {
@@ -191,9 +192,19 @@ private List getEnhanceableMetadataValue(Item item) {
}
private boolean wasValueAlreadyUsedForEnhancement(Item item, MetadataValue metadataValue) {
- return getMetadataValues(item, getVirtualSourceMetadataField()).stream()
+
+ if (isPlaceholderAtPlace(getVirtualFields(item), metadataValue.getPlace())) {
+ return true;
+ }
+
+ return getVirtualSourceFields(item).stream()
.anyMatch(virtualSourceField -> virtualSourceField.getPlace() == metadataValue.getPlace()
&& hasAuthorityEqualsTo(metadataValue, virtualSourceField.getValue()));
+
+ }
+
+ private boolean isPlaceholderAtPlace(List metadataValues, int place) {
+ return place < metadataValues.size() ? isPlaceholder(metadataValues.get(place)) : false;
}
private boolean hasAuthorityEqualsTo(MetadataValue metadataValue, String authority) {
@@ -209,10 +220,22 @@ private Item findRelatedEntityItem(Context context, MetadataValue metadataValue)
}
}
+ private boolean isPlaceholder(MetadataValue metadataValue) {
+ return PLACEHOLDER_PARENT_METADATA_VALUE.equals(metadataValue.getValue());
+ }
+
private List getMetadataValues(Item item, String metadataField) {
return itemService.getMetadataByMetadataString(item, metadataField);
}
+ private List getVirtualSourceFields(Item item) {
+ return getMetadataValues(item, getVirtualSourceMetadataField());
+ }
+
+ private List getVirtualFields(Item item) {
+ return getMetadataValues(item, getVirtualMetadataField());
+ }
+
private void addVirtualField(Context context, Item item, String value) throws SQLException {
itemService.addMetadata(context, item, VIRTUAL_METADATA_SCHEMA, VIRTUAL_METADATA_ELEMENT,
getVirtualQualifier(), null, value);
diff --git a/dspace-api/src/main/java/org/dspace/content/integration/crosswalks/XlsCrosswalk.java b/dspace-api/src/main/java/org/dspace/content/integration/crosswalks/XlsCrosswalk.java
index 026b6f375dfa..cbbfee4fb49b 100644
--- a/dspace-api/src/main/java/org/dspace/content/integration/crosswalks/XlsCrosswalk.java
+++ b/dspace-api/src/main/java/org/dspace/content/integration/crosswalks/XlsCrosswalk.java
@@ -11,6 +11,7 @@
import java.io.OutputStream;
import java.util.List;
+import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
@@ -45,7 +46,7 @@ protected void writeRows(List> rows, OutputStream out) {
int cellCount = 0;
for (String field : row) {
Cell cell = sheetRow.createCell(cellCount++);
- cell.setCellValue(field);
+ cell.setCellValue(StringUtils.length(field) > 32726 ? field.substring(0, 32725) + "…" : field );
}
}
diff --git a/dspace-api/src/main/java/org/dspace/content/integration/crosswalks/virtualfields/ItemDOIService.java b/dspace-api/src/main/java/org/dspace/content/integration/crosswalks/virtualfields/ItemDOIService.java
new file mode 100644
index 000000000000..03229f634a6b
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/content/integration/crosswalks/virtualfields/ItemDOIService.java
@@ -0,0 +1,59 @@
+/**
+ * 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.content.integration.crosswalks.virtualfields;
+
+import java.util.Comparator;
+import java.util.List;
+
+import org.dspace.content.Item;
+import org.dspace.content.MetadataValue;
+import org.dspace.content.service.ItemService;
+import org.dspace.services.ConfigurationService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+
+public class ItemDOIService {
+ static final String CFG_PREFIX = "identifier.doi.prefix";
+
+ static final String DOI_METADATA = "dc.identifier.doi";
+
+ @Autowired
+ protected ItemService itemService;
+ @Autowired
+ private ConfigurationService configurationService;
+
+ public String[] getAlternativeDOIFromItem(Item item) {
+ List metadataValueList = itemService.getMetadataByMetadataString(item, DOI_METADATA);
+ return getAlternativeDOI(metadataValueList, getPrimaryDOI(metadataValueList));
+ }
+ private String[] getAlternativeDOI(List metadataValueList, String primaryValue) {
+ return metadataValueList.stream().map(MetadataValue::getValue)
+ .filter(value -> !value.equals(primaryValue)).toArray(String[]::new);
+ }
+
+ public String getPrimaryDOIFromItem(Item item) {
+ return getPrimaryDOI(itemService.getMetadataByMetadataString(item, DOI_METADATA));
+ }
+
+ private String getPrimaryDOI(List metadataValueList) {
+ return metadataValueList.stream().filter(metadata -> metadata.getValue().contains(getPrefix()))
+ .min(Comparator.comparingInt(MetadataValue::getPlace)).map(MetadataValue::getValue)
+ .orElse(!metadataValueList.isEmpty() ? metadataValueList.get(0).getValue() : null);
+ }
+
+ protected String getPrefix() {
+ String prefix;
+ prefix = this.configurationService.getProperty(CFG_PREFIX);
+ if (null == prefix) {
+ throw new RuntimeException("Unable to load DOI prefix from "
+ + "configuration. Cannot find property " +
+ CFG_PREFIX + ".");
+ }
+ return prefix;
+ }
+}
diff --git a/dspace-api/src/main/java/org/dspace/content/integration/crosswalks/virtualfields/VirtualFieldAlternativeDOI.java b/dspace-api/src/main/java/org/dspace/content/integration/crosswalks/virtualfields/VirtualFieldAlternativeDOI.java
new file mode 100644
index 000000000000..3966566196cb
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/content/integration/crosswalks/virtualfields/VirtualFieldAlternativeDOI.java
@@ -0,0 +1,30 @@
+/**
+ * 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.content.integration.crosswalks.virtualfields;
+
+import org.apache.commons.lang3.StringUtils;
+import org.dspace.content.Item;
+import org.dspace.core.Context;
+import org.springframework.beans.factory.annotation.Autowired;
+
+
+public class VirtualFieldAlternativeDOI implements VirtualField {
+
+ @Autowired
+ private ItemDOIService itemDOIService;
+
+ @Override
+ public String[] getMetadata(Context context, Item item, String fieldName) {
+ String[] qualifiers = StringUtils.split(fieldName, ".");
+ if (qualifiers.length != 3) {
+ throw new IllegalArgumentException("Invalid field name " + fieldName);
+ }
+
+ return itemDOIService.getAlternativeDOIFromItem(item);
+ }
+}
diff --git a/dspace-api/src/main/java/org/dspace/content/integration/crosswalks/virtualfields/VirtualFieldPrimaryDOI.java b/dspace-api/src/main/java/org/dspace/content/integration/crosswalks/virtualfields/VirtualFieldPrimaryDOI.java
new file mode 100644
index 000000000000..3039ded0df84
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/content/integration/crosswalks/virtualfields/VirtualFieldPrimaryDOI.java
@@ -0,0 +1,30 @@
+/**
+ * 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.content.integration.crosswalks.virtualfields;
+
+import org.apache.commons.lang3.StringUtils;
+import org.dspace.content.Item;
+import org.dspace.core.Context;
+import org.springframework.beans.factory.annotation.Autowired;
+
+
+public class VirtualFieldPrimaryDOI implements VirtualField {
+
+ @Autowired
+ private ItemDOIService itemDOIService;
+
+ @Override
+ public String[] getMetadata(Context context, Item item, String fieldName) {
+ String[] qualifiers = StringUtils.split(fieldName, ".");
+ if (qualifiers.length != 3) {
+ throw new IllegalArgumentException("Invalid field name " + fieldName);
+ }
+
+ return new String[] {itemDOIService.getPrimaryDOIFromItem(item)};
+ }
+}
diff --git a/dspace-api/src/main/java/org/dspace/content/security/AccessItemMode.java b/dspace-api/src/main/java/org/dspace/content/security/AccessItemMode.java
index 2aee66fed1ff..e2954bf8f83c 100644
--- a/dspace-api/src/main/java/org/dspace/content/security/AccessItemMode.java
+++ b/dspace-api/src/main/java/org/dspace/content/security/AccessItemMode.java
@@ -9,6 +9,8 @@
import java.util.List;
+import org.dspace.content.logic.Filter;
+
/**
* Interface to be extended for the configuration related to access item modes.
*
@@ -50,4 +52,6 @@ public interface AccessItemMode {
* @return the group list
*/
public List getGroups();
+
+ public Filter getAdditionalFilter();
}
diff --git a/dspace-api/src/main/java/org/dspace/content/security/CrisSecurity.java b/dspace-api/src/main/java/org/dspace/content/security/CrisSecurity.java
index 3fcd83864175..9a472b8a40c3 100644
--- a/dspace-api/src/main/java/org/dspace/content/security/CrisSecurity.java
+++ b/dspace-api/src/main/java/org/dspace/content/security/CrisSecurity.java
@@ -23,6 +23,7 @@ public enum CrisSecurity {
ITEM_ADMIN,
SUBMITTER,
SUBMITTER_GROUP,
- GROUP;
+ GROUP,
+ ALL;
}
diff --git a/dspace-api/src/main/java/org/dspace/content/security/CrisSecurityServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/security/CrisSecurityServiceImpl.java
index 4a8b2c313846..99add81e862b 100644
--- a/dspace-api/src/main/java/org/dspace/content/security/CrisSecurityServiceImpl.java
+++ b/dspace-api/src/main/java/org/dspace/content/security/CrisSecurityServiceImpl.java
@@ -11,6 +11,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
import java.util.UUID;
import org.apache.commons.collections.CollectionUtils;
@@ -55,37 +56,46 @@ public boolean hasAccess(Context context, Item item, EPerson user, AccessItemMod
.anyMatch(security -> hasAccess(context, item, user, accessMode, security));
}
- private boolean hasAccess(Context context, Item item, EPerson user, AccessItemMode accessMode,
- CrisSecurity crisSecurity) {
-
+ private boolean hasAccess(
+ Context context, Item item, EPerson user, AccessItemMode accessMode, CrisSecurity crisSecurity
+ ) {
try {
+ final boolean checkSecurity = checkSecurity(context, item, user, accessMode, crisSecurity);
- switch (crisSecurity) {
- case ADMIN:
- return authorizeService.isAdmin(context, user);
- case CUSTOM:
- return hasAccessByCustomPolicy(context, item, user, accessMode);
- case GROUP:
- return hasAccessByGroup(context, user, accessMode.getGroups());
- case ITEM_ADMIN:
- return authorizeService.isAdmin(context, user, item);
- case OWNER:
- return isOwner(user, item);
- case SUBMITTER:
- return user != null && user.equals(item.getSubmitter());
- case SUBMITTER_GROUP:
- return isUserInSubmitterGroup(context, item, user);
- case NONE:
- default:
- return false;
- }
-
+ return Optional.ofNullable(accessMode.getAdditionalFilter())
+ .map(filter -> checkSecurity && filter.getResult(context, item))
+ .orElse(checkSecurity);
} catch (SQLException e) {
- throw new RuntimeException(e);
+ throw new SQLRuntimeException(e);
}
}
+ private boolean checkSecurity(Context context, Item item, EPerson user, AccessItemMode accessMode,
+ CrisSecurity crisSecurity) throws SQLException {
+ switch (crisSecurity) {
+ case ADMIN:
+ return authorizeService.isAdmin(context, user);
+ case CUSTOM:
+ return hasAccessByCustomPolicy(context, item, user, accessMode);
+ case GROUP:
+ return hasAccessByGroup(context, user, accessMode.getGroups());
+ case ITEM_ADMIN:
+ return authorizeService.isAdmin(context, user, item);
+ case OWNER:
+ return isOwner(user, item);
+ case SUBMITTER:
+ return user != null && user.equals(item.getSubmitter());
+ case SUBMITTER_GROUP:
+ return isUserInSubmitterGroup(context, item, user);
+ case ALL:
+ return true;
+ case NONE:
+ default:
+ return false;
+ }
+ }
+
private boolean isOwner(EPerson eperson, Item item) {
return ePersonService.isOwnerOfItem(eperson, item);
}
diff --git a/dspace-api/src/main/java/org/dspace/content/service/BitstreamService.java b/dspace-api/src/main/java/org/dspace/content/service/BitstreamService.java
index 3f5b17630a27..85a4fd140e9a 100644
--- a/dspace-api/src/main/java/org/dspace/content/service/BitstreamService.java
+++ b/dspace-api/src/main/java/org/dspace/content/service/BitstreamService.java
@@ -22,6 +22,7 @@
import org.dspace.content.Bundle;
import org.dspace.content.Collection;
import org.dspace.content.Community;
+import org.dspace.content.DSpaceObject;
import org.dspace.content.Item;
import org.dspace.core.Context;
@@ -243,4 +244,8 @@ List findShowableByItem(Context context, UUID itemId, String bundleNa
List findByItemAndBundleAndMetadata(Context context, Item item, String bundleName,
Map filterMetadata);
+ boolean isOriginalBitstream(DSpaceObject dso) throws SQLException;
+
+ void updateThumbnailResourcePolicies(Context context, Bitstream bitstream) throws SQLException;
+
}
diff --git a/dspace-api/src/main/java/org/dspace/eperson/AccountServiceImpl.java b/dspace-api/src/main/java/org/dspace/eperson/AccountServiceImpl.java
index 283f101f2ba5..8be6aac7e392 100644
--- a/dspace-api/src/main/java/org/dspace/eperson/AccountServiceImpl.java
+++ b/dspace-api/src/main/java/org/dspace/eperson/AccountServiceImpl.java
@@ -11,25 +11,36 @@
import java.sql.SQLException;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.UUID;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
import javax.mail.MessagingException;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dspace.authenticate.service.AuthenticationService;
import org.dspace.authorize.AuthorizeException;
+import org.dspace.content.Item;
+import org.dspace.content.MetadataValue;
+import org.dspace.content.service.MetadataValueService;
import org.dspace.core.Context;
import org.dspace.core.Email;
import org.dspace.core.I18nUtil;
import org.dspace.core.Utils;
+import org.dspace.eperson.dto.RegistrationDataPatch;
import org.dspace.eperson.service.AccountService;
import org.dspace.eperson.service.EPersonService;
import org.dspace.eperson.service.GroupService;
import org.dspace.eperson.service.RegistrationDataService;
import org.dspace.services.ConfigurationService;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.log.LogMessage;
/**
* Methods for handling registration by email and forgotten passwords. When
@@ -50,8 +61,16 @@ public class AccountServiceImpl implements AccountService {
* log4j log
*/
private static final Logger log = LogManager.getLogger(AccountServiceImpl.class);
+
+ private static final Map> allowedMergeArguments =
+ Map.of(
+ "email",
+ (RegistrationData registrationData, EPerson eperson) -> eperson.setEmail(registrationData.getEmail())
+ );
+
@Autowired(required = true)
protected EPersonService ePersonService;
+
@Autowired(required = true)
protected RegistrationDataService registrationDataService;
@Autowired
@@ -63,6 +82,9 @@ public class AccountServiceImpl implements AccountService {
@Autowired
private AuthenticationService authenticationService;
+ @Autowired
+ private MetadataValueService metadataValueService;
+
protected AccountServiceImpl() {
}
@@ -79,9 +101,9 @@ protected AccountServiceImpl() {
*
* @param context DSpace context
* @param email Email address to send the registration email to
- * @throws java.sql.SQLException passed through.
- * @throws java.io.IOException passed through.
- * @throws javax.mail.MessagingException passed through.
+ * @throws java.sql.SQLException passed through.
+ * @throws java.io.IOException passed through.
+ * @throws javax.mail.MessagingException passed through.
* @throws org.dspace.authorize.AuthorizeException passed through.
*/
@Override
@@ -94,7 +116,7 @@ public void sendRegistrationInfo(Context context, String email, List group
if (!authenticationService.canSelfRegister(context, null, email)) {
throw new IllegalStateException("self registration is not allowed with this email address");
}
- sendInfo(context, email, groups, true, true);
+ sendInfo(context, email, groups, RegistrationTypeEnum.REGISTER, true);
}
/**
@@ -108,19 +130,36 @@ public void sendRegistrationInfo(Context context, String email, List group
* Authorization error (throws AuthorizeException).
*