mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 10:04:21 +00:00
Merge branch 'master' into DS-4266-bitstream-format-crud
This commit is contained in:
@@ -54,10 +54,7 @@ EXPOSE 8080 8009
|
|||||||
|
|
||||||
ENV JAVA_OPTS=-Xmx2000m
|
ENV JAVA_OPTS=-Xmx2000m
|
||||||
|
|
||||||
RUN ln -s $DSPACE_INSTALL/webapps/solr /usr/local/tomcat/webapps/solr && \
|
RUN mv /usr/local/tomcat/webapps/ROOT /usr/local/tomcat/webapps/ROOT.bk && \
|
||||||
|
ln -s $DSPACE_INSTALL/webapps/spring-rest /usr/local/tomcat/webapps/ROOT && \
|
||||||
ln -s $DSPACE_INSTALL/webapps/spring-rest /usr/local/tomcat/webapps/spring-rest && \
|
ln -s $DSPACE_INSTALL/webapps/spring-rest /usr/local/tomcat/webapps/spring-rest && \
|
||||||
ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest && \
|
ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest
|
||||||
ln -s $DSPACE_INSTALL/webapps/oai /usr/local/tomcat/webapps/oai && \
|
|
||||||
ln -s $DSPACE_INSTALL/webapps/rdf /usr/local/tomcat/webapps/rdf && \
|
|
||||||
ln -s $DSPACE_INSTALL/webapps/sword /usr/local/tomcat/webapps/sword && \
|
|
||||||
ln -s $DSPACE_INSTALL/webapps/swordv2 /usr/local/tomcat/webapps/swordv2
|
|
||||||
|
@@ -54,16 +54,11 @@ EXPOSE 8080 8009
|
|||||||
|
|
||||||
ENV JAVA_OPTS=-Xmx2000m
|
ENV JAVA_OPTS=-Xmx2000m
|
||||||
|
|
||||||
RUN ln -s $DSPACE_INSTALL/webapps/solr /usr/local/tomcat/webapps/solr && \
|
RUN mv /usr/local/tomcat/webapps/ROOT /usr/local/tomcat/webapps/ROOT.bk && \
|
||||||
|
ln -s $DSPACE_INSTALL/webapps/spring-rest /usr/local/tomcat/webapps/ROOT && \
|
||||||
ln -s $DSPACE_INSTALL/webapps/spring-rest /usr/local/tomcat/webapps/spring-rest && \
|
ln -s $DSPACE_INSTALL/webapps/spring-rest /usr/local/tomcat/webapps/spring-rest && \
|
||||||
ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest && \
|
ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest
|
||||||
ln -s $DSPACE_INSTALL/webapps/oai /usr/local/tomcat/webapps/oai && \
|
|
||||||
ln -s $DSPACE_INSTALL/webapps/rdf /usr/local/tomcat/webapps/rdf && \
|
|
||||||
ln -s $DSPACE_INSTALL/webapps/sword /usr/local/tomcat/webapps/sword && \
|
|
||||||
ln -s $DSPACE_INSTALL/webapps/swordv2 /usr/local/tomcat/webapps/swordv2
|
|
||||||
|
|
||||||
COPY dspace/src/main/docker/test/solr_web.xml $DSPACE_INSTALL/webapps/solr/WEB-INF/web.xml
|
|
||||||
COPY dspace/src/main/docker/test/rest_web.xml $DSPACE_INSTALL/webapps/rest/WEB-INF/web.xml
|
COPY dspace/src/main/docker/test/rest_web.xml $DSPACE_INSTALL/webapps/rest/WEB-INF/web.xml
|
||||||
|
|
||||||
RUN sed -i -e "s|\${dspace.dir}|$DSPACE_INSTALL|" $DSPACE_INSTALL/webapps/solr/WEB-INF/web.xml && \
|
RUN sed -i -e "s|\${dspace.dir}|$DSPACE_INSTALL|" $DSPACE_INSTALL/webapps/rest/WEB-INF/web.xml
|
||||||
sed -i -e "s|\${dspace.dir}|$DSPACE_INSTALL|" $DSPACE_INSTALL/webapps/rest/WEB-INF/web.xml
|
|
||||||
|
@@ -78,7 +78,7 @@ public class RequestItem implements ReloadableEntity<Integer> {
|
|||||||
private Date request_date = null;
|
private Date request_date = null;
|
||||||
|
|
||||||
@Column(name = "accept_request")
|
@Column(name = "accept_request")
|
||||||
private Boolean accept_request = null;
|
private boolean accept_request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protected constructor, create object using:
|
* Protected constructor, create object using:
|
||||||
@@ -88,6 +88,7 @@ public class RequestItem implements ReloadableEntity<Integer> {
|
|||||||
protected RequestItem() {
|
protected RequestItem() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Integer getID() {
|
public Integer getID() {
|
||||||
return requestitem_id;
|
return requestitem_id;
|
||||||
}
|
}
|
||||||
|
@@ -8,10 +8,17 @@
|
|||||||
package org.dspace.storage.rdbms;
|
package org.dspace.storage.rdbms;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.transform.TransformerException;
|
||||||
|
|
||||||
import org.dspace.administer.MetadataImporter;
|
import org.dspace.administer.MetadataImporter;
|
||||||
|
import org.dspace.administer.RegistryImportException;
|
||||||
import org.dspace.administer.RegistryLoader;
|
import org.dspace.administer.RegistryLoader;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.NonUniqueMetadataException;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.services.ConfigurationService;
|
import org.dspace.services.ConfigurationService;
|
||||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
@@ -21,6 +28,7 @@ import org.flywaydb.core.api.MigrationInfo;
|
|||||||
import org.flywaydb.core.api.callback.FlywayCallback;
|
import org.flywaydb.core.api.callback.FlywayCallback;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a FlywayCallback class which automatically updates the
|
* This is a FlywayCallback class which automatically updates the
|
||||||
@@ -49,7 +57,7 @@ public class DatabaseRegistryUpdater implements FlywayCallback {
|
|||||||
private static final Logger log = LoggerFactory.getLogger(DatabaseRegistryUpdater.class);
|
private static final Logger log = LoggerFactory.getLogger(DatabaseRegistryUpdater.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to actually update our registries from latest configs
|
* Method to actually update our registries from latest configuration files.
|
||||||
*/
|
*/
|
||||||
private void updateRegistries() {
|
private void updateRegistries() {
|
||||||
ConfigurationService config = DSpaceServicesFactory.getInstance().getConfigurationService();
|
ConfigurationService config = DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||||
@@ -63,35 +71,32 @@ public class DatabaseRegistryUpdater implements FlywayCallback {
|
|||||||
+ "registries" + File.separator;
|
+ "registries" + File.separator;
|
||||||
|
|
||||||
// Load updates to Bitstream format registry (if any)
|
// Load updates to Bitstream format registry (if any)
|
||||||
log.info("Updating Bitstream Format Registry based on " + base + "bitstream-formats.xml");
|
log.info("Updating Bitstream Format Registry based on {}bitstream-formats.xml", base);
|
||||||
RegistryLoader.loadBitstreamFormats(context, base + "bitstream-formats.xml");
|
RegistryLoader.loadBitstreamFormats(context, base + "bitstream-formats.xml");
|
||||||
|
|
||||||
// Load updates to Metadata schema registries (if any)
|
// Load updates to Metadata schema registries (if any)
|
||||||
log.info("Updating Metadata Registries based on metadata type configs in " + base);
|
log.info("Updating Metadata Registries based on metadata type configs in {}", base);
|
||||||
MetadataImporter.loadRegistry(base + "dublin-core-types.xml", true);
|
for (String namespaceFile: config.getArrayProperty("registry.metadata.load")) {
|
||||||
MetadataImporter.loadRegistry(base + "dcterms-types.xml", true);
|
log.info("Reading {}", namespaceFile);
|
||||||
MetadataImporter.loadRegistry(base + "local-types.xml", true);
|
MetadataImporter.loadRegistry(base + namespaceFile, true);
|
||||||
MetadataImporter.loadRegistry(base + "relationship-formats.xml", true);
|
}
|
||||||
MetadataImporter.loadRegistry(base + "person-types.xml", true);
|
|
||||||
MetadataImporter.loadRegistry(base + "project-types.xml", true);
|
|
||||||
MetadataImporter.loadRegistry(base + "orgunit-types.xml", true);
|
|
||||||
MetadataImporter.loadRegistry(base + "journal-types.xml", true);
|
|
||||||
MetadataImporter.loadRegistry(base + "journalissue-types.xml", true);
|
|
||||||
MetadataImporter.loadRegistry(base + "journalvolume-types.xml", true);
|
|
||||||
MetadataImporter.loadRegistry(base + "eperson-types.xml", true);
|
|
||||||
MetadataImporter.loadRegistry(base + "sword-metadata.xml", true);
|
|
||||||
|
|
||||||
// Check if XML Workflow is enabled in workflow.cfg
|
// Check if XML Workflow is enabled in workflow.cfg
|
||||||
if (WorkflowServiceFactory.getInstance().getWorkflowService() instanceof XmlWorkflowService) {
|
if (WorkflowServiceFactory.getInstance().getWorkflowService() instanceof XmlWorkflowService) {
|
||||||
// If so, load in the workflow metadata types as well
|
// If so, load in the workflow metadata types as well
|
||||||
MetadataImporter.loadRegistry(base + "workflow-types.xml", true);
|
String workflowTypes = "workflow-types.xml";
|
||||||
|
log.info("Reading {}", workflowTypes);
|
||||||
|
MetadataImporter.loadRegistry(base + workflowTypes, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.restoreAuthSystemState();
|
context.restoreAuthSystemState();
|
||||||
// Commit changes and close context
|
// Commit changes and close context
|
||||||
context.complete();
|
context.complete();
|
||||||
log.info("All Bitstream Format Regitry and Metadata Registry updates were completed.");
|
log.info("All Bitstream Format Regitry and Metadata Registry updates were completed.");
|
||||||
} catch (Exception e) {
|
} catch (IOException | SQLException | ParserConfigurationException
|
||||||
|
| TransformerException | RegistryImportException
|
||||||
|
| AuthorizeException | NonUniqueMetadataException
|
||||||
|
| SAXException e) {
|
||||||
log.error("Error attempting to update Bitstream Format and/or Metadata Registries", e);
|
log.error("Error attempting to update Bitstream Format and/or Metadata Registries", e);
|
||||||
throw new RuntimeException("Error attempting to update Bitstream Format and/or Metadata Registries", e);
|
throw new RuntimeException("Error attempting to update Bitstream Format and/or Metadata Registries", e);
|
||||||
} finally {
|
} finally {
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>dspace-oai</artifactId>
|
<artifactId>dspace-oai</artifactId>
|
||||||
<packaging>war</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>DSpace OAI-PMH</name>
|
<name>DSpace OAI-PMH</name>
|
||||||
<description>DSpace OAI-PMH Web Application and API</description>
|
<description>DSpace OAI-PMH Extension</description>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>dspace-parent</artifactId>
|
<artifactId>dspace-parent</artifactId>
|
||||||
@@ -16,34 +16,19 @@
|
|||||||
<!-- This is the path to the root [dspace-src] directory. -->
|
<!-- This is the path to the root [dspace-src] directory. -->
|
||||||
<root.basedir>${basedir}/..</root.basedir>
|
<root.basedir>${basedir}/..</root.basedir>
|
||||||
<xoai.version>3.2.10</xoai.version>
|
<xoai.version>3.2.10</xoai.version>
|
||||||
<jtwig.version>2.0.1</jtwig.version>
|
<!-- NOTE: Once updated to Spring Boot v2, this should update to 5.87.0.RELEASE -->
|
||||||
|
<jtwig.version>5.86.1.RELEASE</jtwig.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<attachClasses>true</attachClasses>
|
|
||||||
<!-- In version 2.1-alpha-1, this was incorrectly named warSourceExcludes -->
|
|
||||||
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
|
|
||||||
<warSourceExcludes>WEB-INF/lib/*.jar</warSourceExcludes>
|
|
||||||
<!-- Filter the web.xml (needed for IDE compatibility/debugging) -->
|
|
||||||
<filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.mycila</groupId>
|
<groupId>com.mycila</groupId>
|
||||||
<artifactId>license-maven-plugin</artifactId>
|
<artifactId>license-maven-plugin</artifactId>
|
||||||
<configuration>
|
<configuration>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>src/main/webapp/**</exclude>
|
<!-- Ignore license header requirements on CSS/images/HTML/XSL -->
|
||||||
|
<exclude>src/main/resources/**</exclude>
|
||||||
<exclude>**/*.xsl</exclude>
|
<exclude>**/*.xsl</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -106,74 +91,63 @@
|
|||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>log4j</groupId>
|
<groupId>log4j</groupId>
|
||||||
<artifactId>log4j</artifactId>
|
<artifactId>log4j</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-log4j12</artifactId>
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
|
<!-- Later version provided by SolrJ -->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.codehaus.woodstox</groupId>
|
||||||
|
<artifactId>wstx-asl</artifactId>
|
||||||
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Java Injection and MVC -->
|
<!-- Java Injection -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.inject</groupId>
|
<groupId>javax.inject</groupId>
|
||||||
<artifactId>javax.inject</artifactId>
|
<artifactId>javax.inject</artifactId>
|
||||||
<version>1</version>
|
<version>1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Needed to support Spring @Configuration classes (to register servlets/beans with Spring Boot webapp) -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-webmvc</artifactId>
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
<version>${spring.version}</version>
|
<version>${spring-boot.version}</version>
|
||||||
</dependency>
|
<exclusions>
|
||||||
<dependency>
|
<exclusion>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-beans</artifactId>
|
<artifactId>spring-boot-starter-logging</artifactId>
|
||||||
<version>${spring.version}</version>
|
</exclusion>
|
||||||
</dependency>
|
</exclusions>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-context</artifactId>
|
|
||||||
<version>${spring.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-web</artifactId>
|
|
||||||
<version>${spring.version}</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Templating Engine -->
|
<!-- Templating Engine -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.lyncode</groupId>
|
<groupId>org.jtwig</groupId>
|
||||||
<artifactId>jtwig-spring</artifactId>
|
<artifactId>jtwig-spring-boot-starter</artifactId>
|
||||||
<version>${jtwig.version}</version>
|
<version>${jtwig.version}</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
|
<!-- We don't need spring-boot-starter-web, it is provided by our Spring Boot webapp -->
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
|
<!-- More recent version is pulled in via solr-core -->
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>org.javassist</groupId>
|
<groupId>org.ow2.asm</groupId>
|
||||||
<artifactId>javassist</artifactId>
|
<artifactId>asm</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
|
<!-- This exclusion may be removable once we update to Spring Boot v2 -->
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
<exclusion>
|
|
||||||
<groupId>javax.servlet</groupId>
|
|
||||||
<artifactId>servlet-api</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>log4j</groupId>
|
|
||||||
<artifactId>log4j</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-log4j12</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -283,7 +257,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.parboiled</groupId>
|
<groupId>org.parboiled</groupId>
|
||||||
<artifactId>parboiled-core</artifactId>
|
<artifactId>parboiled-core</artifactId>
|
||||||
<version>1.1.6</version>
|
<version>1.1.7</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -293,24 +267,4 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<developers>
|
|
||||||
<developer>
|
|
||||||
<name>DSpace @ Lyncode</name>
|
|
||||||
<email>dspace@lyncode.com</email>
|
|
||||||
<organization>Lyncode</organization>
|
|
||||||
<organizationUrl>http://www.lyncode.com</organizationUrl>
|
|
||||||
</developer>
|
|
||||||
<developer>
|
|
||||||
<id>helix84</id>
|
|
||||||
<name>Ivan Másar</name>
|
|
||||||
<email>helix84@centrum.sk</email>
|
|
||||||
</developer>
|
|
||||||
<developer>
|
|
||||||
<name>Ariel J. Lira</name>
|
|
||||||
<email>arieljlira@gmail.com</email>
|
|
||||||
<organization>SeDiCI</organization>
|
|
||||||
<organizationUrl>http://sedici.unlp.edu.ar</organizationUrl>
|
|
||||||
</developer>
|
|
||||||
</developers>
|
|
||||||
</project>
|
</project>
|
||||||
|
@@ -0,0 +1,75 @@
|
|||||||
|
/**
|
||||||
|
* 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.configuration;
|
||||||
|
import static java.lang.Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
import org.dspace.xoai.app.BasicConfiguration;
|
||||||
|
import org.dspace.xoai.services.api.xoai.ItemRepositoryResolver;
|
||||||
|
import org.dspace.xoai.services.impl.xoai.DSpaceItemRepositoryResolver;
|
||||||
|
import org.jtwig.spring.JtwigViewResolver;
|
||||||
|
import org.jtwig.spring.boot.config.JtwigViewResolverConfigurer;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OAI-PMH webapp configuration. Replaces the old web.xml
|
||||||
|
* <p>
|
||||||
|
* This @Configuration class is automatically discovered by Spring Boot via a @ComponentScan
|
||||||
|
* on the org.dspace.app.configuration package.
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Tim Donohue
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
// Import additional configuration and beans from BasicConfiguration
|
||||||
|
@Import(BasicConfiguration.class)
|
||||||
|
// Scan for controllers in this package
|
||||||
|
@ComponentScan("org.dspace.xoai.controller")
|
||||||
|
public class OAIWebConfig extends WebMvcConfigurerAdapter implements JtwigViewResolverConfigurer {
|
||||||
|
|
||||||
|
// Path where OAI is deployed. Defaults to "oai"
|
||||||
|
// NOTE: deployment on this path is handled by org.dspace.xoai.controller.DSpaceOAIDataProvider
|
||||||
|
@Value("${oai.path:oai}")
|
||||||
|
private String oaiPath;
|
||||||
|
|
||||||
|
private static final String TWIG_HTML_EXTENSION = ".twig.html";
|
||||||
|
private static final String VIEWS_LOCATION = "classpath:/templates/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure all resources under src/main/resources/static/ directory are available
|
||||||
|
* off the /{oai.path}/static subpath
|
||||||
|
**/
|
||||||
|
@Override
|
||||||
|
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||||
|
registry.addResourceHandler("/" + oaiPath + "/static/**")
|
||||||
|
.addResourceLocations("classpath:/static/")
|
||||||
|
.setCachePeriod(MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the Jtwig template engine for Spring Boot
|
||||||
|
* Ensures Jtwig looks for templates in proper location with proper extension
|
||||||
|
**/
|
||||||
|
@Override
|
||||||
|
public void configure(JtwigViewResolver viewResolver) {
|
||||||
|
viewResolver.setPrefix(VIEWS_LOCATION);
|
||||||
|
viewResolver.setSuffix(TWIG_HTML_EXTENSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ItemRepositoryResolver xoaiItemRepositoryResolver() {
|
||||||
|
return new DSpaceItemRepositoryResolver();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -1,62 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.xoai.app;
|
|
||||||
|
|
||||||
import static java.lang.Integer.MAX_VALUE;
|
|
||||||
|
|
||||||
import com.lyncode.jtwig.mvc.JtwigViewResolver;
|
|
||||||
import org.dspace.xoai.services.api.xoai.ItemRepositoryResolver;
|
|
||||||
import org.dspace.xoai.services.impl.xoai.DSpaceItemRepositoryResolver;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
import org.springframework.web.servlet.ViewResolver;
|
|
||||||
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
|
|
||||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
|
||||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
|
||||||
|
|
||||||
@Import( {
|
|
||||||
BasicConfiguration.class
|
|
||||||
})
|
|
||||||
@Configuration
|
|
||||||
@EnableWebMvc
|
|
||||||
@ComponentScan("org.dspace.xoai.controller")
|
|
||||||
public class DSpaceWebappConfiguration extends WebMvcConfigurerAdapter {
|
|
||||||
private static final String TWIG_HTML_EXTENSION = ".twig.html";
|
|
||||||
private static final String VIEWS_LOCATION = "/WEB-INF/views/";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
|
||||||
registry.addResourceHandler("/static/**")
|
|
||||||
.addResourceLocations("/static/")
|
|
||||||
.setCachePeriod(MAX_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
|
|
||||||
configurer.enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ViewResolver viewResolver() {
|
|
||||||
JtwigViewResolver viewResolver = new JtwigViewResolver();
|
|
||||||
viewResolver.setPrefix(VIEWS_LOCATION);
|
|
||||||
viewResolver.setSuffix(TWIG_HTML_EXTENSION);
|
|
||||||
viewResolver.setCached(false);
|
|
||||||
|
|
||||||
return viewResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ItemRepositoryResolver xoaiItemRepositoryResolver() {
|
|
||||||
return new DSpaceItemRepositoryResolver();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -40,6 +40,7 @@ import org.dspace.xoai.services.api.xoai.ItemRepositoryResolver;
|
|||||||
import org.dspace.xoai.services.api.xoai.SetRepositoryResolver;
|
import org.dspace.xoai.services.api.xoai.SetRepositoryResolver;
|
||||||
import org.dspace.xoai.services.impl.xoai.DSpaceResumptionTokenFormatter;
|
import org.dspace.xoai.services.impl.xoai.DSpaceResumptionTokenFormatter;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
@@ -49,6 +50,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
* @author Lyncode Development Team (dspace at lyncode dot com)
|
* @author Lyncode Development Team (dspace at lyncode dot com)
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
|
// Use the configured "oai.path" for all requests, or "/oai" by default
|
||||||
|
@RequestMapping("/${oai.path:oai}")
|
||||||
|
// Only enable this controller if "oai.enabled=true"
|
||||||
|
@ConditionalOnProperty("oai.enabled")
|
||||||
public class DSpaceOAIDataProvider {
|
public class DSpaceOAIDataProvider {
|
||||||
private static final Logger log = getLogger(DSpaceOAIDataProvider.class);
|
private static final Logger log = getLogger(DSpaceOAIDataProvider.class);
|
||||||
|
|
||||||
@@ -67,7 +72,7 @@ public class DSpaceOAIDataProvider {
|
|||||||
|
|
||||||
private DSpaceResumptionTokenFormatter resumptionTokenFormat = new DSpaceResumptionTokenFormatter();
|
private DSpaceResumptionTokenFormatter resumptionTokenFormat = new DSpaceResumptionTokenFormatter();
|
||||||
|
|
||||||
@RequestMapping("/")
|
@RequestMapping({"", "/"})
|
||||||
public String indexAction(HttpServletResponse response, Model model) throws ServletException {
|
public String indexAction(HttpServletResponse response, Model model) throws ServletException {
|
||||||
try {
|
try {
|
||||||
XOAIManager manager = xoaiManagerResolver.getManager();
|
XOAIManager manager = xoaiManagerResolver.getManager();
|
||||||
|
@@ -10,6 +10,8 @@ package org.dspace.xoai.services.impl;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.persistence.NoResultException;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
@@ -30,11 +32,16 @@ public class DSpaceEarliestDateResolver implements EarliestDateResolver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Date getEarliestDate(Context context) throws InvalidMetadataFieldException, SQLException {
|
public Date getEarliestDate(Context context) throws InvalidMetadataFieldException, SQLException {
|
||||||
String query = "SELECT MIN(text_value) as value FROM metadatavalue WHERE metadata_field_id = ?";
|
|
||||||
|
|
||||||
MetadataValueService metadataValueService = ContentServiceFactory.getInstance().getMetadataValueService();
|
MetadataValueService metadataValueService = ContentServiceFactory.getInstance().getMetadataValueService();
|
||||||
MetadataValue minimum = metadataValueService.getMinimum(context,
|
MetadataValue minimum = null;
|
||||||
fieldResolver.getFieldID(context, "dc.date.available"));
|
try {
|
||||||
|
minimum = metadataValueService.getMinimum(context,
|
||||||
|
fieldResolver.getFieldID(context, "dc.date.available"));
|
||||||
|
} catch (NoResultException e) {
|
||||||
|
// This error only occurs if no metadataFields of this type exist (i.e. no minimum exists)
|
||||||
|
// It can be safely ignored in this scenario, as it implies the DSpace is empty.
|
||||||
|
}
|
||||||
|
|
||||||
if (null != minimum) {
|
if (null != minimum) {
|
||||||
String str = minimum.getValue();
|
String str = minimum.getValue();
|
||||||
try {
|
try {
|
||||||
|
@@ -27,6 +27,8 @@ import org.dspace.xoai.services.api.EarliestDateResolver;
|
|||||||
import org.dspace.xoai.services.api.config.ConfigurationService;
|
import org.dspace.xoai.services.api.config.ConfigurationService;
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
|
||||||
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Lyncode Development Team (dspace at lyncode dot com)
|
* @author Lyncode Development Team (dspace at lyncode dot com)
|
||||||
@@ -68,17 +70,27 @@ public class DSpaceRepositoryConfiguration implements RepositoryConfiguration {
|
|||||||
public String getBaseUrl() {
|
public String getBaseUrl() {
|
||||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
|
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
|
||||||
.getRequest();
|
.getRequest();
|
||||||
|
|
||||||
|
// Parse the current OAI "context" path out of the last HTTP request.
|
||||||
|
// (e.g. for "http://mydspace.edu/oai/request", the oaiContextPath is "request")
|
||||||
|
UriComponentsBuilder builder = ServletUriComponentsBuilder.fromRequest(request);
|
||||||
|
List<String> pathSegments = builder.buildAndExpand().getPathSegments();
|
||||||
|
String oaiContextPath = pathSegments.get(pathSegments.size() - 1);
|
||||||
|
|
||||||
if (baseUrl == null) {
|
if (baseUrl == null) {
|
||||||
baseUrl = configurationService.getProperty("oai.url");
|
baseUrl = configurationService.getProperty("oai.url");
|
||||||
if (baseUrl == null) {
|
if (baseUrl == null) {
|
||||||
log.warn(
|
log.warn(
|
||||||
"{ OAI 2.0 :: DSpace } Not able to retrieve the oai.url property from oai.cfg. Falling back to " +
|
"{ OAI 2.0 :: DSpace } Not able to retrieve the oai.url property from oai.cfg. Falling back to " +
|
||||||
"request address");
|
"request address");
|
||||||
|
// initialize baseUrl to a fallback "oai.url" which is the current request with OAI context removed.
|
||||||
baseUrl = request.getRequestURL().toString()
|
baseUrl = request.getRequestURL().toString()
|
||||||
.replace(request.getPathInfo(), "");
|
.replace(oaiContextPath, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return baseUrl + request.getPathInfo();
|
|
||||||
|
// BaseURL is the path of OAI with the current OAI context appended
|
||||||
|
return baseUrl + "/" + oaiContextPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
@@ -6,6 +6,12 @@
|
|||||||
|
|
||||||
http://www.dspace.org/license/
|
http://www.dspace.org/license/
|
||||||
|
|
||||||
|
#}
|
||||||
|
{#
|
||||||
|
|
||||||
|
DSpace OAI default index template. To override this template, place a customized version in
|
||||||
|
the [webapp]/WEB-INF/classes/templates/ folder, and reboot your servlet engine.
|
||||||
|
|
||||||
#}
|
#}
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||||
<html>
|
<html>
|
||||||
@@ -13,8 +19,8 @@
|
|||||||
<title>DSpace OAI-PMH Data Provider</title>
|
<title>DSpace OAI-PMH Data Provider</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
<script src="{{ path 'static/js/jquery.js' }}" type="text/javascript"></script>
|
<script src="static/js/jquery.js" type="text/javascript"></script>
|
||||||
<script src="{{ path 'static/js/bootstrap.min.js' }}" type="text/javascript"></script>
|
<script src="static/js/bootstrap.min.js" type="text/javascript"></script>
|
||||||
|
|
||||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||||
@@ -24,9 +30,9 @@
|
|||||||
<![endif]-->
|
<![endif]-->
|
||||||
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="{{ path 'static/css/bootstrap.min.css' }}" type="text/css" />
|
<link rel="stylesheet" href="static/css/bootstrap.min.css" type="text/css" />
|
||||||
<link rel="stylesheet" href="{{ path 'static/css/bootstrap-theme.min.css' }}" type="text/css" />
|
<link rel="stylesheet" href="static/css/bootstrap-theme.min.css" type="text/css" />
|
||||||
<link rel="stylesheet" href="{{ path 'static/css/style.css' }}" type="text/css" />
|
<link rel="stylesheet" href="static/css/style.css" type="text/css" />
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -56,11 +62,11 @@
|
|||||||
<p class="vertical-space"></p>
|
<p class="vertical-space"></p>
|
||||||
<p class="list-group-item-text">
|
<p class="list-group-item-text">
|
||||||
<div class="btn-group btn-group-justified">
|
<div class="btn-group btn-group-justified">
|
||||||
<a class="btn btn-default" href="{{ concat('/', item.baseUrl) | path }}?verb=Identify">Identify</a>
|
<a class="btn btn-default" href="{{ item.baseUrl }}?verb=Identify">Identify</a>
|
||||||
<a class="btn btn-default" href="{{ concat('/', item.baseUrl) | path }}?verb=ListSets">List Sets</a>
|
<a class="btn btn-default" href="{{ item.baseUrl }}?verb=ListSets">List Sets</a>
|
||||||
<a class="btn btn-default" href="{{ concat('/', item.baseUrl) | path }}?verb=ListMetadataFormats">List Metadata Formats</a>
|
<a class="btn btn-default" href="{{ item.baseUrl }}?verb=ListMetadataFormats">List Metadata Formats</a>
|
||||||
<a class="btn btn-default" href="{{ concat('/', item.baseUrl) | path }}?verb=ListIdentifiers&metadataPrefix=oai_dc">List Identifiers</a>
|
<a class="btn btn-default" href="{{ item.baseUrl }}?verb=ListIdentifiers&metadataPrefix=oai_dc">List Identifiers</a>
|
||||||
<a class="btn btn-default" href="{{ concat('/', item.baseUrl) | path }}?verb=ListRecords&metadataPrefix=oai_dc">List Records</a>
|
<a class="btn btn-default" href="{{ item.baseUrl }}?verb=ListRecords&metadataPrefix=oai_dc">List Records</a>
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -73,11 +79,11 @@
|
|||||||
<p><small>Design by Lyncode</small></p>
|
<p><small>Design by Lyncode</small></p>
|
||||||
<p>
|
<p>
|
||||||
<a href="http://www.lyncode.com">
|
<a href="http://www.lyncode.com">
|
||||||
<img style="height: 20px;" src="{{ path '/static/img/lyncode.png' }}" alt="Lyncode" />
|
<img style="height: 20px;" src="static/img/lyncode.png" alt="Lyncode" />
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div> <!-- /container -->
|
</div> <!-- /container -->
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@@ -1,60 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
|
|
||||||
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/
|
|
||||||
|
|
||||||
-->
|
|
||||||
<beans
|
|
||||||
xmlns="http://www.springframework.org/schema/beans"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
|
|
||||||
|
|
||||||
<!-- Acquires the DSpace Utility Class with initialized Service Manager -->
|
|
||||||
<bean id="dspace" class="org.dspace.utils.DSpace"/>
|
|
||||||
|
|
||||||
<!-- Acquires reference to EventService -->
|
|
||||||
<bean id="dspace.eventService" factory-bean="dspace" factory-method="getEventService"/>
|
|
||||||
|
|
||||||
<!-- Inject the Default LoggerUsageEventListener into the EventService -->
|
|
||||||
<bean class="org.dspace.usage.LoggerUsageEventListener">
|
|
||||||
<property name="eventService">
|
|
||||||
<ref bean="dspace.eventService"/>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- Inject the SolrLoggerUsageEventListener into the EventService -->
|
|
||||||
<bean class="org.dspace.statistics.SolrLoggerUsageEventListener">
|
|
||||||
<property name="eventService">
|
|
||||||
<ref bean="dspace.eventService"/>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- Google Analytics recording -->
|
|
||||||
<bean class="org.dspace.google.GoogleRecorderEventListener">
|
|
||||||
<property name="eventService">
|
|
||||||
<ref bean="dspace.eventService"/>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- TabFileUsageEventListener -->
|
|
||||||
<!-- Uncomment to enable
|
|
||||||
<bean class="org.dspace.usage.TabFileUsageEventListener">
|
|
||||||
<property name="eventService" >
|
|
||||||
<ref bean="dspace.eventService"/>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Uncomment to enable PassiveUsageEventListener
|
|
||||||
<bean class="org.dspace.app.statistics.PassiveUsageEventListener">
|
|
||||||
<property name="eventService" >
|
|
||||||
<ref bean="dspace.eventService"/>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
-->
|
|
||||||
</beans>
|
|
@@ -1,83 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<!--
|
|
||||||
|
|
||||||
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/
|
|
||||||
|
|
||||||
-->
|
|
||||||
<web-app id="DSpace-OAI" version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
|
|
||||||
|
|
||||||
<display-name>XOAI Data Provider</display-name>
|
|
||||||
|
|
||||||
<context-param>
|
|
||||||
<description>The location of the DSpace home directory</description>
|
|
||||||
<param-name>dspace.dir</param-name>
|
|
||||||
<param-value>${dspace.dir}</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<context-param>
|
|
||||||
<param-name>log4jConfiguration</param-name>
|
|
||||||
<param-value>${dspace.dir}/config/log4j2.xml</param-value>
|
|
||||||
<description>The location of the Log4J configuration</description>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<!-- Location of root application context configs (to be loaded by ContextLoaderListener below) -->
|
|
||||||
<!-- This contains the beans that initialize DSpace Services -->
|
|
||||||
<context-param>
|
|
||||||
<param-name>contextConfigLocation</param-name>
|
|
||||||
<param-value>/WEB-INF/spring/*.xml</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<!-- Initializes the DSpace Context object -->
|
|
||||||
<listener>
|
|
||||||
<listener-class>org.dspace.app.util.DSpaceContextListener</listener-class>
|
|
||||||
</listener>
|
|
||||||
|
|
||||||
<!-- Initializes the DSpace Kernel -->
|
|
||||||
<listener>
|
|
||||||
<listener-class>
|
|
||||||
org.dspace.servicemanager.servlet.DSpaceKernelServletContextListener
|
|
||||||
</listener-class>
|
|
||||||
</listener>
|
|
||||||
|
|
||||||
<!-- Registers this DSpace webapp as "running" -->
|
|
||||||
<listener>
|
|
||||||
<listener-class>org.dspace.app.util.DSpaceWebappListener</listener-class>
|
|
||||||
</listener>
|
|
||||||
|
|
||||||
<!-- Load the root application context / beans (defined in contextConfigLocation above) -->
|
|
||||||
<listener>
|
|
||||||
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
|
|
||||||
</listener>
|
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>oai</servlet-name>
|
|
||||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
|
||||||
<!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext
|
|
||||||
instead of the default XmlWebApplicationContext -->
|
|
||||||
<init-param>
|
|
||||||
<param-name>contextClass</param-name>
|
|
||||||
<param-value>
|
|
||||||
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
|
|
||||||
</param-value>
|
|
||||||
</init-param>
|
|
||||||
<!-- @Configuration class which defines our servlet context config -->
|
|
||||||
<!-- This defines beans that are specific to OAI webapp -->
|
|
||||||
<init-param>
|
|
||||||
<param-name>contextConfigLocation</param-name>
|
|
||||||
<param-value>org.dspace.xoai.app.DSpaceWebappConfiguration</param-value>
|
|
||||||
</init-param>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<!-- Load the oai servlet for all paths -->
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>oai</servlet-name>
|
|
||||||
<url-pattern>/*</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
</web-app>
|
|
@@ -10,11 +10,9 @@ package org.dspace.xoai.tests;
|
|||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
import org.dspace.xoai.services.api.FieldResolver;
|
import org.dspace.xoai.services.api.FieldResolver;
|
||||||
import org.dspace.xoai.services.api.config.ConfigurationService;
|
|
||||||
import org.dspace.xoai.services.api.context.ContextService;
|
import org.dspace.xoai.services.api.context.ContextService;
|
||||||
import org.dspace.xoai.services.api.xoai.DSpaceFilterResolver;
|
import org.dspace.xoai.services.api.xoai.DSpaceFilterResolver;
|
||||||
import org.dspace.xoai.services.impl.xoai.BaseDSpaceFilterResolver;
|
import org.dspace.xoai.services.impl.xoai.BaseDSpaceFilterResolver;
|
||||||
import org.dspace.xoai.tests.helpers.stubs.StubbedConfigurationService;
|
|
||||||
import org.dspace.xoai.tests.helpers.stubs.StubbedFieldResolver;
|
import org.dspace.xoai.tests.helpers.stubs.StubbedFieldResolver;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -29,14 +27,6 @@ public class DSpaceBasicTestConfiguration {
|
|||||||
return new BaseDSpaceFilterResolver();
|
return new BaseDSpaceFilterResolver();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private StubbedConfigurationService configurationService = new StubbedConfigurationService();
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ConfigurationService configurationService() {
|
|
||||||
return configurationService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public ContextService contextService() {
|
public ContextService contextService() {
|
||||||
return mock(ContextService.class);
|
return mock(ContextService.class);
|
||||||
|
@@ -1,123 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.xoai.tests;
|
|
||||||
|
|
||||||
import com.lyncode.xoai.dataprovider.services.api.ItemRepository;
|
|
||||||
import com.lyncode.xoai.dataprovider.services.api.ResourceResolver;
|
|
||||||
import com.lyncode.xoai.dataprovider.services.api.SetRepository;
|
|
||||||
import org.dspace.core.Context;
|
|
||||||
import org.dspace.xoai.services.api.EarliestDateResolver;
|
|
||||||
import org.dspace.xoai.services.api.cache.XOAICacheService;
|
|
||||||
import org.dspace.xoai.services.api.config.XOAIManagerResolver;
|
|
||||||
import org.dspace.xoai.services.api.context.ContextService;
|
|
||||||
import org.dspace.xoai.services.api.context.ContextServiceException;
|
|
||||||
import org.dspace.xoai.services.api.xoai.IdentifyResolver;
|
|
||||||
import org.dspace.xoai.services.api.xoai.ItemRepositoryResolver;
|
|
||||||
import org.dspace.xoai.services.api.xoai.SetRepositoryResolver;
|
|
||||||
import org.dspace.xoai.services.impl.cache.DSpaceEmptyCacheService;
|
|
||||||
import org.dspace.xoai.services.impl.xoai.DSpaceIdentifyResolver;
|
|
||||||
import org.dspace.xoai.tests.helpers.stubs.StubbedEarliestDateResolver;
|
|
||||||
import org.dspace.xoai.tests.helpers.stubs.StubbedResourceResolver;
|
|
||||||
import org.dspace.xoai.tests.helpers.stubs.StubbedSetRepository;
|
|
||||||
import org.dspace.xoai.tests.helpers.stubs.StubbedXOAIManagerResolver;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
import org.springframework.web.servlet.ViewResolver;
|
|
||||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
|
||||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
|
||||||
|
|
||||||
@Import(DSpaceBasicTestConfiguration.class)
|
|
||||||
@Configuration
|
|
||||||
@EnableWebMvc
|
|
||||||
public class DSpaceTestConfiguration extends WebMvcConfigurerAdapter {
|
|
||||||
private static final String TWIG_HTML_EXTENSION = ".twig.html";
|
|
||||||
private static final String VIEWS_LOCATION = "/WEB-INF/views/";
|
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ContextService contextService() {
|
|
||||||
return new ContextService() {
|
|
||||||
@Override
|
|
||||||
public Context getContext() throws ContextServiceException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private StubbedResourceResolver resourceResolver = new StubbedResourceResolver();
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ResourceResolver resourceResolver() {
|
|
||||||
return resourceResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ViewResolver viewResolver() {
|
|
||||||
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
|
|
||||||
viewResolver.setPrefix(VIEWS_LOCATION);
|
|
||||||
viewResolver.setSuffix(TWIG_HTML_EXTENSION);
|
|
||||||
// viewResolver.setCached(true);
|
|
||||||
// viewResolver.setTheme(null);
|
|
||||||
|
|
||||||
return viewResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public XOAIManagerResolver xoaiManagerResolver() {
|
|
||||||
return new StubbedXOAIManagerResolver();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public XOAICacheService xoaiCacheService() {
|
|
||||||
return new DSpaceEmptyCacheService();
|
|
||||||
}
|
|
||||||
|
|
||||||
private StubbedSetRepository setRepository = new StubbedSetRepository();
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
StubbedSetRepository setRepository() {
|
|
||||||
return setRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ItemRepositoryResolver itemRepositoryResolver() {
|
|
||||||
return new ItemRepositoryResolver() {
|
|
||||||
@Override
|
|
||||||
public ItemRepository getItemRepository() throws ContextServiceException {
|
|
||||||
try {
|
|
||||||
return null;
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new ContextServiceException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public SetRepositoryResolver setRepositoryResolver() {
|
|
||||||
return new SetRepositoryResolver() {
|
|
||||||
@Override
|
|
||||||
public SetRepository getSetRepository() throws ContextServiceException {
|
|
||||||
return setRepository;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public IdentifyResolver identifyResolver() {
|
|
||||||
return new DSpaceIdentifyResolver();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public EarliestDateResolver earliestDateResolver() {
|
|
||||||
return new StubbedEarliestDateResolver();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,37 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.xoai.tests.helpers;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
|
||||||
|
|
||||||
public class HttpRequestBuilder {
|
|
||||||
private MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
|
|
||||||
public HttpRequestBuilder withUrl(String url) {
|
|
||||||
try {
|
|
||||||
URI uri = new URI(url);
|
|
||||||
} catch (URISyntaxException e) {
|
|
||||||
// ASD
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpRequestBuilder usingGetMethod() {
|
|
||||||
request.setMethod("GET");
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpServletRequest build() {
|
|
||||||
|
|
||||||
return request;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,28 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.xoai.tests.helpers;
|
|
||||||
|
|
||||||
public class SyntacticSugar {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor
|
|
||||||
*/
|
|
||||||
private SyntacticSugar() { }
|
|
||||||
|
|
||||||
public static <T> T given(T elem) {
|
|
||||||
return elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T the(T elem) {
|
|
||||||
return elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T and(T elem) {
|
|
||||||
return elem;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,183 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.xoai.tests.helpers.stubs;
|
|
||||||
|
|
||||||
import static com.lyncode.xoai.dataprovider.core.Granularity.Second;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.xml.stream.XMLStreamException;
|
|
||||||
|
|
||||||
import com.lyncode.xoai.builders.dataprovider.ElementBuilder;
|
|
||||||
import com.lyncode.xoai.builders.dataprovider.MetadataBuilder;
|
|
||||||
import com.lyncode.xoai.dataprovider.exceptions.MetadataBindException;
|
|
||||||
import com.lyncode.xoai.dataprovider.exceptions.WritingXmlException;
|
|
||||||
import com.lyncode.xoai.dataprovider.xml.XmlOutputContext;
|
|
||||||
import com.lyncode.xoai.dataprovider.xml.xoai.Metadata;
|
|
||||||
import org.apache.solr.client.solrj.SolrClient;
|
|
||||||
import org.apache.solr.client.solrj.SolrServerException;
|
|
||||||
import org.apache.solr.common.SolrInputDocument;
|
|
||||||
|
|
||||||
public class ItemRepositoryBuilder {
|
|
||||||
private final SolrClient solrServer;
|
|
||||||
|
|
||||||
public ItemRepositoryBuilder(SolrClient solrServer) {
|
|
||||||
this.solrServer = solrServer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemRepositoryBuilder withItem(DSpaceItemBuilder builder) {
|
|
||||||
try {
|
|
||||||
solrServer.add(index(builder));
|
|
||||||
solrServer.commit();
|
|
||||||
} catch (MetadataBindException | WritingXmlException | IOException
|
|
||||||
| SQLException | ParseException | XMLStreamException
|
|
||||||
| SolrServerException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private SolrInputDocument index(DSpaceItemBuilder item)
|
|
||||||
throws SQLException, MetadataBindException, ParseException, XMLStreamException, WritingXmlException {
|
|
||||||
SolrInputDocument doc = new SolrInputDocument();
|
|
||||||
|
|
||||||
doc.addField("item.id", item.getId());
|
|
||||||
doc.addField("item.public", item.isPublic());
|
|
||||||
doc.addField("item.lastmodified", item.getLastModifiedDate());
|
|
||||||
doc.addField("item.submitter", item.getSubmitter());
|
|
||||||
doc.addField("item.handle", item.getHandle());
|
|
||||||
doc.addField("item.deleted", item.isDeleted());
|
|
||||||
|
|
||||||
for (String col : item.getCollections()) {
|
|
||||||
doc.addField("item.collections", col);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String col : item.getCommunities()) {
|
|
||||||
doc.addField("item.communities", col);
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
||||||
XmlOutputContext context = XmlOutputContext.emptyContext(out, Second);
|
|
||||||
item.getMetadata().write(context);
|
|
||||||
context.getWriter().flush();
|
|
||||||
context.getWriter().close();
|
|
||||||
doc.addField("item.compile", out.toString());
|
|
||||||
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DSpaceItemBuilder {
|
|
||||||
private final List<String> collections = new ArrayList<>();
|
|
||||||
private final List<String> communities = new ArrayList<>();
|
|
||||||
private final MetadataBuilder metadataBuilder = new MetadataBuilder();
|
|
||||||
private String handle;
|
|
||||||
private int id;
|
|
||||||
private String submitter;
|
|
||||||
private Date lastModifiedDate;
|
|
||||||
private boolean deleted;
|
|
||||||
private boolean aPublic = true;
|
|
||||||
|
|
||||||
|
|
||||||
public DSpaceItemBuilder withLastModifiedDate(Date lastModifiedDate) {
|
|
||||||
this.lastModifiedDate = lastModifiedDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DSpaceItemBuilder withCollection(String colName) {
|
|
||||||
collections.add(colName);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DSpaceItemBuilder withCommunity(String comName) {
|
|
||||||
communities.add(comName);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DSpaceItemBuilder whichSsPublic() {
|
|
||||||
aPublic = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DSpaceItemBuilder whichSsPrivate() {
|
|
||||||
aPublic = false;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DSpaceItemBuilder whichIsDeleted() {
|
|
||||||
this.deleted = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DSpaceItemBuilder whichIsNotDeleted() {
|
|
||||||
this.deleted = false;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DSpaceItemBuilder withMetadata(String schema, String element, String value) {
|
|
||||||
metadataBuilder.withElement(new ElementBuilder().withName(schema).withField(element, value).build());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHandle() {
|
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DSpaceItemBuilder withHandle(String handle) {
|
|
||||||
this.handle = handle;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DSpaceItemBuilder withSubmitter(String submitter) {
|
|
||||||
this.submitter = submitter;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DSpaceItemBuilder withId(int id) {
|
|
||||||
this.id = id;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSubmitter() {
|
|
||||||
return submitter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getLastModifiedDate() {
|
|
||||||
return lastModifiedDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getCollections() {
|
|
||||||
return collections;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getCommunities() {
|
|
||||||
return communities;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Metadata getMetadata() {
|
|
||||||
return metadataBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDeleted() {
|
|
||||||
return deleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isPublic() {
|
|
||||||
return aPublic;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,63 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.xoai.tests.helpers.stubs;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.dspace.xoai.services.api.config.ConfigurationService;
|
|
||||||
|
|
||||||
public class StubbedConfigurationService implements ConfigurationService {
|
|
||||||
private Map<String, Object> values = new HashMap<String, Object>();
|
|
||||||
|
|
||||||
|
|
||||||
public StubbedConfigurationService hasBooleanProperty(String key, boolean value) {
|
|
||||||
values.put(key, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StubbedConfigurationService hasBooleanProperty(String module, String key, boolean value) {
|
|
||||||
values.put(module + "." + key, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StubbedConfigurationService hasProperty(String key, String value) {
|
|
||||||
values.put(key, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StubbedConfigurationService withoutProperty(String key) {
|
|
||||||
values.remove(key);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StubbedConfigurationService hasProperty(String module, String key, String value) {
|
|
||||||
values.put(module + "." + key, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getProperty(String key) {
|
|
||||||
return (String) values.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getProperty(String module, String key) {
|
|
||||||
return (String) values.get(module + "." + key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getBooleanProperty(String module, String key, boolean defaultValue) {
|
|
||||||
Boolean value = (Boolean) values.get(module + "." + key);
|
|
||||||
if (value == null) {
|
|
||||||
return defaultValue;
|
|
||||||
} else {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,29 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.xoai.tests.helpers.stubs;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import org.dspace.core.Context;
|
|
||||||
import org.dspace.xoai.exceptions.InvalidMetadataFieldException;
|
|
||||||
import org.dspace.xoai.services.api.EarliestDateResolver;
|
|
||||||
|
|
||||||
public class StubbedEarliestDateResolver implements EarliestDateResolver {
|
|
||||||
private Date date = new Date();
|
|
||||||
|
|
||||||
public StubbedEarliestDateResolver is(Date date) {
|
|
||||||
this.date = date;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Date getEarliestDate(Context context) throws InvalidMetadataFieldException, SQLException {
|
|
||||||
return date;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,44 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.xoai.tests.helpers.stubs;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import javax.xml.transform.Transformer;
|
|
||||||
import javax.xml.transform.TransformerConfigurationException;
|
|
||||||
import javax.xml.transform.TransformerFactory;
|
|
||||||
|
|
||||||
import com.lyncode.xoai.dataprovider.services.api.ResourceResolver;
|
|
||||||
|
|
||||||
public class StubbedResourceResolver implements ResourceResolver {
|
|
||||||
private static TransformerFactory factory = TransformerFactory.newInstance();
|
|
||||||
|
|
||||||
private Map<String, InputStream> inputStreamMap = new HashMap<String, InputStream>();
|
|
||||||
private Map<String, Transformer> transformerMap = new HashMap<String, Transformer>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getResource(String path) throws IOException {
|
|
||||||
return inputStreamMap.get(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Transformer getTransformer(String path) throws IOException, TransformerConfigurationException {
|
|
||||||
return transformerMap.get(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public StubbedResourceResolver hasIdentityTransformerFor(String path) {
|
|
||||||
try {
|
|
||||||
transformerMap.put(path, factory.newTransformer());
|
|
||||||
} catch (TransformerConfigurationException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,74 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.xoai.tests.helpers.stubs;
|
|
||||||
|
|
||||||
import static java.lang.Math.min;
|
|
||||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.lyncode.xoai.dataprovider.core.ListSetsResult;
|
|
||||||
import com.lyncode.xoai.dataprovider.core.Set;
|
|
||||||
import com.lyncode.xoai.dataprovider.services.api.SetRepository;
|
|
||||||
|
|
||||||
public class StubbedSetRepository implements SetRepository {
|
|
||||||
private List<Set> sets = new ArrayList<Set>();
|
|
||||||
private boolean supports = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportSets() {
|
|
||||||
return supports;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ListSetsResult retrieveSets(int offset, int length) {
|
|
||||||
if (offset > sets.size()) {
|
|
||||||
return new ListSetsResult(false, new ArrayList<Set>(), sets.size());
|
|
||||||
}
|
|
||||||
return new ListSetsResult(offset + length < sets.size(),
|
|
||||||
sets.subList(offset, min(offset + length, sets.size())), sets.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean exists(String setSpec) {
|
|
||||||
for (Set set : sets) {
|
|
||||||
if (set.getSetSpec().equals(setSpec)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StubbedSetRepository doesSupportSets() {
|
|
||||||
this.supports = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StubbedSetRepository doesNotSupportSets() {
|
|
||||||
this.supports = false;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StubbedSetRepository withSet(String name, String spec) {
|
|
||||||
this.sets.add(new Set(spec, name));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StubbedSetRepository withRandomlyGeneratedSets(int number) {
|
|
||||||
for (int i = 0; i < number; i++) {
|
|
||||||
this.sets.add(new Set(randomAlphabetic(10), randomAlphabetic(10)));
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() {
|
|
||||||
this.sets.clear();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.xoai.tests.helpers.stubs;
|
|
||||||
|
|
||||||
import com.lyncode.xoai.dataprovider.core.XOAIManager;
|
|
||||||
import com.lyncode.xoai.dataprovider.exceptions.ConfigurationException;
|
|
||||||
import com.lyncode.xoai.dataprovider.services.api.ResourceResolver;
|
|
||||||
import com.lyncode.xoai.dataprovider.xml.xoaiconfig.Configuration;
|
|
||||||
import org.dspace.xoai.services.api.config.XOAIManagerResolver;
|
|
||||||
import org.dspace.xoai.services.api.config.XOAIManagerResolverException;
|
|
||||||
import org.dspace.xoai.services.api.xoai.DSpaceFilterResolver;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
|
|
||||||
public class StubbedXOAIManagerResolver implements XOAIManagerResolver {
|
|
||||||
@Autowired
|
|
||||||
ResourceResolver resourceResolver;
|
|
||||||
@Autowired
|
|
||||||
DSpaceFilterResolver filterResolver;
|
|
||||||
|
|
||||||
private Configuration builder = new Configuration();
|
|
||||||
|
|
||||||
public Configuration configuration() {
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XOAIManager getManager() throws XOAIManagerResolverException {
|
|
||||||
try {
|
|
||||||
return new XOAIManager(filterResolver, resourceResolver, builder);
|
|
||||||
} catch (ConfigurationException e) {
|
|
||||||
throw new XOAIManagerResolverException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,186 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.xoai.tests.integration.xoai;
|
|
||||||
|
|
||||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import javax.xml.xpath.XPathExpressionException;
|
|
||||||
|
|
||||||
import com.lyncode.builder.MapBuilder;
|
|
||||||
import com.lyncode.xoai.dataprovider.services.api.ResourceResolver;
|
|
||||||
import com.lyncode.xoai.dataprovider.services.impl.BaseDateProvider;
|
|
||||||
import com.lyncode.xoai.dataprovider.xml.xoaiconfig.Configuration;
|
|
||||||
import com.lyncode.xoai.dataprovider.xml.xoaiconfig.FormatConfiguration;
|
|
||||||
import org.apache.solr.client.solrj.SolrClient;
|
|
||||||
import org.dspace.xoai.controller.DSpaceOAIDataProvider;
|
|
||||||
import org.dspace.xoai.services.api.EarliestDateResolver;
|
|
||||||
import org.dspace.xoai.services.api.FieldResolver;
|
|
||||||
import org.dspace.xoai.services.api.config.ConfigurationService;
|
|
||||||
import org.dspace.xoai.services.api.config.XOAIManagerResolver;
|
|
||||||
import org.dspace.xoai.tests.DSpaceTestConfiguration;
|
|
||||||
import org.dspace.xoai.tests.helpers.stubs.ItemRepositoryBuilder;
|
|
||||||
import org.dspace.xoai.tests.helpers.stubs.StubbedConfigurationService;
|
|
||||||
import org.dspace.xoai.tests.helpers.stubs.StubbedEarliestDateResolver;
|
|
||||||
import org.dspace.xoai.tests.helpers.stubs.StubbedFieldResolver;
|
|
||||||
import org.dspace.xoai.tests.helpers.stubs.StubbedResourceResolver;
|
|
||||||
import org.dspace.xoai.tests.helpers.stubs.StubbedSetRepository;
|
|
||||||
import org.dspace.xoai.tests.helpers.stubs.StubbedXOAIManagerResolver;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|
||||||
import org.springframework.test.context.web.WebAppConfiguration;
|
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
|
||||||
import org.springframework.test.web.servlet.ResultMatcher;
|
|
||||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
|
|
||||||
import org.springframework.test.web.servlet.result.XpathResultMatchers;
|
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
|
||||||
|
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
|
||||||
@WebAppConfiguration
|
|
||||||
@ContextConfiguration(classes = {DSpaceTestConfiguration.class, DSpaceOAIDataProvider.class})
|
|
||||||
public abstract class AbstractDSpaceTest {
|
|
||||||
private static final BaseDateProvider baseDateProvider = new BaseDateProvider();
|
|
||||||
@Autowired
|
|
||||||
WebApplicationContext wac;
|
|
||||||
private MockMvc mockMvc;
|
|
||||||
|
|
||||||
private StubbedXOAIManagerResolver xoaiManagerResolver;
|
|
||||||
private StubbedConfigurationService configurationService;
|
|
||||||
private StubbedFieldResolver databaseService;
|
|
||||||
private StubbedEarliestDateResolver earliestDateResolver;
|
|
||||||
private StubbedSetRepository setRepository;
|
|
||||||
private StubbedResourceResolver resourceResolver;
|
|
||||||
private SolrClient solrServer;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() {
|
|
||||||
xoaiManagerResolver = (StubbedXOAIManagerResolver) this.wac.getBean(XOAIManagerResolver.class);
|
|
||||||
configurationService = (StubbedConfigurationService) this.wac.getBean(ConfigurationService.class);
|
|
||||||
databaseService = (StubbedFieldResolver) this.wac.getBean(FieldResolver.class);
|
|
||||||
earliestDateResolver = (StubbedEarliestDateResolver) this.wac.getBean(EarliestDateResolver.class);
|
|
||||||
setRepository = this.wac.getBean(StubbedSetRepository.class);
|
|
||||||
setRepository.clear();
|
|
||||||
// solrServer = this.wac.getBean(SolrServer.class);
|
|
||||||
resourceResolver = (StubbedResourceResolver) this.wac.getBean(ResourceResolver.class);
|
|
||||||
xoaiManagerResolver.configuration();
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void teardown() {
|
|
||||||
// Nullify all resources so that JUnit will clean them up
|
|
||||||
xoaiManagerResolver = null;
|
|
||||||
configurationService = null;
|
|
||||||
databaseService = null;
|
|
||||||
earliestDateResolver = null;
|
|
||||||
setRepository = null;
|
|
||||||
resourceResolver = null;
|
|
||||||
mockMvc = null;
|
|
||||||
solrServer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected MockMvc againstTheDataProvider() {
|
|
||||||
if (this.mockMvc == null) {
|
|
||||||
this.mockMvc = webAppContextSetup(this.wac).build();
|
|
||||||
}
|
|
||||||
return this.mockMvc;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Configuration theConfiguration() {
|
|
||||||
return xoaiManagerResolver.configuration();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected StubbedConfigurationService theDSpaceConfiguration() {
|
|
||||||
return configurationService;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected StubbedFieldResolver theDatabase() {
|
|
||||||
return databaseService;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected StubbedEarliestDateResolver theEarlistEarliestDate() {
|
|
||||||
return earliestDateResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected XpathResultMatchers oaiXPath(String xpath) throws XPathExpressionException {
|
|
||||||
return MockMvcResultMatchers.xpath(this.replaceXpath(xpath), new MapBuilder<String, String>()
|
|
||||||
.withPair("o", "http://www.openarchives.org/OAI/2.0/")
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
private String replaceXpath(String xpath) {
|
|
||||||
int offset = 0;
|
|
||||||
String newXpath = "";
|
|
||||||
Pattern pattern = Pattern.compile("/[^/]+");
|
|
||||||
Matcher matcher = pattern.matcher(xpath);
|
|
||||||
while (matcher.find()) {
|
|
||||||
if (matcher.start() > offset) {
|
|
||||||
newXpath += xpath.substring(offset, matcher.start());
|
|
||||||
}
|
|
||||||
if (!matcher.group().contains(":") && !matcher.group().startsWith("/@")) {
|
|
||||||
newXpath += "/o:" + matcher.group().substring(1);
|
|
||||||
} else {
|
|
||||||
newXpath += matcher.group();
|
|
||||||
}
|
|
||||||
offset = matcher.end() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return newXpath;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String representationOfDate(Date date) {
|
|
||||||
return baseDateProvider.format(date);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected StubbedSetRepository theSetRepository() {
|
|
||||||
return setRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected com.lyncode.xoai.dataprovider.xml.xoaiconfig.ContextConfiguration aContext(String baseUrl) {
|
|
||||||
return new com.lyncode.xoai.dataprovider.xml.xoaiconfig.ContextConfiguration(baseUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected XpathResultMatchers responseDate() throws XPathExpressionException {
|
|
||||||
return oaiXPath("/OAI-PMH/responseDate");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ResultMatcher verb(org.hamcrest.Matcher<? super String> matcher) throws XPathExpressionException {
|
|
||||||
return oaiXPath("/OAI-PMH/request/@verb").string(matcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected XpathResultMatchers resumptionToken() throws XPathExpressionException {
|
|
||||||
return oaiXPath("//resumptionToken");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected StubbedResourceResolver theResourseResolver() {
|
|
||||||
return resourceResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected FormatConfiguration aFormat(String id) {
|
|
||||||
return new FormatConfiguration(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ItemRepositoryBuilder.DSpaceItemBuilder anItem() {
|
|
||||||
return new ItemRepositoryBuilder.DSpaceItemBuilder();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ItemRepositoryBuilder itemRepositoryBuilder;
|
|
||||||
|
|
||||||
public ItemRepositoryBuilder theItemRepository() {
|
|
||||||
if (itemRepositoryBuilder == null) {
|
|
||||||
itemRepositoryBuilder = new ItemRepositoryBuilder(solrServer);
|
|
||||||
}
|
|
||||||
return itemRepositoryBuilder;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,50 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.xoai.tests.integration.xoai;
|
|
||||||
|
|
||||||
import static org.dspace.xoai.tests.helpers.SyntacticSugar.and;
|
|
||||||
import static org.dspace.xoai.tests.helpers.SyntacticSugar.given;
|
|
||||||
import static org.hamcrest.core.Is.is;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class IdentifyTest extends AbstractDSpaceTest {
|
|
||||||
|
|
||||||
public static final Date EARLIEST_DATE = new Date();
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void requestForIdentifyWithoutRequiredConfigurationAdminEmailSetShouldFail() throws Exception {
|
|
||||||
given(theDSpaceConfiguration()
|
|
||||||
.withoutProperty("mail.admin"));
|
|
||||||
and(given(theConfiguration().withContextConfigurations(aContext("request"))));
|
|
||||||
|
|
||||||
againstTheDataProvider().perform(get("/request?verb=Identify"))
|
|
||||||
.andExpect(status().isInternalServerError());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void requestForIdentifyShouldReturnTheConfiguredValues() throws Exception {
|
|
||||||
given(theDSpaceConfiguration()
|
|
||||||
.hasProperty("dspace.name", "Test")
|
|
||||||
.hasProperty("mail.admin", "test@test.com"));
|
|
||||||
|
|
||||||
and(given(theEarlistEarliestDate().is(EARLIEST_DATE)));
|
|
||||||
and(given(theConfiguration().withContextConfigurations(aContext("request"))));
|
|
||||||
|
|
||||||
againstTheDataProvider().perform(get("/request?verb=Identify"))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(oaiXPath("//repositoryName").string("Test"))
|
|
||||||
.andExpect(oaiXPath("//adminEmail").string("test@test.com"))
|
|
||||||
.andExpect(
|
|
||||||
oaiXPath("//earliestDatestamp").string(is(representationOfDate(EARLIEST_DATE))));
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,65 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.xoai.tests.integration.xoai;
|
|
||||||
|
|
||||||
import static org.dspace.xoai.tests.helpers.SyntacticSugar.and;
|
|
||||||
import static org.dspace.xoai.tests.helpers.SyntacticSugar.given;
|
|
||||||
import static org.hamcrest.core.Is.is;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class ListSetsTest extends AbstractDSpaceTest {
|
|
||||||
@Test
|
|
||||||
public void listSetsWithLessSetsThenMaxSetsPerPage() throws Exception {
|
|
||||||
given(theConfiguration()
|
|
||||||
.withMaxListSetsSize(100)
|
|
||||||
.withContextConfigurations(aContext("request")));
|
|
||||||
and(given(theSetRepository()
|
|
||||||
.doesSupportSets()
|
|
||||||
.withSet("name", "spec")));
|
|
||||||
|
|
||||||
againstTheDataProvider().perform(get("/request?verb=ListSets"))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andDo(print())
|
|
||||||
.andExpect(responseDate().exists())
|
|
||||||
.andExpect(verb(is("ListSets")))
|
|
||||||
.andExpect(oaiXPath("//set").nodeCount(1))
|
|
||||||
.andExpect(oaiXPath("//set/setSpec").string("spec"))
|
|
||||||
.andExpect(oaiXPath("//set/setName").string("name"))
|
|
||||||
.andExpect(resumptionToken().doesNotExist());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void listSetsWithMoreSetsThenMaxSetsPerPage() throws Exception {
|
|
||||||
given(theConfiguration()
|
|
||||||
.withMaxListSetsSize(10)
|
|
||||||
.withContextConfigurations(aContext("request")));
|
|
||||||
|
|
||||||
and(given(theSetRepository()
|
|
||||||
.doesSupportSets()
|
|
||||||
.withRandomlyGeneratedSets(20)));
|
|
||||||
|
|
||||||
againstTheDataProvider().perform(get("/request?verb=ListSets"))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(responseDate().exists())
|
|
||||||
.andExpect(verb(is("ListSets")))
|
|
||||||
.andExpect(oaiXPath("//set").nodeCount(10))
|
|
||||||
.andExpect(resumptionToken().string("////10"))
|
|
||||||
.andExpect(oaiXPath("//resumptionToken/@completeListSize").number(Double.valueOf(20)));
|
|
||||||
|
|
||||||
and(againstTheDataProvider().perform(get("/request?verb=ListSets&resumptionToken=////10"))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(responseDate().exists())
|
|
||||||
.andExpect(verb(is("ListSets")))
|
|
||||||
.andExpect(oaiXPath("//set").nodeCount(10))
|
|
||||||
.andExpect(resumptionToken().string("")));
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,35 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.xoai.tests.integration.xoai;
|
|
||||||
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class OAIContextTest extends AbstractDSpaceTest {
|
|
||||||
public static final String ROOT_URL = "/";
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void requestToRootShouldGiveListOfContextsWithBadRequestError() throws Exception {
|
|
||||||
againstTheDataProvider().perform(get(ROOT_URL))
|
|
||||||
.andDo(print())
|
|
||||||
.andExpect(status().isBadRequest())
|
|
||||||
.andExpect(model().attributeExists("contexts"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void requestForUnknownContextShouldGiveListOfContextsWithBadRequestError() throws Exception {
|
|
||||||
againstTheDataProvider().perform(get("/unexistentContext"))
|
|
||||||
.andDo(print())
|
|
||||||
.andExpect(status().isBadRequest())
|
|
||||||
.andExpect(model().attributeExists("contexts"));
|
|
||||||
}
|
|
||||||
}
|
|
@@ -2,9 +2,9 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>dspace-rdf</artifactId>
|
<artifactId>dspace-rdf</artifactId>
|
||||||
<packaging>war</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>DSpace RDF</name>
|
<name>DSpace RDF</name>
|
||||||
<description>Parent project for the RDF API and Webapp</description>
|
<description>DSpace RDF (Linked Data) Extension</description>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
@@ -57,20 +57,17 @@
|
|||||||
<artifactId>dspace-services</artifactId>
|
<artifactId>dspace-services</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Spring 3 dependencies -->
|
<!-- Needed to support Spring @Configuration classes (to register servlets/beans with Spring Boot webapp) -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-core</artifactId>
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
</dependency>
|
<version>${spring-boot.version}</version>
|
||||||
|
<exclusions>
|
||||||
<dependency>
|
<exclusion>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-context</artifactId>
|
<artifactId>spring-boot-starter-logging</artifactId>
|
||||||
</dependency>
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-web</artifactId>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* 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.configuration;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RDF webapp configuration. Replaces the old web.xml
|
||||||
|
* <p>
|
||||||
|
* This @Configuration class is automatically discovered by Spring via a @ComponentScan.
|
||||||
|
* <p>
|
||||||
|
* All RDF web configurations (beans) can be enabled or disabled by setting "rdf.enabled"
|
||||||
|
* to true or false, respectively (in your DSpace configuration). Default is "false".
|
||||||
|
* <p>
|
||||||
|
* All @Value annotated configurations below can also be overridden in your DSpace configuration.
|
||||||
|
*
|
||||||
|
* @author Tim Donohue
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class RDFWebConfig {
|
||||||
|
// Path where RDF should be deployed (when enabled). Defaults to "rdf"
|
||||||
|
@Value("${rdf.path:rdf}")
|
||||||
|
private String rdfPath;
|
||||||
|
|
||||||
|
// Servlet Beans. All of the below bean definitions map servlets to respond to specific URL patterns
|
||||||
|
// These are the combined equivalent of <servlet> and <servlet-mapping> in web.xml
|
||||||
|
// All beans are only loaded when rdf.enabled = true
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty("rdf.enabled")
|
||||||
|
public ServletRegistrationBean rdfSerializationBean() {
|
||||||
|
ServletRegistrationBean bean = new ServletRegistrationBean( new org.dspace.rdf.providing.DataProviderServlet(),
|
||||||
|
"/" + rdfPath + "/handle/*");
|
||||||
|
bean.setLoadOnStartup(1);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty("rdf.enabled")
|
||||||
|
public ServletRegistrationBean rdfLocalURIRedirectionBean() {
|
||||||
|
ServletRegistrationBean bean = new ServletRegistrationBean(
|
||||||
|
new org.dspace.rdf.providing.LocalURIRedirectionServlet(), "/" + rdfPath + "/resource/*");
|
||||||
|
bean.setLoadOnStartup(1);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -1,71 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
|
|
||||||
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/
|
|
||||||
|
|
||||||
-->
|
|
||||||
<web-app id="DSpace-RDF" version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
|
|
||||||
|
|
||||||
<display-name>RDF Data Provider</display-name>
|
|
||||||
|
|
||||||
<context-param>
|
|
||||||
<description>
|
|
||||||
The location of the DSpace home directory
|
|
||||||
</description>
|
|
||||||
<param-name>dspace.dir</param-name>
|
|
||||||
<param-value>${dspace.dir}</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<context-param>
|
|
||||||
<param-name>log4jConfiguration</param-name>
|
|
||||||
<param-value>${dspace.dir}/config/log4j2.xml</param-value>
|
|
||||||
<description>
|
|
||||||
The location of the Log4J configuration
|
|
||||||
</description>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<filter>
|
|
||||||
<filter-name>dspace.request</filter-name>
|
|
||||||
<filter-class>org.dspace.utils.servlet.DSpaceWebappServletFilter</filter-class>
|
|
||||||
</filter>
|
|
||||||
|
|
||||||
<filter-mapping>
|
|
||||||
<filter-name>dspace.request</filter-name>
|
|
||||||
<url-pattern>/*</url-pattern>
|
|
||||||
</filter-mapping>
|
|
||||||
|
|
||||||
<listener>
|
|
||||||
<listener-class>org.dspace.app.util.DSpaceContextListener</listener-class>
|
|
||||||
</listener>
|
|
||||||
|
|
||||||
<listener>
|
|
||||||
<listener-class>org.dspace.servicemanager.servlet.DSpaceKernelServletContextListener</listener-class>
|
|
||||||
</listener>
|
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>rdf-serialization</servlet-name>
|
|
||||||
<servlet-class>org.dspace.rdf.providing.DataProviderServlet</servlet-class>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>local-uri-redirection</servlet-name>
|
|
||||||
<servlet-class>org.dspace.rdf.providing.LocalURIRedirectionServlet</servlet-class>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>rdf-serialization</servlet-name>
|
|
||||||
<url-pattern>/handle/*</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>local-uri-redirection</servlet-name>
|
|
||||||
<url-pattern>/resource/*</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
</web-app>
|
|
@@ -27,9 +27,10 @@
|
|||||||
<resource.delimiter>@</resource.delimiter>
|
<resource.delimiter>@</resource.delimiter>
|
||||||
<!-- Define our starting class for our Spring Boot Application -->
|
<!-- Define our starting class for our Spring Boot Application -->
|
||||||
<start-class>org.dspace.app.rest.Application</start-class>
|
<start-class>org.dspace.app.rest.Application</start-class>
|
||||||
<spring-boot.version>1.4.4.RELEASE</spring-boot.version>
|
<!-- Library for reading JSON documents: https://github.com/json-path/JsonPath -->
|
||||||
<json-path.version>2.2.0</json-path.version>
|
<json-path.version>2.4.0</json-path.version>
|
||||||
<!-- <springdata.commons>1.13.0.RELEASE</springdata.commons> -->
|
<!-- Library for managing JSON Web Tokens (JWT): https://bitbucket.org/connect2id/nimbus-jose-jwt/wiki/Home -->
|
||||||
|
<nimbus-jose-jwt.version>6.2</nimbus-jose-jwt.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
@@ -255,6 +256,26 @@
|
|||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>dspace-services</artifactId>
|
<artifactId>dspace-services</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- DSpace modules to deploy (this modules are all optional, but add features/endpoints to webapp) -->
|
||||||
|
<!-- You may choose to comment out any of these modules if you do not want/need its features -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dspace</groupId>
|
||||||
|
<artifactId>dspace-oai</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dspace</groupId>
|
||||||
|
<artifactId>dspace-rdf</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dspace</groupId>
|
||||||
|
<artifactId>dspace-sword</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dspace</groupId>
|
||||||
|
<artifactId>dspace-swordv2</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-collections4</artifactId>
|
<artifactId>commons-collections4</artifactId>
|
||||||
@@ -266,7 +287,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.nimbusds</groupId>
|
<groupId>com.nimbusds</groupId>
|
||||||
<artifactId>nimbus-jose-jwt</artifactId>
|
<artifactId>nimbus-jose-jwt</artifactId>
|
||||||
<version>6.2</version>
|
<version>${nimbus-jose-jwt.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.solr</groupId>
|
<groupId>org.apache.solr</groupId>
|
||||||
@@ -288,13 +309,18 @@
|
|||||||
<groupId>org.json</groupId>
|
<groupId>org.json</groupId>
|
||||||
<artifactId>json</artifactId>
|
<artifactId>json</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
|
<!-- More recent version used for testing below -->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>com.jayway.jsonpath</groupId>
|
||||||
|
<artifactId>json-path</artifactId>
|
||||||
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.jayway.jsonpath</groupId>
|
<groupId>com.jayway.jsonpath</groupId>
|
||||||
<artifactId>json-path</artifactId>
|
<artifactId>json-path</artifactId>
|
||||||
<scope>test</scope>
|
|
||||||
<version>${json-path.version}</version>
|
<version>${json-path.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.jayway.jsonpath</groupId>
|
<groupId>com.jayway.jsonpath</groupId>
|
||||||
|
@@ -14,6 +14,7 @@ import org.dspace.app.rest.filter.DSpaceRequestContextFilter;
|
|||||||
import org.dspace.app.rest.model.hateoas.DSpaceRelProvider;
|
import org.dspace.app.rest.model.hateoas.DSpaceRelProvider;
|
||||||
import org.dspace.app.rest.parameter.resolver.SearchFilterResolver;
|
import org.dspace.app.rest.parameter.resolver.SearchFilterResolver;
|
||||||
import org.dspace.app.rest.utils.ApplicationConfig;
|
import org.dspace.app.rest.utils.ApplicationConfig;
|
||||||
|
import org.dspace.app.rest.utils.DSpaceConfigurationInitializer;
|
||||||
import org.dspace.app.rest.utils.DSpaceKernelInitializer;
|
import org.dspace.app.rest.utils.DSpaceKernelInitializer;
|
||||||
import org.dspace.app.util.DSpaceContextListener;
|
import org.dspace.app.util.DSpaceContextListener;
|
||||||
import org.dspace.utils.servlet.DSpaceWebappServletFilter;
|
import org.dspace.utils.servlet.DSpaceWebappServletFilter;
|
||||||
@@ -22,7 +23,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
import org.springframework.boot.web.servlet.ServletContextInitializer;
|
|
||||||
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
@@ -62,7 +62,6 @@ public class Application extends SpringBootServletInitializer {
|
|||||||
* This is necessary to allow us to build a deployable WAR, rather than
|
* This is necessary to allow us to build a deployable WAR, rather than
|
||||||
* always relying on embedded Tomcat.
|
* always relying on embedded Tomcat.
|
||||||
* <p>
|
* <p>
|
||||||
* <p>
|
|
||||||
* See: http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-create-a-deployable-war-file
|
* See: http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-create-a-deployable-war-file
|
||||||
*
|
*
|
||||||
* @param application
|
* @param application
|
||||||
@@ -70,13 +69,10 @@ public class Application extends SpringBootServletInitializer {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
||||||
|
// Pass this Application class, and our initializers for DSpace Kernel and Configuration
|
||||||
|
// NOTE: Kernel must be initialized before Configuration
|
||||||
return application.sources(Application.class)
|
return application.sources(Application.class)
|
||||||
.initializers(new DSpaceKernelInitializer());
|
.initializers(new DSpaceKernelInitializer(), new DSpaceConfigurationInitializer());
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ServletContextInitializer contextInitializer() {
|
|
||||||
return servletContext -> servletContext.setInitParameter("dspace.dir", configuration.getDspaceHome());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,7 +85,6 @@ public class Application extends SpringBootServletInitializer {
|
|||||||
@Order(2)
|
@Order(2)
|
||||||
protected DSpaceContextListener dspaceContextListener() {
|
protected DSpaceContextListener dspaceContextListener() {
|
||||||
// This listener initializes the DSpace Context object
|
// This listener initializes the DSpace Context object
|
||||||
// (and loads all DSpace configs)
|
|
||||||
return new DSpaceContextListener();
|
return new DSpaceContextListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.app.rest;
|
package org.dspace.app.rest;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -19,6 +20,7 @@ import org.dspace.app.rest.link.HalLinkService;
|
|||||||
import org.dspace.app.rest.model.RelationshipRest;
|
import org.dspace.app.rest.model.RelationshipRest;
|
||||||
import org.dspace.app.rest.model.RelationshipRestWrapper;
|
import org.dspace.app.rest.model.RelationshipRestWrapper;
|
||||||
import org.dspace.app.rest.model.hateoas.RelationshipResourceWrapper;
|
import org.dspace.app.rest.model.hateoas.RelationshipResourceWrapper;
|
||||||
|
import org.dspace.app.rest.repository.RelationshipRestRepository;
|
||||||
import org.dspace.app.rest.utils.ContextUtil;
|
import org.dspace.app.rest.utils.ContextUtil;
|
||||||
import org.dspace.app.rest.utils.Utils;
|
import org.dspace.app.rest.utils.Utils;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
@@ -52,9 +54,17 @@ public class RelationshipRestController {
|
|||||||
private static final String REGEX_REQUESTMAPPING_LABEL = "/{label:^(?!^\\d+$)" +
|
private static final String REGEX_REQUESTMAPPING_LABEL = "/{label:^(?!^\\d+$)" +
|
||||||
"(?!^[0-9a-fxA-FX]{8}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{12}$)[\\w+\\-]+$+}";
|
"(?!^[0-9a-fxA-FX]{8}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{12}$)[\\w+\\-]+$+}";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regular expression in the request mapping to accept number as identifier
|
||||||
|
*/
|
||||||
|
private static final String REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT = "/{id:\\d+}";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RelationshipTypeService relationshipTypeService;
|
private RelationshipTypeService relationshipTypeService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RelationshipRestRepository relationshipRestRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RelationshipService relationshipService;
|
private RelationshipService relationshipService;
|
||||||
|
|
||||||
@@ -130,4 +140,29 @@ public class RelationshipRestController {
|
|||||||
return relationshipResourceWrapper;
|
return relationshipResourceWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* Method to change the left item of a relationship with a given item in the body
|
||||||
|
* @return The modified relationship
|
||||||
|
*/
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT + "/leftItem",
|
||||||
|
consumes = {"text/uri-list"})
|
||||||
|
public RelationshipRest updateRelationshipLeft(@PathVariable Integer id, HttpServletResponse response,
|
||||||
|
HttpServletRequest request) throws SQLException {
|
||||||
|
Context context = ContextUtil.obtainContext(request);
|
||||||
|
return relationshipRestRepository.put(context,"/api/core/relationships/", id,
|
||||||
|
utils.getStringListFromRequest(request), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to change the right item of a relationship with a given item in the body
|
||||||
|
* @return The modified relationship
|
||||||
|
*/
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT + "/rightItem",
|
||||||
|
consumes = {"text/uri-list"})
|
||||||
|
public RelationshipRest updateRelationshipRight(@PathVariable Integer id, HttpServletResponse response,
|
||||||
|
HttpServletRequest request) throws SQLException {
|
||||||
|
Context context = ContextUtil.obtainContext(request);
|
||||||
|
return relationshipRestRepository.put(context,"/api/core/relationships/", id,
|
||||||
|
utils.getStringListFromRequest(request), true);
|
||||||
|
}
|
||||||
|
}
|
@@ -832,7 +832,7 @@ public class RestResourceController implements InitializingBean {
|
|||||||
link = linkTo(this.getClass(), apiCategory, model).slash(uuid)
|
link = linkTo(this.getClass(), apiCategory, model).slash(uuid)
|
||||||
.slash(subpath + '?' + querystring).withSelfRel();
|
.slash(subpath + '?' + querystring).withSelfRel();
|
||||||
} else {
|
} else {
|
||||||
link = linkTo(this.getClass(), apiCategory, model).slash(uuid).withSelfRel();
|
link = linkTo(this.getClass(), apiCategory, model).slash(uuid).slash(subpath).withSelfRel();
|
||||||
}
|
}
|
||||||
|
|
||||||
Page<HALResource> halResources = pageResult.map(linkRepository::wrapResource);
|
Page<HALResource> halResources = pageResult.map(linkRepository::wrapResource);
|
||||||
|
@@ -1,17 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.rest.exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class creates an Exception to be used when the given DSpaceObjectType is invalid
|
|
||||||
*/
|
|
||||||
public class InvalidDSpaceObjectTypeException extends InvalidRequestException {
|
|
||||||
public InvalidDSpaceObjectTypeException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,21 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.rest.exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class provides an exception for when the given request is invalid
|
|
||||||
*/
|
|
||||||
public class InvalidRequestException extends Exception {
|
|
||||||
public InvalidRequestException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public InvalidRequestException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,17 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.rest.exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception thrown when the search endpoint receives an invalid facet name
|
|
||||||
*/
|
|
||||||
public class InvalidSearchFacetException extends InvalidRequestException {
|
|
||||||
public InvalidSearchFacetException(final String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,21 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.rest.exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class provides an exception to be used when the SearchFilter given is invalid
|
|
||||||
*/
|
|
||||||
public class InvalidSearchFilterException extends InvalidRequestException {
|
|
||||||
public InvalidSearchFilterException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public InvalidSearchFilterException(final String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,17 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.rest.exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class makes an Exception to be used when a certain sorting is invalid
|
|
||||||
*/
|
|
||||||
public class InvalidSortingException extends InvalidRequestException {
|
|
||||||
public InvalidSortingException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -54,13 +54,13 @@ public class BrowseEntryHalLinkFactory extends HalLinkFactory<BrowseEntryResourc
|
|||||||
return BrowseEntryResource.class;
|
return BrowseEntryResource.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO use the reflaction to discover the link repository and additional information on the link annotation to
|
// TODO use the reflection to discover the link repository and additional information on the link annotation to
|
||||||
// build the parameters?
|
// build the parameters?
|
||||||
private UriComponentsBuilder addFilterParams(UriComponentsBuilder uriComponentsBuilder,
|
private UriComponentsBuilder addFilterParams(UriComponentsBuilder uriComponentsBuilder,
|
||||||
final BrowseEntryRest data) {
|
final BrowseEntryRest data) {
|
||||||
UriComponentsBuilder result;
|
UriComponentsBuilder result;
|
||||||
if (data.getAuthority() != null) {
|
if (data.getAuthority() != null) {
|
||||||
result = uriComponentsBuilder.queryParam("filterValue", data.getAuthority());
|
result = uriComponentsBuilder.queryParam("filterAuthority", data.getAuthority());
|
||||||
} else {
|
} else {
|
||||||
result = uriComponentsBuilder.queryParam("filterValue", data.getValue());
|
result = uriComponentsBuilder.queryParam("filterValue", data.getValue());
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,6 @@ import org.dspace.app.rest.converter.DiscoverFacetResultsConverter;
|
|||||||
import org.dspace.app.rest.converter.DiscoverFacetsConverter;
|
import org.dspace.app.rest.converter.DiscoverFacetsConverter;
|
||||||
import org.dspace.app.rest.converter.DiscoverResultConverter;
|
import org.dspace.app.rest.converter.DiscoverResultConverter;
|
||||||
import org.dspace.app.rest.converter.DiscoverSearchSupportConverter;
|
import org.dspace.app.rest.converter.DiscoverSearchSupportConverter;
|
||||||
import org.dspace.app.rest.exception.InvalidRequestException;
|
|
||||||
import org.dspace.app.rest.model.FacetConfigurationRest;
|
import org.dspace.app.rest.model.FacetConfigurationRest;
|
||||||
import org.dspace.app.rest.model.FacetResultsRest;
|
import org.dspace.app.rest.model.FacetResultsRest;
|
||||||
import org.dspace.app.rest.model.SearchConfigurationRest;
|
import org.dspace.app.rest.model.SearchConfigurationRest;
|
||||||
@@ -91,8 +90,7 @@ public class DiscoveryRestRepository extends AbstractDSpaceRestRepository {
|
|||||||
|
|
||||||
public SearchResultsRest getSearchObjects(final String query, final String dsoType, final String dsoScope,
|
public SearchResultsRest getSearchObjects(final String query, final String dsoType, final String dsoScope,
|
||||||
final String configuration,
|
final String configuration,
|
||||||
final List<SearchFilter> searchFilters, final Pageable page)
|
final List<SearchFilter> searchFilters, final Pageable page) {
|
||||||
throws InvalidRequestException {
|
|
||||||
Context context = obtainContext();
|
Context context = obtainContext();
|
||||||
IndexableObject scopeObject = scopeResolver.resolveScope(context, dsoScope);
|
IndexableObject scopeObject = scopeResolver.resolveScope(context, dsoScope);
|
||||||
DiscoveryConfiguration discoveryConfiguration = searchConfigurationService
|
DiscoveryConfiguration discoveryConfiguration = searchConfigurationService
|
||||||
@@ -131,8 +129,7 @@ public class DiscoveryRestRepository extends AbstractDSpaceRestRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public FacetResultsRest getFacetObjects(String facetName, String prefix, String query, String dsoType,
|
public FacetResultsRest getFacetObjects(String facetName, String prefix, String query, String dsoType,
|
||||||
String dsoScope, final String configuration, List<SearchFilter> searchFilters, Pageable page)
|
String dsoScope, final String configuration, List<SearchFilter> searchFilters, Pageable page) {
|
||||||
throws InvalidRequestException {
|
|
||||||
|
|
||||||
Context context = obtainContext();
|
Context context = obtainContext();
|
||||||
|
|
||||||
@@ -158,7 +155,7 @@ public class DiscoveryRestRepository extends AbstractDSpaceRestRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SearchResultsRest getAllFacets(String query, String dsoType, String dsoScope, String configuration,
|
public SearchResultsRest getAllFacets(String query, String dsoType, String dsoScope, String configuration,
|
||||||
List<SearchFilter> searchFilters) throws InvalidRequestException {
|
List<SearchFilter> searchFilters) {
|
||||||
|
|
||||||
Context context = obtainContext();
|
Context context = obtainContext();
|
||||||
Pageable page = new PageRequest(1, 1);
|
Pageable page = new PageRequest(1, 1);
|
||||||
|
@@ -34,6 +34,7 @@ import org.dspace.eperson.EPerson;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
||||||
import org.springframework.security.access.AccessDeniedException;
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -128,29 +129,59 @@ public class RelationshipRestRepository extends DSpaceRestRepository<Relationshi
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Disabled the put until https://jira.duraspace.org/browse/DS-4230 is discussed
|
* Method to replace either the right or left item of a relationship with a given new item
|
||||||
@Override
|
* Called by request mappings in RelationshipRestController
|
||||||
protected RelationshipRest put(Context context, HttpServletRequest request, String apiCategory, String model,
|
* - For replace right item (itemToReplaceIsRight = true)
|
||||||
Integer id, List<String> stringList)
|
* => Newly proposed changed relationship: left = old-left; right = new-item
|
||||||
throws RepositoryMethodNotImplementedException, SQLException, AuthorizeException {
|
* - For replace left item (itemToReplaceIsRight = false)
|
||||||
|
* => Newly proposed changed relationship: left = new-item; right = old-right
|
||||||
|
* @param context
|
||||||
|
* @param contextPath What API call was made to get here
|
||||||
|
* @param id ID of the relationship we wish to modify
|
||||||
|
* @param stringList Item to replace either right or left item of relationship with
|
||||||
|
* @param itemToReplaceIsRight Boolean to decide whether to replace right item (true) or left item (false)
|
||||||
|
* @return The (modified) relationship
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public RelationshipRest put(Context context, String contextPath, Integer id, List<String> stringList,
|
||||||
|
Boolean itemToReplaceIsRight) throws SQLException {
|
||||||
|
|
||||||
Relationship relationship = relationshipService.find(context, id);
|
Relationship relationship;
|
||||||
|
try {
|
||||||
|
relationship = relationshipService.find(context, id);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new ResourceNotFoundException(contextPath + " with id: " + id + " not found");
|
||||||
|
}
|
||||||
if (relationship == null) {
|
if (relationship == null) {
|
||||||
throw new ResourceNotFoundException(apiCategory + "." + model + " with id: " + id + " not found");
|
throw new ResourceNotFoundException(contextPath + " with id: " + id + " not found");
|
||||||
}
|
}
|
||||||
List<DSpaceObject> dSpaceObjects = utils.constructDSpaceObjectList(context, stringList);
|
List<DSpaceObject> dSpaceObjects = utils.constructDSpaceObjectList(context, stringList);
|
||||||
if (dSpaceObjects.size() == 2 && dSpaceObjects.get(0).getType() == Constants.ITEM
|
if (dSpaceObjects.size() == 1 && dSpaceObjects.get(0).getType() == Constants.ITEM) {
|
||||||
&& dSpaceObjects.get(1).getType() == Constants.ITEM) {
|
|
||||||
Item leftItem = (Item) dSpaceObjects.get(0);
|
Item replacementItemInRelationship = (Item) dSpaceObjects.get(0);
|
||||||
Item rightItem = (Item) dSpaceObjects.get(1);
|
Item leftItem;
|
||||||
|
Item rightItem;
|
||||||
|
if (itemToReplaceIsRight) {
|
||||||
|
leftItem = relationship.getLeftItem();
|
||||||
|
rightItem = replacementItemInRelationship;
|
||||||
|
} else {
|
||||||
|
leftItem = replacementItemInRelationship;
|
||||||
|
rightItem = relationship.getRightItem();
|
||||||
|
}
|
||||||
|
|
||||||
if (isAllowedToModifyRelationship(context, relationship, leftItem, rightItem)) {
|
if (isAllowedToModifyRelationship(context, relationship, leftItem, rightItem)) {
|
||||||
relationship.setLeftItem(leftItem);
|
relationship.setLeftItem(leftItem);
|
||||||
relationship.setRightItem(rightItem);
|
relationship.setRightItem(rightItem);
|
||||||
|
|
||||||
relationshipService.updatePlaceInRelationship(context, relationship, false);
|
try {
|
||||||
relationshipService.update(context, relationship);
|
relationshipService.updatePlaceInRelationship(context, relationship, false);
|
||||||
|
relationshipService.update(context, relationship);
|
||||||
|
context.commit();
|
||||||
|
context.reloadEntity(relationship);
|
||||||
|
} catch (AuthorizeException e) {
|
||||||
|
throw new AccessDeniedException("You do not have write rights on this relationship's items");
|
||||||
|
}
|
||||||
|
|
||||||
return relationshipConverter.fromModel(relationship);
|
return relationshipConverter.fromModel(relationship);
|
||||||
} else {
|
} else {
|
||||||
@@ -161,7 +192,6 @@ public class RelationshipRestRepository extends DSpaceRestRepository<Relationshi
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will check with the current user has write rights on both one of the original items and one of the
|
* This method will check with the current user has write rights on both one of the original items and one of the
|
||||||
@@ -198,4 +228,4 @@ public class RelationshipRestRepository extends DSpaceRestRepository<Relationshi
|
|||||||
log.error("Error deleting Relationship specified by ID:" + id, e);
|
log.error("Error deleting Relationship specified by ID:" + id, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -84,23 +84,24 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
|||||||
|
|
||||||
//Logout configuration
|
//Logout configuration
|
||||||
.logout()
|
.logout()
|
||||||
//On logout, clear the "session" salt
|
//On logout, clear the "session" salt
|
||||||
.addLogoutHandler(customLogoutHandler)
|
.addLogoutHandler(customLogoutHandler)
|
||||||
//Configure the logout entry point
|
//Configure the logout entry point
|
||||||
.logoutRequestMatcher(new AntPathRequestMatcher("/api/authn/logout"))
|
.logoutRequestMatcher(new AntPathRequestMatcher("/api/authn/logout"))
|
||||||
//When logout is successful, return OK (204) status
|
//When logout is successful, return OK (204) status
|
||||||
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.NO_CONTENT))
|
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.NO_CONTENT))
|
||||||
//Everyone can call this endpoint
|
//Everyone can call this endpoint
|
||||||
.permitAll()
|
.permitAll()
|
||||||
.and()
|
.and()
|
||||||
|
|
||||||
//Configure the URL patterns with their authentication requirements
|
//Configure the URL patterns with their authentication requirements
|
||||||
.authorizeRequests()
|
//Enable Spring Security authorization on /api/ URLs only
|
||||||
//Allow POST by anyone on the login endpoint
|
.antMatcher("/api/**").authorizeRequests()
|
||||||
.antMatchers(HttpMethod.POST,"/api/authn/login").permitAll()
|
//Allow POST by anyone on the login endpoint
|
||||||
//TRACE, CONNECT, OPTIONS, HEAD
|
.antMatchers(HttpMethod.POST,"/api/authn/login").permitAll()
|
||||||
//Everyone can call GET on the status endpoint
|
//TRACE, CONNECT, OPTIONS, HEAD
|
||||||
.antMatchers(HttpMethod.GET, "/api/authn/status").permitAll()
|
//Everyone can call GET on the status endpoint
|
||||||
|
.antMatchers(HttpMethod.GET, "/api/authn/status").permitAll()
|
||||||
.and()
|
.and()
|
||||||
|
|
||||||
//Add a filter before our login endpoints to do the authentication based on the data in the HTTP request
|
//Add a filter before our login endpoints to do the authentication based on the data in the HTTP request
|
||||||
|
@@ -13,24 +13,24 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.data.web.config.EnableSpringDataWebSupport;
|
import org.springframework.data.web.config.EnableSpringDataWebSupport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provide extra configuration for our Spring Boot Application
|
* This class provides extra configuration for our Spring Boot Application
|
||||||
|
* <p>
|
||||||
|
* NOTE: @ComponentScan on "org.dspace.app.configuration" provides a way for other DSpace modules or plugins
|
||||||
|
* to "inject" their own Spring configurations / subpaths into our Spring Boot webapp.
|
||||||
*
|
*
|
||||||
* @author Andrea Bollini (andrea.bollini at 4science.it)
|
* @author Andrea Bollini (andrea.bollini at 4science.it)
|
||||||
|
* @author Tim Donohue
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableSpringDataWebSupport
|
@EnableSpringDataWebSupport
|
||||||
@ComponentScan( {"org.dspace.app.rest.converter", "org.dspace.app.rest.repository", "org.dspace.app.rest.utils"})
|
@ComponentScan( {"org.dspace.app.rest.converter", "org.dspace.app.rest.repository", "org.dspace.app.rest.utils",
|
||||||
|
"org.dspace.app.configuration"})
|
||||||
public class ApplicationConfig {
|
public class ApplicationConfig {
|
||||||
@Value("${dspace.dir}")
|
// Allowed CORS origins. Defaults to * (everywhere)
|
||||||
private String dspaceHome;
|
// Can be overridden in DSpace configuration
|
||||||
|
@Value("${rest.cors.allowed-origins:*}")
|
||||||
@Value("${cors.allowed-origins}")
|
|
||||||
private String corsAllowedOrigins;
|
private String corsAllowedOrigins;
|
||||||
|
|
||||||
public String getDspaceHome() {
|
|
||||||
return dspaceHome;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getCorsAllowedOrigins() {
|
public String[] getCorsAllowedOrigins() {
|
||||||
if (corsAllowedOrigins != null) {
|
if (corsAllowedOrigins != null) {
|
||||||
return corsAllowedOrigins.split("\\s*,\\s*");
|
return corsAllowedOrigins.split("\\s*,\\s*");
|
||||||
|
@@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* 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.rest.utils;
|
||||||
|
|
||||||
|
import org.apache.commons.configuration2.Configuration;
|
||||||
|
import org.apache.commons.configuration2.spring.ConfigurationPropertySource;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.context.ApplicationContextInitializer;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class that will initialize the DSpace Configuration on Spring Boot startup.
|
||||||
|
* <P>
|
||||||
|
* NOTE: MUST be loaded after DSpaceKernelInitializer, as it requires the kernel is already initialized.
|
||||||
|
* <P>
|
||||||
|
* This initializer ensures that our DSpace Configuration is loaded into Spring's list of PropertySources
|
||||||
|
* very early in the Spring Boot startup process. That is important as it allows us to use DSpace configurations
|
||||||
|
* within @ConditionalOnProperty annotations on beans, as well as @Value annotations and XML bean definitions.
|
||||||
|
* <P>
|
||||||
|
* Used by org.dspace.app.rest.Application
|
||||||
|
*/
|
||||||
|
public class DSpaceConfigurationInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(DSpaceConfigurationInitializer.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(final ConfigurableApplicationContext applicationContext) {
|
||||||
|
// Load DSpace Configuration service (requires kernel already initialized)
|
||||||
|
ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||||
|
Configuration configuration = configurationService.getConfiguration();
|
||||||
|
|
||||||
|
// Create an Apache Commons Configuration Property Source from our configuration
|
||||||
|
ConfigurationPropertySource apacheCommonsConfigPropertySource =
|
||||||
|
new ConfigurationPropertySource(configuration.getClass().getName(), configuration);
|
||||||
|
|
||||||
|
// Append it to the Environment's list of PropertySources
|
||||||
|
applicationContext.getEnvironment().getPropertySources().addLast(apacheCommonsConfigPropertySource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -11,6 +11,7 @@ import java.io.File;
|
|||||||
import javax.naming.Context;
|
import javax.naming.Context;
|
||||||
import javax.naming.InitialContext;
|
import javax.naming.InitialContext;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.dspace.kernel.DSpaceKernel;
|
import org.dspace.kernel.DSpaceKernel;
|
||||||
import org.dspace.kernel.DSpaceKernelManager;
|
import org.dspace.kernel.DSpaceKernelManager;
|
||||||
import org.dspace.servicemanager.DSpaceKernelImpl;
|
import org.dspace.servicemanager.DSpaceKernelImpl;
|
||||||
@@ -22,6 +23,7 @@ import org.springframework.context.ApplicationContextInitializer;
|
|||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.context.event.ContextClosedEvent;
|
import org.springframework.context.event.ContextClosedEvent;
|
||||||
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class that will initialize the DSpace Kernel on Spring Boot startup.
|
* Utility class that will initialize the DSpace Kernel on Spring Boot startup.
|
||||||
@@ -35,16 +37,16 @@ public class DSpaceKernelInitializer implements ApplicationContextInitializer<Co
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(final ConfigurableApplicationContext applicationContext) {
|
public void initialize(final ConfigurableApplicationContext applicationContext) {
|
||||||
|
// Check if the kernel is already started
|
||||||
String dspaceHome = applicationContext.getEnvironment().getProperty("dspace.dir");
|
|
||||||
|
|
||||||
this.dspaceKernel = DSpaceKernelManager.getDefaultKernel();
|
this.dspaceKernel = DSpaceKernelManager.getDefaultKernel();
|
||||||
if (this.dspaceKernel == null) {
|
if (this.dspaceKernel == null) {
|
||||||
DSpaceKernelImpl kernelImpl = null;
|
DSpaceKernelImpl kernelImpl = null;
|
||||||
try {
|
try {
|
||||||
|
// Load the kernel with default settings
|
||||||
kernelImpl = DSpaceKernelInit.getKernel(null);
|
kernelImpl = DSpaceKernelInit.getKernel(null);
|
||||||
if (!kernelImpl.isRunning()) {
|
if (!kernelImpl.isRunning()) {
|
||||||
kernelImpl.start(getProvidedHome(dspaceHome)); // init the kernel
|
// Determine configured DSpace home & init the Kernel
|
||||||
|
kernelImpl.start(getDSpaceHome(applicationContext.getEnvironment()));
|
||||||
}
|
}
|
||||||
this.dspaceKernel = kernelImpl;
|
this.dspaceKernel = kernelImpl;
|
||||||
|
|
||||||
@@ -65,8 +67,8 @@ public class DSpaceKernelInitializer implements ApplicationContextInitializer<Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (applicationContext.getParent() == null) {
|
if (applicationContext.getParent() == null) {
|
||||||
//Set the DSpace Kernel Application context as a parent of the Spring Boot context so that
|
// Set the DSpace Kernel Application context as a parent of the Spring Boot context so that
|
||||||
//we can auto-wire all DSpace Kernel services
|
// we can auto-wire all DSpace Kernel services
|
||||||
applicationContext.setParent(dspaceKernel.getServiceManager().getApplicationContext());
|
applicationContext.setParent(dspaceKernel.getServiceManager().getApplicationContext());
|
||||||
|
|
||||||
//Add a listener for Spring Boot application shutdown so that we can nicely cleanup the DSpace kernel.
|
//Add a listener for Spring Boot application shutdown so that we can nicely cleanup the DSpace kernel.
|
||||||
@@ -75,29 +77,35 @@ public class DSpaceKernelInitializer implements ApplicationContextInitializer<Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find DSpace's "home" directory.
|
* Find DSpace's "home" directory (from current environment)
|
||||||
* Initially look for JNDI Resource called "java:/comp/env/dspace.dir".
|
* Initially look for JNDI Resource called "java:/comp/env/dspace.dir".
|
||||||
* If not found, look for "dspace.dir" initial context parameter.
|
* If not found, use value provided in "dspace.dir" in Spring Environment
|
||||||
*/
|
*/
|
||||||
private String getProvidedHome(String dspaceHome) {
|
private String getDSpaceHome(ConfigurableEnvironment environment) {
|
||||||
String providedHome = null;
|
// Load the "dspace.dir" property from Spring Boot's Configuration (application.properties)
|
||||||
|
// This gives us the location of our DSpace configurations, necessary to start the kernel
|
||||||
|
String providedHome = environment.getProperty(DSpaceConfigurationService.DSPACE_HOME);
|
||||||
|
|
||||||
|
String dspaceHome = null;
|
||||||
try {
|
try {
|
||||||
|
// Allow ability to override home directory via JNDI
|
||||||
Context ctx = new InitialContext();
|
Context ctx = new InitialContext();
|
||||||
providedHome = (String) ctx.lookup("java:/comp/env/" + DSpaceConfigurationService.DSPACE_HOME);
|
dspaceHome = (String) ctx.lookup("java:/comp/env/" + DSpaceConfigurationService.DSPACE_HOME);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
if (providedHome == null) {
|
// Otherwise, verify the 'providedHome' value is non-empty, exists and includes DSpace configs
|
||||||
if (dspaceHome != null && !dspaceHome.equals("") &&
|
if (dspaceHome == null) {
|
||||||
!dspaceHome.equals("${" + DSpaceConfigurationService.DSPACE_HOME + "}")) {
|
if (StringUtils.isNotBlank(providedHome) &&
|
||||||
File test = new File(dspaceHome);
|
!providedHome.equals("${" + DSpaceConfigurationService.DSPACE_HOME + "}")) {
|
||||||
|
File test = new File(providedHome);
|
||||||
if (test.exists() && new File(test, DSpaceConfigurationService.DSPACE_CONFIG_PATH).exists()) {
|
if (test.exists() && new File(test, DSpaceConfigurationService.DSPACE_CONFIG_PATH).exists()) {
|
||||||
providedHome = dspaceHome;
|
dspaceHome = providedHome;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return providedHome;
|
return dspaceHome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -16,11 +16,7 @@ import org.apache.commons.lang3.ArrayUtils;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.app.rest.converter.query.SearchQueryConverter;
|
import org.dspace.app.rest.converter.query.SearchQueryConverter;
|
||||||
import org.dspace.app.rest.exception.InvalidDSpaceObjectTypeException;
|
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
||||||
import org.dspace.app.rest.exception.InvalidRequestException;
|
|
||||||
import org.dspace.app.rest.exception.InvalidSearchFacetException;
|
|
||||||
import org.dspace.app.rest.exception.InvalidSearchFilterException;
|
|
||||||
import org.dspace.app.rest.exception.InvalidSortingException;
|
|
||||||
import org.dspace.app.rest.parameter.SearchFilter;
|
import org.dspace.app.rest.parameter.SearchFilter;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
@@ -71,7 +67,7 @@ public class DiscoverQueryBuilder implements InitializingBean {
|
|||||||
DiscoveryConfiguration discoveryConfiguration,
|
DiscoveryConfiguration discoveryConfiguration,
|
||||||
String query, List<SearchFilter> searchFilters,
|
String query, List<SearchFilter> searchFilters,
|
||||||
String dsoType, Pageable page)
|
String dsoType, Pageable page)
|
||||||
throws InvalidRequestException {
|
throws DSpaceBadRequestException {
|
||||||
|
|
||||||
DiscoverQuery queryArgs = buildCommonDiscoverQuery(context, discoveryConfiguration, query, searchFilters,
|
DiscoverQuery queryArgs = buildCommonDiscoverQuery(context, discoveryConfiguration, query, searchFilters,
|
||||||
dsoType);
|
dsoType);
|
||||||
@@ -104,7 +100,7 @@ public class DiscoverQueryBuilder implements InitializingBean {
|
|||||||
DiscoveryConfiguration discoveryConfiguration,
|
DiscoveryConfiguration discoveryConfiguration,
|
||||||
String prefix, String query, List<SearchFilter> searchFilters,
|
String prefix, String query, List<SearchFilter> searchFilters,
|
||||||
String dsoType, Pageable page, String facetName)
|
String dsoType, Pageable page, String facetName)
|
||||||
throws InvalidRequestException {
|
throws DSpaceBadRequestException {
|
||||||
|
|
||||||
DiscoverQuery queryArgs = buildCommonDiscoverQuery(context, discoveryConfiguration, query, searchFilters,
|
DiscoverQuery queryArgs = buildCommonDiscoverQuery(context, discoveryConfiguration, query, searchFilters,
|
||||||
dsoType);
|
dsoType);
|
||||||
@@ -129,7 +125,7 @@ public class DiscoverQueryBuilder implements InitializingBean {
|
|||||||
|
|
||||||
private DiscoverQuery addFacetingForFacets(Context context, IndexableObject scope, String prefix,
|
private DiscoverQuery addFacetingForFacets(Context context, IndexableObject scope, String prefix,
|
||||||
DiscoverQuery queryArgs, DiscoveryConfiguration discoveryConfiguration, String facetName, Pageable page)
|
DiscoverQuery queryArgs, DiscoveryConfiguration discoveryConfiguration, String facetName, Pageable page)
|
||||||
throws InvalidSearchFacetException {
|
throws DSpaceBadRequestException {
|
||||||
|
|
||||||
DiscoverySearchFilterFacet facet = discoveryConfiguration.getSidebarFacet(facetName);
|
DiscoverySearchFilterFacet facet = discoveryConfiguration.getSidebarFacet(facetName);
|
||||||
if (facet != null) {
|
if (facet != null) {
|
||||||
@@ -139,7 +135,7 @@ public class DiscoverQueryBuilder implements InitializingBean {
|
|||||||
fillFacetIntoQueryArgs(context, scope, prefix, queryArgs, facet, pageSize);
|
fillFacetIntoQueryArgs(context, scope, prefix, queryArgs, facet, pageSize);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidSearchFacetException(facetName + " is not a valid search facet");
|
throw new DSpaceBadRequestException(facetName + " is not a valid search facet");
|
||||||
}
|
}
|
||||||
|
|
||||||
return queryArgs;
|
return queryArgs;
|
||||||
@@ -173,7 +169,7 @@ public class DiscoverQueryBuilder implements InitializingBean {
|
|||||||
private DiscoverQuery buildCommonDiscoverQuery(Context context, DiscoveryConfiguration discoveryConfiguration,
|
private DiscoverQuery buildCommonDiscoverQuery(Context context, DiscoveryConfiguration discoveryConfiguration,
|
||||||
String query,
|
String query,
|
||||||
List<SearchFilter> searchFilters, String dsoType)
|
List<SearchFilter> searchFilters, String dsoType)
|
||||||
throws InvalidSearchFilterException, InvalidDSpaceObjectTypeException {
|
throws DSpaceBadRequestException {
|
||||||
DiscoverQuery queryArgs = buildBaseQueryForConfiguration(discoveryConfiguration);
|
DiscoverQuery queryArgs = buildBaseQueryForConfiguration(discoveryConfiguration);
|
||||||
|
|
||||||
//Add search filters
|
//Add search filters
|
||||||
@@ -202,7 +198,7 @@ public class DiscoverQueryBuilder implements InitializingBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void configureSorting(Pageable page, DiscoverQuery queryArgs,
|
private void configureSorting(Pageable page, DiscoverQuery queryArgs,
|
||||||
DiscoverySortConfiguration searchSortConfiguration) throws InvalidSortingException {
|
DiscoverySortConfiguration searchSortConfiguration) throws DSpaceBadRequestException {
|
||||||
String sortBy = null;
|
String sortBy = null;
|
||||||
String sortOrder = null;
|
String sortOrder = null;
|
||||||
|
|
||||||
@@ -237,11 +233,11 @@ public class DiscoverQueryBuilder implements InitializingBean {
|
|||||||
} else if ("desc".equalsIgnoreCase(sortOrder)) {
|
} else if ("desc".equalsIgnoreCase(sortOrder)) {
|
||||||
queryArgs.setSortField(sortField, DiscoverQuery.SORT_ORDER.desc);
|
queryArgs.setSortField(sortField, DiscoverQuery.SORT_ORDER.desc);
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidSortingException(sortOrder + " is not a valid sort order");
|
throw new DSpaceBadRequestException(sortOrder + " is not a valid sort order");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidSortingException(sortBy + " is not a valid sort field");
|
throw new DSpaceBadRequestException(sortBy + " is not a valid sort field");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,16 +269,16 @@ public class DiscoverQueryBuilder implements InitializingBean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getDsoTypeId(String dsoType) throws InvalidDSpaceObjectTypeException {
|
private int getDsoTypeId(String dsoType) throws DSpaceBadRequestException {
|
||||||
int index = ArrayUtils.indexOf(Constants.typeText, dsoType.toUpperCase());
|
int index = ArrayUtils.indexOf(Constants.typeText, dsoType.toUpperCase());
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
throw new InvalidDSpaceObjectTypeException(dsoType + " is not a valid DSpace Object type");
|
throw new DSpaceBadRequestException(dsoType + " is not a valid DSpace Object type");
|
||||||
}
|
}
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] convertFilters(Context context, DiscoveryConfiguration discoveryConfiguration,
|
private String[] convertFilters(Context context, DiscoveryConfiguration discoveryConfiguration,
|
||||||
List<SearchFilter> searchFilters) throws InvalidSearchFilterException {
|
List<SearchFilter> searchFilters) throws DSpaceBadRequestException {
|
||||||
ArrayList<String> filterQueries = new ArrayList<>(CollectionUtils.size(searchFilters));
|
ArrayList<String> filterQueries = new ArrayList<>(CollectionUtils.size(searchFilters));
|
||||||
|
|
||||||
SearchQueryConverter searchQueryConverter = new SearchQueryConverter();
|
SearchQueryConverter searchQueryConverter = new SearchQueryConverter();
|
||||||
@@ -291,7 +287,7 @@ public class DiscoverQueryBuilder implements InitializingBean {
|
|||||||
for (SearchFilter searchFilter : CollectionUtils.emptyIfNull(transformedFilters)) {
|
for (SearchFilter searchFilter : CollectionUtils.emptyIfNull(transformedFilters)) {
|
||||||
DiscoverySearchFilter filter = discoveryConfiguration.getSearchFilter(searchFilter.getName());
|
DiscoverySearchFilter filter = discoveryConfiguration.getSearchFilter(searchFilter.getName());
|
||||||
if (filter == null) {
|
if (filter == null) {
|
||||||
throw new InvalidSearchFilterException(searchFilter.getName() + " is not a valid search filter");
|
throw new DSpaceBadRequestException(searchFilter.getName() + " is not a valid search filter");
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscoverFilterQuery filterQuery = searchService.toFilterQuery(context,
|
DiscoverFilterQuery filterQuery = searchService.toFilterQuery(context,
|
||||||
@@ -304,7 +300,7 @@ public class DiscoverQueryBuilder implements InitializingBean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new InvalidSearchFilterException("There was a problem parsing the search filters.", e);
|
throw new DSpaceBadRequestException("There was a problem parsing the search filters.", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return filterQueries.toArray(new String[filterQueries.size()]);
|
return filterQueries.toArray(new String[filterQueries.size()]);
|
||||||
|
@@ -7,34 +7,31 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
#
|
#
|
||||||
# Spring Boot application.properties
|
# Spring Boot's application.properties
|
||||||
# Docs (including info on how to override these default settings)
|
#
|
||||||
|
# This properties file is used by Spring Boot to initialize its ApplicationContext and configure
|
||||||
|
# default Spring beans. It also uses the "dspace.dir" custom setting to locate your DSpace installation,
|
||||||
|
# and load all DSpace services and configurations.
|
||||||
|
#
|
||||||
|
# WARNING: Because this properties file initializes Spring Boot, it loads *before* any DSpace specific
|
||||||
|
# configurations/settings. Therefore settings in this file CANNOT depend on any DSpace configurations.
|
||||||
|
# The *only* DSpace configuration allowed in this file is "dspace.dir", which is documented below.
|
||||||
|
#
|
||||||
|
# Docs (including info on how to override these default settings)
|
||||||
# http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
|
# http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
|
||||||
# For common settings see:
|
# For common settings see:
|
||||||
# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
|
# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
|
||||||
#
|
#
|
||||||
#
|
|
||||||
# TODO: Eventually would could think of "wiring" this up to use Commons Configuration as well
|
|
||||||
# See, for example: http://stackoverflow.com/questions/25271537/remote-propertysource
|
|
||||||
# and https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
|
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# DSpace Settings
|
# DSpace Settings
|
||||||
#
|
#
|
||||||
# DSpace installation directory
|
# DSpace home/installation directory
|
||||||
|
# REQUIRED to be specified in this application.properties file, as it is used to locate and initialize
|
||||||
|
# the DSpace Kernel and all Services (including configuration). See org.dspace.app.rest.Application.getDSpaceHome()
|
||||||
|
# NOTE: this configuration is filled out by Apache Ant during the DSpace install/update process. It does NOT
|
||||||
|
# interact with or read its configuration from dspace.cfg.
|
||||||
dspace.dir=${dspace.dir}
|
dspace.dir=${dspace.dir}
|
||||||
#dspace.dir=d:/install/dspace7
|
|
||||||
|
|
||||||
########################
|
|
||||||
# DSpace API CORS Settings
|
|
||||||
#
|
|
||||||
cors.allowed-origins = *
|
|
||||||
|
|
||||||
########################
|
|
||||||
# Spring Boot Settings
|
|
||||||
#
|
|
||||||
# Testing an "application Name"
|
|
||||||
spring.application.name = DSpace Spring Rest
|
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# Spring DATA Rest settings
|
# Spring DATA Rest settings
|
||||||
@@ -75,15 +72,6 @@ server.port=8080
|
|||||||
# (Optional, defaults to root context)
|
# (Optional, defaults to root context)
|
||||||
#server.context-path=/spring-data-rest
|
#server.context-path=/spring-data-rest
|
||||||
|
|
||||||
# This creates a Tomcat context-param named "dspace.dir"
|
|
||||||
# and sets it to the value of the "dspace.dir" property (listed above)
|
|
||||||
server.context-parameters.dspace.dir=${dspace.dir}
|
|
||||||
|
|
||||||
# This creates a Tomcat context-param named "dspace-config"
|
|
||||||
# (Used by DSpaceContextListener to load the configurations)
|
|
||||||
# This is only needed in DSpace 5 or below to initialize ConfigurationManager
|
|
||||||
#server.context-parameters.dspace-config=${dspace.dir}/config/dspace.cfg
|
|
||||||
|
|
||||||
# Error handling settings
|
# Error handling settings
|
||||||
# Always include the fullstacktrace in error pages
|
# Always include the fullstacktrace in error pages
|
||||||
# Can be set to "never" if you don't want it.
|
# Can be set to "never" if you don't want it.
|
||||||
@@ -94,8 +82,8 @@ server.error.include-stacktrace = always
|
|||||||
#
|
#
|
||||||
# DISABLE a few autoconfiguration scripts, as DSpace initializes/configures these already
|
# DISABLE a few autoconfiguration scripts, as DSpace initializes/configures these already
|
||||||
# * DataSourceAutoConfiguration (DB connection / datasource)
|
# * DataSourceAutoConfiguration (DB connection / datasource)
|
||||||
|
# * HibernateJpaAutoConfiguration (Hibernate ORM)
|
||||||
# * FlywayAutoConfiguration (Flyway migrations)
|
# * FlywayAutoConfiguration (Flyway migrations)
|
||||||
# * HibernateJpaAutoConfiguration (Hibernate)
|
|
||||||
# * SolrAutoConfiguration (Solr)
|
# * SolrAutoConfiguration (Solr)
|
||||||
#
|
#
|
||||||
# TODO: At some point we may want to investigate whether we can re-enable these and remove the custom DSpace init code
|
# TODO: At some point we may want to investigate whether we can re-enable these and remove the custom DSpace init code
|
||||||
|
@@ -55,11 +55,11 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<form class="form-signin">
|
<form id="login-form" class="form-signin">
|
||||||
<h2 class="form-signin-heading">HAL Browser</h2>
|
<h2 class="form-signin-heading">HAL Browser</h2>
|
||||||
<input type="text" class="input-block-level" placeholder="Username" id="username">
|
<input type="text" class="input-block-level" placeholder="Username" id="username">
|
||||||
<input type="password" class="input-block-level" placeholder="Password" id="password">
|
<input type="password" class="input-block-level" placeholder="Password" id="password">
|
||||||
<button type="button" class="btn btn-large btn-primary" id="login">Sign in</button>
|
<button type="submit" class="btn btn-large btn-primary" id="login">Sign in</button>
|
||||||
<div class="other-login-methods hidden">
|
<div class="other-login-methods hidden">
|
||||||
<h3>Other login methods:</h3>
|
<h3>Other login methods:</h3>
|
||||||
|
|
||||||
@@ -133,13 +133,13 @@
|
|||||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#login").click(function() {
|
$("#login-form").submit(function() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
//This depends on this file to be called login.html
|
//This depends on this file to be called login.html
|
||||||
url : window.location.href.replace("login.html", "") + 'api/authn/login',
|
url : window.location.href.replace("login.html", "") + 'api/authn/login',
|
||||||
type : 'POST',
|
type : 'POST',
|
||||||
async : false,
|
async : false,
|
||||||
data : 'password='+$("#password").val()+'&user='+$("#username").val() ,
|
data : 'password='+encodeURIComponent($("#password").val())+'&user='+encodeURIComponent($("#username").val()),
|
||||||
headers : {
|
headers : {
|
||||||
"Content-Type" : 'application/x-www-form-urlencoded',
|
"Content-Type" : 'application/x-www-form-urlencoded',
|
||||||
"Accept:" : '*/*'
|
"Accept:" : '*/*'
|
||||||
@@ -149,6 +149,8 @@
|
|||||||
toastr.error('The credentials you entered are invalid. Please try again.', 'Login Failed');
|
toastr.error('The credentials you entered are invalid. Please try again.', 'Login Failed');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@@ -0,0 +1,281 @@
|
|||||||
|
/**
|
||||||
|
* 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.oai;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.xpath;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import com.lyncode.xoai.dataprovider.core.XOAIManager;
|
||||||
|
import com.lyncode.xoai.dataprovider.exceptions.ConfigurationException;
|
||||||
|
import com.lyncode.xoai.dataprovider.services.api.ResourceResolver;
|
||||||
|
import com.lyncode.xoai.dataprovider.services.impl.BaseDateProvider;
|
||||||
|
import com.lyncode.xoai.dataprovider.xml.xoaiconfig.Configuration;
|
||||||
|
import com.lyncode.xoai.dataprovider.xml.xoaiconfig.ContextConfiguration;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.builder.CollectionBuilder;
|
||||||
|
import org.dspace.app.rest.builder.CommunityBuilder;
|
||||||
|
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
||||||
|
import org.dspace.content.Community;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.dspace.xoai.services.api.EarliestDateResolver;
|
||||||
|
import org.dspace.xoai.services.api.cache.XOAICacheService;
|
||||||
|
import org.dspace.xoai.services.api.config.XOAIManagerResolver;
|
||||||
|
import org.dspace.xoai.services.api.xoai.DSpaceFilterResolver;
|
||||||
|
|
||||||
|
import org.junit.Assume;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||||
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration test to verify the /oai endpoint is responding as a valid OAI-PMH endpoint.
|
||||||
|
* This tests that our dspace-oai module is running at this endpoint.
|
||||||
|
* <P>
|
||||||
|
* This is an AbstractControllerIntegrationTest because dspace-oai makes use of Controllers.
|
||||||
|
*
|
||||||
|
* @author Tim Donohue
|
||||||
|
*/
|
||||||
|
// Ensure the OAI SERVER IS ENABLED before any tests run.
|
||||||
|
// This annotation overrides default DSpace config settings loaded into Spring Context
|
||||||
|
@TestPropertySource(properties = {"oai.enabled = true"})
|
||||||
|
public class OAIpmhIT extends AbstractControllerIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigurationService configurationService;
|
||||||
|
|
||||||
|
// All OAI-PMH paths that we test against
|
||||||
|
private final String ROOT_PATH = "/oai";
|
||||||
|
private final String DEFAULT_CONTEXT_PATH = "request";
|
||||||
|
private final String DEFAULT_CONTEXT = ROOT_PATH + "/" + DEFAULT_CONTEXT_PATH;
|
||||||
|
|
||||||
|
// Mock to ensure XOAI caching is disabled for all tests (see @Before method)
|
||||||
|
@MockBean
|
||||||
|
private XOAICacheService xoaiCacheService;
|
||||||
|
|
||||||
|
// Spy on the current EarliestDateResolver bean, to allow us to change behavior in tests below
|
||||||
|
@SpyBean
|
||||||
|
private EarliestDateResolver earliestDateResolver;
|
||||||
|
|
||||||
|
// XOAI's BaseDateProvider (used for date-based testing below)
|
||||||
|
private static BaseDateProvider baseDateProvider = new BaseDateProvider();
|
||||||
|
|
||||||
|
// Spy on the current XOAIManagerResolver bean, to allow us to change behavior of XOAIManager in tests
|
||||||
|
// See also: createMockXOAIManager() method
|
||||||
|
@SpyBean
|
||||||
|
private XOAIManagerResolver xoaiManagerResolver;
|
||||||
|
|
||||||
|
// Beans required by createMockXOAIManager()
|
||||||
|
@Autowired
|
||||||
|
private ResourceResolver resourceResolver;
|
||||||
|
@Autowired
|
||||||
|
private DSpaceFilterResolver filterResolver;
|
||||||
|
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void onlyRunIfConfigExists() {
|
||||||
|
// These integration tests REQUIRE that OAIWebConfig is found/available (as this class deploys OAI)
|
||||||
|
// If this class is not available, the below "Assume" will cause all tests to be SKIPPED
|
||||||
|
// NOTE: OAIWebConfig is provided by the 'dspace-oai' module
|
||||||
|
try {
|
||||||
|
Class.forName("org.dspace.app.configuration.OAIWebConfig");
|
||||||
|
} catch (ClassNotFoundException ce) {
|
||||||
|
Assume.assumeNoException(ce);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable XOAI Caching for ALL tests
|
||||||
|
when(xoaiCacheService.isActive()).thenReturn(false);
|
||||||
|
when(xoaiCacheService.hasCache(anyString())).thenReturn(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void requestToRootShouldGiveListOfContextsWithBadRequestError() throws Exception {
|
||||||
|
// Attempt to call the root endpoint
|
||||||
|
getClient().perform(get(ROOT_PATH))
|
||||||
|
// Expect a 400 response code (OAI requires a context)
|
||||||
|
.andExpect(status().isBadRequest())
|
||||||
|
// Expect that a list of valid contexts is returned
|
||||||
|
.andExpect(model().attributeExists("contexts"))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void requestForUnknownContextShouldGiveListOfContextsWithBadRequestError() throws Exception {
|
||||||
|
// Attempt to call an nonexistent OAI-PMH context
|
||||||
|
getClient().perform(get(ROOT_PATH + "/nonexistentContext"))
|
||||||
|
// Expect a 400 response code (OAI requires a context)
|
||||||
|
.andExpect(status().isBadRequest())
|
||||||
|
// Expect that a list of valid contexts is returned
|
||||||
|
.andExpect(model().attributeExists("contexts"))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void requestForIdentifyWithoutRequiredConfigShouldFail() throws Exception {
|
||||||
|
// Clear out the required "mail.admin" configuration
|
||||||
|
configurationService.setProperty("mail.admin", null);
|
||||||
|
|
||||||
|
// Attempt to make an Identify request to root context
|
||||||
|
getClient().perform(get(DEFAULT_CONTEXT).param("verb", "Identify"))
|
||||||
|
// Expect a 500 response code (mail.admin MUST be set)
|
||||||
|
.andExpect(status().isInternalServerError())
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void requestForIdentifyShouldReturnTheConfiguredValues() throws Exception {
|
||||||
|
|
||||||
|
// Get current date/time and store as "now"
|
||||||
|
Date now = new Date();
|
||||||
|
// Return "now" when "getEarliestDate()" is called for the currently loaded EarliestDateResolver bean
|
||||||
|
doReturn(now).when(earliestDateResolver).getEarliestDate(context);
|
||||||
|
|
||||||
|
// Attempt to make an Identify request to root context
|
||||||
|
getClient().perform(get(DEFAULT_CONTEXT).param("verb", "Identify"))
|
||||||
|
// Expect a 200 response code
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
// Expect the content type to be "text/xml"
|
||||||
|
.andExpect(content().contentType("text/xml"))
|
||||||
|
// Expect <scheme>oai</scheme>
|
||||||
|
.andExpect(xpath("OAI-PMH/Identify/description/oai-identifier/scheme").string("oai"))
|
||||||
|
// Expect protocol version 2.0
|
||||||
|
.andExpect(xpath("OAI-PMH/Identify/protocolVersion").string("2.0"))
|
||||||
|
// Expect repositoryName to be the same as "dspace.name" config
|
||||||
|
.andExpect(xpath("OAI-PMH/Identify/repositoryName")
|
||||||
|
.string(configurationService.getProperty("dspace.name")))
|
||||||
|
// Expect adminEmail to be the same as "mail.admin" config
|
||||||
|
.andExpect(xpath("OAI-PMH/Identify/adminEmail")
|
||||||
|
.string(configurationService.getProperty("mail.admin")))
|
||||||
|
// Expect baseURL to be the same as our "oai.url" with the DEFAULT_CONTEXT_PATH appended
|
||||||
|
.andExpect(xpath("OAI-PMH/Identify/baseURL")
|
||||||
|
.string(configurationService.getProperty("oai.url") + "/" + DEFAULT_CONTEXT_PATH))
|
||||||
|
// Expect earliestDatestamp to be "now", i.e. current date, (as mocked above)
|
||||||
|
.andExpect(xpath("OAI-PMH/Identify/earliestDatestamp")
|
||||||
|
.string(baseDateProvider.format(now)))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listSetsWithLessSetsThenMaxSetsPerPage() throws Exception {
|
||||||
|
//Turn off the authorization system, otherwise we can't make the objects
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
// Create a Community & a Collection
|
||||||
|
Community parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Child Collection")
|
||||||
|
.build();
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
// Call ListSets verb, and verify both Collection & Community are listed as sets
|
||||||
|
getClient().perform(get(DEFAULT_CONTEXT).param("verb", "ListSets"))
|
||||||
|
// Expect 200 response, with valid response date and verb=ListSets
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(xpath("OAI-PMH/responseDate").exists())
|
||||||
|
.andExpect(xpath("OAI-PMH/request/@verb").string("ListSets"))
|
||||||
|
// Expect two Sets to be returned
|
||||||
|
.andExpect(xpath("//set").nodeCount(2))
|
||||||
|
// First setSpec should start with "com_" (Community)
|
||||||
|
.andExpect(xpath("(//set/setSpec)[1]").string(startsWith("com_")))
|
||||||
|
// First set name should be Community name
|
||||||
|
.andExpect(xpath("(//set/setName)[1]").string("Parent Community"))
|
||||||
|
// Second setSpec should start with "col_" (Collection)
|
||||||
|
.andExpect(xpath("(//set/setSpec)[2]").string(startsWith("col_")))
|
||||||
|
// Second set name should be Collection name
|
||||||
|
.andExpect(xpath("(//set/setName)[2]").string("Child Collection"))
|
||||||
|
// No resumption token should be returned
|
||||||
|
.andExpect(xpath("//resumptionToken").doesNotExist())
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listSetsWithMoreSetsThenMaxSetsPerPage() throws Exception {
|
||||||
|
//Turn off the authorization system, otherwise we can't make the objects
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
// Create 3 Communities (1 as a subcommunity) & 2 Collections
|
||||||
|
Community firstCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("First Community")
|
||||||
|
.build();
|
||||||
|
Community secondCommunity = CommunityBuilder.createSubCommunity(context, firstCommunity)
|
||||||
|
.withName("Second Community")
|
||||||
|
.build();
|
||||||
|
CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Third Community")
|
||||||
|
.build();
|
||||||
|
CollectionBuilder.createCollection(context, firstCommunity)
|
||||||
|
.withName("First Collection")
|
||||||
|
.build();
|
||||||
|
CollectionBuilder.createCollection(context, secondCommunity)
|
||||||
|
.withName("Second Collection")
|
||||||
|
.build();
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
|
||||||
|
// Create a custom XOAI configuration, with maxListSetsSize = 3 for DEFAULT_CONTEXT requests
|
||||||
|
// (This limits the number of sets returned in a single response)
|
||||||
|
Configuration xoaiConfig =
|
||||||
|
new Configuration().withMaxListSetsSize(3)
|
||||||
|
.withContextConfigurations(new ContextConfiguration(DEFAULT_CONTEXT_PATH));
|
||||||
|
// When xoaiManagerResolver.getManager() is called, return a MockXOAIManager based on the above configuration
|
||||||
|
doReturn(createMockXOAIManager(xoaiConfig)).when(xoaiManagerResolver).getManager();
|
||||||
|
|
||||||
|
// Call ListSets verb, and verify all 5 Collections/Communities are listed as sets
|
||||||
|
getClient().perform(get(DEFAULT_CONTEXT).param("verb", "ListSets"))
|
||||||
|
// Expect 200 response, with valid response date and verb=ListSets
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(xpath("OAI-PMH/responseDate").exists())
|
||||||
|
.andExpect(xpath("OAI-PMH/request/@verb").string("ListSets"))
|
||||||
|
// Expect ONLY 3 (of 5) Sets to be returned
|
||||||
|
.andExpect(xpath("//set").nodeCount(3))
|
||||||
|
// Expect resumption token to exist and be equal to "////3"
|
||||||
|
.andExpect(xpath("//resumptionToken").string("////3"))
|
||||||
|
// Expect resumption token to have completeListSize=5
|
||||||
|
.andExpect(xpath("//resumptionToken/@completeListSize").number(Double.valueOf(5)))
|
||||||
|
;
|
||||||
|
|
||||||
|
// Call ListSets verb, and verify all 5 Collections/Communities are listed as sets
|
||||||
|
getClient().perform(get(DEFAULT_CONTEXT).param("verb", "ListSets"))
|
||||||
|
// Expect 200 response, with valid response date and verb=ListSets
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(xpath("OAI-PMH/responseDate").exists())
|
||||||
|
.andExpect(xpath("OAI-PMH/request/@verb").string("ListSets"))
|
||||||
|
// Expect ONLY 3 (of 5) Sets to be returned
|
||||||
|
.andExpect(xpath("//set").nodeCount(3))
|
||||||
|
// Expect resumption token to exist and be equal to "////3"
|
||||||
|
.andExpect(xpath("//resumptionToken").string("////3"))
|
||||||
|
// Expect resumption token to have completeListSize=5
|
||||||
|
.andExpect(xpath("//resumptionToken/@completeListSize").number(Double.valueOf(5)))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a fake/mock XOAIManager class based on the given xoaiConfig. May be used by above tests
|
||||||
|
* to provide custom configurations to XOAI (overriding defaults in xoai.xml)
|
||||||
|
* @param xoaiConfig XOAI Configuration
|
||||||
|
* @return new XOAIManager initialized with the given Configuration
|
||||||
|
* @throws ConfigurationException
|
||||||
|
*/
|
||||||
|
private XOAIManager createMockXOAIManager(Configuration xoaiConfig) throws ConfigurationException {
|
||||||
|
return new XOAIManager(filterResolver, resourceResolver, xoaiConfig);
|
||||||
|
}
|
||||||
|
}
|
146
dspace-spring-rest/src/test/java/org/dspace/app/rdf/RdfIT.java
Normal file
146
dspace-spring-rest/src/test/java/org/dspace/app/rdf/RdfIT.java
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
/**
|
||||||
|
* 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.rdf;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.builder.CommunityBuilder;
|
||||||
|
import org.dspace.app.rest.test.AbstractWebClientIntegrationTest;
|
||||||
|
import org.dspace.content.Community;
|
||||||
|
import org.dspace.content.service.SiteService;
|
||||||
|
import org.dspace.rdf.RDFUtil;
|
||||||
|
import org.dspace.rdf.conversion.RDFConverter;
|
||||||
|
import org.dspace.rdf.factory.RDFFactoryImpl;
|
||||||
|
import org.dspace.rdf.storage.RDFStorage;
|
||||||
|
import org.dspace.rdf.storage.RDFStorageImpl;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.junit.Assume;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Spy;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration test to verify that the /rdf endpoint is responding as a valid RDF endpoint.
|
||||||
|
* This tests that our dspace-rdf module is running at this endpoint.
|
||||||
|
* <P>
|
||||||
|
* This is a AbstractWebClientIntegrationTest because testing dspace-rdf requires
|
||||||
|
* running a web server (as dspace-rdf makes use of Servlets, not Controllers).
|
||||||
|
* <P>
|
||||||
|
* NOTE: At this time, these ITs do NOT run against a real RDF triplestore. Instead,
|
||||||
|
* individual tests are expected to mock triplestore responses via a spy-able RDFStorage.
|
||||||
|
*
|
||||||
|
* @author Tim Donohue
|
||||||
|
*/
|
||||||
|
// Ensure the RDF endpoint IS ENABLED before any tests run.
|
||||||
|
// This annotation overrides default DSpace config settings loaded into Spring Context
|
||||||
|
@TestPropertySource(properties = {"rdf.enabled = true"})
|
||||||
|
public class RdfIT extends AbstractWebClientIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigurationService configurationService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SiteService siteService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RDFConverter rdfConverter;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RDFFactoryImpl rdfFactory;
|
||||||
|
|
||||||
|
// Create a new spy-able instance of RDFStorage. We will use this instance in all below tests (see @Before)
|
||||||
|
// so that we can fake a triplestore backend. No triplestore is used in these tests.
|
||||||
|
@Spy
|
||||||
|
RDFStorage rdfStorage = new RDFStorageImpl();
|
||||||
|
|
||||||
|
// All RDF paths that we test against
|
||||||
|
private final String SERIALIZE_PATH = "/rdf/handle";
|
||||||
|
private final String REDIRECTION_PATH = "/rdf/resource";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void onlyRunIfConfigExists() {
|
||||||
|
// These integration tests REQUIRE that RDFWebConfig is found/available (as this class deploys RDF)
|
||||||
|
// If this class is not available, the below "Assume" will cause all tests to be SKIPPED
|
||||||
|
// NOTE: RDFWebConfig is provided by the 'dspace-rdf' module
|
||||||
|
try {
|
||||||
|
Class.forName("org.dspace.app.configuration.RDFWebConfig");
|
||||||
|
} catch (ClassNotFoundException ce) {
|
||||||
|
Assume.assumeNoException(ce);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change the running RDFFactory to use our spy-able, default instance of RDFStorage
|
||||||
|
// Again, this lets us fake a triplestore backend in individual tests below.
|
||||||
|
rdfFactory.setStorage(rdfStorage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void serializationTest() throws Exception {
|
||||||
|
//Turn off the authorization system, otherwise we can't make the objects
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
// Create a Community
|
||||||
|
Community community = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Test Community")
|
||||||
|
.build();
|
||||||
|
// Ensure Community is written to test DB immediately
|
||||||
|
context.commit();
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
// Get the RDF identifiers for this new Community & our Site object
|
||||||
|
String communityIdentifier = RDFUtil.generateIdentifier(context, community);
|
||||||
|
String siteIdentifier = RDFUtil.generateIdentifier(context, siteService.findSite(context));
|
||||||
|
|
||||||
|
// Mock an RDF triplestore's response by returning the RDF conversion of our Community
|
||||||
|
// when rdfStorage.load() is called with the RDF identifier for this Community
|
||||||
|
doReturn(rdfConverter.convert(context, community)).when(rdfStorage).load(communityIdentifier);
|
||||||
|
|
||||||
|
// Perform a GET request on the RDF /handle path, using our new Community's Handle
|
||||||
|
ResponseEntity<String> response = getResponseAsString(SERIALIZE_PATH + "/" + community.getHandle());
|
||||||
|
// Expect a 200 response code, and text/turtle (RDF Turtle syntax) response
|
||||||
|
assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
|
||||||
|
assertThat(response.getHeaders().getContentType().toString(), equalTo("text/turtle;charset=UTF-8"));
|
||||||
|
|
||||||
|
// Turtle response should include the RDF identifier of Community
|
||||||
|
assertThat(response.getBody(), containsString(communityIdentifier));
|
||||||
|
// Turtle response should also note that this Community is part of our Site object
|
||||||
|
assertThat(response.getBody(), containsString("dspace:isPartOfRepository <" + siteIdentifier + "> ;"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void redirectionTest() throws Exception {
|
||||||
|
//Turn off the authorization system, otherwise we can't make the objects
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
// Create a Community
|
||||||
|
Community community = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Test Community")
|
||||||
|
.build();
|
||||||
|
// Ensure Community is written to test DB immediately (so that a lookup via handle will succeed below)
|
||||||
|
context.commit();
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String communityHandle = community.getHandle();
|
||||||
|
|
||||||
|
// Perform a GET request on the RDF /resource path, using this Community's Handle
|
||||||
|
ResponseEntity<String> response = getResponseAsString(REDIRECTION_PATH + "/" + communityHandle);
|
||||||
|
// Expect a 303 (See Other) response code, redirecting us to the HTTP URI of the Community
|
||||||
|
assertThat(response.getStatusCode(), equalTo(HttpStatus.SEE_OTHER));
|
||||||
|
// Expect location of redirection to be [dspace.url]/handle/[community_handle]
|
||||||
|
assertThat(response.getHeaders().getLocation(), equalTo(
|
||||||
|
URI.create(configurationService.getProperty("dspace.url") + "/handle/" + communityHandle + "/")));
|
||||||
|
}
|
||||||
|
}
|
@@ -387,6 +387,78 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe
|
|||||||
not(matchMetadata("dc.title", "Internal publication")))));
|
not(matchMetadata("dc.title", "Internal publication")))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/**
|
||||||
|
* This test was introduced to reproduce the bug DS-4269 Pagination links must be consistent also when there is not
|
||||||
|
* explicit pagination parameters in the request (i.e. defaults apply)
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void browsePaginationWithoutExplicitParams() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
//** GIVEN **
|
||||||
|
//1. A community-collection structure with one parent community and one collection.
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
|
||||||
|
|
||||||
|
//2. Twenty-one public items that are readable by Anonymous
|
||||||
|
for (int i = 0; i <= 20; i++) {
|
||||||
|
ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("Public item " + String.format("%02d", i))
|
||||||
|
.withIssueDate("2017-10-17")
|
||||||
|
.withAuthor("Test, Author" + String.format("%02d", i))
|
||||||
|
.withSubject("Java").withSubject("Unit Testing")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
//** WHEN **
|
||||||
|
//An anonymous user browses the items in the Browse by item endpoint
|
||||||
|
getClient().perform(get("/api/discover/browses/title/items"))
|
||||||
|
//** THEN **
|
||||||
|
//The status has to be 200 OK
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
//We expect the content type to be "application/hal+json;charset=UTF-8"
|
||||||
|
.andExpect(content().contentType(contentType))
|
||||||
|
//We expect 21 public items
|
||||||
|
.andExpect(jsonPath("$.page.size", is(20)))
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", is(21)))
|
||||||
|
.andExpect(jsonPath("$.page.totalPages", is(2)))
|
||||||
|
.andExpect(jsonPath("$.page.number", is(0)))
|
||||||
|
// embedded items are already checked by other test, we focus on links here
|
||||||
|
.andExpect(jsonPath("$._links.next.href", Matchers.containsString("/api/discover/browses/title/items?")))
|
||||||
|
.andExpect(jsonPath("$._links.last.href", Matchers.containsString("/api/discover/browses/title/items?")))
|
||||||
|
.andExpect(
|
||||||
|
jsonPath("$._links.first.href", Matchers.containsString("/api/discover/browses/title/items?")))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", Matchers.endsWith("/api/discover/browses/title/items")));
|
||||||
|
|
||||||
|
//** WHEN **
|
||||||
|
//An anonymous user browses the items in the Browse by item endpoint
|
||||||
|
getClient().perform(get("/api/discover/browses/author/entries"))
|
||||||
|
//** THEN **
|
||||||
|
//The status has to be 200 OK
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
//We expect the content type to be "application/hal+json;charset=UTF-8"
|
||||||
|
.andExpect(content().contentType(contentType))
|
||||||
|
//We expect 21 public items
|
||||||
|
.andExpect(jsonPath("$.page.size", is(20)))
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", is(21)))
|
||||||
|
.andExpect(jsonPath("$.page.totalPages", is(2)))
|
||||||
|
.andExpect(jsonPath("$.page.number", is(0)))
|
||||||
|
// embedded items are already checked by other test, we focus on links here
|
||||||
|
.andExpect(jsonPath("$._links.next.href",
|
||||||
|
Matchers.containsString("/api/discover/browses/author/entries?")))
|
||||||
|
.andExpect(jsonPath("$._links.last.href",
|
||||||
|
Matchers.containsString("/api/discover/browses/author/entries?")))
|
||||||
|
.andExpect(jsonPath("$._links.first.href",
|
||||||
|
Matchers.containsString("/api/discover/browses/author/entries?")))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", Matchers.endsWith("/api/discover/browses/author/entries")));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPaginationBrowseByDateIssuedItems() throws Exception {
|
public void testPaginationBrowseByDateIssuedItems() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.app.rest;
|
package org.dspace.app.rest;
|
||||||
|
|
||||||
|
import static com.jayway.jsonpath.JsonPath.read;
|
||||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||||
import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadata;
|
import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadata;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
@@ -21,6 +22,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
@@ -37,6 +39,7 @@ import org.dspace.app.rest.test.MetadataPatchSuite;
|
|||||||
import org.dspace.authorize.service.AuthorizeService;
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
import org.dspace.content.Collection;
|
import org.dspace.content.Collection;
|
||||||
import org.dspace.content.Community;
|
import org.dspace.content.Community;
|
||||||
|
import org.dspace.content.service.CommunityService;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.eperson.EPerson;
|
import org.dspace.eperson.EPerson;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
@@ -44,18 +47,22 @@ import org.junit.Test;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration Tests against the /api/core/communities endpoint (including any subpaths)
|
||||||
|
*/
|
||||||
public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest {
|
public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
CommunityConverter communityConverter;
|
CommunityConverter communityConverter;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
CommunityService communityService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
AuthorizeService authorizeService;
|
AuthorizeService authorizeService;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createTest() throws Exception {
|
public void createTest() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
|
||||||
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
CommunityRest comm = new CommunityRest();
|
CommunityRest comm = new CommunityRest();
|
||||||
// We send a name but the created community should set this to the title
|
// We send a name but the created community should set this to the title
|
||||||
@@ -86,41 +93,54 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
comm.setMetadata(metadataRest);
|
comm.setMetadata(metadataRest);
|
||||||
|
|
||||||
String authToken = getAuthToken(admin.getEmail(), password);
|
String authToken = getAuthToken(admin.getEmail(), password);
|
||||||
getClient(authToken).perform(post("/api/core/communities")
|
|
||||||
|
// Capture the UUID of the created Community (see andDo() below)
|
||||||
|
AtomicReference<UUID> idRef = new AtomicReference<UUID>();
|
||||||
|
try {
|
||||||
|
getClient(authToken).perform(post("/api/core/communities")
|
||||||
.content(mapper.writeValueAsBytes(comm))
|
.content(mapper.writeValueAsBytes(comm))
|
||||||
.contentType(contentType))
|
.contentType(contentType))
|
||||||
.andExpect(status().isCreated())
|
.andExpect(status().isCreated())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
.andExpect(jsonPath("$", Matchers.allOf(
|
.andExpect(jsonPath("$", Matchers.allOf(
|
||||||
hasJsonPath("$.id", not(empty())),
|
hasJsonPath("$.id", not(empty())),
|
||||||
hasJsonPath("$.uuid", not(empty())),
|
hasJsonPath("$.uuid", not(empty())),
|
||||||
hasJsonPath("$.name", is("Title Text")),
|
hasJsonPath("$.name", is("Title Text")),
|
||||||
hasJsonPath("$.handle", not(empty())),
|
hasJsonPath("$.handle", not(empty())),
|
||||||
hasJsonPath("$.type", is("community")),
|
hasJsonPath("$.type", is("community")),
|
||||||
hasJsonPath("$._links.collections.href", not(empty())),
|
hasJsonPath("$._links.collections.href", not(empty())),
|
||||||
hasJsonPath("$._links.logo.href", not(empty())),
|
hasJsonPath("$._links.logo.href", not(empty())),
|
||||||
hasJsonPath("$._links.subcommunities.href", not(empty())),
|
hasJsonPath("$._links.subcommunities.href", not(empty())),
|
||||||
hasJsonPath("$._links.self.href", not(empty())),
|
hasJsonPath("$._links.self.href", not(empty())),
|
||||||
hasJsonPath("$.metadata", Matchers.allOf(
|
hasJsonPath("$.metadata", Matchers.allOf(
|
||||||
matchMetadata("dc.description", "<p>Some cool HTML code here</p>"),
|
matchMetadata("dc.description", "<p>Some cool HTML code here</p>"),
|
||||||
matchMetadata("dc.description.abstract",
|
matchMetadata("dc.description.abstract",
|
||||||
"Sample top-level community created via the REST API"),
|
"Sample top-level community created via the REST API"),
|
||||||
matchMetadata("dc.description.tableofcontents", "<p>HTML News</p>"),
|
matchMetadata("dc.description.tableofcontents", "<p>HTML News</p>"),
|
||||||
matchMetadata("dc.rights", "Custom Copyright Text"),
|
matchMetadata("dc.rights", "Custom Copyright Text"),
|
||||||
matchMetadata("dc.title", "Title Text")
|
matchMetadata("dc.title", "Title Text")
|
||||||
)))));
|
)
|
||||||
|
)
|
||||||
|
)))
|
||||||
|
// capture "id" returned in JSON response
|
||||||
|
.andDo(result -> idRef
|
||||||
|
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));
|
||||||
|
} finally {
|
||||||
|
// Delete the created community (cleanup after ourselves!)
|
||||||
|
CommunityBuilder.deleteCommunity(idRef.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createWithParentTest() throws Exception {
|
public void createWithParentTest() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
|
||||||
//We turn off the authorization system in order to create the structure as defined below
|
//We turn off the authorization system in order to create the structure as defined below
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
//** GIVEN **
|
// Create a parent community to POST a new sub-community to
|
||||||
//1. A community-collection structure with one parent community with sub-community and one collection.
|
|
||||||
parentCommunity = CommunityBuilder.createCommunity(context)
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
.withName("Parent Community")
|
.withName("Parent Community")
|
||||||
.build();
|
.build();
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
CommunityRest comm = new CommunityRest();
|
CommunityRest comm = new CommunityRest();
|
||||||
@@ -140,23 +160,26 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
new MetadataValueRest("Title Text")));
|
new MetadataValueRest("Title Text")));
|
||||||
|
|
||||||
String authToken = getAuthToken(admin.getEmail(), password);
|
String authToken = getAuthToken(admin.getEmail(), password);
|
||||||
getClient(authToken).perform(post("/api/core/communities")
|
// Capture the UUID of the created Community (see andDo() below)
|
||||||
|
AtomicReference<UUID> idRef = new AtomicReference<UUID>();
|
||||||
|
try {
|
||||||
|
getClient(authToken).perform(post("/api/core/communities")
|
||||||
.content(mapper.writeValueAsBytes(comm))
|
.content(mapper.writeValueAsBytes(comm))
|
||||||
.param("parent", parentCommunity.getID().toString())
|
.param("parent", parentCommunity.getID().toString())
|
||||||
.contentType(contentType))
|
.contentType(contentType))
|
||||||
.andExpect(status().isCreated())
|
.andExpect(status().isCreated())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
.andExpect(jsonPath("$", Matchers.allOf(
|
.andExpect(jsonPath("$", Matchers.allOf(
|
||||||
hasJsonPath("$.id", not(empty())),
|
hasJsonPath("$.id", not(empty())),
|
||||||
hasJsonPath("$.uuid", not(empty())),
|
hasJsonPath("$.uuid", not(empty())),
|
||||||
hasJsonPath("$.name", is("Title Text")),
|
hasJsonPath("$.name", is("Title Text")),
|
||||||
hasJsonPath("$.handle", not(empty())),
|
hasJsonPath("$.handle", not(empty())),
|
||||||
hasJsonPath("$.type", is("community")),
|
hasJsonPath("$.type", is("community")),
|
||||||
hasJsonPath("$._links.collections.href", not(empty())),
|
hasJsonPath("$._links.collections.href", not(empty())),
|
||||||
hasJsonPath("$._links.logo.href", not(empty())),
|
hasJsonPath("$._links.logo.href", not(empty())),
|
||||||
hasJsonPath("$._links.subcommunities.href", not(empty())),
|
hasJsonPath("$._links.subcommunities.href", not(empty())),
|
||||||
hasJsonPath("$._links.self.href", not(empty())),
|
hasJsonPath("$._links.self.href", not(empty())),
|
||||||
hasJsonPath("$.metadata", Matchers.allOf(
|
hasJsonPath("$.metadata", Matchers.allOf(
|
||||||
MetadataMatcher.matchMetadata("dc.description",
|
MetadataMatcher.matchMetadata("dc.description",
|
||||||
"<p>Some cool HTML code here</p>"),
|
"<p>Some cool HTML code here</p>"),
|
||||||
MetadataMatcher.matchMetadata("dc.description.abstract",
|
MetadataMatcher.matchMetadata("dc.description.abstract",
|
||||||
@@ -167,13 +190,18 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
"Custom Copyright Text"),
|
"Custom Copyright Text"),
|
||||||
MetadataMatcher.matchMetadata("dc.title",
|
MetadataMatcher.matchMetadata("dc.title",
|
||||||
"Title Text")
|
"Title Text")
|
||||||
)))));
|
)
|
||||||
|
)
|
||||||
|
)))
|
||||||
|
// capture "id" returned in JSON response
|
||||||
|
.andDo(result -> idRef
|
||||||
|
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));
|
||||||
|
} finally {
|
||||||
|
// Delete the created community (cleanup after ourselves!)
|
||||||
|
CommunityBuilder.deleteCommunity(idRef.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createUnauthorizedTest() throws Exception {
|
public void createUnauthorizedTest() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
@@ -854,6 +882,7 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void patchCommunityMetadataAuthorized() throws Exception {
|
public void patchCommunityMetadataAuthorized() throws Exception {
|
||||||
runPatchMetadataTests(admin, 200);
|
runPatchMetadataTests(admin, 200);
|
||||||
}
|
}
|
||||||
|
@@ -1768,6 +1768,12 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
new MetadataPatchSuite().runWith(getClient(token), "/api/core/items/" + item.getID(), expectedStatus);
|
new MetadataPatchSuite().runWith(getClient(token), "/api/core/items/" + item.getID(), expectedStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test will try creating an item with the InArchive property set to false. This endpoint does not allow
|
||||||
|
* us to create Items which aren't final (final means that they'd be in archive) and thus it'll throw a
|
||||||
|
* BadRequestException which is what we're testing for
|
||||||
|
* @throws Exception If something goes wrong
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testCreateItemInArchiveFalseBadRequestException() throws Exception {
|
public void testCreateItemInArchiveFalseBadRequestException() throws Exception {
|
||||||
|
|
||||||
|
@@ -45,7 +45,6 @@ import org.dspace.content.service.RelationshipTypeService;
|
|||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.I18nUtil;
|
import org.dspace.core.I18nUtil;
|
||||||
import org.dspace.eperson.EPerson;
|
import org.dspace.eperson.EPerson;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
@@ -195,7 +194,6 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
.withName("Sub Community")
|
.withName("Sub Community")
|
||||||
.build();
|
.build();
|
||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
|
|
||||||
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
||||||
|
|
||||||
Item author1 = ItemBuilder.createItem(context, col1)
|
Item author1 = ItemBuilder.createItem(context, col1)
|
||||||
@@ -269,7 +267,6 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
.withName("Sub Community")
|
.withName("Sub Community")
|
||||||
.build();
|
.build();
|
||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
|
|
||||||
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
||||||
|
|
||||||
Item author1 = ItemBuilder.createItem(context, col1)
|
Item author1 = ItemBuilder.createItem(context, col1)
|
||||||
@@ -1420,7 +1417,14 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore
|
/**
|
||||||
|
* This test will create a relationship with author 1 - publication 1
|
||||||
|
* Then modify this relationship by changing the left item to author 2 via PUT > Verify
|
||||||
|
* Then modify this relationship by changing the right item to publication 2 via PUT > Verify
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
public void putRelationshipAdminAccess() throws Exception {
|
public void putRelationshipAdminAccess() throws Exception {
|
||||||
|
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
@@ -1432,7 +1436,6 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
.withName("Sub Community")
|
.withName("Sub Community")
|
||||||
.build();
|
.build();
|
||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
|
|
||||||
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
||||||
|
|
||||||
Item author1 = ItemBuilder.createItem(context, col1)
|
Item author1 = ItemBuilder.createItem(context, col1)
|
||||||
@@ -1456,6 +1459,13 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
.withRelationshipType("Publication")
|
.withRelationshipType("Publication")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
Item publication2 = ItemBuilder.createItem(context, col3)
|
||||||
|
.withTitle("Publication2")
|
||||||
|
.withAuthor("Testy, TEst")
|
||||||
|
.withIssueDate("2015-01-01")
|
||||||
|
.withRelationshipType("Publication")
|
||||||
|
.build();
|
||||||
|
|
||||||
RelationshipType isAuthorOfPublicationRelationshipType = relationshipTypeService
|
RelationshipType isAuthorOfPublicationRelationshipType = relationshipTypeService
|
||||||
.findbyTypesAndLabels(context, entityTypeService.findByEntityType(context, "Publication"),
|
.findbyTypesAndLabels(context, entityTypeService.findByEntityType(context, "Publication"),
|
||||||
entityTypeService.findByEntityType(context, "Person"),
|
entityTypeService.findByEntityType(context, "Person"),
|
||||||
@@ -1485,19 +1495,37 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
Map<String,Object> map = mapper.readValue(content, Map.class);
|
Map<String,Object> map = mapper.readValue(content, Map.class);
|
||||||
String id = String.valueOf(map.get("id"));
|
String id = String.valueOf(map.get("id"));
|
||||||
|
|
||||||
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id)
|
//Modify the left item in the relationship publication > publication 2
|
||||||
.contentType(MediaType.parseMediaType
|
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id + "/leftItem")
|
||||||
(org.springframework.data.rest.webmvc.RestMediaTypes
|
.contentType(MediaType.parseMediaType
|
||||||
.TEXT_URI_LIST_VALUE))
|
(org.springframework.data.rest.webmvc.RestMediaTypes
|
||||||
.content(
|
.TEXT_URI_LIST_VALUE))
|
||||||
"https://localhost:8080/spring-rest/api/core/items/" + publication.getID() + "\n" +
|
.content(
|
||||||
"https://localhost:8080/spring-rest/api/core/items/" + author2.getID()))
|
"https://localhost:8080/spring-rest/api/core/items/" + publication2.getID()))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andReturn();
|
.andReturn();
|
||||||
|
|
||||||
|
//verify left item change and other not changed
|
||||||
getClient(token).perform(get("/api/core/relationships/" + id))
|
getClient(token).perform(get("/api/core/relationships/" + id))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.rightId", is(author2.getID().toString())));
|
.andExpect(jsonPath("$.leftId", is(publication2.getID().toString())))
|
||||||
|
.andExpect(jsonPath("$.rightId", is(author1.getID().toString())));
|
||||||
|
|
||||||
|
//Modify the right item in the relationship publication > publication 2
|
||||||
|
MvcResult mvcResult3 = getClient(token).perform(put("/api/core/relationships/" + id + "/rightItem")
|
||||||
|
.contentType(MediaType.parseMediaType
|
||||||
|
(org.springframework.data.rest.webmvc.RestMediaTypes
|
||||||
|
.TEXT_URI_LIST_VALUE))
|
||||||
|
.content(
|
||||||
|
"https://localhost:8080/spring-rest/api/core/items/" + author2.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
//verify right item change and other not changed
|
||||||
|
getClient(token).perform(get("/api/core/relationships/" + id))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.rightId", is(author2.getID().toString())))
|
||||||
|
.andExpect(jsonPath("$.leftId", is(publication2.getID().toString())));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1506,7 +1534,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
* Change it to a relationship between publication 1 and author 2
|
* Change it to a relationship between publication 1 and author 2
|
||||||
* Verify this is possible for a user with WRITE permissions on author 1 and author 2
|
* Verify this is possible for a user with WRITE permissions on author 1 and author 2
|
||||||
*/
|
*/
|
||||||
@Ignore
|
@Test
|
||||||
public void putRelationshipWriteAccessOnAuthors() throws Exception {
|
public void putRelationshipWriteAccessOnAuthors() throws Exception {
|
||||||
|
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
@@ -1518,7 +1546,6 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
.withName("Sub Community")
|
.withName("Sub Community")
|
||||||
.build();
|
.build();
|
||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
|
|
||||||
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
||||||
|
|
||||||
Item author1 = ItemBuilder.createItem(context, col1)
|
Item author1 = ItemBuilder.createItem(context, col1)
|
||||||
@@ -1580,17 +1607,17 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
Map<String,Object> map = mapper.readValue(content, Map.class);
|
Map<String,Object> map = mapper.readValue(content, Map.class);
|
||||||
String id = String.valueOf(map.get("id"));
|
String id = String.valueOf(map.get("id"));
|
||||||
|
|
||||||
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id)
|
//change right item from author 1 > author 2
|
||||||
.contentType(MediaType.parseMediaType("text/uri-list"))
|
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id + "/rightItem")
|
||||||
.content(
|
.contentType(MediaType.parseMediaType("text/uri-list"))
|
||||||
"https://localhost:8080/spring-rest/api/core/items/" + publication.getID() + "\n" +
|
.content("https://localhost:8080/spring-rest/api/core/items/" + author2.getID()))
|
||||||
"https://localhost:8080/spring-rest/api/core/items/" + author2.getID()))
|
.andExpect(status().isOk())
|
||||||
.andExpect(status().isOk())
|
.andReturn();
|
||||||
.andReturn();
|
//verify change and other not changed
|
||||||
|
|
||||||
getClient(token).perform(get("/api/core/relationships/" + id))
|
getClient(token).perform(get("/api/core/relationships/" + id))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.rightId", is(author2.getID().toString())));
|
.andExpect(jsonPath("$.rightId", is(author2.getID().toString())))
|
||||||
|
.andExpect(jsonPath("$.leftId", is(publication.getID().toString())));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1599,7 +1626,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
* Change it to a relationship between publication 1 and author 2
|
* Change it to a relationship between publication 1 and author 2
|
||||||
* Verify this is possible for a user with WRITE permissions on publication 1
|
* Verify this is possible for a user with WRITE permissions on publication 1
|
||||||
*/
|
*/
|
||||||
@Ignore
|
@Test
|
||||||
public void putRelationshipWriteAccessOnPublication() throws Exception {
|
public void putRelationshipWriteAccessOnPublication() throws Exception {
|
||||||
|
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
@@ -1611,7 +1638,6 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
.withName("Sub Community")
|
.withName("Sub Community")
|
||||||
.build();
|
.build();
|
||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
|
|
||||||
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
||||||
|
|
||||||
Item author1 = ItemBuilder.createItem(context, col1)
|
Item author1 = ItemBuilder.createItem(context, col1)
|
||||||
@@ -1671,18 +1697,17 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
String content = mvcResult.getResponse().getContentAsString();
|
String content = mvcResult.getResponse().getContentAsString();
|
||||||
Map<String,Object> map = mapper.readValue(content, Map.class);
|
Map<String,Object> map = mapper.readValue(content, Map.class);
|
||||||
String id = String.valueOf(map.get("id"));
|
String id = String.valueOf(map.get("id"));
|
||||||
|
//change rightItem from author1 > author2
|
||||||
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id)
|
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id + "/rightItem")
|
||||||
.contentType(MediaType.parseMediaType("text/uri-list"))
|
.contentType(MediaType.parseMediaType("text/uri-list"))
|
||||||
.content(
|
.content("https://localhost:8080/spring-rest/api/core/items/" + author2.getID()))
|
||||||
"https://localhost:8080/spring-rest/api/core/items/" + publication.getID() + "\n" +
|
.andExpect(status().isOk())
|
||||||
"https://localhost:8080/spring-rest/api/core/items/" + author2.getID()))
|
.andReturn();
|
||||||
.andExpect(status().isOk())
|
//verify right item change and other not changed
|
||||||
.andReturn();
|
|
||||||
|
|
||||||
getClient(token).perform(get("/api/core/relationships/" + id))
|
getClient(token).perform(get("/api/core/relationships/" + id))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.rightId", is(author2.getID().toString())));
|
.andExpect(jsonPath("$.rightId", is(author2.getID().toString())))
|
||||||
|
.andExpect(jsonPath("$.leftId", is(publication.getID().toString())));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1692,7 +1717,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
* Change it to a relationship between publication 2 and author 1
|
* Change it to a relationship between publication 2 and author 1
|
||||||
* Verify this is possible for a user with WRITE permissions on publication 1 and publication 2
|
* Verify this is possible for a user with WRITE permissions on publication 1 and publication 2
|
||||||
*/
|
*/
|
||||||
@Ignore
|
@Test
|
||||||
public void putRelationshipWriteAccessOnPublications() throws Exception {
|
public void putRelationshipWriteAccessOnPublications() throws Exception {
|
||||||
|
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
@@ -1704,7 +1729,6 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
.withName("Sub Community")
|
.withName("Sub Community")
|
||||||
.build();
|
.build();
|
||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
|
|
||||||
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
||||||
|
|
||||||
Item author1 = ItemBuilder.createItem(context, col1)
|
Item author1 = ItemBuilder.createItem(context, col1)
|
||||||
@@ -1714,13 +1738,6 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
.withRelationshipType("Person")
|
.withRelationshipType("Person")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Item author2 = ItemBuilder.createItem(context, col1)
|
|
||||||
.withTitle("Author2")
|
|
||||||
.withIssueDate("2017-10-12")
|
|
||||||
.withAuthor("Smith, Donalaze")
|
|
||||||
.withRelationshipType("Person")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Item publication1 = ItemBuilder.createItem(context, col3)
|
Item publication1 = ItemBuilder.createItem(context, col3)
|
||||||
.withTitle("Publication1")
|
.withTitle("Publication1")
|
||||||
.withAuthor("Testy, TEst")
|
.withAuthor("Testy, TEst")
|
||||||
@@ -1771,19 +1788,17 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
String content = mvcResult.getResponse().getContentAsString();
|
String content = mvcResult.getResponse().getContentAsString();
|
||||||
Map<String,Object> map = mapper.readValue(content, Map.class);
|
Map<String,Object> map = mapper.readValue(content, Map.class);
|
||||||
String id = String.valueOf(map.get("id"));
|
String id = String.valueOf(map.get("id"));
|
||||||
|
//change leftItem
|
||||||
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id)
|
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id + "/leftItem")
|
||||||
.contentType(MediaType.parseMediaType("text/uri-list"))
|
.contentType(MediaType.parseMediaType("text/uri-list"))
|
||||||
.content(
|
.content("https://localhost:8080/spring-rest/api/core/items/" + publication2.getID()))
|
||||||
"https://localhost:8080/spring-rest/api/core/items/" + publication2.getID() + "\n" +
|
.andExpect(status().isOk())
|
||||||
"https://localhost:8080/spring-rest/api/core/items/" + author1.getID()))
|
.andReturn();
|
||||||
.andExpect(status().isOk())
|
//verify change and other not changed
|
||||||
.andReturn();
|
|
||||||
|
|
||||||
getClient(token).perform(get("/api/core/relationships/" + id))
|
getClient(token).perform(get("/api/core/relationships/" + id))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.leftId", is(publication2.getID().toString())));
|
.andExpect(jsonPath("$.leftId", is(publication2.getID().toString())))
|
||||||
|
.andExpect(jsonPath("$.rightId", is(author1.getID().toString())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1792,7 +1807,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
* Change it to a relationship between publication 2 and author 1
|
* Change it to a relationship between publication 2 and author 1
|
||||||
* Verify this is possible for a user with WRITE permissions on author 1
|
* Verify this is possible for a user with WRITE permissions on author 1
|
||||||
*/
|
*/
|
||||||
@Ignore
|
@Test
|
||||||
public void putRelationshipWriteAccessOnAuthor() throws Exception {
|
public void putRelationshipWriteAccessOnAuthor() throws Exception {
|
||||||
|
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
@@ -1804,7 +1819,6 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
.withName("Sub Community")
|
.withName("Sub Community")
|
||||||
.build();
|
.build();
|
||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
|
|
||||||
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
||||||
|
|
||||||
Item author1 = ItemBuilder.createItem(context, col1)
|
Item author1 = ItemBuilder.createItem(context, col1)
|
||||||
@@ -1814,13 +1828,6 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
.withRelationshipType("Person")
|
.withRelationshipType("Person")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Item author2 = ItemBuilder.createItem(context, col1)
|
|
||||||
.withTitle("Author2")
|
|
||||||
.withIssueDate("2017-10-12")
|
|
||||||
.withAuthor("Smith, Donalaze")
|
|
||||||
.withRelationshipType("Person")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Item publication1 = ItemBuilder.createItem(context, col3)
|
Item publication1 = ItemBuilder.createItem(context, col3)
|
||||||
.withTitle("Publication1")
|
.withTitle("Publication1")
|
||||||
.withAuthor("Testy, TEst")
|
.withAuthor("Testy, TEst")
|
||||||
@@ -1872,19 +1879,17 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
String content = mvcResult.getResponse().getContentAsString();
|
String content = mvcResult.getResponse().getContentAsString();
|
||||||
Map<String,Object> map = mapper.readValue(content, Map.class);
|
Map<String,Object> map = mapper.readValue(content, Map.class);
|
||||||
String id = String.valueOf(map.get("id"));
|
String id = String.valueOf(map.get("id"));
|
||||||
|
//change left item
|
||||||
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id)
|
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id + "/leftItem")
|
||||||
.contentType(MediaType.parseMediaType("text/uri-list"))
|
.contentType(MediaType.parseMediaType("text/uri-list"))
|
||||||
.content(
|
.content("https://localhost:8080/spring-rest/api/core/items/" + publication2.getID()))
|
||||||
"https://localhost:8080/spring-rest/api/core/items/" + publication2.getID() + "\n" +
|
.andExpect(status().isOk())
|
||||||
"https://localhost:8080/spring-rest/api/core/items/" + author1.getID()))
|
.andReturn();
|
||||||
.andExpect(status().isOk())
|
//verify change and other not changed
|
||||||
.andReturn();
|
|
||||||
|
|
||||||
getClient(token).perform(get("/api/core/relationships/" + id))
|
getClient(token).perform(get("/api/core/relationships/" + id))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.leftId", is(publication2.getID().toString())));
|
.andExpect(jsonPath("$.leftId", is(publication2.getID().toString())))
|
||||||
|
.andExpect(jsonPath("$.rightId", is(author1.getID().toString())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1893,7 +1898,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
* Change it to a relationship between publication 1 and author 2
|
* Change it to a relationship between publication 1 and author 2
|
||||||
* Verify this is NOT possible for a user without WRITE permissions
|
* Verify this is NOT possible for a user without WRITE permissions
|
||||||
*/
|
*/
|
||||||
@Ignore
|
@Test
|
||||||
public void putRelationshipNoAccess() throws Exception {
|
public void putRelationshipNoAccess() throws Exception {
|
||||||
|
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
@@ -1905,7 +1910,6 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
.withName("Sub Community")
|
.withName("Sub Community")
|
||||||
.build();
|
.build();
|
||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
|
|
||||||
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
||||||
|
|
||||||
Item author1 = ItemBuilder.createItem(context, col1)
|
Item author1 = ItemBuilder.createItem(context, col1)
|
||||||
@@ -1964,15 +1968,17 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
Map<String,Object> map = mapper.readValue(content, Map.class);
|
Map<String,Object> map = mapper.readValue(content, Map.class);
|
||||||
String id = String.valueOf(map.get("id"));
|
String id = String.valueOf(map.get("id"));
|
||||||
token = getAuthToken(user.getEmail(), password);
|
token = getAuthToken(user.getEmail(), password);
|
||||||
|
//attempt change, expect not allowed
|
||||||
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id)
|
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id + "/rightItem")
|
||||||
.contentType(MediaType.parseMediaType("text/uri-list"))
|
.contentType(MediaType.parseMediaType("text/uri-list"))
|
||||||
.content(
|
.content("https://localhost:8080/spring-rest/api/core/items/" + author2.getID()))
|
||||||
"https://localhost:8080/spring-rest/api/core/items/" + publication.getID() + "\n" +
|
.andExpect(status().isForbidden())
|
||||||
"https://localhost:8080/spring-rest/api/core/items/" + author2.getID()))
|
.andReturn();
|
||||||
.andExpect(status().isForbidden())
|
//verify nothing changed
|
||||||
.andReturn();
|
getClient(token).perform(get("/api/core/relationships/" + id))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.leftId", is(publication.getID().toString())))
|
||||||
|
.andExpect(jsonPath("$.rightId", is(author1.getID().toString())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1980,7 +1986,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
* Change it to a relationship between publication 1 and author 2
|
* Change it to a relationship between publication 1 and author 2
|
||||||
* Verify this is NOT possible for a user with WRITE permissions on author 1
|
* Verify this is NOT possible for a user with WRITE permissions on author 1
|
||||||
*/
|
*/
|
||||||
@Ignore
|
@Test
|
||||||
public void putRelationshipOnlyAccessOnOneAuthor() throws Exception {
|
public void putRelationshipOnlyAccessOnOneAuthor() throws Exception {
|
||||||
|
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
@@ -2053,15 +2059,17 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
Map<String,Object> map = mapper.readValue(content, Map.class);
|
Map<String,Object> map = mapper.readValue(content, Map.class);
|
||||||
String id = String.valueOf(map.get("id"));
|
String id = String.valueOf(map.get("id"));
|
||||||
token = getAuthToken(user.getEmail(), password);
|
token = getAuthToken(user.getEmail(), password);
|
||||||
|
//attempt right item change, expect not allowed
|
||||||
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id)
|
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id + "/rightItem")
|
||||||
.contentType(MediaType.parseMediaType("text/uri-list"))
|
.contentType(MediaType.parseMediaType("text/uri-list"))
|
||||||
.content(
|
.content("https://localhost:8080/spring-rest/api/core/items/" + author2.getID()))
|
||||||
"https://localhost:8080/spring-rest/api/core/items/" + publication.getID() + "\n" +
|
.andExpect(status().isForbidden())
|
||||||
"https://localhost:8080/spring-rest/api/core/items/" + author2.getID()))
|
.andReturn();
|
||||||
.andExpect(status().isForbidden())
|
//verify not changed
|
||||||
.andReturn();
|
getClient(token).perform(get("/api/core/relationships/" + id))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.leftId", is(publication.getID().toString())))
|
||||||
|
.andExpect(jsonPath("$.rightId", is(author1.getID().toString())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2069,7 +2077,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
* Change it to a relationship between publication 2 and author 1
|
* Change it to a relationship between publication 2 and author 1
|
||||||
* Verify this is NOT possible for a user with WRITE permissions on publication 1
|
* Verify this is NOT possible for a user with WRITE permissions on publication 1
|
||||||
*/
|
*/
|
||||||
@Ignore
|
@Test
|
||||||
public void putRelationshipOnlyAccessOnOnePublication() throws Exception {
|
public void putRelationshipOnlyAccessOnOnePublication() throws Exception {
|
||||||
|
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
@@ -2081,7 +2089,6 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
.withName("Sub Community")
|
.withName("Sub Community")
|
||||||
.build();
|
.build();
|
||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
|
|
||||||
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
|
||||||
|
|
||||||
Item author1 = ItemBuilder.createItem(context, col1)
|
Item author1 = ItemBuilder.createItem(context, col1)
|
||||||
@@ -2091,13 +2098,6 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
.withRelationshipType("Person")
|
.withRelationshipType("Person")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Item author2 = ItemBuilder.createItem(context, col1)
|
|
||||||
.withTitle("Author2")
|
|
||||||
.withIssueDate("2017-10-12")
|
|
||||||
.withAuthor("Smith, Donalaze")
|
|
||||||
.withRelationshipType("Person")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Item publication1 = ItemBuilder.createItem(context, col3)
|
Item publication1 = ItemBuilder.createItem(context, col3)
|
||||||
.withTitle("Publication1")
|
.withTitle("Publication1")
|
||||||
.withAuthor("Testy, TEst")
|
.withAuthor("Testy, TEst")
|
||||||
@@ -2147,18 +2147,109 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
String content = mvcResult.getResponse().getContentAsString();
|
String content = mvcResult.getResponse().getContentAsString();
|
||||||
Map<String,Object> map = mapper.readValue(content, Map.class);
|
Map<String,Object> map = mapper.readValue(content, Map.class);
|
||||||
String id = String.valueOf(map.get("id"));
|
String id = String.valueOf(map.get("id"));
|
||||||
|
//attempt left item change, expect not allowed
|
||||||
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id)
|
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id + "/leftItem")
|
||||||
.contentType(MediaType.parseMediaType("text/uri-list"))
|
.contentType(MediaType.parseMediaType("text/uri-list"))
|
||||||
.content(
|
.content("https://localhost:8080/spring-rest/api/core/items/" + publication2.getID()))
|
||||||
"https://localhost:8080/spring-rest/api/core/items/" + publication2.getID() + "\n" +
|
.andExpect(status().isForbidden())
|
||||||
"https://localhost:8080/spring-rest/api/core/items/" + author1.getID()))
|
.andReturn();
|
||||||
.andExpect(status().isForbidden())
|
//verify not changed
|
||||||
.andReturn();
|
|
||||||
|
|
||||||
getClient(token).perform(get("/api/core/relationships/" + id))
|
getClient(token).perform(get("/api/core/relationships/" + id))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.leftId", is(publication1.getID().toString())));
|
.andExpect(jsonPath("$.leftId", is(publication1.getID().toString())))
|
||||||
|
.andExpect(jsonPath("$.rightId", is(author1.getID().toString())));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Test
|
||||||
|
public void putRelationshipWithNonexistentID() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
|
||||||
|
.withName("Sub Community")
|
||||||
|
.build();
|
||||||
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
|
Item publication1 = ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("Publication1")
|
||||||
|
.withAuthor("Testy, TEst")
|
||||||
|
.withIssueDate("2015-01-01")
|
||||||
|
.withRelationshipType("Publication")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
int nonexistentRelationshipID = 404404404;
|
||||||
|
//attempt left item change on non-existent relationship
|
||||||
|
MvcResult mvcResult = getClient(token).perform(
|
||||||
|
put("/api/core/relationships/" + nonexistentRelationshipID + "/leftItem")
|
||||||
|
.contentType(MediaType.parseMediaType("text/uri-list"))
|
||||||
|
.content("https://localhost:8080/spring-rest/api/core/items/" + publication1.getID()))
|
||||||
|
.andExpect(status().isNotFound())
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void putRelationshipWithInvalidItemIDInBody() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
|
||||||
|
.withName("Sub Community")
|
||||||
|
.build();
|
||||||
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
|
Item author1 = ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("Author1")
|
||||||
|
.withIssueDate("2017-10-17")
|
||||||
|
.withAuthor("Smith, Donald")
|
||||||
|
.withRelationshipType("Person")
|
||||||
|
.build();
|
||||||
|
Item publication1 = ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("Publication1")
|
||||||
|
.withAuthor("Testy, TEst")
|
||||||
|
.withIssueDate("2015-01-01")
|
||||||
|
.withRelationshipType("Publication")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
RelationshipType isAuthorOfPublicationRelationshipType = relationshipTypeService
|
||||||
|
.findbyTypesAndLabels(context, entityTypeService.findByEntityType(context, "Publication"),
|
||||||
|
entityTypeService.findByEntityType(context, "Person"),
|
||||||
|
"isAuthorOfPublication", "isPublicationOfAuthor");
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
MvcResult mvcResult = getClient(token).perform(post("/api/core/relationships")
|
||||||
|
.param("relationshipType",
|
||||||
|
isAuthorOfPublicationRelationshipType.getID()
|
||||||
|
.toString())
|
||||||
|
.contentType(MediaType.parseMediaType("text/uri-list"))
|
||||||
|
.content(
|
||||||
|
"https://localhost:8080/spring-rest/api/core/items/" + publication1.getID() + "\n" +
|
||||||
|
"https://localhost:8080/spring-rest/api/core/items/" + author1.getID()))
|
||||||
|
.andExpect(status().isCreated())
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
String content = mvcResult.getResponse().getContentAsString();
|
||||||
|
Map<String, Object> map = mapper.readValue(content, Map.class);
|
||||||
|
String id = String.valueOf(map.get("id"));
|
||||||
|
|
||||||
|
int nonexistentItemID = 404404404;
|
||||||
|
//attempt left item change on non-existent relationship
|
||||||
|
MvcResult mvcResult2 = getClient(token).perform(put("/api/core/relationships/" + id + "/leftItem")
|
||||||
|
.contentType(MediaType.parseMediaType("text/uri-list"))
|
||||||
|
.content("https://localhost:8080/spring-rest/api/core/items/" + nonexistentItemID))
|
||||||
|
.andExpect(status().isUnprocessableEntity())
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -10,6 +10,7 @@ package org.dspace.app.rest.builder;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.CharEncoding;
|
import org.apache.commons.lang3.CharEncoding;
|
||||||
@@ -92,4 +93,26 @@ public class CommunityBuilder extends AbstractDSpaceObjectBuilder<Community> {
|
|||||||
protected DSpaceObjectService<Community> getService() {
|
protected DSpaceObjectService<Community> getService() {
|
||||||
return communityService;
|
return communityService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the Test Community referred to by the given UUID
|
||||||
|
* @param uuid UUID of Test Community to delete
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static void deleteCommunity(UUID uuid) throws SQLException, IOException {
|
||||||
|
try (Context c = new Context()) {
|
||||||
|
c.turnOffAuthorisationSystem();
|
||||||
|
Community community = communityService.find(c, uuid);
|
||||||
|
if (community != null) {
|
||||||
|
try {
|
||||||
|
communityService.delete(c, community);
|
||||||
|
} catch (AuthorizeException e) {
|
||||||
|
// cannot occur, just wrap it to make the compiler happy
|
||||||
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.complete();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@ import org.apache.commons.io.Charsets;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.dspace.app.rest.Application;
|
import org.dspace.app.rest.Application;
|
||||||
import org.dspace.app.rest.model.patch.Operation;
|
import org.dspace.app.rest.model.patch.Operation;
|
||||||
|
import org.dspace.app.rest.utils.DSpaceConfigurationInitializer;
|
||||||
import org.dspace.app.rest.utils.DSpaceKernelInitializer;
|
import org.dspace.app.rest.utils.DSpaceKernelInitializer;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -44,11 +45,18 @@ import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
|
|||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract controller integration test class that will take care of setting up the
|
* Abstract integration test class that will take care of setting up the Spring Boot environment to run
|
||||||
* Spring Boot environment to run the integration test
|
* integration tests against @Controller classes (Spring Controllers).
|
||||||
|
* <P>
|
||||||
|
* This Abstract class uses Spring Boot's default mock environment testing scheme, which relies on MockMvc to "mock"
|
||||||
|
* a webserver and call Spring Controllers directly. This avoids the cost of starting a webserver.
|
||||||
|
* <P>
|
||||||
|
* If you need to test a Servlet (or something not a Spring Controller), you will NOT be able to use this class.
|
||||||
|
* Instead, please use the AbstractWebClientIntegrationTest in this same package.
|
||||||
*
|
*
|
||||||
* @author Tom Desair
|
* @author Tom Desair
|
||||||
* @author Tim Donohue
|
* @author Tim Donohue
|
||||||
|
* @see org.dspace.app.rest.test.AbstractWebClientIntegrationTest
|
||||||
*/
|
*/
|
||||||
// Run tests with JUnit 4 and Spring TestContext Framework
|
// Run tests with JUnit 4 and Spring TestContext Framework
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@@ -56,8 +64,8 @@ import org.springframework.web.context.WebApplicationContext;
|
|||||||
// NOTE: By default, Spring caches and reuses ApplicationContext for each integration test (to speed up tests)
|
// NOTE: By default, Spring caches and reuses ApplicationContext for each integration test (to speed up tests)
|
||||||
// See: https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#integration-testing
|
// See: https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#integration-testing
|
||||||
@SpringBootTest(classes = Application.class)
|
@SpringBootTest(classes = Application.class)
|
||||||
// Load DSpaceKernelInitializer in Spring ApplicationContext (to initialize DSpace Kernel)
|
// Load DSpace initializers in Spring ApplicationContext (to initialize DSpace Kernel & Configuration)
|
||||||
@ContextConfiguration(initializers = DSpaceKernelInitializer.class)
|
@ContextConfiguration(initializers = { DSpaceKernelInitializer.class, DSpaceConfigurationInitializer.class })
|
||||||
// Tell Spring to make ApplicationContext an instance of WebApplicationContext (for web-based tests)
|
// Tell Spring to make ApplicationContext an instance of WebApplicationContext (for web-based tests)
|
||||||
@WebAppConfiguration
|
@WebAppConfiguration
|
||||||
public class AbstractControllerIntegrationTest extends AbstractIntegrationTestWithDatabase {
|
public class AbstractControllerIntegrationTest extends AbstractIntegrationTestWithDatabase {
|
||||||
|
@@ -184,6 +184,9 @@ public class AbstractIntegrationTestWithDatabase extends AbstractDSpaceIntegrati
|
|||||||
.getServiceByName(SearchService.class.getName(), MockSolrServiceImpl.class);
|
.getServiceByName(SearchService.class.getName(), MockSolrServiceImpl.class);
|
||||||
searchService.reset();
|
searchService.reset();
|
||||||
|
|
||||||
|
// Reload our ConfigurationService (to reset configs to defaults again)
|
||||||
|
DSpaceServicesFactory.getInstance().getConfigurationService().reloadConfig();
|
||||||
|
|
||||||
// NOTE: we explicitly do NOT destroy our default eperson & admin as they
|
// NOTE: we explicitly do NOT destroy our default eperson & admin as they
|
||||||
// are cached and reused for all tests. This speeds up all tests.
|
// are cached and reused for all tests. This speeds up all tests.
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@@ -0,0 +1,118 @@
|
|||||||
|
/**
|
||||||
|
* 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.rest.test;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.dspace.app.rest.Application;
|
||||||
|
import org.dspace.app.rest.utils.DSpaceConfigurationInitializer;
|
||||||
|
import org.dspace.app.rest.utils.DSpaceKernelInitializer;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.context.embedded.LocalServerPort;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract web client integration test class that will initialize the Spring Boot test environment by starting up
|
||||||
|
* a full test webserver (on a random port).
|
||||||
|
* <P>
|
||||||
|
* As running a test webserver is an expensive operation, this Abstract class is only necessary to perform
|
||||||
|
* Integration Tests on *Servlets*. If you are performing integration tests on a Spring Controller
|
||||||
|
* (@Controller annotation), you should use AbstractControllerIntegrationTest
|
||||||
|
* <P>
|
||||||
|
* NOTE: The annotations on this class should be kept in sync with those on AbstractControllerIntegrationTest.
|
||||||
|
* The ONLY differences should be in the "webEnvironment" param passed to @SpringBootTest, and the removal
|
||||||
|
* of @WebAppConfiguration (which is only allowed in a mock environment)
|
||||||
|
*
|
||||||
|
* @author Tim Donohue
|
||||||
|
* @see org.dspace.app.rest.test.AbstractControllerIntegrationTest
|
||||||
|
*/
|
||||||
|
// Run tests with JUnit 4 and Spring TestContext Framework
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
// Specify main class to use to load Spring ApplicationContext
|
||||||
|
// ALSO tell Spring to start a web server on a random port
|
||||||
|
// NOTE: By default, Spring caches and reuses ApplicationContext for each integration test (to speed up tests)
|
||||||
|
// See: https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#integration-testing
|
||||||
|
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
// Load DSpace initializers in Spring ApplicationContext (to initialize DSpace Kernel & Configuration)
|
||||||
|
@ContextConfiguration(initializers = { DSpaceKernelInitializer.class, DSpaceConfigurationInitializer.class })
|
||||||
|
public class AbstractWebClientIntegrationTest extends AbstractIntegrationTestWithDatabase {
|
||||||
|
// (Random) port chosen for test web server
|
||||||
|
@LocalServerPort
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
// RestTemplate class with access to test web server
|
||||||
|
@Autowired
|
||||||
|
private TestRestTemplate restTemplate;
|
||||||
|
|
||||||
|
// Spring Application context
|
||||||
|
@Autowired
|
||||||
|
protected ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get client TestRestTemplate for making HTTP requests to test webserver
|
||||||
|
* @return TestRestTemplate
|
||||||
|
*/
|
||||||
|
public TestRestTemplate getClient() {
|
||||||
|
return restTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the full URL of a request at a specific path.
|
||||||
|
* (http://localhost:[port][path])
|
||||||
|
* @param path Path (should start with a slash)
|
||||||
|
* @return full URL
|
||||||
|
*/
|
||||||
|
public String getURL(String path) {
|
||||||
|
return "http://localhost:" + port + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a GET request and return response as a String
|
||||||
|
* @param path path to perform GET against
|
||||||
|
* @return ResponseEntity with a String body
|
||||||
|
*/
|
||||||
|
public ResponseEntity<String> getResponseAsString(String path) {
|
||||||
|
return getClient().getForEntity(getURL(path), String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform an authenticated (via Basic Auth) GET request and return response as a String
|
||||||
|
* @param path path to perform GET against
|
||||||
|
* @param username Username
|
||||||
|
* @param password Password
|
||||||
|
* @return ResponseEntity with a String body
|
||||||
|
*/
|
||||||
|
public ResponseEntity<String> getResponseAsString(String path, String username, String password) {
|
||||||
|
return getClient().withBasicAuth(username, password).getForEntity(getURL(path), String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform an authenticated (via Basic Auth) POST request and return response as a String.
|
||||||
|
* @param path path to perform GET against
|
||||||
|
* @param username Username (may be null to perform an unauthenticated POST)
|
||||||
|
* @param password Password
|
||||||
|
* @return ResponseEntity with a String body
|
||||||
|
*/
|
||||||
|
public ResponseEntity<String> postResponseAsString(String path, String username, String password,
|
||||||
|
HttpEntity requestEntity) {
|
||||||
|
// If username is not empty, perform an authenticated POST. Else attempt without AuthN
|
||||||
|
if (StringUtils.isNotBlank(username)) {
|
||||||
|
return getClient().withBasicAuth(username, password).postForEntity(getURL(path), requestEntity,
|
||||||
|
String.class);
|
||||||
|
} else {
|
||||||
|
return getClient().postForEntity(getURL(path), requestEntity, String.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -23,10 +23,7 @@ import java.util.Arrays;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.dspace.app.rest.exception.InvalidDSpaceObjectTypeException;
|
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
||||||
import org.dspace.app.rest.exception.InvalidSearchFacetException;
|
|
||||||
import org.dspace.app.rest.exception.InvalidSearchFilterException;
|
|
||||||
import org.dspace.app.rest.exception.InvalidSortingException;
|
|
||||||
import org.dspace.app.rest.parameter.SearchFilter;
|
import org.dspace.app.rest.parameter.SearchFilter;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
@@ -245,20 +242,20 @@ public class DiscoverQueryBuilderTest {
|
|||||||
new ReflectionEquals(new DiscoverHitHighlightingField("fulltext", 0, 3))));
|
new ReflectionEquals(new DiscoverHitHighlightingField("fulltext", 0, 3))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = InvalidDSpaceObjectTypeException.class)
|
@Test(expected = DSpaceBadRequestException.class)
|
||||||
public void testInvalidDSOType() throws Exception {
|
public void testInvalidDSOType() throws Exception {
|
||||||
queryBuilder
|
queryBuilder
|
||||||
.buildQuery(context, scope, discoveryConfiguration, query, Arrays.asList(searchFilter), "TEST", page);
|
.buildQuery(context, scope, discoveryConfiguration, query, Arrays.asList(searchFilter), "TEST", page);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = InvalidSortingException.class)
|
@Test(expected = DSpaceBadRequestException.class)
|
||||||
public void testInvalidSortField() throws Exception {
|
public void testInvalidSortField() throws Exception {
|
||||||
page = new PageRequest(2, 10, Sort.Direction.ASC, "test");
|
page = new PageRequest(2, 10, Sort.Direction.ASC, "test");
|
||||||
queryBuilder
|
queryBuilder
|
||||||
.buildQuery(context, scope, discoveryConfiguration, query, Arrays.asList(searchFilter), "ITEM", page);
|
.buildQuery(context, scope, discoveryConfiguration, query, Arrays.asList(searchFilter), "ITEM", page);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = InvalidSearchFilterException.class)
|
@Test(expected = DSpaceBadRequestException.class)
|
||||||
public void testInvalidSearchFilter1() throws Exception {
|
public void testInvalidSearchFilter1() throws Exception {
|
||||||
searchFilter = new SearchFilter("test", "equals", "Smith, Donald");
|
searchFilter = new SearchFilter("test", "equals", "Smith, Donald");
|
||||||
|
|
||||||
@@ -266,7 +263,7 @@ public class DiscoverQueryBuilderTest {
|
|||||||
.buildQuery(context, scope, discoveryConfiguration, query, Arrays.asList(searchFilter), "ITEM", page);
|
.buildQuery(context, scope, discoveryConfiguration, query, Arrays.asList(searchFilter), "ITEM", page);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = InvalidSearchFilterException.class)
|
@Test(expected = DSpaceBadRequestException.class)
|
||||||
public void testInvalidSearchFilter2() throws Exception {
|
public void testInvalidSearchFilter2() throws Exception {
|
||||||
when(searchService.toFilterQuery(any(Context.class), any(String.class), any(String.class), any(String.class)))
|
when(searchService.toFilterQuery(any(Context.class), any(String.class), any(String.class), any(String.class)))
|
||||||
.thenThrow(SQLException.class);
|
.thenThrow(SQLException.class);
|
||||||
@@ -297,7 +294,7 @@ public class DiscoverQueryBuilderTest {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = InvalidSearchFacetException.class)
|
@Test(expected = DSpaceBadRequestException.class)
|
||||||
public void testInvalidSearchFacet() throws Exception {
|
public void testInvalidSearchFacet() throws Exception {
|
||||||
queryBuilder.buildFacetQuery(context, scope, discoveryConfiguration, null, query,
|
queryBuilder.buildFacetQuery(context, scope, discoveryConfiguration, null, query,
|
||||||
Arrays.asList(searchFilter), "item", page, "test");
|
Arrays.asList(searchFilter), "item", page, "test");
|
||||||
|
@@ -0,0 +1,117 @@
|
|||||||
|
/**
|
||||||
|
* 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.sword;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.test.AbstractWebClientIntegrationTest;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.junit.Assume;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration test to verify that the /sword endpoint is responding as a valid SWORD endpoint.
|
||||||
|
* This tests that our dspace-sword module is running at this endpoint.
|
||||||
|
* <P>
|
||||||
|
* This is a AbstractWebClientIntegrationTest because testing dspace-sword requires
|
||||||
|
* running a web server (as dspace-sword makes use of Servlets, not Controllers).
|
||||||
|
*
|
||||||
|
* @author Tim Donohue
|
||||||
|
*/
|
||||||
|
// Ensure the SWORD SERVER IS ENABLED before any tests run.
|
||||||
|
// This annotation overrides default DSpace config settings loaded into Spring Context
|
||||||
|
@TestPropertySource(properties = {"sword-server.enabled = true"})
|
||||||
|
public class Swordv1IT extends AbstractWebClientIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigurationService configurationService;
|
||||||
|
|
||||||
|
// All SWORD paths that we test against
|
||||||
|
private final String SERVICE_DOC_PATH = "/sword/servicedocument";
|
||||||
|
private final String DEPOSIT_PATH = "/sword/deposit";
|
||||||
|
private final String MEDIA_LINK_PATH = "/sword/media-link";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void onlyRunIfConfigExists() {
|
||||||
|
// These integration tests REQUIRE that SWORDWebConfig is found/available (as this class deploys SWORD)
|
||||||
|
// If this class is not available, the below "Assume" will cause all tests to be SKIPPED
|
||||||
|
// NOTE: SWORDWebConfig is provided by the 'dspace-sword' module
|
||||||
|
try {
|
||||||
|
Class.forName("org.dspace.app.configuration.SWORDWebConfig");
|
||||||
|
} catch (ClassNotFoundException ce) {
|
||||||
|
Assume.assumeNoException(ce);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure SWORD URL configurations are set correctly (based on our integration test server's paths)
|
||||||
|
// SWORD validates requests against these configs, and throws a 404 if they don't match the request path
|
||||||
|
configurationService.setProperty("sword-server.servicedocument.url", getURL(SERVICE_DOC_PATH));
|
||||||
|
configurationService.setProperty("sword-server.deposit.url", getURL(DEPOSIT_PATH));
|
||||||
|
configurationService.setProperty("sword-server.media-link.url", getURL(MEDIA_LINK_PATH));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void serviceDocumentUnauthorizedTest() throws Exception {
|
||||||
|
// Attempt to load the ServiceDocument without first authenticating
|
||||||
|
ResponseEntity<String> response = getResponseAsString(SERVICE_DOC_PATH);
|
||||||
|
// Expect a 401 response code
|
||||||
|
assertThat(response.getStatusCode(), equalTo(HttpStatus.UNAUTHORIZED));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void serviceDocumentTest() throws Exception {
|
||||||
|
// Attempt to load the ServiceDocument as an Admin user.
|
||||||
|
ResponseEntity<String> response = getResponseAsString(SERVICE_DOC_PATH,
|
||||||
|
admin.getEmail(), password);
|
||||||
|
// Expect a 200 response code, and an ATOM UTF-8 document
|
||||||
|
assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
|
||||||
|
assertThat(response.getHeaders().getContentType().toString(), equalTo("application/atomsvc+xml;charset=UTF-8"));
|
||||||
|
|
||||||
|
// Check for SWORD version in response body
|
||||||
|
assertThat(response.getBody(), containsString("<sword:version>1.3</sword:version>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void depositUnauthorizedTest() throws Exception {
|
||||||
|
// Attempt to access /deposit endpoint without sending authentication information
|
||||||
|
ResponseEntity<String> response = postResponseAsString(DEPOSIT_PATH, null, null, null);
|
||||||
|
// Expect a 401 response code
|
||||||
|
assertThat(response.getStatusCode(), equalTo(HttpStatus.UNAUTHORIZED));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void depositTest() throws Exception {
|
||||||
|
// TODO: Actually test a full deposit via SWORD.
|
||||||
|
// Currently, we are just ensuring the /deposit endpoint exists (see above) and isn't throwing a 404
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mediaLinkUnauthorizedTest() throws Exception {
|
||||||
|
// Attempt to access /media-link endpoint without sending authentication information
|
||||||
|
ResponseEntity<String> response = getResponseAsString(MEDIA_LINK_PATH);
|
||||||
|
// Expect a 401 response code
|
||||||
|
assertThat(response.getStatusCode(), equalTo(HttpStatus.UNAUTHORIZED));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void mediaLinkTest() throws Exception {
|
||||||
|
// TODO: Actually test a /media-link request.
|
||||||
|
// Currently, we are just ensuring the /media-link endpoint exists (see above) and isn't throwing a 404
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -0,0 +1,149 @@
|
|||||||
|
/**
|
||||||
|
* 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.sword2;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.test.AbstractWebClientIntegrationTest;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.junit.Assume;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration test to verify the /swordv2 endpoint is responding as a valid SWORDv2 endpoint.
|
||||||
|
* This tests that our dspace-swordv2 module is running at this endpoint.
|
||||||
|
* <P>
|
||||||
|
* This is a AbstractWebClientIntegrationTest because testing dspace-swordv2 requires
|
||||||
|
* running a web server (as dspace-swordv2 makes use of Servlets, not Controllers).
|
||||||
|
*
|
||||||
|
* @author Tim Donohue
|
||||||
|
*/
|
||||||
|
// Ensure the SWORDv2 SERVER IS ENABLED before any tests run.
|
||||||
|
// This annotation overrides default DSpace config settings loaded into Spring Context
|
||||||
|
@TestPropertySource(properties = {"swordv2-server.enabled = true"})
|
||||||
|
public class Swordv2IT extends AbstractWebClientIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigurationService configurationService;
|
||||||
|
|
||||||
|
// All SWORD v2 paths that we test against
|
||||||
|
private final String SERVICE_DOC_PATH = "/swordv2/servicedocument";
|
||||||
|
private final String COLLECTION_PATH = "/swordv2/collection";
|
||||||
|
private final String MEDIA_RESOURCE_PATH = "/swordv2/edit-media";
|
||||||
|
private final String CONTAINER_PATH = "/swordv2/edit";
|
||||||
|
private final String STATEMENT_PATH = "/swordv2/statement";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void onlyRunIfConfigExists() {
|
||||||
|
// These integration tests REQUIRE that SWORDv2WebConfig is found/available (as this class deploys SWORDv2)
|
||||||
|
// If this class is not available, the below "Assume" will cause all tests to be SKIPPED
|
||||||
|
// NOTE: SWORDv2WebConfig is provided by the 'dspace-swordv2' module
|
||||||
|
try {
|
||||||
|
Class.forName("org.dspace.app.configuration.SWORDv2WebConfig");
|
||||||
|
} catch (ClassNotFoundException ce) {
|
||||||
|
Assume.assumeNoException(ce);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure SWORDv2 URL configurations are set correctly (based on our integration test server's paths)
|
||||||
|
// SWORDv2 validates requests against these configs, and throws a 404 if they don't match the request path
|
||||||
|
configurationService.setProperty("swordv2-server.servicedocument.url", getURL(SERVICE_DOC_PATH));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void serviceDocumentUnauthorizedTest() throws Exception {
|
||||||
|
// Attempt to GET the ServiceDocument without first authenticating
|
||||||
|
ResponseEntity<String> response = getResponseAsString(SERVICE_DOC_PATH);
|
||||||
|
// Expect a 401 response code
|
||||||
|
assertThat(response.getStatusCode(), equalTo(HttpStatus.UNAUTHORIZED));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void serviceDocumentTest() throws Exception {
|
||||||
|
// Attempt to GET the ServiceDocument as an Admin user.
|
||||||
|
ResponseEntity<String> response = getResponseAsString(SERVICE_DOC_PATH,
|
||||||
|
admin.getEmail(), password);
|
||||||
|
// Expect a 200 response code, and an ATOM UTF-8 document
|
||||||
|
assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
|
||||||
|
assertThat(response.getHeaders().getContentType().toString(),
|
||||||
|
equalTo("application/atomserv+xml;charset=UTF-8"));
|
||||||
|
|
||||||
|
// Check for correct SWORD version in response body
|
||||||
|
assertThat(response.getBody(),
|
||||||
|
containsString("<version xmlns=\"http://purl.org/net/sword/terms/\">2.0</version>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void collectionUnauthorizedTest() throws Exception {
|
||||||
|
// Attempt to POST to /collection endpoint without sending authentication information
|
||||||
|
ResponseEntity<String> response = postResponseAsString(COLLECTION_PATH, null, null, null);
|
||||||
|
// Expect a 401 response code
|
||||||
|
assertThat(response.getStatusCode(), equalTo(HttpStatus.UNAUTHORIZED));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void collectionTest() throws Exception {
|
||||||
|
// TODO: Actually test collection endpoint via SWORDv2.
|
||||||
|
// Currently, we are just ensuring the /collection endpoint exists (see above) and isn't throwing a 404
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mediaResourceUnauthorizedTest() throws Exception {
|
||||||
|
// Attempt to POST to /mediaresource endpoint without sending authentication information
|
||||||
|
ResponseEntity<String> response = postResponseAsString(MEDIA_RESOURCE_PATH, null, null, null);
|
||||||
|
// Expect a 401 response code
|
||||||
|
assertThat(response.getStatusCode(), equalTo(HttpStatus.UNAUTHORIZED));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void mediaResourceTest() throws Exception {
|
||||||
|
// TODO: Actually test this endpoint via SWORDv2.
|
||||||
|
// Currently, we are just ensuring the /mediaresource endpoint exists (see above) and isn't throwing a 404
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void containerUnauthorizedTest() throws Exception {
|
||||||
|
// Attempt to POST to /container endpoint without sending authentication information
|
||||||
|
ResponseEntity<String> response = postResponseAsString(CONTAINER_PATH, null, null, null);
|
||||||
|
// Expect a 401 response code
|
||||||
|
assertThat(response.getStatusCode(), equalTo(HttpStatus.UNAUTHORIZED));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void containerTest() throws Exception {
|
||||||
|
// TODO: Actually test this endpoint via SWORDv2.
|
||||||
|
// Currently, we are just ensuring the /container endpoint exists (see above) and isn't throwing a 404
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void statementUnauthorizedTest() throws Exception {
|
||||||
|
// Attempt to GET /statement endpoint without sending authentication information
|
||||||
|
ResponseEntity<String> response = getResponseAsString(STATEMENT_PATH);
|
||||||
|
// Expect a 401 response code
|
||||||
|
assertThat(response.getStatusCode(), equalTo(HttpStatus.UNAUTHORIZED));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void statementTest() throws Exception {
|
||||||
|
// TODO: Actually test this endpoint via SWORDv2.
|
||||||
|
// Currently, we are just ensuring the /statement endpoint exists (see above) and isn't throwing a 404
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -2,10 +2,10 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>dspace-sword</artifactId>
|
<artifactId>dspace-sword</artifactId>
|
||||||
<packaging>war</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>DSpace SWORD</name>
|
<name>DSpace SWORD</name>
|
||||||
<description>
|
<description>
|
||||||
DSpace SWORD Deposit Service Provider Web Application
|
DSpace SWORD Deposit Service Provider Extension
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@@ -24,28 +24,6 @@
|
|||||||
<root.basedir>${basedir}/..</root.basedir>
|
<root.basedir>${basedir}/..</root.basedir>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<attachClasses>true</attachClasses>
|
|
||||||
<!-- In version 2.1-alpha-1, this was incorrectly named warSourceExcludes -->
|
|
||||||
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
|
|
||||||
<warSourceExcludes>WEB-INF/lib/*.jar</warSourceExcludes>
|
|
||||||
<!-- Filter the web.xml (needed for IDE compatibility/debugging) -->
|
|
||||||
<filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
<profile>
|
<profile>
|
||||||
<id>oracle-support</id>
|
<id>oracle-support</id>
|
||||||
@@ -95,6 +73,19 @@
|
|||||||
<artifactId>dspace-api-lang</artifactId>
|
<artifactId>dspace-api-lang</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Needed to support Spring @Configuration classes (to register servlets/beans with Spring Boot webapp) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-logging</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jaxen</groupId>
|
<groupId>jaxen</groupId>
|
||||||
<artifactId>jaxen</artifactId>
|
<artifactId>jaxen</artifactId>
|
||||||
|
@@ -0,0 +1,88 @@
|
|||||||
|
/**
|
||||||
|
* 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.configuration;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.boot.web.servlet.ServletContextInitializer;
|
||||||
|
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SWORD webapp configuration. Replaces the old web.xml
|
||||||
|
* <p>
|
||||||
|
* This @Configuration class is automatically discovered by Spring via a @ComponentScan.
|
||||||
|
* <p>
|
||||||
|
* All SWORD web configurations (beans) can be enabled or disabled by setting "sword-server.enabled"
|
||||||
|
* to true or false, respectively (in your DSpace configuration). Default is "false".
|
||||||
|
* <p>
|
||||||
|
* All @Value annotated configurations below can also be overridden in your DSpace configuration.
|
||||||
|
*
|
||||||
|
* @author Tim Donohue
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class SWORDWebConfig {
|
||||||
|
// Path where SWORD should be deployed (when enabled). Defaults to "sword"
|
||||||
|
@Value("${sword-server.path:sword}")
|
||||||
|
private String swordPath;
|
||||||
|
|
||||||
|
// SWORD Server class. Defaults to "org.dspace.sword.DSpaceSWORDServer"
|
||||||
|
@Value("${sword-server.class:org.dspace.sword.DSpaceSWORDServer}")
|
||||||
|
private String serverClass;
|
||||||
|
|
||||||
|
// SWORD Authentication Method. Defaults to "Basic"
|
||||||
|
@Value("${sword-server.authentication-method:Basic}")
|
||||||
|
private String authenticationMethod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize all required Context Parameters (i.e. <context-param> in web.xml), based on configurations above.
|
||||||
|
* <p>
|
||||||
|
* This bean is only loaded when sword-server.enabled = true
|
||||||
|
* @return ServletContextInitializer which includes all required params
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty("sword-server.enabled")
|
||||||
|
public ServletContextInitializer swordv1ContextInitializer() {
|
||||||
|
return servletContext -> {
|
||||||
|
servletContext.setInitParameter("sword-server-class", serverClass);
|
||||||
|
servletContext.setInitParameter("authentication-method", authenticationMethod);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Servlet Beans. All of the below bean definitions map servlets to respond to specific URL patterns
|
||||||
|
// These are the combined equivalent of <servlet> and <servlet-mapping> in web.xml
|
||||||
|
// All beans are only loaded when sword-server.enabled = true
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty("sword-server.enabled")
|
||||||
|
public ServletRegistrationBean swordv1ServiceDocumentBean() {
|
||||||
|
ServletRegistrationBean bean = new ServletRegistrationBean( new org.purl.sword.server.ServiceDocumentServlet(),
|
||||||
|
"/" + swordPath + "/servicedocument/*");
|
||||||
|
bean.setLoadOnStartup(1);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty("sword-server.enabled")
|
||||||
|
public ServletRegistrationBean swordv1DepositBean() {
|
||||||
|
ServletRegistrationBean bean = new ServletRegistrationBean( new org.purl.sword.server.DepositServlet(),
|
||||||
|
"/" + swordPath + "/deposit/*");
|
||||||
|
bean.setLoadOnStartup(1);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty("sword-server.enabled")
|
||||||
|
public ServletRegistrationBean swordv1MediaLinkBean() {
|
||||||
|
ServletRegistrationBean bean = new ServletRegistrationBean( new org.purl.sword.server.AtomDocumentServlet(),
|
||||||
|
"/" + swordPath + "/media-link/*");
|
||||||
|
bean.setLoadOnStartup(1);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
}
|
@@ -27,11 +27,6 @@ import org.purl.sword.base.SWORDException;
|
|||||||
*/
|
*/
|
||||||
public class AtomDocumentServlet extends DepositServlet {
|
public class AtomDocumentServlet extends DepositServlet {
|
||||||
|
|
||||||
public AtomDocumentServlet()
|
|
||||||
throws ServletException {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the get request.
|
* Process the get request.
|
||||||
*/
|
*/
|
||||||
|
@@ -1,91 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
|
||||||
<!--
|
|
||||||
|
|
||||||
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/
|
|
||||||
|
|
||||||
-->
|
|
||||||
<web-app id="DSpace-SWORDv1" version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
|
|
||||||
|
|
||||||
<display-name>DSpace SWORD Server</display-name>
|
|
||||||
|
|
||||||
<!-- ConfigurationService initialization for dspace.dir -->
|
|
||||||
<context-param>
|
|
||||||
<description>The location of the DSpace home directory</description>
|
|
||||||
<param-name>dspace.dir</param-name>
|
|
||||||
<param-value>${dspace.dir}</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<context-param>
|
|
||||||
<description>The SWORDServer class name</description>
|
|
||||||
<param-name>sword-server-class</param-name>
|
|
||||||
<param-value>org.dspace.sword.DSpaceSWORDServer</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<context-param>
|
|
||||||
<param-name>log4jConfiguration</param-name>
|
|
||||||
<param-value>${dspace.dir}/config/log4j2.xml</param-value>
|
|
||||||
<description>
|
|
||||||
The location of the Log4J configuration
|
|
||||||
</description>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<context-param>
|
|
||||||
<description>The type of authentication used : [Basic|None]</description>
|
|
||||||
<param-name>authentication-method</param-name>
|
|
||||||
<param-value>Basic</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Listener to initialise DSpace configuration and clean up the application
|
|
||||||
-->
|
|
||||||
<listener>
|
|
||||||
<listener-class>
|
|
||||||
org.dspace.app.util.DSpaceContextListener
|
|
||||||
</listener-class>
|
|
||||||
</listener>
|
|
||||||
<listener>
|
|
||||||
<listener-class>
|
|
||||||
org.dspace.servicemanager.servlet.DSpaceKernelServletContextListener
|
|
||||||
</listener-class>
|
|
||||||
</listener>
|
|
||||||
|
|
||||||
<!-- Servlets -->
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>servicedocument</servlet-name>
|
|
||||||
<servlet-class>org.purl.sword.server.ServiceDocumentServlet</servlet-class>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>deposit</servlet-name>
|
|
||||||
<servlet-class>org.purl.sword.server.DepositServlet</servlet-class>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>media-link</servlet-name>
|
|
||||||
<servlet-class>org.purl.sword.server.AtomDocumentServlet</servlet-class>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<!-- Servlet Mappings -->
|
|
||||||
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>servicedocument</servlet-name>
|
|
||||||
<url-pattern>/servicedocument/*</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>deposit</servlet-name>
|
|
||||||
<url-pattern>/deposit/*</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>media-link</servlet-name>
|
|
||||||
<url-pattern>/media-link/*</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
</web-app>
|
|
@@ -2,9 +2,9 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>dspace-swordv2</artifactId>
|
<artifactId>dspace-swordv2</artifactId>
|
||||||
<packaging>war</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>DSpace SWORD v2</name>
|
<name>DSpace SWORD v2</name>
|
||||||
<description>DSpace SWORD v2 Deposit Service Provider Web Application</description>
|
<description>DSpace SWORD v2 Deposit Service Provider Extension</description>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
A Parent POM that Maven inherits DSpace Default
|
A Parent POM that Maven inherits DSpace Default
|
||||||
@@ -22,29 +22,6 @@
|
|||||||
<root.basedir>${basedir}/..</root.basedir>
|
<root.basedir>${basedir}/..</root.basedir>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<attachClasses>true</attachClasses>
|
|
||||||
<!-- In version 2.1-alpha-1, this was incorrectly named warSourceExcludes -->
|
|
||||||
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
|
|
||||||
<warSourceExcludes>WEB-INF/lib/*.jar</warSourceExcludes>
|
|
||||||
<!-- Filter the web.xml (needed for IDE compatibility/debugging) -->
|
|
||||||
<filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
<profile>
|
<profile>
|
||||||
<id>oracle-support</id>
|
<id>oracle-support</id>
|
||||||
@@ -83,6 +60,8 @@
|
|||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SWORDv2 Java implementation -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.swordapp</groupId>
|
<groupId>org.swordapp</groupId>
|
||||||
<artifactId>sword2-server</artifactId>
|
<artifactId>sword2-server</artifactId>
|
||||||
@@ -98,26 +77,41 @@
|
|||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
<artifactId>servlet-api</artifactId>
|
<artifactId>servlet-api</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>log4j</groupId>
|
<groupId>log4j</groupId>
|
||||||
<artifactId>log4j</artifactId>
|
<artifactId>log4j</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-log4j12</artifactId>
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
|
<!-- Exclude an old version of Jena in favor of new Apache Jena, which is pulled in by dspace-parent -->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>com.hp.hpl.jena</groupId>
|
||||||
|
<artifactId>jena</artifactId>
|
||||||
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.swordapp</groupId>
|
<!-- DSpace Java API -->
|
||||||
<artifactId>sword2-server</artifactId>
|
|
||||||
<version>1.0</version>
|
|
||||||
<type>war</type>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>dspace-api</artifactId>
|
<artifactId>dspace-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Needed to support Spring @Configuration classes (to register servlets/beans with Spring Boot webapp) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-logging</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
<artifactId>log4j-api</artifactId>
|
<artifactId>log4j-api</artifactId>
|
||||||
@@ -134,7 +128,6 @@
|
|||||||
<groupId>org.apache.abdera</groupId>
|
<groupId>org.apache.abdera</groupId>
|
||||||
<artifactId>abdera-client</artifactId>
|
<artifactId>abdera-client</artifactId>
|
||||||
<version>1.1.3</version>
|
<version>1.1.3</version>
|
||||||
|
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>org.apache.ws.commons.axiom</groupId>
|
<groupId>org.apache.ws.commons.axiom</groupId>
|
||||||
|
@@ -0,0 +1,143 @@
|
|||||||
|
/**
|
||||||
|
* 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.configuration;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.boot.web.servlet.ServletContextInitializer;
|
||||||
|
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SWORDv2 webapp configuration. Replaces the old web.xml
|
||||||
|
* <p>
|
||||||
|
* This @Configuration class is automatically discovered by Spring via a @ComponentScan.
|
||||||
|
* <p>
|
||||||
|
* All SWORDv2 web configurations (beans) can be enabled or disabled by setting "swordv2-server.enabled"
|
||||||
|
* to true or false, respectively (in your DSpace configuration). Default is "false".
|
||||||
|
* <p>
|
||||||
|
* All @Value annotated configurations below can also be overridden in your DSpace configuration.
|
||||||
|
*
|
||||||
|
* @author Tim Donohue
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class SWORDv2WebConfig {
|
||||||
|
// Path where SWORDv2 should be deployed (when enabled). Defaults to "swordv2"
|
||||||
|
@Value("${swordv2-server.path:swordv2}")
|
||||||
|
private String swordv2Path;
|
||||||
|
|
||||||
|
// ServiceDocumentManager server implementation class name (default: org.dspace.sword2.ServiceDocumentManagerDSpace)
|
||||||
|
@Value("${swordv2-server.service-document-impl:org.dspace.sword2.ServiceDocumentManagerDSpace}")
|
||||||
|
private String serviceDocImpl;
|
||||||
|
|
||||||
|
// CollectionListManager server implementation class name (default: org.dspace.sword2.CollectionListManagerDSpace)
|
||||||
|
@Value("${swordv2-server.collection-list-impl:org.dspace.sword2.CollectionListManagerDSpace}")
|
||||||
|
private String collectionListImpl;
|
||||||
|
|
||||||
|
// CollectionDepositManager server implementation class name
|
||||||
|
// (default: org.dspace.sword2.CollectionDepositManagerDSpace)
|
||||||
|
@Value("${swordv2-server.collection-deposit-impl:org.dspace.sword2.CollectionDepositManagerDSpace}")
|
||||||
|
private String collectionDepositImpl;
|
||||||
|
|
||||||
|
// MediaResourceManager server implementation class name (default: org.dspace.sword2.MediaResourceManagerDSpace)
|
||||||
|
@Value("${swordv2-server.media-resource-impl:org.dspace.sword2.MediaResourceManagerDSpace}")
|
||||||
|
private String mediaResourceImpl;
|
||||||
|
|
||||||
|
// ContainerManager server implementation class name (default: org.dspace.sword2.ContainerManagerDSpace)
|
||||||
|
@Value("${swordv2-server.container-impl:org.dspace.sword2.ContainerManagerDSpace}")
|
||||||
|
private String containerImpl;
|
||||||
|
|
||||||
|
// StatementManager server implementation class name (default: org.dspace.sword2.StatementManagerDSpace)
|
||||||
|
@Value("${swordv2-server.statement-impl:org.dspace.sword2.StatementManagerDSpace}")
|
||||||
|
private String statementImpl;
|
||||||
|
|
||||||
|
// SwordConfiguration server implementation class name (default: org.dspace.sword2.SwordConfigurationDSpace)
|
||||||
|
@Value("${swordv2-server.config-impl:org.dspace.sword2.SwordConfigurationDSpace}")
|
||||||
|
private String configImpl;
|
||||||
|
|
||||||
|
// Authentication Method. Defaults to "Basic"
|
||||||
|
@Value("${swordv2-server.auth-type:Basic}")
|
||||||
|
private String authenticationMethod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize all required Context Parameters (i.e. <context-param> in web.xml), based on configurations above.
|
||||||
|
* <p>
|
||||||
|
* This bean is only loaded when swordv2-server.enabled = true
|
||||||
|
* @return ServletContextInitializer which includes all required params
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty("swordv2-server.enabled")
|
||||||
|
public ServletContextInitializer swordv2ContextInitializer() {
|
||||||
|
return servletContext -> {
|
||||||
|
servletContext.setInitParameter("service-document-impl", serviceDocImpl);
|
||||||
|
servletContext.setInitParameter("collection-list-impl", collectionListImpl);
|
||||||
|
servletContext.setInitParameter("collection-deposit-impl", collectionDepositImpl);
|
||||||
|
servletContext.setInitParameter("media-resource-impl", mediaResourceImpl);
|
||||||
|
servletContext.setInitParameter("container-impl", containerImpl);
|
||||||
|
servletContext.setInitParameter("statement-impl", statementImpl);
|
||||||
|
servletContext.setInitParameter("config-impl", configImpl);
|
||||||
|
servletContext.setInitParameter("authentication-method", authenticationMethod);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Servlet Beans. All of the below bean definitions map servlets to respond to specific URL patterns
|
||||||
|
// These are the combined equivalent of <servlet> and <servlet-mapping> in web.xml
|
||||||
|
// All beans are only loaded when swordv2-server.enabled = true
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty("swordv2-server.enabled")
|
||||||
|
public ServletRegistrationBean swordv2ServiceDocumentBean() {
|
||||||
|
ServletRegistrationBean bean =
|
||||||
|
new ServletRegistrationBean(new org.swordapp.server.servlets.ServiceDocumentServletDefault(),
|
||||||
|
"/" + swordv2Path + "/servicedocument/*");
|
||||||
|
bean.setLoadOnStartup(1);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty("swordv2-server.enabled")
|
||||||
|
public ServletRegistrationBean swordv2CollectionBean() {
|
||||||
|
ServletRegistrationBean bean =
|
||||||
|
new ServletRegistrationBean( new org.swordapp.server.servlets.CollectionServletDefault(),
|
||||||
|
"/" + swordv2Path + "/collection/*");
|
||||||
|
bean.setLoadOnStartup(1);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty("swordv2-server.enabled")
|
||||||
|
public ServletRegistrationBean swordv2MediaResourceBean() {
|
||||||
|
ServletRegistrationBean bean =
|
||||||
|
new ServletRegistrationBean( new org.swordapp.server.servlets.MediaResourceServletDefault(),
|
||||||
|
"/" + swordv2Path + "/edit-media/*");
|
||||||
|
bean.setLoadOnStartup(1);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty("swordv2-server.enabled")
|
||||||
|
public ServletRegistrationBean swordv2ContainerBean() {
|
||||||
|
ServletRegistrationBean bean =
|
||||||
|
new ServletRegistrationBean( new org.swordapp.server.servlets.ContainerServletDefault(),
|
||||||
|
"/" + swordv2Path + "/edit/*");
|
||||||
|
bean.setLoadOnStartup(1);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty("swordv2-server.enabled")
|
||||||
|
public ServletRegistrationBean swordv2StatementBean() {
|
||||||
|
ServletRegistrationBean bean =
|
||||||
|
new ServletRegistrationBean( new org.swordapp.server.servlets.StatementServletDefault(),
|
||||||
|
"/" + swordv2Path + "/statement/*");
|
||||||
|
bean.setLoadOnStartup(1);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -1,154 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
|
||||||
<!--
|
|
||||||
|
|
||||||
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/
|
|
||||||
|
|
||||||
-->
|
|
||||||
<web-app id="DSpace-SWORDv2" version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
|
|
||||||
|
|
||||||
<display-name>DSpace SWORD 2.0 Server</display-name>
|
|
||||||
|
|
||||||
<!-- ConfigurationService initialization for dspace.dir -->
|
|
||||||
<context-param>
|
|
||||||
<description>The location of the DSpace home directory</description>
|
|
||||||
<param-name>dspace.dir</param-name>
|
|
||||||
<param-value>${dspace.dir}</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<!-- Configuration Information -->
|
|
||||||
|
|
||||||
<context-param>
|
|
||||||
<description>The ServiceDocumentManager server implementation class name</description>
|
|
||||||
<param-name>service-document-impl</param-name>
|
|
||||||
<param-value>org.dspace.sword2.ServiceDocumentManagerDSpace</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<context-param>
|
|
||||||
<param-name>log4jConfiguration</param-name>
|
|
||||||
<param-value>${dspace.dir}/config/log4j2.xml</param-value>
|
|
||||||
<description>
|
|
||||||
The location of the Log4J configuration
|
|
||||||
</description>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<!-- This can be omitted if the server does not wish to support
|
|
||||||
listing collection contents -->
|
|
||||||
<context-param>
|
|
||||||
<description>The CollectionListManager server implementation class name</description>
|
|
||||||
<param-name>collection-list-impl</param-name>
|
|
||||||
<param-value>org.dspace.sword2.CollectionListManagerDSpace</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<context-param>
|
|
||||||
<description>The CollectionDepositManager server implementation class name</description>
|
|
||||||
<param-name>collection-deposit-impl</param-name>
|
|
||||||
<param-value>org.dspace.sword2.CollectionDepositManagerDSpace</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<context-param>
|
|
||||||
<description>The MediaResourceManager server implementation class name</description>
|
|
||||||
<param-name>media-resource-impl</param-name>
|
|
||||||
<param-value>org.dspace.sword2.MediaResourceManagerDSpace</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<context-param>
|
|
||||||
<description>The ContainerManager server implementation class name</description>
|
|
||||||
<param-name>container-impl</param-name>
|
|
||||||
<param-value>org.dspace.sword2.ContainerManagerDSpace</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<context-param>
|
|
||||||
<description>The StatementManager server implementation class name</description>
|
|
||||||
<param-name>statement-impl</param-name>
|
|
||||||
<param-value>org.dspace.sword2.StatementManagerDSpace</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<!-- This option here is an actual implementation of the configuration class, which
|
|
||||||
contains some default values -->
|
|
||||||
<context-param>
|
|
||||||
<description>The SwordConfiguration server implementation class name</description>
|
|
||||||
<param-name>config-impl</param-name>
|
|
||||||
<param-value>org.dspace.sword2.SwordConfigurationDSpace</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<context-param>
|
|
||||||
<description>The type of authentication used : [Basic|None]</description>
|
|
||||||
<param-name>authentication-method</param-name>
|
|
||||||
<param-value>Basic</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Listener to initialise DSpace configuration and clean up the application
|
|
||||||
-->
|
|
||||||
<listener>
|
|
||||||
<listener-class>
|
|
||||||
org.dspace.app.util.DSpaceContextListener
|
|
||||||
</listener-class>
|
|
||||||
</listener>
|
|
||||||
<listener>
|
|
||||||
<listener-class>
|
|
||||||
org.dspace.servicemanager.servlet.DSpaceKernelServletContextListener
|
|
||||||
</listener-class>
|
|
||||||
</listener>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Servlets -->
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>servicedocument</servlet-name>
|
|
||||||
<servlet-class>org.swordapp.server.servlets.ServiceDocumentServletDefault</servlet-class>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>collection</servlet-name>
|
|
||||||
<servlet-class>org.swordapp.server.servlets.CollectionServletDefault</servlet-class>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>mediaresource</servlet-name>
|
|
||||||
<servlet-class>org.swordapp.server.servlets.MediaResourceServletDefault</servlet-class>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>container</servlet-name>
|
|
||||||
<servlet-class>org.swordapp.server.servlets.ContainerServletDefault</servlet-class>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>statement</servlet-name>
|
|
||||||
<servlet-class>org.swordapp.server.servlets.StatementServletDefault</servlet-class>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<!-- Servlet Mappings -->
|
|
||||||
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>servicedocument</servlet-name>
|
|
||||||
<url-pattern>/servicedocument/*</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>collection</servlet-name>
|
|
||||||
<url-pattern>/collection/*</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>mediaresource</servlet-name>
|
|
||||||
<url-pattern>/edit-media/*</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>container</servlet-name>
|
|
||||||
<url-pattern>/edit/*</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>statement</servlet-name>
|
|
||||||
<url-pattern>/statement/*</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
</web-app>
|
|
@@ -26,7 +26,7 @@ dspace.dir = /dspace
|
|||||||
dspace.hostname = localhost
|
dspace.hostname = localhost
|
||||||
|
|
||||||
# DSpace base host URL. Include port number etc.
|
# DSpace base host URL. Include port number etc.
|
||||||
dspace.baseUrl = http://localhost:8080
|
dspace.baseUrl = http://localhost:8080/spring-rest
|
||||||
|
|
||||||
# Full link your end users will use to access DSpace. In most cases, this will be the baseurl followed by
|
# Full link your end users will use to access DSpace. In most cases, this will be the baseurl followed by
|
||||||
# the context path to the UI you are using.
|
# the context path to the UI you are using.
|
||||||
@@ -37,7 +37,7 @@ dspace.url = ${dspace.baseUrl}
|
|||||||
|
|
||||||
# This is the URL that will be used for the REST endpoints to be served on.
|
# This is the URL that will be used for the REST endpoints to be served on.
|
||||||
# This will typically be followed by /api to determine the root endpoints.
|
# This will typically be followed by /api to determine the root endpoints.
|
||||||
dspace.restUrl = ${dspace.baseUrl}/spring-rest
|
dspace.restUrl = ${dspace.baseUrl}
|
||||||
|
|
||||||
# Optional: DSpace URL for mobile access
|
# Optional: DSpace URL for mobile access
|
||||||
# This
|
# This
|
||||||
@@ -766,6 +766,24 @@ org.dspace.app.batchitemimport.work.dir = ${dspace.dir}/imports
|
|||||||
# XSL file configured by: crosswalk.dissemination.DataCite.stylesheet file.)
|
# XSL file configured by: crosswalk.dissemination.DataCite.stylesheet file.)
|
||||||
#identifier.doi.ezid.publisher = a publisher
|
#identifier.doi.ezid.publisher = a publisher
|
||||||
|
|
||||||
|
##### Registry Loader #####
|
||||||
|
# Metadata namespaces. These files are loaded from
|
||||||
|
# ${dspace.dir}/config/registries/ into the database during installation
|
||||||
|
# and upgrade.
|
||||||
|
registry.metadata.load = dublin-core-types.xml
|
||||||
|
registry.metadata.load = dcterms-types.xml
|
||||||
|
registry.metadata.load = local-types.xml
|
||||||
|
registry.metadata.load = eperson-types.xml
|
||||||
|
registry.metadata.load = sword-metadata.xml
|
||||||
|
registry.metadata.load = relationship-formats.xml
|
||||||
|
registry.metadata.load = person-types.xml
|
||||||
|
registry.metadata.load = project-types.xml
|
||||||
|
registry.metadata.load = orgunit-types.xml
|
||||||
|
registry.metadata.load = journal-types.xml
|
||||||
|
registry.metadata.load = journalissue-types.xml
|
||||||
|
registry.metadata.load = journalvolume-types.xml
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------------------------------#
|
#---------------------------------------------------------------#
|
||||||
#--------------JSPUI & XMLUI CONFIGURATIONS---------------------#
|
#--------------JSPUI & XMLUI CONFIGURATIONS---------------------#
|
||||||
|
@@ -4,12 +4,24 @@
|
|||||||
# These configs are used by the OAI-PMH interface #
|
# These configs are used by the OAI-PMH interface #
|
||||||
#---------------------------------------------------------------#
|
#---------------------------------------------------------------#
|
||||||
|
|
||||||
|
# Whether or not to enable the OAI module
|
||||||
|
# When "true", the OAI module is accessible on ${oai.path}
|
||||||
|
# When "false" or commented out, OAI is disabled/inaccessible.
|
||||||
|
# (Requires reboot of servlet container, e.g. Tomcat, to reload)
|
||||||
|
#oai.enabled = true
|
||||||
|
|
||||||
|
# Path where OAI module is available
|
||||||
|
# Defaults to "oai", which means the OAI module would be available
|
||||||
|
# at ${dspace.restURL}/oai/
|
||||||
|
# (Requires reboot of servlet container, e.g. Tomcat, to reload)
|
||||||
|
oai.path = oai
|
||||||
|
|
||||||
# Storage: solr | database (solr is recommended)
|
# Storage: solr | database (solr is recommended)
|
||||||
oai.storage=solr
|
oai.storage=solr
|
||||||
|
|
||||||
# The base URL of the OAI webapp (do not include the context e.g. /request, /openaire, etc).
|
# The base URL of the OAI webapp (do not include the context e.g. /request, /openaire, etc).
|
||||||
# Note: Comment out if you want to fallback to the request's URL.
|
# Note: Comment out if you want to fallback to the request's URL.
|
||||||
oai.url = ${dspace.baseUrl}/oai
|
oai.url = ${dspace.baseUrl}/${oai.path}
|
||||||
|
|
||||||
# Base solr index
|
# Base solr index
|
||||||
oai.solr.url=${solr.server}/oai
|
oai.solr.url=${solr.server}/oai
|
||||||
|
@@ -1,12 +1,29 @@
|
|||||||
# These configs are used by dspace-rdf and the buildin Linked Data export (rdfizer)
|
#---------------------------------------------------------------#
|
||||||
|
#----------------RDF (LINKED DATA) CONFIGURATIONS---------------#
|
||||||
|
#---------------------------------------------------------------#
|
||||||
|
# These configs are only used by the RDF (Linked Data) #
|
||||||
|
# interface (provided by dspace-rdf and the built-in Linked #
|
||||||
|
# Data export (rdfizer)).
|
||||||
|
#---------------------------------------------------------------#
|
||||||
|
|
||||||
|
# Whether or not to enable the RDF module
|
||||||
|
# When "true", the RDF module is accessible on ${rdf.path}
|
||||||
|
# When "false" or commented out, RDF is disabled/inaccessible.
|
||||||
|
# (Requires reboot of servlet container, e.g. Tomcat, to reload)
|
||||||
|
#rdf.enabled = true
|
||||||
|
|
||||||
|
# Path where RDF module is available (in the Spring REST webapp)
|
||||||
|
# Defaults to "rdf", which means the RDF module would be available
|
||||||
|
# at ${dspace.restURL}/rdf/
|
||||||
|
# (Requires reboot of servlet container, e.g. Tomcat, to reload)
|
||||||
|
rdf.path = rdf
|
||||||
|
|
||||||
# Configure if content negotiation should be enabled
|
# Configure if content negotiation should be enabled
|
||||||
rdf.contentNegotiation.enable = false
|
rdf.contentNegotiation.enable = false
|
||||||
|
|
||||||
# Set the url of the dspace-rdf module here. This is necessary to use content
|
# Set the url of the RDF module here. This is necessary to use content
|
||||||
# negotiation
|
# negotiation
|
||||||
rdf.contextPath = ${dspace.baseUrl}/rdf
|
rdf.contextPath = ${dspace.baseUrl}/${rdf.path}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Address of the public SPARQL endpoint
|
# Address of the public SPARQL endpoint
|
||||||
|
@@ -1,9 +1,17 @@
|
|||||||
#---------------------------------------------------------------#
|
#---------------------------------------------------------------#
|
||||||
#--------------------REST CONFIGURATIONS------------------------#
|
#--------------------REST CONFIGURATIONS------------------------#
|
||||||
#---------------------------------------------------------------#
|
#---------------------------------------------------------------#
|
||||||
# These configs are used by the REST module #
|
# These configs are used by the RESTv7 module #
|
||||||
#---------------------------------------------------------------#
|
#---------------------------------------------------------------#
|
||||||
|
# Allowed CORS origins. Defaults to * (everywhere)
|
||||||
|
# Multiple allowed origin URLs may be comma separated
|
||||||
|
# (Requires reboot of servlet container, e.g. Tomcat, to reload)
|
||||||
|
rest.cors.allowed-origins = *
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------#
|
||||||
|
# These configs are used by the deprecated REST (v4-6) module #
|
||||||
|
#---------------------------------------------------------------#
|
||||||
# record stats in DSpace statistics module
|
# record stats in DSpace statistics module
|
||||||
rest.stats = true
|
rest.stats = true
|
||||||
|
|
||||||
@@ -137,4 +145,4 @@ rest.report-regex-xml-entity = ^.*&#.*$
|
|||||||
rest.report-regex-non-ascii = ^.*[^\\p{ASCII}].*$
|
rest.report-regex-non-ascii = ^.*[^\\p{ASCII}].*$
|
||||||
|
|
||||||
# The maximum number of results to return for 1 request
|
# The maximum number of results to return for 1 request
|
||||||
rest.search.max.results = 100
|
rest.search.max.results = 100
|
||||||
|
@@ -6,6 +6,28 @@
|
|||||||
# SWORD protocol) #
|
# SWORD protocol) #
|
||||||
#---------------------------------------------------------------#
|
#---------------------------------------------------------------#
|
||||||
|
|
||||||
|
# Whether or not to enable the SWORD v1 module
|
||||||
|
# When "true", the SWORD module is accessible on ${sword-server.path}
|
||||||
|
# When "false" or commented out, SWORD is disabled/inaccessible.
|
||||||
|
# (Requires reboot of servlet container, e.g. Tomcat, to reload)
|
||||||
|
#sword-server.enabled = true
|
||||||
|
|
||||||
|
# Path where SWORD v1 module is available (in the Spring REST webapp)
|
||||||
|
# Defaults to "sword", which means the SWORD mould would be available
|
||||||
|
# at ${dspace.restURL}/sword/
|
||||||
|
# (Requires reboot of servlet container, e.g. Tomcat, to reload)
|
||||||
|
#sword-server.path = sword
|
||||||
|
|
||||||
|
# The SWORDServer class name (in charge of all SWORD activities)
|
||||||
|
# This Java class must implement 'org.purl.sword.server.SWORDServer'
|
||||||
|
# (Requires reboot of servlet container, e.g. Tomcat, to reload)
|
||||||
|
#sword-server.class = org.dspace.sword.DSpaceSWORDServer
|
||||||
|
|
||||||
|
# The Authentication Method SWORD should use.
|
||||||
|
# Valid values are "Basic" or "None". Default is "Basic"
|
||||||
|
# (Requires reboot of servlet container, e.g. Tomcat, to reload)
|
||||||
|
#sword-server.authentication-method = Basic
|
||||||
|
|
||||||
# tell the SWORD METS implementation which package ingester to use
|
# tell the SWORD METS implementation which package ingester to use
|
||||||
# to install deposited content. This should refer to one of the
|
# to install deposited content. This should refer to one of the
|
||||||
# classes configured for:
|
# classes configured for:
|
||||||
|
@@ -6,6 +6,18 @@
|
|||||||
# SWORD 2.0 protocol) #
|
# SWORD 2.0 protocol) #
|
||||||
#---------------------------------------------------------------#
|
#---------------------------------------------------------------#
|
||||||
|
|
||||||
|
# Whether or not to enable the SWORD v2 module
|
||||||
|
# When "true", the SWORD v2 module is accessible on ${swordv2-server.path}
|
||||||
|
# When "false" or commented out, SWORD v2 is disabled/inaccessible.
|
||||||
|
# (Requires reboot of servlet container, e.g. Tomcat, to reload)
|
||||||
|
#swordv2-server.enabled = true
|
||||||
|
|
||||||
|
# Path where SWORD v2 module is available (in the Spring REST webapp)
|
||||||
|
# Defaults to "swordv2", which means the SWORD v2 module would be available
|
||||||
|
# at ${dspace.restURL}/swordv2/
|
||||||
|
# (Requires reboot of servlet container, e.g. Tomcat, to reload)
|
||||||
|
#swordv2-server.path = swordv2
|
||||||
|
|
||||||
# the base url of the sword 2.0 system
|
# the base url of the sword 2.0 system
|
||||||
#
|
#
|
||||||
# the default if {dspace.url}/swordv2
|
# the default if {dspace.url}/swordv2
|
||||||
@@ -194,6 +206,32 @@ swordv2-server.generator.version = 2.0
|
|||||||
# Other valid values: 'None'
|
# Other valid values: 'None'
|
||||||
swordv2-server.auth-type = Basic
|
swordv2-server.auth-type = Basic
|
||||||
|
|
||||||
|
# SWORD v2 server implementation classes
|
||||||
|
# These are the default implementation classes to use for SWORD functions.
|
||||||
|
# Uncomment if you wish to change the implementation class.
|
||||||
|
# (Requires reboot of servlet container, e.g. Tomcat, to reload these settings)
|
||||||
|
#
|
||||||
|
# ServiceDocumentManager server implementation
|
||||||
|
#swordv2-server.service-document-impl = org.dspace.sword2.ServiceDocumentManagerDSpace
|
||||||
|
#
|
||||||
|
# CollectionListManager server implementation class
|
||||||
|
#swordv2-server.collection-list-impl = org.dspace.sword2.CollectionListManagerDSpace
|
||||||
|
#
|
||||||
|
# CollectionDepositManager server implementation class
|
||||||
|
#swordv2-server.collection-deposit-impl = org.dspace.sword2.CollectionDepositManagerDSpace
|
||||||
|
#
|
||||||
|
# MediaResourceManager server implementation class
|
||||||
|
#swordv2-server.media-resource-impl = org.dspace.sword2.MediaResourceManagerDSpace
|
||||||
|
#
|
||||||
|
# ContainerManager server implementation class name
|
||||||
|
#swordv2-server.container-impl = org.dspace.sword2.ContainerManagerDSpace
|
||||||
|
#
|
||||||
|
# StatementManager server implementation class
|
||||||
|
#swordv2-server.statement-impl = org.dspace.sword2.StatementManagerDSpace
|
||||||
|
#
|
||||||
|
# SwordConfiguration server implementation class
|
||||||
|
#swordv2-server.config-impl = org.dspace.sword2.SwordConfigurationDSpace
|
||||||
|
|
||||||
# The location where uploaded files and packages are
|
# The location where uploaded files and packages are
|
||||||
# stored while being processed
|
# stored while being processed
|
||||||
swordv2-server.upload.tempdir = ${upload.temp.dir}
|
swordv2-server.upload.tempdir = ${upload.temp.dir}
|
||||||
|
@@ -1,169 +0,0 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<groupId>org.dspace.modules</groupId>
|
|
||||||
<artifactId>oai</artifactId>
|
|
||||||
<packaging>war</packaging>
|
|
||||||
<name>DSpace OAI-PMH :: Local Customizations</name>
|
|
||||||
<description>
|
|
||||||
This project allows you to overlay your own local OAI customizations
|
|
||||||
on top of the default OAI-PMH web application provided with DSpace.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<artifactId>modules</artifactId>
|
|
||||||
<groupId>org.dspace</groupId>
|
|
||||||
<version>7.0-SNAPSHOT</version>
|
|
||||||
<relativePath>..</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<!-- This is the path to the root [dspace-src] directory. -->
|
|
||||||
<root.basedir>${basedir}/../../..</root.basedir>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<!-- Unpack the "additions" module into our target directory,
|
|
||||||
so that any custom classes in that module can be included
|
|
||||||
into this WAR's WEB-INF/classes (see maven-war-plugin below). -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>unpack</id>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>unpack-dependencies</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<includeGroupIds>org.dspace.modules</includeGroupIds>
|
|
||||||
<includeArtifactIds>additions</includeArtifactIds>
|
|
||||||
<!--NOTE: by default this will also unpack transitive dependencies. To disable, uncomment this next line:
|
|
||||||
<excludeTransitive>true</excludeTransitive>
|
|
||||||
-->
|
|
||||||
<outputDirectory>${project.build.directory}/additions</outputDirectory>
|
|
||||||
<excludes>META-INF/**</excludes>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<archiveClasses>false</archiveClasses>
|
|
||||||
<!-- Filter the web.xml (needed for IDE compatibility/debugging) -->
|
|
||||||
<filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
|
|
||||||
<!-- Copy any 'additions' (see m-dependency-p above) into WEB-INF/classes.
|
|
||||||
This ensures they are loaded prior to dependencies in WEB-INF/lib
|
|
||||||
(per Servlet 3.0 spec, section 10.5), and allows them to override
|
|
||||||
default classes in this WAR -->
|
|
||||||
<webResources>
|
|
||||||
<resource>
|
|
||||||
<directory>${project.build.directory}/additions</directory>
|
|
||||||
<targetPath>WEB-INF/classes</targetPath>
|
|
||||||
</resource>
|
|
||||||
</webResources>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<profiles>
|
|
||||||
<profile>
|
|
||||||
<id>oracle-support</id>
|
|
||||||
<activation>
|
|
||||||
<property>
|
|
||||||
<name>db.name</name>
|
|
||||||
<value>oracle</value>
|
|
||||||
</property>
|
|
||||||
</activation>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.oracle</groupId>
|
|
||||||
<artifactId>ojdbc6</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.dspace.modules</groupId>
|
|
||||||
<artifactId>additions</artifactId>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.lyncode</groupId>
|
|
||||||
<artifactId>builder-commons</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.dspace</groupId>
|
|
||||||
<artifactId>dspace-oai</artifactId>
|
|
||||||
<type>war</type>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.dspace</groupId>
|
|
||||||
<artifactId>dspace-oai</artifactId>
|
|
||||||
<type>jar</type>
|
|
||||||
<classifier>classes</classifier>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.lyncode</groupId>
|
|
||||||
<artifactId>builder-commons</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.servlet</groupId>
|
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<!--
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
|
||||||
<artifactId>log4j-slf4j-impl</artifactId>
|
|
||||||
</dependency>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.lyncode</groupId>
|
|
||||||
<artifactId>builder-commons</artifactId>
|
|
||||||
<version>1.0.2</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Note: XOAI requires hamcrest both for testing and runtime -->
|
|
||||||
<!-- As our Parent POM sets this to 'test' scope, we must override it -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.hamcrest</groupId>
|
|
||||||
<artifactId>hamcrest-all</artifactId>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<developers>
|
|
||||||
<developer>
|
|
||||||
<id>lyncode</id>
|
|
||||||
<email>dspace@lyncode.com</email>
|
|
||||||
<name>DSpace @ Lyncode</name>
|
|
||||||
<url>http://www.lyncode.com</url>
|
|
||||||
</developer>
|
|
||||||
</developers>
|
|
||||||
</project>
|
|
@@ -1,112 +0,0 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<groupId>org.dspace.modules</groupId>
|
|
||||||
<artifactId>rdf</artifactId>
|
|
||||||
<packaging>war</packaging>
|
|
||||||
<name>DSpace RDF :: Local Customizations</name>
|
|
||||||
<description>
|
|
||||||
Overlay RDF customizations
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<artifactId>modules</artifactId>
|
|
||||||
<groupId>org.dspace</groupId>
|
|
||||||
<version>7.0-SNAPSHOT</version>
|
|
||||||
<relativePath>..</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<!-- This is the path to the root [dspace-src] directory. -->
|
|
||||||
<root.basedir>${basedir}/../../..</root.basedir>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<!-- Unpack the "additions" module into our target directory,
|
|
||||||
so that any custom classes in that module can be included
|
|
||||||
into this WAR's WEB-INF/classes (see maven-war-plugin below). -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>unpack</id>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>unpack-dependencies</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<includeGroupIds>org.dspace.modules</includeGroupIds>
|
|
||||||
<includeArtifactIds>additions</includeArtifactIds>
|
|
||||||
<!--NOTE: by default this will also unpack transitive dependencies. To disable, uncomment this next line:
|
|
||||||
<excludeTransitive>true</excludeTransitive>
|
|
||||||
-->
|
|
||||||
<outputDirectory>${project.build.directory}/additions</outputDirectory>
|
|
||||||
<excludes>META-INF/**</excludes>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<archiveClasses>false</archiveClasses>
|
|
||||||
<!-- Filter the web.xml (needed for IDE compatibility/debugging) -->
|
|
||||||
<filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
|
|
||||||
<!-- Copy any 'additions' (see m-dependency-p above) into WEB-INF/classes.
|
|
||||||
This ensures they are loaded prior to dependencies in WEB-INF/lib
|
|
||||||
(per Servlet 3.0 spec, section 10.5), and allows them to override
|
|
||||||
default classes in this WAR -->
|
|
||||||
<webResources>
|
|
||||||
<resource>
|
|
||||||
<directory>${project.build.directory}/additions</directory>
|
|
||||||
<targetPath>WEB-INF/classes</targetPath>
|
|
||||||
</resource>
|
|
||||||
</webResources>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<profiles>
|
|
||||||
<profile>
|
|
||||||
<id>oracle-support</id>
|
|
||||||
<activation>
|
|
||||||
<property>
|
|
||||||
<name>db.name</name>
|
|
||||||
<value>oracle</value>
|
|
||||||
</property>
|
|
||||||
</activation>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.oracle</groupId>
|
|
||||||
<artifactId>ojdbc6</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.dspace.modules</groupId>
|
|
||||||
<artifactId>additions</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.dspace</groupId>
|
|
||||||
<artifactId>dspace-rdf</artifactId>
|
|
||||||
<type>war</type>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.servlet</groupId>
|
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
@@ -1,129 +0,0 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<groupId>org.dspace.modules</groupId>
|
|
||||||
<artifactId>sword</artifactId>
|
|
||||||
<packaging>war</packaging>
|
|
||||||
<name>DSpace SWORD :: Local Customizations</name>
|
|
||||||
<description>
|
|
||||||
This project allows you to overlay your own local SWORD customizations
|
|
||||||
on top of the default SWORD web application provided with DSpace.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
A Parent POM that Maven inherits DSpace Default
|
|
||||||
POM attributes from.
|
|
||||||
-->
|
|
||||||
<parent>
|
|
||||||
<groupId>org.dspace</groupId>
|
|
||||||
<artifactId>modules</artifactId>
|
|
||||||
<version>7.0-SNAPSHOT</version>
|
|
||||||
<relativePath>..</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<!-- This is the path to the root [dspace-src] directory. -->
|
|
||||||
<root.basedir>${basedir}/../../..</root.basedir>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<!-- Unpack the "additions" module into our target directory,
|
|
||||||
so that any custom classes in that module can be included
|
|
||||||
into this WAR's WEB-INF/classes (see maven-war-plugin below). -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>unpack</id>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>unpack-dependencies</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<includeGroupIds>org.dspace.modules</includeGroupIds>
|
|
||||||
<includeArtifactIds>additions</includeArtifactIds>
|
|
||||||
<!--NOTE: by default this will also unpack transitive dependencies. To disable, uncomment this next line:
|
|
||||||
<excludeTransitive>true</excludeTransitive>
|
|
||||||
-->
|
|
||||||
<outputDirectory>${project.build.directory}/additions</outputDirectory>
|
|
||||||
<excludes>META-INF/**</excludes>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<archiveClasses>false</archiveClasses>
|
|
||||||
<!-- Filter the web.xml (needed for IDE compatibility/debugging) -->
|
|
||||||
<filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
|
|
||||||
<!-- Copy any 'additions' (see m-dependency-p above) into WEB-INF/classes.
|
|
||||||
This ensures they are loaded prior to dependencies in WEB-INF/lib
|
|
||||||
(per Servlet 3.0 spec, section 10.5), and allows them to override
|
|
||||||
default classes in this WAR -->
|
|
||||||
<webResources>
|
|
||||||
<resource>
|
|
||||||
<directory>${project.build.directory}/additions</directory>
|
|
||||||
<targetPath>WEB-INF/classes</targetPath>
|
|
||||||
</resource>
|
|
||||||
</webResources>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<profiles>
|
|
||||||
<profile>
|
|
||||||
<id>oracle-support</id>
|
|
||||||
<activation>
|
|
||||||
<property>
|
|
||||||
<name>db.name</name>
|
|
||||||
<value>oracle</value>
|
|
||||||
</property>
|
|
||||||
</activation>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.oracle</groupId>
|
|
||||||
<artifactId>ojdbc6</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.dspace.modules</groupId>
|
|
||||||
<artifactId>additions</artifactId>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>xml-apis</groupId>
|
|
||||||
<artifactId>xml-apis</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.dspace</groupId>
|
|
||||||
<artifactId>dspace-sword</artifactId>
|
|
||||||
<type>war</type>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.dspace</groupId>
|
|
||||||
<artifactId>dspace-sword</artifactId>
|
|
||||||
<type>jar</type>
|
|
||||||
<classifier>classes</classifier>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.servlet</groupId>
|
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
@@ -1,144 +0,0 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<groupId>org.dspace.modules</groupId>
|
|
||||||
<artifactId>swordv2</artifactId>
|
|
||||||
<packaging>war</packaging>
|
|
||||||
<name>DSpace SWORD v2 :: Local Customizations</name>
|
|
||||||
<description>
|
|
||||||
This project allows you to overlay your own local SWORD v2 customizations
|
|
||||||
on top of the default SWORD v2 web application provided with DSpace.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
A Parent POM that Maven inherits DSpace Default
|
|
||||||
POM attributes from.
|
|
||||||
-->
|
|
||||||
<parent>
|
|
||||||
<groupId>org.dspace</groupId>
|
|
||||||
<artifactId>modules</artifactId>
|
|
||||||
<version>7.0-SNAPSHOT</version>
|
|
||||||
<relativePath>..</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<!-- This is the path to the root [dspace-src] directory. -->
|
|
||||||
<root.basedir>${basedir}/../../..</root.basedir>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<!-- Unpack the "additions" module into our target directory,
|
|
||||||
so that any custom classes in that module can be included
|
|
||||||
into this WAR's WEB-INF/classes (see maven-war-plugin below). -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>unpack</id>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>unpack-dependencies</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<includeGroupIds>org.dspace.modules</includeGroupIds>
|
|
||||||
<includeArtifactIds>additions</includeArtifactIds>
|
|
||||||
<!--NOTE: by default this will also unpack transitive dependencies. To disable, uncomment this next line:
|
|
||||||
<excludeTransitive>true</excludeTransitive>
|
|
||||||
-->
|
|
||||||
<outputDirectory>${project.build.directory}/additions</outputDirectory>
|
|
||||||
<excludes>META-INF/**</excludes>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<archiveClasses>false</archiveClasses>
|
|
||||||
<!-- Filter the web.xml (needed for IDE compatibility/debugging) -->
|
|
||||||
<filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
|
|
||||||
<!-- Copy any 'additions' (see m-dependency-p above) into WEB-INF/classes.
|
|
||||||
This ensures they are loaded prior to dependencies in WEB-INF/lib
|
|
||||||
(per Servlet 3.0 spec, section 10.5), and allows them to override
|
|
||||||
default classes in this WAR -->
|
|
||||||
<webResources>
|
|
||||||
<resource>
|
|
||||||
<directory>${project.build.directory}/additions</directory>
|
|
||||||
<targetPath>WEB-INF/classes</targetPath>
|
|
||||||
</resource>
|
|
||||||
</webResources>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<profiles>
|
|
||||||
<profile>
|
|
||||||
<id>oracle-support</id>
|
|
||||||
<activation>
|
|
||||||
<property>
|
|
||||||
<name>db.name</name>
|
|
||||||
<value>oracle</value>
|
|
||||||
</property>
|
|
||||||
</activation>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.oracle</groupId>
|
|
||||||
<artifactId>ojdbc6</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</profile>
|
|
||||||
<profile>
|
|
||||||
<id>postgres-support</id>
|
|
||||||
<activation>
|
|
||||||
<property>
|
|
||||||
<name>!db.name</name>
|
|
||||||
</property>
|
|
||||||
</activation>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.postgresql</groupId>
|
|
||||||
<artifactId>postgresql</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.dspace.modules</groupId>
|
|
||||||
<artifactId>additions</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- DSpace Custom SWORDv2 Web application -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.dspace</groupId>
|
|
||||||
<artifactId>dspace-swordv2</artifactId>
|
|
||||||
<type>war</type>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- DSpace Implementation of SWORDv2 Provider -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.dspace</groupId>
|
|
||||||
<artifactId>dspace-swordv2</artifactId>
|
|
||||||
<type>jar</type>
|
|
||||||
<classifier>classes</classifier>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.servlet</groupId>
|
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
@@ -198,13 +198,11 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>dspace-oai</artifactId>
|
<artifactId>dspace-oai</artifactId>
|
||||||
<classifier>classes</classifier>
|
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>dspace-rdf</artifactId>
|
<artifactId>dspace-rdf</artifactId>
|
||||||
<type>war</type>
|
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -227,13 +225,11 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>dspace-sword</artifactId>
|
<artifactId>dspace-sword</artifactId>
|
||||||
<classifier>classes</classifier>
|
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>dspace-swordv2</artifactId>
|
<artifactId>dspace-swordv2</artifactId>
|
||||||
<classifier>classes</classifier>
|
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
@@ -290,8 +286,6 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dspace</groupId>
|
<groupId>org.dspace</groupId>
|
||||||
<artifactId>dspace-oai</artifactId>
|
<artifactId>dspace-oai</artifactId>
|
||||||
<type>jar</type>
|
|
||||||
<classifier>classes</classifier>
|
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>com.lyncode</groupId>
|
<groupId>com.lyncode</groupId>
|
||||||
|
@@ -1,219 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
|
|
||||||
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/
|
|
||||||
|
|
||||||
-->
|
|
||||||
<!--
|
|
||||||
THIS FILE EXISTS TO SIMPLIFY TESTING IN DOCKER.
|
|
||||||
This file overrides the solr localhost restriction.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<web-app version='2.5'
|
|
||||||
xmlns='http://java.sun.com/xml/ns/javaee'
|
|
||||||
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
|
|
||||||
xsi:schemaLocation='http://java.sun.com/xml/ns/javaee
|
|
||||||
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd'>
|
|
||||||
|
|
||||||
<!-- Uncomment if you are trying to use a Resin version before 3.0.19.
|
|
||||||
Their XML implementation isn't entirely compatible with Xerces.
|
|
||||||
Below are the implementations to use with Sun's JVM.
|
|
||||||
<system-property javax.xml.xpath.XPathFactory=
|
|
||||||
"com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl"/>
|
|
||||||
<system-property javax.xml.parsers.DocumentBuilderFactory=
|
|
||||||
"com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl"/>
|
|
||||||
<system-property javax.xml.parsers.SAXParserFactory=
|
|
||||||
"com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<env-entry>
|
|
||||||
<description>Solr home: configuration, cores etc.</description>
|
|
||||||
<env-entry-name>solr/home</env-entry-name>
|
|
||||||
<env-entry-value>${dspace.dir}/solr</env-entry-value>
|
|
||||||
<env-entry-type>java.lang.String</env-entry-type>
|
|
||||||
</env-entry>
|
|
||||||
|
|
||||||
<!-- Tell Solr where its log4j configuration is located -->
|
|
||||||
<!-- NOTE: Solr cannot use the default DSpace log4j configuration as it
|
|
||||||
isn't initialized until the DSpace Kernel starts up, and we don't want
|
|
||||||
Solr to depend on the DSpace Kernel/API -->
|
|
||||||
<context-param>
|
|
||||||
<description>
|
|
||||||
URL locating a Log4J configuration file (properties or XML).
|
|
||||||
</description>
|
|
||||||
<param-name>log4jConfiguration</param-name>
|
|
||||||
<param-value>${dspace.dir}/config/log4j-solr.xml</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<listener>
|
|
||||||
<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
|
|
||||||
</listener>
|
|
||||||
|
|
||||||
<filter>
|
|
||||||
<description>Activate logging</description>
|
|
||||||
<filter-name>log4jServletFilter</filter-name>
|
|
||||||
<filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
|
|
||||||
</filter>
|
|
||||||
|
|
||||||
<!-- Any path (name) registered in solrconfig.xml will be sent to that filter -->
|
|
||||||
<filter>
|
|
||||||
<filter-name>LocalHostRestrictionFilter</filter-name>
|
|
||||||
<filter-class>org.dspace.solr.filters.LocalHostRestrictionFilter</filter-class>
|
|
||||||
</filter>
|
|
||||||
|
|
||||||
<!-- Any path (name) registered in solrconfig.xml will be sent to that filter -->
|
|
||||||
<filter>
|
|
||||||
<filter-name>SolrRequestFilter</filter-name>
|
|
||||||
<filter-class>org.apache.solr.servlet.SolrDispatchFilter</filter-class>
|
|
||||||
<!-- If you are wiring Solr into a larger web application which controls
|
|
||||||
the web context root, you will probably want to mount Solr under
|
|
||||||
a path prefix (app.war with /app/solr mounted into it, for example).
|
|
||||||
You will need to put this prefix in front of the SolrDispatchFilter
|
|
||||||
url-pattern mapping too (/solr/*), and also on any paths for
|
|
||||||
legacy Solr servlet mappings you may be using.
|
|
||||||
For the Admin UI to work properly in a path-prefixed configuration,
|
|
||||||
the admin folder containing the resources needs to be under the app context root
|
|
||||||
named to match the path-prefix. For example:
|
|
||||||
|
|
||||||
.war
|
|
||||||
xxx
|
|
||||||
js
|
|
||||||
main.js
|
|
||||||
-->
|
|
||||||
<!--
|
|
||||||
<init-param>
|
|
||||||
<param-name>path-prefix</param-name>
|
|
||||||
<param-value>/xxx</param-value>
|
|
||||||
</init-param>
|
|
||||||
-->
|
|
||||||
</filter>
|
|
||||||
|
|
||||||
<filter-mapping>
|
|
||||||
<filter-name>log4jServletFilter</filter-name>
|
|
||||||
<url-pattern>/*</url-pattern>
|
|
||||||
<dispatcher>REQUEST</dispatcher>
|
|
||||||
<dispatcher>FORWARD</dispatcher>
|
|
||||||
<dispatcher>INCLUDE</dispatcher>
|
|
||||||
<dispatcher>ERROR</dispatcher>
|
|
||||||
</filter-mapping>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<filter-mapping>
|
|
||||||
<filter-name>LocalHostRestrictionFilter</filter-name>
|
|
||||||
<url-pattern>/*</url-pattern>
|
|
||||||
</filter-mapping>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<filter-mapping>
|
|
||||||
<!--
|
|
||||||
NOTE: When using multicore, /admin JSP URLs with a core specified
|
|
||||||
such as /solr/coreName/admin/stats.jsp get forwarded by a
|
|
||||||
RequestDispatcher to /solr/admin/stats.jsp with the specified core
|
|
||||||
put into request scope keyed as "org.apache.solr.SolrCore".
|
|
||||||
|
|
||||||
It is unnecessary, and potentially problematic, to have the SolrDispatchFilter
|
|
||||||
configured to also filter on forwards. Do not configure
|
|
||||||
this dispatcher as <dispatcher>FORWARD</dispatcher>.
|
|
||||||
-->
|
|
||||||
<filter-name>SolrRequestFilter</filter-name>
|
|
||||||
<url-pattern>/*</url-pattern>
|
|
||||||
</filter-mapping>
|
|
||||||
|
|
||||||
<!-- Otherwise it will continue to the old servlets -->
|
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>Zookeeper</servlet-name>
|
|
||||||
<servlet-class>org.apache.solr.servlet.ZookeeperInfoServlet</servlet-class>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>LoadAdminUI</servlet-name>
|
|
||||||
<servlet-class>org.apache.solr.servlet.LoadAdminUiServlet</servlet-class>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<!-- Remove in Solr 5.0 -->
|
|
||||||
<!-- This sends SC_MOVED_PERMANENTLY (301) for resources that changed in 4.0 -->
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>RedirectOldAdminUI</servlet-name>
|
|
||||||
<servlet-class>org.apache.solr.servlet.RedirectServlet</servlet-class>
|
|
||||||
<init-param>
|
|
||||||
<param-name>destination</param-name>
|
|
||||||
<param-value>${context}/#/</param-value>
|
|
||||||
</init-param>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>RedirectOldZookeeper</servlet-name>
|
|
||||||
<servlet-class>org.apache.solr.servlet.RedirectServlet</servlet-class>
|
|
||||||
<init-param>
|
|
||||||
<param-name>destination</param-name>
|
|
||||||
<param-value>${context}/zookeeper</param-value>
|
|
||||||
</init-param>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>RedirectLogging</servlet-name>
|
|
||||||
<servlet-class>org.apache.solr.servlet.RedirectServlet</servlet-class>
|
|
||||||
<init-param>
|
|
||||||
<param-name>destination</param-name>
|
|
||||||
<param-value>${context}/#/~logging</param-value>
|
|
||||||
</init-param>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>SolrRestApi</servlet-name>
|
|
||||||
<servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class>
|
|
||||||
<init-param>
|
|
||||||
<param-name>org.restlet.application</param-name>
|
|
||||||
<param-value>org.apache.solr.rest.SolrRestApi</param-value>
|
|
||||||
</init-param>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>RedirectOldAdminUI</servlet-name>
|
|
||||||
<url-pattern>/admin/</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>RedirectOldAdminUI</servlet-name>
|
|
||||||
<url-pattern>/admin</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>RedirectOldZookeeper</servlet-name>
|
|
||||||
<url-pattern>/zookeeper.jsp</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>RedirectLogging</servlet-name>
|
|
||||||
<url-pattern>/logging</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
<!-- Servlet Mapping -->
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>Zookeeper</servlet-name>
|
|
||||||
<url-pattern>/zookeeper</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>LoadAdminUI</servlet-name>
|
|
||||||
<url-pattern>/admin.html</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>SolrRestApi</servlet-name>
|
|
||||||
<url-pattern>/schema/*</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
<mime-mapping>
|
|
||||||
<extension>.xsl</extension>
|
|
||||||
<!-- per http://www.w3.org/TR/2006/PR-xslt20-20061121/ -->
|
|
||||||
<mime-type>application/xslt+xml</mime-type>
|
|
||||||
</mime-mapping>
|
|
||||||
|
|
||||||
<welcome-file-list>
|
|
||||||
<welcome-file>admin.html</welcome-file>
|
|
||||||
</welcome-file-list>
|
|
||||||
|
|
||||||
</web-app>
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user