mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-18 07:23:08 +00:00
Add dspace-rest, using Jersey, light support for Collection / Community
This commit is contained in:
5
dspace-rest/LICENSE
Normal file
5
dspace-rest/LICENSE
Normal file
@@ -0,0 +1,5 @@
|
||||
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/
|
16
dspace-rest/README
Normal file
16
dspace-rest/README
Normal file
@@ -0,0 +1,16 @@
|
||||
A RESTful web services API for DSpace.
|
||||
|
||||
Built on JERSEY
|
||||
|
||||
mvn clean package
|
||||
Deploy /target/rest.war to tomcat.
|
||||
|
||||
Endpoints:
|
||||
- http://localhost:8080/dspace-rest/collections
|
||||
-- http://localhost:8080/dspace-rest/collections/{collectionID}
|
||||
-- http://localhost:8080/dspace-rest/collections/{collectionID}?expand=parentCommunityID,parentCommunityIDList,itemIDList
|
||||
-- http://localhost:8080/dspace-rest/collections/123
|
||||
|
||||
- http://localhost:8080/dspace-rest/communities
|
||||
|
||||
There is an ?expand= query parameter for expensive operations. You can tack it on the end of /collections endpoints. It is optional, all, some or none.
|
61
dspace-rest/pom.xml
Normal file
61
dspace-rest/pom.xml
Normal file
@@ -0,0 +1,61 @@
|
||||
<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.rest</groupId>
|
||||
<artifactId>dspace-rest</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>DSpace RESTful web services API</name>
|
||||
<url>http://demo.dspace.org</url>
|
||||
<dependencies>
|
||||
<!-- Jersey, for RESTful web services -->
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-server</artifactId>
|
||||
<version>1.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-servlet</artifactId>
|
||||
<version>1.17</version>
|
||||
</dependency>
|
||||
<!-- JSON serialization, should I use jackson?-->
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-json</artifactId>
|
||||
<version>1.8</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Use DSpace, for now, an older version to minimize spring generated dependency on Discovery -->
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-api</artifactId>
|
||||
<version>1.8.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Connecting to DSpace datasource sets a dependency on Postgres DB-->
|
||||
<dependency>
|
||||
<groupId>commons-dbcp</groupId>
|
||||
<artifactId>commons-dbcp</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>9.0-801.jdbc3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<finalName>${artifactId}</finalName>
|
||||
</build>
|
||||
</project>
|
@@ -0,0 +1,77 @@
|
||||
package org.dspace.rest;
|
||||
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.core.Context;
|
||||
|
||||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/*
|
||||
The "Path" annotation indicates the URI this class will be available at relative to your base URL. For
|
||||
example, if this web-app is launched at localhost using a context of "hello" and no URL pattern is defined
|
||||
in the web.xml servlet mapping section, then the web service will be available at:
|
||||
|
||||
http://localhost:8080/<webapp>/collections
|
||||
*/
|
||||
@Path("/collections")
|
||||
public class CollectionsResource {
|
||||
final String collectionsPath = "/dspace-rest/collections/";
|
||||
|
||||
private static Context context;
|
||||
|
||||
/*
|
||||
The "GET" annotation indicates this method will respond to HTTP Get requests.
|
||||
The "Produces" annotation indicates the MIME response the method will return.
|
||||
*/
|
||||
@GET
|
||||
@Path("/")
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
public String listHTML() {
|
||||
StringBuilder everything = new StringBuilder();
|
||||
try {
|
||||
Context context = new Context();
|
||||
|
||||
Collection[] collections = Collection.findAll(context);
|
||||
for(Collection collection : collections) {
|
||||
everything.append("<li><a href='" + collectionsPath + collection.getID() + "'>" + collection.getID() + " - " + collection.getName() + "</a></li>\n");
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
return "ERROR: " + e.getMessage();
|
||||
}
|
||||
|
||||
return "<html><title>Hello!</title><body>Collections<br/><ul>" + everything.toString() + "</ul>.</body></html> ";
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/")
|
||||
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||
public org.dspace.rest.common.Collection[] list(@QueryParam("expand") String expand) {
|
||||
try {
|
||||
if(context == null || !context.isValid() ) {
|
||||
context = new Context();
|
||||
}
|
||||
|
||||
Collection[] collections = Collection.findAll(context);
|
||||
ArrayList<org.dspace.rest.common.Collection> collectionArrayList = new ArrayList<org.dspace.rest.common.Collection>();
|
||||
for(Collection collection : collections) {
|
||||
org.dspace.rest.common.Collection restCollection = new org.dspace.rest.common.Collection(collection, expand);
|
||||
collectionArrayList.add(restCollection);
|
||||
}
|
||||
|
||||
return collectionArrayList.toArray(new org.dspace.rest.common.Collection[0]);
|
||||
|
||||
} catch (SQLException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{collection_id}")
|
||||
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||
public org.dspace.rest.common.Collection getCollection(@PathParam("collection_id") Integer collection_id, @QueryParam("expand") String expand) {
|
||||
return new org.dspace.rest.common.Collection(collection_id, expand);
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
package org.dspace.rest;
|
||||
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.core.Context;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/*
|
||||
The "Path" annotation indicates the URI this class will be available at relative to your base URL. For
|
||||
example, if this web-app is launched at localhost using a context of "hello" and no URL pattern is defined
|
||||
in the web.xml servlet mapping section, then the web service will be available at:
|
||||
|
||||
http://localhost:8080/<webapp>/communities
|
||||
*/
|
||||
@Path("/communities")
|
||||
public class CommunitiesResource {
|
||||
private static Context context;
|
||||
|
||||
/*
|
||||
The "GET" annotation indicates this method will respond to HTTP Get requests.
|
||||
The "Produces" annotation indicates the MIME response the method will return.
|
||||
*/
|
||||
@GET
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
public String list() {
|
||||
StringBuilder everything = new StringBuilder();
|
||||
try {
|
||||
if(context == null || !context.isValid() ) {
|
||||
context = new Context();
|
||||
}
|
||||
Community[] communities = Community.findAllTop(context);
|
||||
for(Community community : communities) {
|
||||
everything.append(community.getName() + "<br/>\n");
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
return "ERROR: " + e.getMessage();
|
||||
}
|
||||
|
||||
return "<html><title>Hello!</title><body>Communities:<br/>" + everything.toString() + ".</body></html> ";
|
||||
}
|
||||
}
|
27
dspace-rest/src/main/java/org/dspace/rest/HelloWorld.java
Normal file
27
dspace-rest/src/main/java/org/dspace/rest/HelloWorld.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package org.dspace.rest;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
/*
|
||||
The "Path" annotation indicates the URI this class will be available at relative to your base URL. For
|
||||
example, if this web-app is launched at localhost using a context of "hello" and no URL pattern is defined
|
||||
in the web.xml servlet mapping section, then the web service will be available at:
|
||||
|
||||
http://localhost:8080/<webapp>/helloworld
|
||||
*/
|
||||
@Path("/helloworld")
|
||||
public class HelloWorld {
|
||||
|
||||
/*
|
||||
The "GET" annotation indicates this method will respond to HTTP Get requests.
|
||||
The "Produces" annotation indicates the MIME response the method will return.
|
||||
*/
|
||||
@GET
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
public String sayHtmlHello() {
|
||||
return "<html><title>Hello!</title><body>Hello, world.</body></html> ";
|
||||
}
|
||||
}
|
217
dspace-rest/src/main/java/org/dspace/rest/common/Collection.java
Normal file
217
dspace-rest/src/main/java/org/dspace/rest/common/Collection.java
Normal file
@@ -0,0 +1,217 @@
|
||||
package org.dspace.rest.common;
|
||||
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.ItemIterator;
|
||||
import org.dspace.core.Context;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA.
|
||||
* User: peterdietz
|
||||
* Date: 5/22/13
|
||||
* Time: 9:41 AM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
@XmlRootElement
|
||||
public class Collection {
|
||||
//Internal value
|
||||
private Integer collectionID;
|
||||
|
||||
//Relationships to other objects
|
||||
private Integer logoID;
|
||||
|
||||
//Exandable relationships
|
||||
private Integer parentCommunityID;
|
||||
private List<Integer> parentCommunityIDList = new ArrayList<Integer>();
|
||||
private List<Integer> itemIDList = new ArrayList<Integer>();
|
||||
|
||||
|
||||
private List<String> expand = new ArrayList<String>();
|
||||
|
||||
//Internal metadata
|
||||
private String name;
|
||||
private String handle;
|
||||
private String license;
|
||||
|
||||
//Calculated
|
||||
private Integer numberItems;
|
||||
|
||||
private static Context context;
|
||||
|
||||
public Collection(){}
|
||||
|
||||
public Collection(org.dspace.content.Collection collection, String expand) {
|
||||
setup(collection, expand);
|
||||
}
|
||||
|
||||
public Collection(Integer collectionID, String expand) {
|
||||
try {
|
||||
if(context == null || !context.isValid() ) {
|
||||
context = new Context();
|
||||
}
|
||||
|
||||
org.dspace.content.Collection collection = org.dspace.content.Collection.find(context, collectionID);
|
||||
setup(collection, expand);
|
||||
|
||||
} catch (Exception e) {
|
||||
this.setName(e.getMessage());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void setup(org.dspace.content.Collection collection, String expand) {
|
||||
List<String> expandFields = new ArrayList<String>();
|
||||
if(expand != null) {
|
||||
expandFields = Arrays.asList(expand.split(","));
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
this.setCollectionID(collection.getID());
|
||||
this.setName(collection.getName());
|
||||
this.setHandle(collection.getHandle());
|
||||
|
||||
if(expandFields.contains("parentCommunityIDList")) {
|
||||
Community[] parentCommunities = collection.getCommunities();
|
||||
for(Community parentCommunity : parentCommunities) {
|
||||
this.addParentCommunityIDList(parentCommunity.getID());
|
||||
}
|
||||
} else {
|
||||
this.addExpand("parentCommunityIDList");
|
||||
}
|
||||
|
||||
if(expandFields.contains("parentCommunityID")) {
|
||||
Community parentCommunity = (Community) collection.getParentObject();
|
||||
this.setParentCommunityID(parentCommunity.getID());
|
||||
} else {
|
||||
this.addExpand("parentCommunityID");
|
||||
}
|
||||
|
||||
if(expandFields.contains("itemIDList")) {
|
||||
ItemIterator childItems = collection.getItems();
|
||||
while(childItems.hasNext()) {
|
||||
Item item = childItems.next();
|
||||
this.addItemIDToList(item.getID());
|
||||
}
|
||||
} else {
|
||||
this.addExpand("itemIDList");
|
||||
}
|
||||
|
||||
if(collection.getLogo() != null) {
|
||||
this.setLogoID(collection.getLogo().getID());
|
||||
}
|
||||
|
||||
this.setLicense(collection.getLicense());
|
||||
this.setNumberItems(collection.countItems());
|
||||
//collection.getMetadata()
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//metadata s
|
||||
//String provenance_description;
|
||||
//String short_description;
|
||||
//String introductory_text;
|
||||
//String copyright_text;
|
||||
//String side_bar_text;
|
||||
|
||||
public Integer getCollectionID() {
|
||||
return collectionID;
|
||||
}
|
||||
|
||||
public void setCollectionID(Integer id) {
|
||||
this.collectionID = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getHandle() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
public void setHandle(String handle) {
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
public Integer getLogoID() {
|
||||
return logoID;
|
||||
}
|
||||
|
||||
public void setLogoID(Integer logoID) {
|
||||
this.logoID = logoID;
|
||||
}
|
||||
|
||||
public String getLicense() {
|
||||
return license;
|
||||
}
|
||||
|
||||
public void setLicense(String license) {
|
||||
this.license = license;
|
||||
}
|
||||
|
||||
public Integer getNumberItems() {
|
||||
return numberItems;
|
||||
}
|
||||
|
||||
public void setNumberItems(Integer numberItems) {
|
||||
this.numberItems = numberItems;
|
||||
}
|
||||
|
||||
public Integer getParentCommunityID() {
|
||||
return parentCommunityID;
|
||||
}
|
||||
|
||||
public void setParentCommunityID(Integer parentCommunityID) {
|
||||
this.parentCommunityID = parentCommunityID;
|
||||
}
|
||||
|
||||
public List<Integer> getParentCommunityIDList() {
|
||||
return parentCommunityIDList;
|
||||
}
|
||||
|
||||
public void setParentCommunityIDList(List<Integer> parentCommunityIDList) {
|
||||
this.parentCommunityIDList = parentCommunityIDList;
|
||||
}
|
||||
|
||||
public void addParentCommunityIDList(Integer communityParentID) {
|
||||
this.parentCommunityIDList.add(communityParentID);
|
||||
}
|
||||
|
||||
|
||||
public List<Integer> getItemIDList() {
|
||||
return itemIDList;
|
||||
}
|
||||
|
||||
public void setItemIDList(List<Integer> itemIDList) {
|
||||
this.itemIDList = itemIDList;
|
||||
}
|
||||
|
||||
public void addItemIDToList(Integer itemID) {
|
||||
this.itemIDList.add(itemID);
|
||||
}
|
||||
|
||||
public List<String> getExpand() {
|
||||
return expand;
|
||||
}
|
||||
|
||||
public void setExpand(List<String> expand) {
|
||||
this.expand = expand;
|
||||
}
|
||||
|
||||
public void addExpand(String expandableAttribute) {
|
||||
this.expand.add(expandableAttribute);
|
||||
}
|
||||
}
|
11
dspace-rest/src/main/webapp/WEB-INF/applicationContext.xml
Normal file
11
dspace-rest/src/main/webapp/WEB-INF/applicationContext.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">
|
||||
|
||||
<!-- Acquires the DSpace Utility Class with initialized Service Manager -->
|
||||
<bean id="dspace" class="org.dspace.utils.DSpace"/>
|
||||
</beans>
|
84
dspace-rest/src/main/webapp/WEB-INF/web.xml
Normal file
84
dspace-rest/src/main/webapp/WEB-INF/web.xml
Normal file
@@ -0,0 +1,84 @@
|
||||
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||
id="WebApp_ID" version="2.5">
|
||||
<servlet>
|
||||
<servlet-name>DSpace REST API</servlet-name>
|
||||
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
|
||||
<init-param>
|
||||
<!--
|
||||
The jersey ServletContainer will look for our Root Resource Class
|
||||
(i.e. our HelloWorld class) in the foo.bar package
|
||||
There are other ways to register this; see the jersey documentation for
|
||||
more details
|
||||
-->
|
||||
<param-name>com.sun.jersey.config.property.packages</param-name>
|
||||
<param-value>org.dspace.rest</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
|
||||
<param-value>true</param-value>
|
||||
</init-param>
|
||||
<!--
|
||||
Load the ServletContainer at startup. A value of 1 indicates the ServletContainer
|
||||
is a high priority servlet to load
|
||||
-->
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>DSpace REST API</servlet-name>
|
||||
<!--
|
||||
The url-pattern can be used to define your URL.
|
||||
Example, running local host with a context of "hello" and path annotation of "world"
|
||||
on the HelloWorld class:
|
||||
|
||||
<url-pattern>/*</url-pattern>
|
||||
The web service will be available at: http://localhost:8080/hello/world
|
||||
|
||||
|
||||
<url-pattern>/jersey/*</url-pattern>
|
||||
The web service will be available at http://localhost:8080/hello/jersey/world
|
||||
-->
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<context-param>
|
||||
<param-name>dspace-config</param-name>
|
||||
<param-value>/dspace/config/dspace.cfg</param-value>
|
||||
</context-param>
|
||||
|
||||
<!-- ConfigurationService initialization for dspace.dir -->
|
||||
<context-param>
|
||||
<description>The location of the main DSpace configuration file</description>
|
||||
<param-name>dspace.dir</param-name>
|
||||
<!-- param-value>${dspace.dir}</param-value -->
|
||||
<param-value>/dspace</param-value>
|
||||
</context-param>
|
||||
|
||||
<context-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>
|
||||
/WEB-INF/applicationContext.xml
|
||||
</param-value>
|
||||
<!--
|
||||
Add this context if using Spring Security
|
||||
/WEB-INF/applicationContext-security.xml
|
||||
-->
|
||||
</context-param>
|
||||
|
||||
<listener>
|
||||
<listener-class>org.dspace.app.util.DSpaceContextListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<!-- kernel start listener (from impl)
|
||||
The following listener can be used instead of the filter below, it is simpler, cleaner
|
||||
and eliminates the need for a DSpaceKernelServletFilter filter to be involved with the
|
||||
request cycle.
|
||||
-->
|
||||
<listener>
|
||||
<listener-class>org.dspace.servicemanager.servlet.DSpaceKernelServletContextListener</listener-class>
|
||||
</listener>
|
||||
|
||||
|
||||
</web-app>
|
0
dspace/modules/rest/pom.xml
Normal file
0
dspace/modules/rest/pom.xml
Normal file
0
dspace/modules/rest/src/main/webapp/.gitignore
vendored
Normal file
0
dspace/modules/rest/src/main/webapp/.gitignore
vendored
Normal file
Reference in New Issue
Block a user