From: Richard Millet Date: Wed, 8 Apr 2009 17:03:49 +0000 (+0000) Subject: Migrated CollectionObject and Identifier service sources from my sandbox to the trunk. X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=7c36e91deba65f369fc22399edbc812a7516e4ea;p=tmp%2Fjakarta-migration.git Migrated CollectionObject and Identifier service sources from my sandbox to the trunk. --- diff --git a/HelloWorld/HelloWorldClient/src/main/java/org/collectionspace/hello/client/CollectionObjectClient.java b/HelloWorld/HelloWorldClient/src/main/java/org/collectionspace/hello/client/CollectionObjectClient.java new file mode 100644 index 000000000..8e5a7cf9f --- /dev/null +++ b/HelloWorld/HelloWorldClient/src/main/java/org/collectionspace/hello/client/CollectionObjectClient.java @@ -0,0 +1,96 @@ +package org.collectionspace.hello.client; + +import javax.ws.rs.core.Response; + +import org.collectionspace.hello.CollectionObject; +import org.collectionspace.hello.CollectionObjectList; + +import org.jboss.resteasy.client.ProxyFactory; +import org.jboss.resteasy.plugins.providers.RegisterBuiltin; +import org.jboss.resteasy.client.ClientResponse; +import org.jboss.resteasy.spi.ResteasyProviderFactory; + +/** + * A CollectionObjectClient. + + * @version $Revision:$ + */ +public class CollectionObjectClient { + + private static final String HOST = "http://localhost:8080"; + private static final String URI = "/helloworld/cspace-nuxeo"; + + /** + * + */ + private static final CollectionObjectClient instance = new CollectionObjectClient(); + /** + * + */ + private CollectionObjectProxy collectionObjectProxy; + + /** + * + * Default constructor for CollectionObjectClient class. + * + */ + private CollectionObjectClient() { + ResteasyProviderFactory factory = ResteasyProviderFactory.getInstance(); + RegisterBuiltin.register(factory); + collectionObjectProxy = ProxyFactory.create(CollectionObjectProxy.class, HOST + URI); + } + + /** + * FIXME Comment this + * + * @return + */ + public static CollectionObjectClient getInstance() { + return instance; + } + + /** + * @return + * @see org.collectionspace.hello.client.CollectionObjectProxy#getCollectionObject() + */ + public ClientResponse getCollectionObjectList() { + return collectionObjectProxy.getCollectionObjectList(); + } + + /** + * @param csid + * @return + * @see org.collectionspace.hello.client.CollectionObjectProxy#getCollectionObject(java.lang.String) + */ + public ClientResponse getCollectionObject(String csid) { + return collectionObjectProxy.getCollectionObject(csid); + } + + /** + * @param collectionobject + * @return + * @see org.collectionspace.hello.client.CollectionObjectProxy#createCollectionObject(org.collectionspace.hello.CollectionObject) + */ + public ClientResponse createCollectionObject(CollectionObject collectionObject) { + return collectionObjectProxy.createCollectionObject(collectionObject); + } + + /** + * @param csid + * @param collectionobject + * @return + * @see org.collectionspace.hello.client.CollectionObjectProxy#updateCollectionObject(java.lang.Long, org.collectionspace.hello.CollectionObject) + */ + public ClientResponse updateCollectionObject(String csid, CollectionObject collectionObject) { + return collectionObjectProxy.updateCollectionObject(csid, collectionObject); + } + + /** + * @param csid + * @return + * @see org.collectionspace.hello.client.CollectionObjectProxy#deleteCollectionObject(java.lang.Long) + */ + public ClientResponse deleteCollectionObject(String csid) { + return collectionObjectProxy.deleteCollectionObject(csid); + } +} diff --git a/HelloWorld/HelloWorldClient/src/main/java/org/collectionspace/hello/client/CollectionObjectProxy.java b/HelloWorld/HelloWorldClient/src/main/java/org/collectionspace/hello/client/CollectionObjectProxy.java new file mode 100644 index 000000000..6097fed14 --- /dev/null +++ b/HelloWorld/HelloWorldClient/src/main/java/org/collectionspace/hello/client/CollectionObjectProxy.java @@ -0,0 +1,46 @@ +package org.collectionspace.hello.client; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +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.core.Response; + +import org.collectionspace.hello.CollectionObject; +import org.collectionspace.hello.CollectionObjectList; +import org.jboss.resteasy.client.ClientResponse; + +/** + * @version $Revision:$ + */ +@Path("/collectionobjects/") +@Produces({"application/xml"}) +@Consumes({"application/xml"}) +public interface CollectionObjectProxy { + + @GET + ClientResponse getCollectionObjectList(); + + //(C)reate + @POST + ClientResponse createCollectionObject(CollectionObject co); + + //(R)ead + @GET + @Path("/{csid}") + ClientResponse getCollectionObject(@PathParam("csid") String csid); + + //(U)pdate + @PUT + @Path("/{csid}") + ClientResponse updateCollectionObject(@PathParam("csid") String csid, CollectionObject co); + + //(D)elete + @DELETE + @Path("/{csid}") + ClientResponse deleteCollectionObject(@PathParam("csid") String csid); +} \ No newline at end of file diff --git a/HelloWorld/HelloWorldClient/src/test/java/org/collectionspace/hello/client/test/CollectionObjectServiceTest.java b/HelloWorld/HelloWorldClient/src/test/java/org/collectionspace/hello/client/test/CollectionObjectServiceTest.java new file mode 100644 index 000000000..aa76d13c3 --- /dev/null +++ b/HelloWorld/HelloWorldClient/src/test/java/org/collectionspace/hello/client/test/CollectionObjectServiceTest.java @@ -0,0 +1,146 @@ +package org.collectionspace.hello.client.test; + +import java.util.ArrayList; +import java.util.List; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import org.jboss.resteasy.client.ClientResponse; +import org.testng.Assert; +import org.testng.annotations.Test; + +import org.collectionspace.hello.CollectionObject; +import org.collectionspace.hello.CollectionObjectList; +import org.collectionspace.hello.client.CollectionObjectClient; + +/** + * A CollectionObjectNuxeoServiceTest. + * + * @version $Revision:$ + */ +public class CollectionObjectServiceTest { + + private CollectionObjectClient collectionObjectClient = CollectionObjectClient.getInstance(); + private String updateId = null; + private String deleteId = null; + + @Test + public void createCollectionObject() { + long identifier = this.createIdentifier(); + + CollectionObject collectionObject = createCollectionObject(identifier); + ClientResponse res = collectionObjectClient.createCollectionObject(collectionObject); + Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode()); + + //store updateId locally for "update" test + if (updateId == null) + updateId = extractId(res); + else + deleteId = extractId(res); + } + + @Test(dependsOnMethods = {"createCollectionObject"}) + public void updateCollectionObject() { + ClientResponse res = collectionObjectClient.getCollectionObject(updateId); + CollectionObject collectionObject = res.getEntity(); + verbose("got collectionobject to update: " + updateId, + collectionObject, CollectionObject.class); + + //collectionObject.setCsid("updated-" + updateId); + collectionObject.setIdentifier("updated-" + collectionObject.getIdentifier()); + collectionObject.setDescription("updated-" + collectionObject.getDescription()); + + res = collectionObjectClient.updateCollectionObject(updateId, collectionObject); + CollectionObject updatedCollectionObject = res.getEntity(); + Assert.assertEquals(updatedCollectionObject.getDescription(), collectionObject.getDescription()); + + verbose("updated collectionObject", updatedCollectionObject, CollectionObject.class); + + return; + } + + @Test(dependsOnMethods = {"createCollectionObject"}) + public void createCollection() { + for (int i = 0; i < 3; i++) { + this.createCollectionObject(); + } + } + + @Test(dependsOnMethods = {"createCollection"}) + public void getCollectionObjectList() { + //the resource method is expected to return at least an empty list + CollectionObjectList coList = collectionObjectClient.getCollectionObjectList().getEntity(); + List coItemList = coList.getCollectionObjectListItem(); + int i = 0; + for(CollectionObjectList.CollectionObjectListItem pli : coItemList) { + verbose("getCollectionObjectList: list-item[" + i + "] csid=" + pli.getCsid()); + verbose("getCollectionObjectList: list-item[" + i + "] identifier=" + pli.getIdentifier()); + verbose("getCollectionObjectList: list-item[" + i + "] URI=" + pli.getUri()); + i++; + } + } + + @Test(dependsOnMethods = {"updateCollectionObject"}) + public void deleteCollectionObject() { + ClientResponse res = collectionObjectClient.deleteCollectionObject(deleteId); + verbose("deleteCollectionObject: csid=" + deleteId); + verbose("deleteCollectionObject: status = " + res.getStatus()); + Assert.assertEquals(res.getStatus(), Response.Status.NO_CONTENT.getStatusCode()); + } + + private CollectionObject createCollectionObject(String csid, String identifier, String description) { + CollectionObject collectionObject = new CollectionObject(); + + collectionObject.setCsid(csid); + collectionObject.setIdentifier(identifier); + collectionObject.setDescription(description); + + return collectionObject; + } + + private CollectionObject createCollectionObject(long identifier) { + CollectionObject collectionObject = createCollectionObject("csid-" + identifier, + "did-" + identifier, "description-" + identifier); + + return collectionObject; + } + + private String extractId(ClientResponse res) { + MultivaluedMap mvm = res.getMetadata(); + String uri = (String) ((ArrayList) mvm.get("Location")).get(0); + String[] segments = uri.split("/"); + String id = segments[segments.length - 1]; + verbose("id=" + id); + return id; + } + + private void verbose(String msg) { + System.out.println("CollectionObjectServiceTest : " + msg); + } + + private void verbose(String msg, Object o, Class clazz) { + try{ + verbose(msg); + JAXBContext jc = JAXBContext.newInstance(clazz); + Marshaller m = jc.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, + Boolean.TRUE); + m.marshal(o, System.out); + }catch(Exception e){ + e.printStackTrace(); + } + } + + private void verboseMap(MultivaluedMap map) { + for(Object entry : map.entrySet()){ + MultivaluedMap.Entry mentry = (MultivaluedMap.Entry) entry; + verbose(" name=" + mentry.getKey() + " value=" + mentry.getValue()); + } + } + + private long createIdentifier() { + long identifier = System.currentTimeMillis(); + return identifier; + } +} diff --git a/HelloWorld/HelloWorldNuxeoService/src/main/java/org/collectionspace/hello/services/CollectionObjectResource.java b/HelloWorld/HelloWorldNuxeoService/src/main/java/org/collectionspace/hello/services/CollectionObjectResource.java new file mode 100644 index 000000000..d861fc89c --- /dev/null +++ b/HelloWorld/HelloWorldNuxeoService/src/main/java/org/collectionspace/hello/services/CollectionObjectResource.java @@ -0,0 +1,300 @@ +package org.collectionspace.hello.services; + +import java.io.ByteArrayInputStream; +import org.collectionspace.hello.services.nuxeo.NuxeoRESTClient; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import java.util.Map; +import javax.ws.rs.DELETE; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.PathParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; +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.*; + + +import org.collectionspace.hello.CollectionObjectList.CollectionObjectListItem; +import org.dom4j.Document; +import org.dom4j.Element; +import org.dom4j.Namespace; +import org.dom4j.io.SAXReader; +import org.restlet.resource.Representation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("/collectionobjects") +@Consumes("application/xml") +@Produces("application/xml") +public class CollectionObjectResource { + + final static String NUXEO_WORKSPACE_UID = "776a8787-9d81-41b0-a02c-1ba674638c0a"; + final static String NUXEO_DOCTYPE = "CollectionObject"; + + final Logger logger = LoggerFactory.getLogger(CollectionObjectResource.class); + + public CollectionObjectResource() { + // do nothing + } + + @GET + public CollectionObjectList getCollectionObjectList(@Context UriInfo ui) { + CollectionObjectList p = new CollectionObjectList(); + try{ + List list = p.getCollectionObjectListItem(); + NuxeoRESTClient nxClient = getClient(); + + List pathParams = new ArrayList(); + Map queryParams = new HashMap(); + pathParams = Arrays.asList("default", NUXEO_WORKSPACE_UID, "browse"); + Representation res = nxClient.get(pathParams, queryParams); + SAXReader reader = new SAXReader(); + Document document = reader.read(res.getStream()); + Element root = document.getRootElement(); + for(Iterator i = root.elementIterator(); i.hasNext();){ + Element element = (Element) i.next(); + CollectionObjectListItem pli = new CollectionObjectListItem(); + // + pli.setCsid(element.attributeValue("csid")); + pli.setUri(element.attributeValue("url")); + pli.setIdentifier(element.attributeValue("identifier")); + list.add(pli); + } + + }catch(Exception e){ + e.printStackTrace(); + } + return p; + } + + @POST + public Response createCollectionObject(CollectionObject co) { + + NuxeoRESTClient nxClient = getClient(); + + List pathParams = new ArrayList(); + Map queryParams = new HashMap(); + pathParams.add("default"); + pathParams.add(NUXEO_WORKSPACE_UID); + pathParams.add("createDocument"); + queryParams.put("docType", NUXEO_DOCTYPE); + + queryParams.put("dublincore:title", co.getIdentifier()); + // CollectionObject core values + queryParams.put("collectionobject:csid", Integer.valueOf(1).toString()); + queryParams.put("collectionobject:identifier", co.getIdentifier()); + queryParams.put("collectionobject:description", co.getDescription()); + + ByteArrayInputStream bais = new ByteArrayInputStream(new byte[0]); + Representation res = nxClient.post(pathParams, queryParams, bais); + + SAXReader reader = new SAXReader(); + try { + Document document = reader.read(res.getStream()); + Element root = document.getRootElement(); + for (Iterator i = root.elementIterator(); i.hasNext();){ + Element element = (Element) i.next(); + if ("docRef".equals(element.getName())){ + String id = (String) element.getData(); + co.setCsid(id); + } + } + } catch(Exception e){ + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Create failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + + verbose("created collectionobject", co); + UriBuilder path = UriBuilder.fromResource(PersonNuxeoResource.class); + path.path("" + co.getCsid()); + Response response = Response.created(path.build()).build(); + + return response; + } + + @GET + @Path("{csid}") + public CollectionObject getCollectionObject(@PathParam("csid") String csid) { + + CollectionObject co = null; + try { + List pathParams = new ArrayList(); + Map queryParams = new HashMap(); + + pathParams.add("default"); + pathParams.add(csid); + pathParams.add("export"); + queryParams.put("format", "XML"); + + NuxeoRESTClient nxClient = getClient(); + Representation res = nxClient.get(pathParams, queryParams); + + SAXReader reader = new SAXReader(); + Document document = reader.read(res.getStream()); + Element root = document.getRootElement(); + co = new CollectionObject(); + + // TODO: recognize schema thru namespace uri +// Namespace ns = new Namespace("collectionobject", "http://collectionspace.org/collectionobject"); + + Iterator siter = root.elementIterator("schema"); + while (siter.hasNext()) { + + Element schemaElement = siter.next(); + System.err.println("CollectionObject.getCollectionObject() called."); + + //TODO: recognize schema thru namespace uri + if ("collectionobject".equals(schemaElement.attribute("name").getValue())){ + co.setCsid(csid); + Element ele = schemaElement.element("identifier"); + if(ele != null){ + co.setIdentifier((String) ele.getData()); + } + ele = schemaElement.element("description"); + if(ele != null){ + co.setDescription((String) ele.getData()); + } + } + } + + } catch(Exception e){ + e.printStackTrace(); + Response response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + "Get failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + if (co == null) { + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Get failed, the requested CollectionObject CSID:" + csid + ": was not found.").type("text/plain").build(); + throw new WebApplicationException(response); + } + verbose("get collectionobject", co); + + return co; + } + + @PUT + @Path("{csid}") + public CollectionObject updateCollectionObject( + @PathParam("csid") String csid, + CollectionObject update) { + + verbose("updating collectionobject input", update); + + List pathParams = new ArrayList(); + Map queryParams = new HashMap(); + pathParams.add("default"); + pathParams.add(update.getCsid()); + pathParams.add("updateDocumentRestlet"); + + //todo: intelligent merge needed + if(update.getIdentifier() != null){ + queryParams.put("collectionobject:identifier", update.getIdentifier()); + } + + if(update.getDescription() != null){ + queryParams.put("collectionobject:description", update.getDescription()); + } + + NuxeoRESTClient nxClient = getClient(); + Representation res = nxClient.get(pathParams, queryParams); + SAXReader reader = new SAXReader(); + String status = ""; + try { + Document document = reader.read(res.getStream()); + Element root = document.getRootElement(); + for(Iterator i = root.elementIterator(); i.hasNext();){ + Element element = (Element) i.next(); + if("docRef".equals(element.getName())){ + status = (String) element.getData(); + verbose("update collectionobject: response=" + status); + } + + } + } catch(Exception e) { + //FIXME: NOT_FOUND? + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Update failed ").type("text/plain").build(); + throw new WebApplicationException(response); + } + + return update; + } + + @DELETE + @Path("{csid}") + public void deleteCollectionObject(@PathParam("csid") String csid) { + + verbose("deleting collectionobject with csid=" + csid); + + NuxeoRESTClient nxClient = getClient(); + List pathParams = new ArrayList(); + Map queryParams = new HashMap(); + + pathParams.add("default"); + pathParams.add(csid); + pathParams.add("deleteDocumentRestlet"); + Representation res = nxClient.get(pathParams, queryParams); + SAXReader reader = new SAXReader(); + String status = ""; + + try { + Document document = reader.read(res.getStream()); + Element root = document.getRootElement(); + for(Iterator i = root.elementIterator(); i.hasNext();){ + Element element = (Element) i.next(); + if("docRef".equals(element.getName())){ + status = (String) element.getData(); + verbose("delete collectionobject: response=" + status); + } + + } + }catch(Exception e){ + //FIXME: NOT_FOUND? + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Delete failed ").type("text/plain").build(); + throw new WebApplicationException(response); + } + + } + + private void verbose(String msg, CollectionObject co) { + try { + verbose(msg); + JAXBContext jc = JAXBContext.newInstance( + CollectionObject.class); + + Marshaller m = jc.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, + Boolean.TRUE); + m.marshal(co, System.out); + } catch(Exception e){ + e.printStackTrace(); + } + + } + + private NuxeoRESTClient getClient() { + NuxeoRESTClient nxClient = new NuxeoRESTClient("http://127.0.0.1:8080/nuxeo"); + nxClient.setAuthType(NuxeoRESTClient.AUTH_TYPE_BASIC); + nxClient.setBasicAuthentication("Administrator", "Administrator"); + return nxClient; + } + + private void verbose(String msg) { + System.out.println("CollectionObjectResource: " + msg); + } +} diff --git a/HelloWorld/HelloWorldNuxeoService/src/main/java/org/collectionspace/hello/services/HelloworldNuxeoApplication.java b/HelloWorld/HelloWorldNuxeoService/src/main/java/org/collectionspace/hello/services/HelloworldNuxeoApplication.java index 9443764b9..e9e233ae1 100644 --- a/HelloWorld/HelloWorldNuxeoService/src/main/java/org/collectionspace/hello/services/HelloworldNuxeoApplication.java +++ b/HelloWorld/HelloWorldNuxeoService/src/main/java/org/collectionspace/hello/services/HelloworldNuxeoApplication.java @@ -10,6 +10,8 @@ public class HelloworldNuxeoApplication extends Application { private Set> empty = new HashSet>(); public HelloworldNuxeoApplication() { + singletons.add(new CollectionObjectResource()); + singletons.add(new IdentifierResource()); singletons.add(new PersonNuxeoResource()); } diff --git a/HelloWorld/HelloWorldNuxeoService/src/main/java/org/collectionspace/hello/services/IdentifierResource.java b/HelloWorld/HelloWorldNuxeoService/src/main/java/org/collectionspace/hello/services/IdentifierResource.java new file mode 100644 index 000000000..a91b4b56f --- /dev/null +++ b/HelloWorld/HelloWorldNuxeoService/src/main/java/org/collectionspace/hello/services/IdentifierResource.java @@ -0,0 +1,78 @@ +package org.collectionspace.hello.services; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; +import javax.ws.rs.core.UriBuilder; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import org.collectionspace.hello.Identifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("/identifiers") +@Consumes("application/xml") +@Produces("application/xml") +public class IdentifierResource { + + final Logger logger = LoggerFactory.getLogger(IdentifierResource.class); + private Map idDB = new ConcurrentHashMap(); + private AtomicLong idCounter = new AtomicLong(); + + public IdentifierResource() { + // do nothing + } + + @POST + public Response createIdentifier(Identifier id) { + if (id.getNamespace() == null) { + id.setNamespace("edu.berkeley"); + } + id.setId(idCounter.incrementAndGet()); + id.setVersion(1); + UUID uuid = UUID.nameUUIDFromBytes(id.getNamespace().getBytes()); + id.setValue(uuid.toString()); + idDB.put(id.getId(), id); + verbose("created Id", id); + UriBuilder path = UriBuilder.fromResource(IdentifierResource.class); + path.path("" + id.getId()); + Response response = Response.created(path.build()).build(); + return response; + } + + @GET + @Path("{id}") + public Identifier getIdentifier(@PathParam("id") Long id) { + Identifier i = idDB.get(id); + if (i == null) { + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "The requested ID was not found.").type("text/plain").build(); + throw new WebApplicationException(response); + } + verbose("get Id", i); + return i; + } + + private void verbose(String msg, Identifier id) { + try { + System.out.println("IdentifierResource : " + msg); + JAXBContext jc = JAXBContext.newInstance(Identifier.class); + Marshaller m = jc.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, + Boolean.TRUE); + m.marshal(id, System.out); + + } catch (Exception e) { + e.printStackTrace(); + } + } +}