dspaceRunnableClass) {
+ this.dspaceRunnableClass = dspaceRunnableClass;
+ }
+
+ /**
+ * Only admin can run Curation script via the scripts and processes endpoints.
+ * @param context The relevant DSpace context
+ * @return True if currentUser is admin, otherwise false
+ */
+ @Override
+ public boolean isAllowedToExecute(Context context) {
+ try {
+ return authorizeService.isAdmin(context);
+ } catch (SQLException e) {
+ throw new RuntimeException("SQLException occurred when checking if the current user is an admin", e);
+ }
+ }
+
+ @Override
+ public Options getOptions() {
+ if (options == null) {
+ super.options = CurationClientOptions.constructOptions();
+ }
+ return options;
+ }
+}
diff --git a/dspace-api/src/main/java/org/dspace/curate/Curator.java b/dspace-api/src/main/java/org/dspace/curate/Curator.java
index 44733174df..8f12750bae 100644
--- a/dspace-api/src/main/java/org/dspace/curate/Curator.java
+++ b/dspace-api/src/main/java/org/dspace/curate/Curator.java
@@ -98,6 +98,7 @@ public class Curator {
communityService = ContentServiceFactory.getInstance().getCommunityService();
itemService = ContentServiceFactory.getInstance().getItemService();
handleService = HandleServiceFactory.getInstance().getHandleService();
+ resolver = new TaskResolver();
}
/**
@@ -142,10 +143,10 @@ public class Curator {
// performance order currently FIFO - to be revisited
perfList.add(taskName);
} catch (IOException ioE) {
- log.error("Task: '" + taskName + "' initialization failure: " + ioE.getMessage());
+ System.out.println("Task: '" + taskName + "' initialization failure: " + ioE.getMessage());
}
} else {
- log.error("Task: '" + taskName + "' does not resolve");
+ System.out.println("Task: '" + taskName + "' does not resolve");
}
return this;
}
@@ -259,13 +260,6 @@ public class Curator {
/**
* Performs all configured tasks upon DSpace object
* (Community, Collection or Item).
- *
- * Note: Site-wide tasks will default to running as
- * an Anonymous User unless you call the Site-wide task
- * via the {@link curate(Context,String)} or
- * {@link #curate(Context, DSpaceObject)} method with an
- * authenticated Context object.
- *
* @param dso the DSpace object
* @throws IOException if IO error
*/
@@ -325,7 +319,7 @@ public class Curator {
taskQ.enqueue(queueId, new TaskQueueEntry(c.getCurrentUser().getName(),
System.currentTimeMillis(), perfList, id));
} else {
- log.error("curate - no TaskQueue implemented");
+ System.out.println("curate - no TaskQueue implemented");
}
}
@@ -346,7 +340,7 @@ public class Curator {
try {
reporter.append(message);
} catch (IOException ex) {
- log.error("Task reporting failure", ex);
+ System.out.println("Task reporting failure: " + ex);
}
}
@@ -552,7 +546,7 @@ public class Curator {
return !suspend(statusCode);
} catch (IOException ioe) {
//log error & pass exception upwards
- log.error("Error executing curation task '" + task.getName() + "'", ioe);
+ System.out.println("Error executing curation task '" + task.getName() + "'; " + ioe);
throw ioe;
}
}
@@ -568,7 +562,7 @@ public class Curator {
return !suspend(statusCode);
} catch (IOException ioe) {
//log error & pass exception upwards
- log.error("Error executing curation task '" + task.getName() + "'", ioe);
+ System.out.println("Error executing curation task '" + task.getName() + "'; " + ioe);
throw ioe;
}
}
diff --git a/dspace-api/src/main/java/org/dspace/discovery/DiscoverQuery.java b/dspace-api/src/main/java/org/dspace/discovery/DiscoverQuery.java
index d3efb3c626..d82779015f 100644
--- a/dspace-api/src/main/java/org/dspace/discovery/DiscoverQuery.java
+++ b/dspace-api/src/main/java/org/dspace/discovery/DiscoverQuery.java
@@ -7,6 +7,9 @@
*/
package org.dspace.discovery;
+import static java.util.Collections.singletonList;
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -31,7 +34,7 @@ public class DiscoverQuery {
**/
private String query;
private List filterQueries;
- private String DSpaceObjectFilter = null;
+ private List dspaceObjectFilters = new ArrayList<>();
private List fieldPresentQueries;
private boolean spellCheck;
@@ -118,20 +121,33 @@ public class DiscoverQuery {
* Sets the DSpace object filter, must be an DSpace Object type integer
* can be used to only return objects from a certain DSpace Object type
*
- * @param DSpaceObjectFilter the DSpace object filer
+ * @param dspaceObjectFilter the DSpace object filter
*/
- public void setDSpaceObjectFilter(String DSpaceObjectFilter) {
- this.DSpaceObjectFilter = DSpaceObjectFilter;
+ public void setDSpaceObjectFilter(String dspaceObjectFilter) {
+ this.dspaceObjectFilters = singletonList(dspaceObjectFilter);
}
/**
- * Gets the DSpace object filter
- * can be used to only return objects from a certain DSpace Object type
+ * Adds a DSpace object filter, must be an DSpace Object type integer.
+ * Can be used to also return objects from a certain DSpace Object type.
*
- * @return the DSpace object filer
+ * @param dspaceObjectFilter the DSpace object filer
*/
- public String getDSpaceObjectFilter() {
- return DSpaceObjectFilter;
+ public void addDSpaceObjectFilter(String dspaceObjectFilter) {
+
+ if (isNotBlank(dspaceObjectFilter)) {
+ this.dspaceObjectFilters.add(dspaceObjectFilter);
+ }
+ }
+
+ /**
+ * Gets the DSpace object filters
+ * can be used to only return objects from certain DSpace Object types
+ *
+ * @return the DSpace object filters
+ */
+ public List getDSpaceObjectFilters() {
+ return dspaceObjectFilters;
}
/**
diff --git a/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java b/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java
index 1c47d46162..88e32d0aaf 100644
--- a/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java
+++ b/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java
@@ -7,6 +7,8 @@
*/
package org.dspace.discovery;
+import static java.util.stream.Collectors.joining;
+
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -751,8 +753,13 @@ public class SolrServiceImpl implements SearchService, IndexingService {
String filterQuery = discoveryQuery.getFilterQueries().get(i);
solrQuery.addFilterQuery(filterQuery);
}
- if (discoveryQuery.getDSpaceObjectFilter() != null) {
- solrQuery.addFilterQuery(SearchUtils.RESOURCE_TYPE_FIELD + ":" + discoveryQuery.getDSpaceObjectFilter());
+ if (discoveryQuery.getDSpaceObjectFilters() != null) {
+ solrQuery.addFilterQuery(
+ discoveryQuery.getDSpaceObjectFilters()
+ .stream()
+ .map(filter -> SearchUtils.RESOURCE_TYPE_FIELD + ":" + filter)
+ .collect(joining(" OR "))
+ );
}
for (int i = 0; i < discoveryQuery.getFieldPresentQueries().size(); i++) {
diff --git a/dspace-api/src/main/java/org/dspace/importer/external/bibtex/service/BibtexImportMetadataSourceServiceImpl.java b/dspace-api/src/main/java/org/dspace/importer/external/bibtex/service/BibtexImportMetadataSourceServiceImpl.java
new file mode 100644
index 0000000000..7468d601f5
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/importer/external/bibtex/service/BibtexImportMetadataSourceServiceImpl.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.importer.external.bibtex.service;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import javax.annotation.Resource;
+
+import org.dspace.importer.external.exception.FileSourceException;
+import org.dspace.importer.external.service.components.AbstractPlainMetadataSource;
+import org.dspace.importer.external.service.components.dto.PlainMetadataKeyValueItem;
+import org.dspace.importer.external.service.components.dto.PlainMetadataSourceDto;
+import org.jbibtex.BibTeXDatabase;
+import org.jbibtex.BibTeXEntry;
+import org.jbibtex.BibTeXParser;
+import org.jbibtex.Key;
+import org.jbibtex.ParseException;
+import org.jbibtex.Value;
+
+/**
+ * Implements a metadata importer for BibTeX files
+ *
+ * @author Pasquale Cavallo (pasquale.cavallo at 4science dot it)
+ */
+public class BibtexImportMetadataSourceServiceImpl extends AbstractPlainMetadataSource {
+
+
+ /**
+ * The string that identifies this import implementation as
+ * MetadataSource implementation
+ *
+ * @return the identifying uri
+ */
+ @Override
+ public String getImportSource() {
+ return "BibTeXMetadataSource";
+ }
+
+ @Override
+ protected List readData (InputStream
+ inputStream) throws FileSourceException {
+ List list = new ArrayList<>();
+ BibTeXDatabase database;
+ try {
+ database = parseBibTex(inputStream);
+ } catch (IOException | ParseException e) {
+ throw new FileSourceException("Unable to parse file with BibTeX parser");
+ }
+ if (database == null || database.getEntries() == null) {
+ throw new FileSourceException("File results in an empty list of metadata");
+ }
+ if (database.getEntries() != null) {
+ for (Entry entry : database.getEntries().entrySet()) {
+ PlainMetadataSourceDto item = new PlainMetadataSourceDto();
+ List keyValues = new ArrayList<>();
+ item.setMetadata(keyValues);
+ PlainMetadataKeyValueItem keyValueItem = new PlainMetadataKeyValueItem();
+ keyValueItem.setKey(entry.getValue().getType().getValue());
+ keyValueItem.setValue(entry.getKey().getValue());
+ keyValues.add(keyValueItem);
+ if (entry.getValue().getFields() != null) {
+ for (Entry subentry : entry.getValue().getFields().entrySet()) {
+ PlainMetadataKeyValueItem innerItem = new PlainMetadataKeyValueItem();
+ innerItem.setKey(subentry.getKey().getValue());
+ innerItem.setValue(subentry.getValue().toUserString());
+ keyValues.add(innerItem);
+ }
+ }
+ list.add(item);
+ }
+ }
+ return list;
+ }
+
+ private BibTeXDatabase parseBibTex(InputStream inputStream) throws IOException, ParseException {
+ Reader reader = new InputStreamReader(inputStream);
+ BibTeXParser bibtexParser = new BibTeXParser();
+ return bibtexParser.parse(reader);
+ }
+
+
+ /**
+ * Retrieve the MetadataFieldMapping containing the mapping between RecordType
+ * (in this case PlainMetadataSourceDto.class) and Metadata
+ *
+ * @return The configured MetadataFieldMapping
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ @Resource(name = "bibtexMetadataFieldMap")
+ public void setMetadataFieldMap(@SuppressWarnings("rawtypes") Map metadataFieldMap) {
+ super.setMetadataFieldMap(metadataFieldMap);
+ }
+
+}
diff --git a/dspace-api/src/main/java/org/dspace/importer/external/exception/FileMultipleOccurencesException.java b/dspace-api/src/main/java/org/dspace/importer/external/exception/FileMultipleOccurencesException.java
new file mode 100644
index 0000000000..d09889a7ff
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/importer/external/exception/FileMultipleOccurencesException.java
@@ -0,0 +1,29 @@
+/**
+ * The contents of this file are subject to the license and copyright
+ * detailed in the LICENSE and NOTICE files at the root of the source
+ * tree and available online at
+ *
+ * http://www.dspace.org/license/
+ */
+
+package org.dspace.importer.external.exception;
+
+/**
+ * This exception could be throws when more than one element is found
+ * in a method that works on one only.
+ *
+ * @author Pasquale Cavallo (pasquale.cavallo at 4science dot it)
+ */
+
+public class FileMultipleOccurencesException extends Exception {
+
+ private static final long serialVersionUID = 1222409723339501937L;
+
+ public FileMultipleOccurencesException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public FileMultipleOccurencesException(String message) {
+ super(message);
+ }
+}
diff --git a/dspace-api/src/main/java/org/dspace/importer/external/exception/FileSourceException.java b/dspace-api/src/main/java/org/dspace/importer/external/exception/FileSourceException.java
new file mode 100644
index 0000000000..c41ce94151
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/importer/external/exception/FileSourceException.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.importer.external.exception;
+
+/**
+ * Represents a problem with the File content: e.g. null input stream, invalid content, ...
+ *
+ * @author Pasquale Cavallo (pasquale.cavallo at 4science dot it)
+ */
+
+public class FileSourceException extends Exception {
+
+ private static final long serialVersionUID = 6895579588455260182L;
+
+ public FileSourceException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public FileSourceException(String message) {
+ super(message);
+ }
+}
diff --git a/dspace-api/src/main/java/org/dspace/importer/external/metadatamapping/AbstractMetadataFieldMapping.java b/dspace-api/src/main/java/org/dspace/importer/external/metadatamapping/AbstractMetadataFieldMapping.java
index 3ce45d6048..aed2f0e084 100644
--- a/dspace-api/src/main/java/org/dspace/importer/external/metadatamapping/AbstractMetadataFieldMapping.java
+++ b/dspace-api/src/main/java/org/dspace/importer/external/metadatamapping/AbstractMetadataFieldMapping.java
@@ -117,16 +117,13 @@ public abstract class AbstractMetadataFieldMapping
public Collection resultToDCValueMapping(RecordType record) {
List values = new LinkedList();
-
for (MetadataContributor query : getMetadataFieldMap().values()) {
try {
values.addAll(query.contributeMetadata(record));
} catch (Exception e) {
log.error("Error", e);
}
-
}
return values;
-
}
}
diff --git a/dspace-api/src/main/java/org/dspace/importer/external/metadatamapping/contributor/SimpleMetadataContributor.java b/dspace-api/src/main/java/org/dspace/importer/external/metadatamapping/contributor/SimpleMetadataContributor.java
new file mode 100644
index 0000000000..21dd1bfcee
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/importer/external/metadatamapping/contributor/SimpleMetadataContributor.java
@@ -0,0 +1,94 @@
+/**
+ * The contents of this file are subject to the license and copyright
+ * detailed in the LICENSE and NOTICE files at the root of the source
+ * tree and available online at
+ *
+ * http://www.dspace.org/license/
+ */
+
+package org.dspace.importer.external.metadatamapping.contributor;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.dspace.importer.external.metadatamapping.MetadataFieldConfig;
+import org.dspace.importer.external.metadatamapping.MetadataFieldMapping;
+import org.dspace.importer.external.metadatamapping.MetadatumDTO;
+import org.dspace.importer.external.service.components.dto.PlainMetadataKeyValueItem;
+import org.dspace.importer.external.service.components.dto.PlainMetadataSourceDto;
+
+/**
+ * Metadata contributor that takes an PlainMetadataSourceDto instance and turns it into a
+ * collection of metadatum
+ *
+ * @author Pasquale Cavallo (pasquale.cavallo at 4science dot it)
+ */
+public class SimpleMetadataContributor implements MetadataContributor {
+
+ private MetadataFieldConfig field;
+
+ private String key;
+
+ private MetadataFieldMapping> metadataFieldMapping;
+
+ public SimpleMetadataContributor(MetadataFieldConfig field, String key) {
+ this.field = field;
+ this.key = key;
+ }
+
+ public SimpleMetadataContributor() { }
+
+ /**
+ * Set the metadataFieldMapping of this SimpleMetadataContributor
+ *
+ * @param metadataFieldMapping the new mapping.
+ */
+ @Override
+ public void setMetadataFieldMapping(
+ MetadataFieldMapping> metadataFieldMapping) {
+ this.metadataFieldMapping = metadataFieldMapping;
+ }
+
+ /**
+ * Retrieve the metadata associated with the given object.
+ * It match the key found in PlainMetadataSourceDto instance with the key passed to constructor.
+ * In case of success, new metadatum is constructer (using field elements and PlainMetadataSourceDto value)
+ * and added to the list.
+ *
+ * @param t A class to retrieve metadata and key to match from. t and contained list "metadata" MUST be not null.
+ * @return a collection of import records. Only the identifier of the found records may be put in the record.
+ */
+ @Override
+ public Collection contributeMetadata(PlainMetadataSourceDto t) {
+ List values = new LinkedList<>();
+ for (PlainMetadataKeyValueItem metadatum : t.getMetadata()) {
+ if (key.equals(metadatum.getKey())) {
+ MetadatumDTO dcValue = new MetadatumDTO();
+ dcValue.setValue(metadatum.getValue());
+ dcValue.setElement(field.getElement());
+ dcValue.setQualifier(field.getQualifier());
+ dcValue.setSchema(field.getSchema());
+ values.add(dcValue);
+ }
+ }
+ return values;
+ }
+
+ /*
+ * Setter to inject field item
+ */
+ public void setField(MetadataFieldConfig field) {
+ this.field = field;
+ }
+
+ /*
+ * Setter to inject key value
+ */
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+}
diff --git a/dspace-api/src/main/java/org/dspace/importer/external/pubmed/service/PubmedImportMetadataSourceServiceImpl.java b/dspace-api/src/main/java/org/dspace/importer/external/pubmed/service/PubmedImportMetadataSourceServiceImpl.java
index bcb5034301..b4d8ee1222 100644
--- a/dspace-api/src/main/java/org/dspace/importer/external/pubmed/service/PubmedImportMetadataSourceServiceImpl.java
+++ b/dspace-api/src/main/java/org/dspace/importer/external/pubmed/service/PubmedImportMetadataSourceServiceImpl.java
@@ -8,6 +8,10 @@
package org.dspace.importer.external.pubmed.service;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
import java.io.StringReader;
import java.util.Collection;
import java.util.LinkedList;
@@ -20,6 +24,7 @@ import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import com.google.common.io.CharStreams;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMXMLBuilderFactory;
import org.apache.axiom.om.OMXMLParserWrapper;
@@ -27,8 +32,12 @@ import org.apache.axiom.om.xpath.AXIOMXPath;
import org.dspace.content.Item;
import org.dspace.importer.external.datamodel.ImportRecord;
import org.dspace.importer.external.datamodel.Query;
+import org.dspace.importer.external.exception.FileMultipleOccurencesException;
+import org.dspace.importer.external.exception.FileSourceException;
import org.dspace.importer.external.exception.MetadataSourceException;
import org.dspace.importer.external.service.AbstractImportMetadataSourceService;
+import org.dspace.importer.external.service.components.FileSource;
+import org.dspace.importer.external.service.components.QuerySource;
import org.jaxen.JaxenException;
/**
@@ -36,11 +45,29 @@ import org.jaxen.JaxenException;
*
* @author Roeland Dillen (roeland at atmire dot com)
*/
-public class PubmedImportMetadataSourceServiceImpl extends AbstractImportMetadataSourceService {
+public class PubmedImportMetadataSourceServiceImpl extends AbstractImportMetadataSourceService
+ implements QuerySource, FileSource {
+
private String baseAddress;
private WebTarget pubmedWebTarget;
+ private List supportedExtensions;
+
+ /**
+ * Set the file extensions supported by this metadata service
+ *
+ * @param supportedExtensionsthe file extensions (xml,txt,...) supported by this service
+ */
+ public void setSupportedExtensions(List supportedExtensions) {
+ this.supportedExtensions = supportedExtensions;
+ }
+
+ @Override
+ public List getSupportedExtensions() {
+ return supportedExtensions;
+ }
+
/**
* Find the number of records matching a query;
*
@@ -49,7 +76,7 @@ public class PubmedImportMetadataSourceServiceImpl extends AbstractImportMetadat
* @throws MetadataSourceException if the underlying methods throw any exception.
*/
@Override
- public int getNbRecords(String query) throws MetadataSourceException {
+ public int getRecordsCount(String query) throws MetadataSourceException {
return retry(new GetNbRecords(query));
}
@@ -61,7 +88,7 @@ public class PubmedImportMetadataSourceServiceImpl extends AbstractImportMetadat
* @throws MetadataSourceException if the underlying methods throw any exception.
*/
@Override
- public int getNbRecords(Query query) throws MetadataSourceException {
+ public int getRecordsCount(Query query) throws MetadataSourceException {
return retry(new GetNbRecords(query));
}
@@ -357,7 +384,6 @@ public class PubmedImportMetadataSourceServiceImpl extends AbstractImportMetadat
@Override
public Collection call() throws Exception {
- List records = new LinkedList();
WebTarget getRecordIdsTarget = pubmedWebTarget
.queryParam("term", query.getParameterAsClass("term", String.class));
@@ -382,13 +408,41 @@ public class PubmedImportMetadataSourceServiceImpl extends AbstractImportMetadat
invocationBuilder = getRecordsTarget.request(MediaType.TEXT_PLAIN_TYPE);
response = invocationBuilder.get();
- List omElements = splitToRecords(response.readEntity(String.class));
-
- for (OMElement record : omElements) {
- records.add(transformSourceRecords(record));
- }
-
- return records;
+ String xml = response.readEntity(String.class);
+ return parseXMLString(xml);
}
}
+
+
+ @Override
+ public List getRecords(InputStream inputStream) throws FileSourceException {
+ String xml = null;
+ try (Reader reader = new InputStreamReader(inputStream, "UTF-8")) {
+ xml = CharStreams.toString(reader);
+ return parseXMLString(xml);
+ } catch (IOException e) {
+ throw new FileSourceException ("Cannot read XML from InputStream", e);
+ }
+ }
+
+ @Override
+ public ImportRecord getRecord(InputStream inputStream) throws FileSourceException, FileMultipleOccurencesException {
+ List importRecord = getRecords(inputStream);
+ if (importRecord == null || importRecord.isEmpty()) {
+ throw new FileSourceException("Cannot find (valid) record in File");
+ } else if (importRecord.size() > 1) {
+ throw new FileMultipleOccurencesException("File contains more than one entry");
+ } else {
+ return importRecord.get(0);
+ }
+ }
+
+ private List parseXMLString(String xml) {
+ List records = new LinkedList();
+ List omElements = splitToRecords(xml);
+ for (OMElement record : omElements) {
+ records.add(transformSourceRecords(record));
+ }
+ return records;
+ }
}
diff --git a/dspace-api/src/main/java/org/dspace/importer/external/service/ImportService.java b/dspace-api/src/main/java/org/dspace/importer/external/service/ImportService.java
index 87c2bd0029..815a10b5a7 100644
--- a/dspace-api/src/main/java/org/dspace/importer/external/service/ImportService.java
+++ b/dspace-api/src/main/java/org/dspace/importer/external/service/ImportService.java
@@ -8,6 +8,10 @@
package org.dspace.importer.external.service;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -19,11 +23,16 @@ import org.apache.logging.log4j.Logger;
import org.dspace.content.Item;
import org.dspace.importer.external.datamodel.ImportRecord;
import org.dspace.importer.external.datamodel.Query;
+import org.dspace.importer.external.exception.FileMultipleOccurencesException;
+import org.dspace.importer.external.exception.FileSourceException;
import org.dspace.importer.external.exception.MetadataSourceException;
import org.dspace.importer.external.service.components.Destroyable;
+import org.dspace.importer.external.service.components.FileSource;
import org.dspace.importer.external.service.components.MetadataSource;
+import org.dspace.importer.external.service.components.QuerySource;
import org.springframework.beans.factory.annotation.Autowired;
+
/**
* Main entry point for the import framework.
* Instead of calling the different importer implementations, the ImportService should be called instead.
@@ -32,8 +41,10 @@ import org.springframework.beans.factory.annotation.Autowired;
* importer implementation you want to use.
*
* @author Roeland Dillen (roeland at atmire dot com)
+ * @author Pasquale Cavallo (pasquale.cavallo@4science.it)
*/
public class ImportService implements Destroyable {
+
private HashMap importSources = new HashMap<>();
Logger log = org.apache.logging.log4j.LogManager.getLogger(ImportService.class);
@@ -101,11 +112,11 @@ public class ImportService implements Destroyable {
public Collection findMatchingRecords(String uri, Item item) throws MetadataSourceException {
try {
List recordList = new LinkedList();
-
for (MetadataSource metadataSource : matchingImports(uri)) {
- recordList.addAll(metadataSource.findMatchingRecords(item));
+ if (metadataSource instanceof QuerySource) {
+ recordList.addAll(((QuerySource)metadataSource).findMatchingRecords(item));
+ }
}
-
return recordList;
} catch (Exception e) {
throw new MetadataSourceException(e);
@@ -125,9 +136,10 @@ public class ImportService implements Destroyable {
try {
List recordList = new LinkedList();
for (MetadataSource metadataSource : matchingImports(uri)) {
- recordList.addAll(metadataSource.findMatchingRecords(query));
+ if (metadataSource instanceof QuerySource) {
+ recordList.addAll(((QuerySource)metadataSource).findMatchingRecords(query));
+ }
}
-
return recordList;
} catch (Exception e) {
throw new MetadataSourceException(e);
@@ -145,8 +157,10 @@ public class ImportService implements Destroyable {
public int getNbRecords(String uri, String query) throws MetadataSourceException {
try {
int total = 0;
- for (MetadataSource MetadataSource : matchingImports(uri)) {
- total += MetadataSource.getNbRecords(query);
+ for (MetadataSource metadataSource : matchingImports(uri)) {
+ if (metadataSource instanceof QuerySource) {
+ total += ((QuerySource)metadataSource).getRecordsCount(query);
+ }
}
return total;
} catch (Exception e) {
@@ -165,8 +179,10 @@ public class ImportService implements Destroyable {
public int getNbRecords(String uri, Query query) throws MetadataSourceException {
try {
int total = 0;
- for (MetadataSource MetadataSource : matchingImports(uri)) {
- total += MetadataSource.getNbRecords(query);
+ for (MetadataSource metadataSource : matchingImports(uri)) {
+ if (metadataSource instanceof QuerySource) {
+ total += ((QuerySource)metadataSource).getRecordsCount(query);
+ }
}
return total;
} catch (Exception e) {
@@ -189,7 +205,9 @@ public class ImportService implements Destroyable {
try {
List recordList = new LinkedList<>();
for (MetadataSource metadataSource : matchingImports(uri)) {
- recordList.addAll(metadataSource.getRecords(query, start, count));
+ if (metadataSource instanceof QuerySource) {
+ recordList.addAll(((QuerySource)metadataSource).getRecords(query, start, count));
+ }
}
return recordList;
} catch (Exception e) {
@@ -209,7 +227,9 @@ public class ImportService implements Destroyable {
try {
List recordList = new LinkedList<>();
for (MetadataSource metadataSource : matchingImports(uri)) {
- recordList.addAll(metadataSource.getRecords(query));
+ if (metadataSource instanceof QuerySource) {
+ recordList.addAll(((QuerySource)metadataSource).getRecords(query));
+ }
}
return recordList;
} catch (Exception e) {
@@ -229,10 +249,12 @@ public class ImportService implements Destroyable {
public ImportRecord getRecord(String uri, String id) throws MetadataSourceException {
try {
for (MetadataSource metadataSource : matchingImports(uri)) {
- if (metadataSource.getRecord(id) != null) {
- return metadataSource.getRecord(id);
+ if (metadataSource instanceof QuerySource) {
+ QuerySource querySource = (QuerySource)metadataSource;
+ if (querySource.getRecord(id) != null) {
+ return querySource.getRecord(id);
+ }
}
-
}
return null;
} catch (Exception e) {
@@ -252,10 +274,12 @@ public class ImportService implements Destroyable {
public ImportRecord getRecord(String uri, Query query) throws MetadataSourceException {
try {
for (MetadataSource metadataSource : matchingImports(uri)) {
- if (metadataSource.getRecord(query) != null) {
- return metadataSource.getRecord(query);
+ if (metadataSource instanceof QuerySource) {
+ QuerySource querySource = (QuerySource)metadataSource;
+ if (querySource.getRecord(query) != null) {
+ return querySource.getRecord(query);
+ }
}
-
}
return null;
} catch (Exception e) {
@@ -272,6 +296,41 @@ public class ImportService implements Destroyable {
return importSources.keySet();
}
+ /*
+ * Get a collection of record from File,
+ * The first match will be return.
+ *
+ * @param file The file from which will read records
+ * @param originalName The original file name or full path
+ * @return a single record contains the metadatum
+ * @throws FileMultipleOccurencesException if more than one entry is found
+ */
+ public ImportRecord getRecord(File file, String originalName)
+ throws FileMultipleOccurencesException, FileSourceException {
+ ImportRecord importRecords = null;
+ for (MetadataSource metadataSource : importSources.values()) {
+ try (InputStream fileInputStream = new FileInputStream(file)) {
+ if (metadataSource instanceof FileSource) {
+ FileSource fileSource = (FileSource)metadataSource;
+ if (fileSource.isValidSourceForFile(originalName)) {
+ importRecords = fileSource.getRecord(fileInputStream);
+ break;
+ }
+ }
+ //catch statements is required because we could have supported format (i.e. XML)
+ //which fail on schema validation
+ } catch (FileSourceException e) {
+ log.debug(metadataSource.getImportSource() + " isn't a valid parser for file");
+ } catch (FileMultipleOccurencesException e) {
+ log.debug("File contains multiple metadata, return with error");
+ throw e;
+ } catch (IOException e1) {
+ throw new FileSourceException("File cannot be read, may be null");
+ }
+ }
+ return importRecords;
+ }
+
/**
* Call destroy on all {@link Destroyable} {@link MetadataSource} objects set in this ImportService
*/
diff --git a/dspace-api/src/main/java/org/dspace/importer/external/service/components/AbstractPlainMetadataSource.java b/dspace-api/src/main/java/org/dspace/importer/external/service/components/AbstractPlainMetadataSource.java
new file mode 100644
index 0000000000..019cf33177
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/importer/external/service/components/AbstractPlainMetadataSource.java
@@ -0,0 +1,103 @@
+/**
+ * The contents of this file are subject to the license and copyright
+ * detailed in the LICENSE and NOTICE files at the root of the source
+ * tree and available online at
+ *
+ * http://www.dspace.org/license/
+ */
+
+package org.dspace.importer.external.service.components;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.dspace.importer.external.datamodel.ImportRecord;
+import org.dspace.importer.external.exception.FileMultipleOccurencesException;
+import org.dspace.importer.external.exception.FileSourceException;
+import org.dspace.importer.external.metadatamapping.AbstractMetadataFieldMapping;
+import org.dspace.importer.external.metadatamapping.MetadatumDTO;
+import org.dspace.importer.external.service.components.dto.PlainMetadataSourceDto;
+
+
+/**
+ * This class is an abstract implementation of {@link MetadataSource} useful in cases
+ * of plain metadata sources.
+ * It provides the methot to mapping metadata to DSpace Format when source is a file
+ * whit a list of strings.
+ *
+ * @author Pasquale Cavallo (pasquale.cavallo at 4science dot it)
+ */
+
+public abstract class AbstractPlainMetadataSource
+ extends AbstractMetadataFieldMapping
+ implements FileSource {
+
+ protected abstract List
+ readData(InputStream fileInpuStream) throws FileSourceException;
+
+
+ private List supportedExtensions;
+
+ /**
+ * Set the file extensions supported by this metadata service
+ *
+ * @param supportedExtensionsthe file extensions (xml,txt,...) supported by this service
+ */
+ public void setSupportedExtensions(List supportedExtensions) {
+ this.supportedExtensions = supportedExtensions;
+ }
+
+ @Override
+ public List getSupportedExtensions() {
+ return supportedExtensions;
+ }
+
+ /**
+ * Return a list of ImportRecord constructed from input file. This list is based on
+ * the results retrieved from the file (InputStream) parsed through abstract method readData
+ *
+ * @param InputStream The inputStream of the file
+ * @return A list of {@link ImportRecord}
+ * @throws FileSourceException if, for any reason, the file is not parsable
+ */
+ @Override
+ public List getRecords(InputStream is) throws FileSourceException {
+ List datas = readData(is);
+ List records = new ArrayList<>();
+ for (PlainMetadataSourceDto item : datas) {
+ records.add(toRecord(item));
+ }
+ return records;
+ }
+
+ /**
+ * Return an ImportRecord constructed from input file. This list is based on
+ * the result retrieved from the file (InputStream) parsed through abstract method
+ * "readData" implementation
+ *
+ * @param InputStream The inputStream of the file
+ * @return An {@link ImportRecord} matching the file content
+ * @throws FileSourceException if, for any reason, the file is not parsable
+ * @throws FileMultipleOccurencesException if the file contains more than one entry
+ */
+ @Override
+ public ImportRecord getRecord(InputStream is) throws FileSourceException, FileMultipleOccurencesException {
+ List datas = readData(is);
+ if (datas == null || datas.isEmpty()) {
+ throw new FileSourceException("File is empty");
+ }
+ if (datas.size() > 1) {
+ throw new FileMultipleOccurencesException("File "
+ + "contains more than one entry (" + datas.size() + " entries");
+ }
+ return toRecord(datas.get(0));
+ }
+
+
+ private ImportRecord toRecord(PlainMetadataSourceDto entry) {
+ List metadata = new ArrayList<>();
+ metadata.addAll(resultToDCValueMapping(entry));
+ return new ImportRecord(metadata);
+ }
+}
diff --git a/dspace-api/src/main/java/org/dspace/importer/external/service/components/FileSource.java b/dspace-api/src/main/java/org/dspace/importer/external/service/components/FileSource.java
new file mode 100644
index 0000000000..febe01ee53
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/importer/external/service/components/FileSource.java
@@ -0,0 +1,70 @@
+/**
+ * The contents of this file are subject to the license and copyright
+ * detailed in the LICENSE and NOTICE files at the root of the source
+ * tree and available online at
+ *
+ * http://www.dspace.org/license/
+ */
+
+package org.dspace.importer.external.service.components;
+
+import java.io.InputStream;
+import java.util.List;
+
+import org.dspace.importer.external.datamodel.ImportRecord;
+import org.dspace.importer.external.exception.FileMultipleOccurencesException;
+import org.dspace.importer.external.exception.FileSourceException;
+
+/**
+ * This interface declare the base methods to work with files containing metadata.
+ *
+ * @author Pasquale Cavallo (pasquale.cavallo at 4science dot it)
+ */
+public interface FileSource extends MetadataSource {
+
+ /**
+ * Return a list of ImportRecord constructed from input file.
+ *
+ * @param InputStream The inputStream of the file
+ * @return A list of {@link ImportRecord}
+ * @throws FileSourceException if, for any reason, the file is not parsable
+ */
+ public List getRecords(InputStream inputStream)
+ throws FileSourceException;
+
+ /**
+ * Return an ImportRecord constructed from input file.
+ *
+ * @param InputStream The inputStream of the file
+ * @return An {@link ImportRecord} matching the file content
+ * @throws FileSourceException if, for any reason, the file is not parsable
+ * @throws FileMultipleOccurencesException if the file contains more than one entry
+ */
+ public ImportRecord getRecord(InputStream inputStream)
+ throws FileSourceException, FileMultipleOccurencesException;
+
+ /**
+ * This method is used to decide if the FileSource manage the file format
+ *
+ * @param originalName the file file original name
+ * @return true if the FileSource can parse the file, false otherwise
+ */
+ public default boolean isValidSourceForFile(String originalName) {
+ List extensions = getSupportedExtensions();
+ if (extensions == null || extensions.isEmpty()) {
+ return false;
+ }
+ if (originalName != null && originalName.contains(".")) {
+ String extension = originalName.substring(originalName.lastIndexOf('.') + 1,
+ originalName.length());
+ return getSupportedExtensions().contains(extension);
+ }
+ return false;
+ }
+
+ /**
+ * Get the file extensions (xml, csv, txt, ...) supported by the FileSource implementation
+ */
+ public List getSupportedExtensions();
+
+}
diff --git a/dspace-api/src/main/java/org/dspace/importer/external/service/components/MetadataSource.java b/dspace-api/src/main/java/org/dspace/importer/external/service/components/MetadataSource.java
index 79bdcfa903..353f77b798 100644
--- a/dspace-api/src/main/java/org/dspace/importer/external/service/components/MetadataSource.java
+++ b/dspace-api/src/main/java/org/dspace/importer/external/service/components/MetadataSource.java
@@ -8,76 +8,14 @@
package org.dspace.importer.external.service.components;
-import java.util.Collection;
-
-import org.dspace.content.Item;
-import org.dspace.importer.external.datamodel.ImportRecord;
-import org.dspace.importer.external.datamodel.Query;
-import org.dspace.importer.external.exception.MetadataSourceException;
-
/**
- * Common interface for all import implementations.
+ * Super interface for all import implementations.
*
* @author Roeland Dillen (roeland at atmire dot com)
+ * @author Pasquale Cavallo (pasquale.cavallo@4science.it)
*/
public interface MetadataSource {
- /**
- * Gets the number of records matching a query
- *
- * @param query the query in string format
- * @return the number of records matching the query
- * @throws MetadataSourceException if the underlying methods throw any exception.
- */
- public int getNbRecords(String query) throws MetadataSourceException;
- /**
- * Gets the number of records matching a query
- *
- * @param query the query object
- * @return the number of records matching the query
- * @throws MetadataSourceException if the underlying methods throw any exception.
- */
- public int getNbRecords(Query query) throws MetadataSourceException;
-
- /**
- * Gets a set of records matching a query. Supports pagination
- *
- * @param query the query. The query will generally be posted 'as is' to the source
- * @param start offset
- * @param count page size
- * @return a collection of fully transformed id's
- * @throws MetadataSourceException if the underlying methods throw any exception.
- */
- public Collection getRecords(String query, int start, int count) throws MetadataSourceException;
-
- /**
- * Find records based on a object query.
- *
- * @param query a query object to base the search on.
- * @return a set of records. Fully transformed.
- * @throws MetadataSourceException if the underlying methods throw any exception.
- */
- public Collection getRecords(Query query) throws MetadataSourceException;
-
- /**
- * Get a single record from the source.
- * The first match will be returned
- *
- * @param id identifier for the record
- * @return a matching record
- * @throws MetadataSourceException if the underlying methods throw any exception.
- */
- public ImportRecord getRecord(String id) throws MetadataSourceException;
-
- /**
- * Get a single record from the source.
- * The first match will be returned
- *
- * @param query a query matching a single record
- * @return a matching record
- * @throws MetadataSourceException if the underlying methods throw any exception.
- */
- public ImportRecord getRecord(Query query) throws MetadataSourceException;
/**
* The string that identifies this import implementation. Preferable a URI
@@ -86,23 +24,4 @@ public interface MetadataSource {
*/
public String getImportSource();
- /**
- * Finds records based on an item
- * Delegates to one or more MetadataSource implementations based on the uri. Results will be aggregated.
- *
- * @param item an item to base the search on
- * @return a collection of import records. Only the identifier of the found records may be put in the record.
- * @throws MetadataSourceException if the underlying methods throw any exception.
- */
- public Collection findMatchingRecords(Item item) throws MetadataSourceException;
-
- /**
- * Finds records based on query object.
- * Delegates to one or more MetadataSource implementations based on the uri. Results will be aggregated.
- *
- * @param query a query object to base the search on.
- * @return a collection of import records. Only the identifier of the found records may be put in the record.
- * @throws MetadataSourceException passed through.
- */
- public Collection findMatchingRecords(Query query) throws MetadataSourceException;
}
diff --git a/dspace-api/src/main/java/org/dspace/importer/external/service/components/QuerySource.java b/dspace-api/src/main/java/org/dspace/importer/external/service/components/QuerySource.java
new file mode 100644
index 0000000000..bcd10cc554
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/importer/external/service/components/QuerySource.java
@@ -0,0 +1,106 @@
+/**
+ * The contents of this file are subject to the license and copyright
+ * detailed in the LICENSE and NOTICE files at the root of the source
+ * tree and available online at
+ *
+ * http://www.dspace.org/license/
+ */
+
+package org.dspace.importer.external.service.components;
+
+import java.util.Collection;
+
+import org.dspace.content.Item;
+import org.dspace.importer.external.datamodel.ImportRecord;
+import org.dspace.importer.external.datamodel.Query;
+import org.dspace.importer.external.exception.MetadataSourceException;
+
+
+/**
+ * Common interface for database-based imports.
+ *
+ * @author Roeland Dillen (roeland at atmire dot com)
+ * @author Pasquale Cavallo (pasquale.cavallo@4science.it)
+ */
+
+public interface QuerySource extends MetadataSource {
+
+ /**
+ * Get a single record from the source.
+ * The first match will be returned
+ *
+ * @param id identifier for the record
+ * @return a matching record
+ * @throws MetadataSourceException if the underlying methods throw any exception.
+ */
+ public ImportRecord getRecord(String id) throws MetadataSourceException;
+
+ /**
+ * Gets the number of records matching a query
+ *
+ * @param query the query in string format
+ * @return the number of records matching the query
+ * @throws MetadataSourceException if the underlying methods throw any exception.
+ */
+ public int getRecordsCount(String query) throws MetadataSourceException;
+
+ /**
+ * Gets the number of records matching a query
+ *
+ * @param query the query object
+ * @return the number of records matching the query
+ * @throws MetadataSourceException if the underlying methods throw any exception.
+ */
+ public int getRecordsCount(Query query) throws MetadataSourceException;
+
+ /**
+ * Gets a set of records matching a query. Supports pagination
+ *
+ * @param query the query. The query will generally be posted 'as is' to the source
+ * @param start offset
+ * @param count page size
+ * @return a collection of fully transformed id's
+ * @throws MetadataSourceException if the underlying methods throw any exception.
+ */
+ public Collection getRecords(String query, int start, int count) throws MetadataSourceException;
+
+ /**
+ * Find records based on a object query.
+ *
+ * @param query a query object to base the search on.
+ * @return a set of records. Fully transformed.
+ * @throws MetadataSourceException if the underlying methods throw any exception.
+ */
+ public Collection getRecords(Query query) throws MetadataSourceException;
+
+ /**
+ * Get a single record from the source.
+ * The first match will be returned
+ *
+ * @param query a query matching a single record
+ * @return a matching record
+ * @throws MetadataSourceException if the underlying methods throw any exception.
+ */
+ public ImportRecord getRecord(Query query) throws MetadataSourceException;
+
+ /**
+ * Finds records based on query object.
+ * Delegates to one or more MetadataSource implementations based on the uri. Results will be aggregated.
+ *
+ * @param query a query object to base the search on.
+ * @return a collection of import records. Only the identifier of the found records may be put in the record.
+ * @throws MetadataSourceException passed through.
+ */
+ public Collection findMatchingRecords(Query query) throws MetadataSourceException;
+
+ /**
+ * Finds records based on an item
+ * Delegates to one or more MetadataSource implementations based on the uri. Results will be aggregated.
+ *
+ * @param item an item to base the search on
+ * @return a collection of import records. Only the identifier of the found records may be put in the record.
+ * @throws MetadataSourceException if the underlying methods throw any exception.
+ */
+ public Collection findMatchingRecords(Item item) throws MetadataSourceException;
+
+}
diff --git a/dspace-api/src/main/java/org/dspace/importer/external/service/components/dto/PlainMetadataKeyValueItem.java b/dspace-api/src/main/java/org/dspace/importer/external/service/components/dto/PlainMetadataKeyValueItem.java
new file mode 100644
index 0000000000..fa362760b9
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/importer/external/service/components/dto/PlainMetadataKeyValueItem.java
@@ -0,0 +1,50 @@
+/**
+ * The contents of this file are subject to the license and copyright
+ * detailed in the LICENSE and NOTICE files at the root of the source
+ * tree and available online at
+ *
+ * http://www.dspace.org/license/
+ */
+package org.dspace.importer.external.service.components.dto;
+
+/**
+ * Simple object to construct items
+ *
+ * @author Pasquale Cavallo (pasquale.cavallo at 4science dot it)
+ */
+public class PlainMetadataKeyValueItem {
+
+ private String key;
+ private String value;
+
+ /*
+ * In a key-value items, like PlainMetadata, this method get the item's key
+ */
+ public String getKey() {
+ return key;
+ }
+
+ /*
+ * In a key-value items, like PlainMetadata, this method set the item's key.
+ * Never set or leave this field to null
+ *
+ */
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ /*
+ * In key-value items, like PlainMetadata, this method get the item's value
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /*
+ * In key-value items, like PlainMetadata, this method set the item's value
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+}
diff --git a/dspace-api/src/main/java/org/dspace/importer/external/service/components/dto/PlainMetadataSourceDto.java b/dspace-api/src/main/java/org/dspace/importer/external/service/components/dto/PlainMetadataSourceDto.java
new file mode 100644
index 0000000000..041823b027
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/importer/external/service/components/dto/PlainMetadataSourceDto.java
@@ -0,0 +1,38 @@
+/**
+ * The contents of this file are subject to the license and copyright
+ * detailed in the LICENSE and NOTICE files at the root of the source
+ * tree and available online at
+ *
+ * http://www.dspace.org/license/
+ */
+package org.dspace.importer.external.service.components.dto;
+
+import java.util.List;
+
+
+/**
+ * Simple object used to construct a list of items.
+ * This type is used in file plain metadata import as RecordType.
+ *
+ * @author Pasquale Cavallo (pasquale.cavallo at 4science dot it)
+ */
+
+public class PlainMetadataSourceDto {
+
+ private List metadata;
+
+ /*
+ * Method used to get the Metadata list
+ */
+ public List getMetadata() {
+ return metadata;
+ }
+
+ /*
+ * Method used to set the metadata list
+ */
+ public void setMetadata(List metadata) {
+ this.metadata = metadata;
+ }
+
+}
diff --git a/dspace-api/src/main/resources/spring/spring-dspace-addon-import-services.xml b/dspace-api/src/main/resources/spring/spring-dspace-addon-import-services.xml
index bbdf085619..c65b004f7e 100644
--- a/dspace-api/src/main/resources/spring/spring-dspace-addon-import-services.xml
+++ b/dspace-api/src/main/resources/spring/spring-dspace-addon-import-services.xml
@@ -21,7 +21,12 @@
-
+
+
+
+
+
+
diff --git a/dspace-api/src/test/data/dspaceFolder/assetstore/curate.txt b/dspace-api/src/test/data/dspaceFolder/assetstore/curate.txt
new file mode 100644
index 0000000000..ff2cb89ef6
--- /dev/null
+++ b/dspace-api/src/test/data/dspaceFolder/assetstore/curate.txt
@@ -0,0 +1,2 @@
+checklinks
+requiredmetadata
diff --git a/dspace-api/src/test/data/dspaceFolder/config/spring/api/scripts.xml b/dspace-api/src/test/data/dspaceFolder/config/spring/api/scripts.xml
index 30fb69a3c4..76cb57a40d 100644
--- a/dspace-api/src/test/data/dspaceFolder/config/spring/api/scripts.xml
+++ b/dspace-api/src/test/data/dspaceFolder/config/spring/api/scripts.xml
@@ -19,6 +19,12 @@
+
+
+
+
+
+
diff --git a/dspace-api/src/test/data/dspaceFolder/config/spring/api/solr-services.xml b/dspace-api/src/test/data/dspaceFolder/config/spring/api/solr-services.xml
index 5ad031b688..80d45bdd58 100644
--- a/dspace-api/src/test/data/dspaceFolder/config/spring/api/solr-services.xml
+++ b/dspace-api/src/test/data/dspaceFolder/config/spring/api/solr-services.xml
@@ -19,19 +19,29 @@
-
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
diff --git a/dspace-api/src/test/data/dspaceFolder/config/submission-forms.xml b/dspace-api/src/test/data/dspaceFolder/config/submission-forms.xml
index 6ddfef9b83..d3d396ffb1 100644
--- a/dspace-api/src/test/data/dspaceFolder/config/submission-forms.xml
+++ b/dspace-api/src/test/data/dspaceFolder/config/submission-forms.xml
@@ -237,7 +237,7 @@ it, please enter the types and the actual numbers or codes.