From 670c7fa12fc97702cd67e845910ad8c5b06d0bf3 Mon Sep 17 00:00:00 2001 From: Aron Roberts Date: Thu, 26 Mar 2009 17:28:15 +0000 Subject: [PATCH] CSPACE-18: CollectionObject service is now running in JBoss, and raw XML tests to create and update are succeeding. (curl-based tests to delete and retrieve individual objects and lists are also succeeding.) Additional notes may be posted as a comment to this issue. Note that this cannot be verified to be working as of 2009-03-26 10:27 due to a JBoss WAR file issue. --- .../src/main/resources/hello.xsd | 291 ++++++++++++++---- .../services/CollectionObjectResource.java | 262 ++++++++++++++++ .../hello/services/HelloworldApplication.java | 1 + .../CollectionObjectServiceRawXmlTest.java | 107 +++++++ 4 files changed, 604 insertions(+), 57 deletions(-) create mode 100644 sandbox/aron/HelloWorld-CollectionObject/HelloWorldService/src/main/java/org/collectionspace/hello/services/CollectionObjectResource.java create mode 100644 sandbox/aron/HelloWorld-CollectionObject/HelloWorldService/src/test/java/org/collectionspace/hello/test/CollectionObjectServiceRawXmlTest.java diff --git a/sandbox/aron/HelloWorld-CollectionObject/HelloWorldJaxb/src/main/resources/hello.xsd b/sandbox/aron/HelloWorld-CollectionObject/HelloWorldJaxb/src/main/resources/hello.xsd index 8943ef963..f9a7e360c 100644 --- a/sandbox/aron/HelloWorld-CollectionObject/HelloWorldJaxb/src/main/resources/hello.xsd +++ b/sandbox/aron/HelloWorld-CollectionObject/HelloWorldJaxb/src/main/resources/hello.xsd @@ -7,71 +7,248 @@ version="0.1" > - - - + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + - - + + + + + + - - + + + + + + + + + + + + diff --git a/sandbox/aron/HelloWorld-CollectionObject/HelloWorldService/src/main/java/org/collectionspace/hello/services/CollectionObjectResource.java b/sandbox/aron/HelloWorld-CollectionObject/HelloWorldService/src/main/java/org/collectionspace/hello/services/CollectionObjectResource.java new file mode 100644 index 000000000..1197cc7cf --- /dev/null +++ b/sandbox/aron/HelloWorld-CollectionObject/HelloWorldService/src/main/java/org/collectionspace/hello/services/CollectionObjectResource.java @@ -0,0 +1,262 @@ +package org.collectionspace.hello.services; + +import java.net.URI; +import java.util.List; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; +import javax.ws.rs.DELETE; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.UriBuilder; +import javax.ws.rs.core.UriInfo; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import org.collectionspace.hello.CollectionObject; +import org.collectionspace.hello.CollectionObjectList; +import org.collectionspace.hello.CollectionObjectListItem; +import org.collectionspace.hello.DefaultCollectionObject; +import org.collectionspace.hello.ServiceMetadata; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("/collectionobjects") +@Consumes("application/xml") +@Produces("application/xml") +public class CollectionObjectResource { + + final Logger logger = LoggerFactory.getLogger(CollectionObjectResource.class); + private Map CollectionObjectDB = + new ConcurrentHashMap(); + private AtomicLong idCounter = new AtomicLong(); + + public CollectionObjectResource() { + } + + @POST + public Response createCollectionObject(CollectionObject c) { + if (c == null) { + Response response = Response.status(Response.Status.BAD_REQUEST).entity( + "Add failed, the CollectionObject provided was empty.").type("text/plain").build(); + throw new WebApplicationException(response); + } + Long id = idCounter.incrementAndGet(); + // c.getServiceMetadata().setCollectionSpaceId(id.toString()); + c.setServiceMetadata( new ServiceMetadata() ); + c.getServiceMetadata().setCollectionSpaceId("100"); + // c.setVersion(1); + CollectionObjectDB.put(c.getServiceMetadata().getCollectionSpaceId(), c); + verbose("created CollectionObject", c); + UriBuilder path = UriBuilder.fromResource(CollectionObjectResource.class); + path.path("" + c.getServiceMetadata().getCollectionSpaceId()); + Response response = Response.created(path.build()).build(); + return response; + } + + @GET + @Path("{id}") + public CollectionObject getCollectionObject(@PathParam("id") String id) { + CollectionObject c = CollectionObjectDB.get(id); + if (c == null) { + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Get failed, the requested CollectionObject ID:" + id + ": was not found.").type("text/plain").build(); + throw new WebApplicationException(response); + } + verbose("get CollectionObject", c); + return c; + } + + @PUT + @Path("{id}") + public CollectionObject updateCollectionObject(@PathParam("id") String id, CollectionObject update) { + CollectionObject current = CollectionObjectDB.get(id); + if (current == null) { + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Update failed, the CollectionObject ID:" + id + ": was not found.").type("text/plain").build(); + throw new WebApplicationException(response); + } + verbose("update CollectionObject input", update); + //todo: intelligent merge needed + // current.getServiceMetadata().setLastUpdated( [current date/time here] ); + current.getDefaultCollectionObject().setObjectNumber( + update.getDefaultCollectionObject().getObjectNumber()); + current.getDefaultCollectionObject().setOtherNumber( + update.getDefaultCollectionObject().getOtherNumber()); + current.getDefaultCollectionObject().setBriefDescription( + update.getDefaultCollectionObject().getBriefDescription()); + current.getDefaultCollectionObject().setComments( + update.getDefaultCollectionObject().getComments()); + current.getDefaultCollectionObject().setDistinguishingFeatures( + update.getDefaultCollectionObject().getDistinguishingFeatures()); + current.getDefaultCollectionObject().setObjectName( + update.getDefaultCollectionObject().getObjectName()); + current.getDefaultCollectionObject().setResponsibleDepartment( + update.getDefaultCollectionObject().getResponsibleDepartment()); + verbose("update CollectionObject output", current); + return current; + } + + // Get a list + @GET + public CollectionObjectList getCollectionObjectList(@Context UriInfo ui) { + CollectionObjectList CollectionObjectList = new CollectionObjectList(); + // The auto-generated method called here has a potentially misleading name; it returns a List. + List list = + CollectionObjectList.getCollectionObjectListItem(); + // builder starts with current URI and has appended path of getCollectionObject method + UriBuilder ub = ui.getAbsolutePathBuilder().path(this.getClass(), "getCollectionObject"); + for (CollectionObject c : CollectionObjectDB.values()) { + CollectionObjectListItem cli = new CollectionObjectListItem(); + cli.setCollectionSpaceId(c.getServiceMetadata().getCollectionSpaceId()); + cli.setObjectNumber(c.getDefaultCollectionObject().getObjectNumber()); + cli.setObjectName(c.getDefaultCollectionObject().getObjectName()); + // builder has {id} variable that must be filled in for each customer + URI uri = ub.build(c.getServiceMetadata().getCollectionSpaceId()); + cli.setUri(uri.toString()); + list.add(cli); + } + return CollectionObjectList; + } + + @DELETE + @Path("{id}") + public void deleteCollectionObject(@PathParam("id") String id) { + CollectionObject removed = CollectionObjectDB.remove(id); + if (removed == null) { + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Delete failed, the CollectionObject ID:" + id + ": was not found.").type("text/plain").build(); + throw new WebApplicationException(response); + } + verbose("deleted CollectionObject", removed); + } + + private void verbose(String msg, CollectionObject c) { + try { + System.out.println("CollectionObjectResource : " + msg); + JAXBContext jc = JAXBContext.newInstance(CollectionObject.class); + Marshaller m = jc.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + m.marshal(c, System.out); + } catch (Exception e) { + e.printStackTrace(); + } + } + +// @POST +// @Consumes("application/xml") +// public Response createCollectionObject(InputStream is) { +// CollectionObject c = readCollectionObject(is); +// c.setId(idCounter.incrementAndGet()); +// c.setVersion(1); +// CollectionObjectDB.put(c.getId(), c); +// try { +// System.out.println("Created CollectionObject " + c.getId()); +// outputCollectionObject(System.out, c); +// } catch (IOException ioe) { +// throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); +// } +// return Response.created(URI.create("/CollectionObjects/" + c.getId())).build(); +// +// } +// +// @GET +// @Path("{id}") +// @Produces("application/xml") +// public StreamingOutput getCollectionObject(@PathParam("id") int id) { +// final CollectionObject c = CollectionObjectDB.get(id); +// if (c == null) { +// throw new WebApplicationException(Response.Status.NOT_FOUND); +// } +// return new StreamingOutput() { +// +// public void write(OutputStream outputStream) throws IOException, WebApplicationException { +// outputCollectionObject(outputStream, c); +// } +// }; +// } +// +// @PUT +// @Path("{id}") +// @Consumes("application/xml") +// @Produces("application/xml") +// public StreamingOutput updateCollectionObject(@PathParam("id") int id, InputStream is) { +// CollectionObject update = readCollectionObject(is); +// CollectionObject current = CollectionObjectDB.get(id); +// if (current == null) { +// throw new WebApplicationException(Response.Status.NOT_FOUND); +// } +// +// current.setFirstName(update.getFirstName()); +// current.setLastName(update.getLastName()); +// current.setStreet(update.getStreet()); +// current.setState(update.getState()); +// current.setZip(update.getZip()); +// current.setCountry(update.getCountry()); +// current.setVersion(current.getVersion() + 1); +// final CollectionObject scurrent = current; +// return new StreamingOutput() { +// +// public void write(OutputStream outputStream) throws IOException, WebApplicationException { +// outputCollectionObject(outputStream, scurrent); +// } +// }; +// } +// +// protected void outputCollectionObject(OutputStream os, CollectionObject c) throws IOException { +// PrintStream writer = new PrintStream(os); +// writer.println(""); +// writer.println(" " + c.getFirstName() + ""); +// writer.println(" " + c.getLastName() + ""); +// writer.println(" " + c.getStreet() + ""); +// writer.println(" " + c.getCity() + ""); +// writer.println(" " + c.getState() + ""); +// writer.println(" " + c.getZip() + ""); +// writer.println(" " + c.getCountry() + ""); +// writer.println(""); +// } +// +// protected CollectionObject readCollectionObject(InputStream is) { +// try { +// DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); +// Document doc = builder.parse(is); +// Element root = doc.getDocumentElement(); +// CollectionObject c = new CollectionObject(); +// if (root.getAttribute("id") != null && !root.getAttribute("id").trim().equals("")) { +// c.setId(Integer.valueOf(root.getAttribute("id"))); +// } +// if (root.getAttribute("version") != null && !root.getAttribute("version").trim().equals("")) { +// c.setVersion(Integer.valueOf(root.getAttribute("version"))); +// } +// NodeList nodes = root.getChildNodes(); +// for (int i = 0; i < nodes.getLength(); i++) { +// Element element = (Element) nodes.item(i); +// if (element.getTagName().equals("first-name")) { +// c.setFirstName(element.getTextContent()); +// } else if (element.getTagName().equals("last-name")) { +// c.setLastName(element.getTextContent()); +// } else if (element.getTagName().equals("street")) { +// c.setStreet(element.getTextContent()); +// } else if (element.getTagName().equals("city")) { +// c.setCity(element.getTextContent()); +// } else if (element.getTagName().equals("state")) { +// c.setState(element.getTextContent()); +// } else if (element.getTagName().equals("zip")) { +// c.setZip(element.getTextContent()); +// } else if (element.getTagName().equals("country")) { +// c.setCountry(element.getTextContent()); +// } +// } +// return c; +// } catch (Exception e) { +// throw new WebApplicationException(e, Response.Status.BAD_REQUEST); +// } +// } +} diff --git a/sandbox/aron/HelloWorld-CollectionObject/HelloWorldService/src/main/java/org/collectionspace/hello/services/HelloworldApplication.java b/sandbox/aron/HelloWorld-CollectionObject/HelloWorldService/src/main/java/org/collectionspace/hello/services/HelloworldApplication.java index b7b7acdc0..572066a3b 100644 --- a/sandbox/aron/HelloWorld-CollectionObject/HelloWorldService/src/main/java/org/collectionspace/hello/services/HelloworldApplication.java +++ b/sandbox/aron/HelloWorld-CollectionObject/HelloWorldService/src/main/java/org/collectionspace/hello/services/HelloworldApplication.java @@ -10,6 +10,7 @@ public class HelloworldApplication extends Application { private Set> empty = new HashSet>(); public HelloworldApplication() { + singletons.add(new CollectionObjectResource()); singletons.add(new PersonResource()); singletons.add(new IdentifierResource()); } diff --git a/sandbox/aron/HelloWorld-CollectionObject/HelloWorldService/src/test/java/org/collectionspace/hello/test/CollectionObjectServiceRawXmlTest.java b/sandbox/aron/HelloWorld-CollectionObject/HelloWorldService/src/test/java/org/collectionspace/hello/test/CollectionObjectServiceRawXmlTest.java new file mode 100644 index 000000000..174994aba --- /dev/null +++ b/sandbox/aron/HelloWorld-CollectionObject/HelloWorldService/src/test/java/org/collectionspace/hello/test/CollectionObjectServiceRawXmlTest.java @@ -0,0 +1,107 @@ +package org.collectionspace.hello.test; + +import org.junit.Assert; +import org.junit.Test; +import org.apache.commons.httpclient.HttpMethodBase; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.methods.EntityEnclosingMethod; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; + +/** + * @version $Revision: 1 $ + */ +public class CollectionObjectServiceRawXmlTest { + + @Test + public void testCollectionObjectResource() throws Exception { + verbose("create a new CollectionObject"); + // Create a new object + String newCollectionObject = + "" + + "" + + "" + + "1984.021.0049" + + "Radio News, vol. 10, no. 2, August 1928" + + "" + + ""; + verbose("new object: " + newCollectionObject); + URL postUrl = new URL("http://localhost:8080/helloworld/cspace/collectionobjects"); + HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection(); + connection.setDoOutput(true); + connection.setInstanceFollowRedirects(false); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/xml"); + OutputStream os = connection.getOutputStream(); + os.write(newCollectionObject.getBytes()); + os.flush(); + verbose("response: " + connection.getResponseMessage()); + Assert.assertEquals(HttpURLConnection.HTTP_CREATED, connection.getResponseCode()); + String createdUrl = connection.getHeaderField("Location"); + verbose("Location: " + createdUrl); + connection.disconnect(); + + + // Get the new object + verbose("get created CollectionObject"); + URL getUrl = new URL(createdUrl); + connection = (HttpURLConnection) getUrl.openConnection(); + connection.setRequestMethod("GET"); + verbose("Content-Type: " + connection.getContentType()); + + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + + String line = reader.readLine(); + while (line != null) { + verbose(line); + line = reader.readLine(); + } + Assert.assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + connection.disconnect(); + + String updateCollectionObject = + "" + + "" + + "" + + "1997.005.0437" + + "Toy, Gotham City Police Helicopter, 1992" + + "" + + ""; + + connection = (HttpURLConnection) getUrl.openConnection(); + connection.setDoOutput(true); + connection.setRequestMethod("PUT"); + connection.setRequestProperty("Content-Type", "application/xml"); + os = connection.getOutputStream(); + os.write(updateCollectionObject.getBytes()); + os.flush(); + verbose("response: " + connection.getResponseMessage()); + Assert.assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + connection.disconnect(); + + // Show the update + verbose("updated CollectionObject"); + connection = (HttpURLConnection) getUrl.openConnection(); + connection.setRequestMethod("GET"); + + verbose("Content-Type: " + connection.getContentType()); + reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + + line = reader.readLine(); + while (line != null) { + verbose(line); + line = reader.readLine(); + } + Assert.assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + connection.disconnect(); + + } + + private void verbose(String msg) { + System.out.println("CollectionObjectServiceRawXmlTest : " + msg); + } +} -- 2.47.3