<nuxeo.version.5.2>5.2-SNAPSHOT</nuxeo.version.5.2>\r
<nuxeo.version.1.5>1.5-SNAPSHOT</nuxeo.version.1.5>\r
</properties>\r
- \r
- \r
+\r
+\r
<dependencies>\r
<dependency>\r
<groupId>org.collectionspace.services</groupId>\r
<version>4.1</version>\r
<scope>test</scope>\r
</dependency>\r
- \r
+\r
<!-- javax -->\r
- \r
+\r
<!-- jboss -->\r
<dependency>\r
<groupId>jboss</groupId>\r
</dependency>\r
\r
</dependencies>\r
- \r
+\r
<build>\r
<finalName>cspace-services</finalName>\r
<plugins>\r
<goals>\r
<goal>undeploy</goal>\r
</goals>\r
+ <phase>pre-integration-test</phase>\r
<configuration>\r
<fileNames>\r
<param>${project.build.directory}/${project.build.finalName}.war</param>\r
<goals>\r
<goal>deploy</goal>\r
</goals>\r
+ <phase>pre-integration-test</phase>\r
<configuration>\r
<fileNames>\r
<param>${project.build.directory}/${project.build.finalName}.war</param>\r
</plugins>\r
</build>\r
</project>\r
+\r
package org.collectionspace.services.jaxrs;
-import org.collectionspace.services.CollectionObjectResource;
+import org.collectionspace.services.collectionobject.CollectionObjectResource;
import org.collectionspace.services.id.IDResource;
import org.collectionspace.services.IntakeResource;
<?xml version="1.0" encoding="UTF-8"?>\r
<jboss-web>\r
- <!-- All secure web resources will use this security domain -->\r
- <security-domain>java:/jaas/cspace</security-domain>\r
-</jboss-web>
\ No newline at end of file
+ <!-- All secure web resources will use this security domain -->\r
+ <security-domain>java:/jaas/cspace</security-domain>\r
+ <context-root>/cspace-services</context-root>\r
+</jboss-web>\r
CollectionObject collectionObject = createCollectionObject(identifier);
ClientResponse<Response> res = collectionObjectClient.createCollectionObject(collectionObject);
+ verbose("createCollectionObject: status = " + res.getStatus());
Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode());
//store updateId locally for "update" test
@Test(dependsOnMethods = {"createCollectionObject"})
public void updateCollectionObject() {
ClientResponse<CollectionObject> res = collectionObjectClient.getCollectionObject(updateId);
+ verbose("getCollectionObject: status = " + res.getStatus());
CollectionObject collectionObject = res.getEntity();
verbose("Got CollectionObject to update with ID: " + updateId,
collectionObject, CollectionObject.class);
// make call to update service
res = collectionObjectClient.updateCollectionObject(updateId, collectionObject);
-
+ verbose("updateCollectionObject: status = " + res.getStatus());
// check the response
CollectionObject updatedCollectionObject = res.getEntity();
Assert.assertEquals(updatedCollectionObject.getObjectName(), collectionObject.getObjectName());
@Test(dependsOnMethods = {"createCollection"})
public void getCollectionObjectList() {
//the resource method is expected to return at least an empty list
- CollectionObjectList coList = collectionObjectClient.getCollectionObjectList().getEntity();
+ ClientResponse<CollectionObjectList> res = collectionObjectClient.getCollectionObjectList();
+ CollectionObjectList coList = res.getEntity();
+ verbose("getCollectionObjectList: status = " + res.getStatus());
+
List<CollectionObjectList.CollectionObjectListItem> coItemList = coList.getCollectionObjectListItem();
int i = 0;
for(CollectionObjectList.CollectionObjectListItem pli : coItemList){
ClientResponse<Response> res = collectionObjectClient.deleteCollectionObject(deleteId);
verbose("deleteCollectionObject: csid=" + deleteId);
verbose("deleteCollectionObject: status = " + res.getStatus());
- Assert.assertEquals(res.getStatus(), Response.Status.NO_CONTENT.getStatusCode());
+ Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode());
}
private CollectionObject createCollectionObject(long identifier) {
<artifactId>org.collectionspace.services.collectionobject.jaxb</artifactId>\r
<version>1.0</version>\r
</dependency>\r
+ <dependency>\r
+ <groupId>org.slf4j</groupId>\r
+ <artifactId>slf4j-api</artifactId>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.slf4j</groupId>\r
+ <artifactId>slf4j-log4j12</artifactId>\r
+ </dependency>\r
\r
<dependency>\r
<groupId>junit</groupId>\r
<version>5.6</version>\r
</dependency>\r
\r
-\r
+ <!-- apache -->\r
+ <dependency>\r
+ <groupId>commons-beanutils</groupId>\r
+ <artifactId>commons-beanutils</artifactId>\r
+ <version>1.6.1</version>\r
+ </dependency>\r
+ <!-- use explict 1.1 version to prevent errors coming from Nuxeo client -->\r
+ <dependency>\r
+ <groupId>commons-logging</groupId>\r
+ <artifactId>commons-logging</artifactId>\r
+ <version>1.1</version>\r
+ </dependency>\r
<!-- javax -->\r
\r
\r
+++ /dev/null
-package org.collectionspace.services;
-
-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 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.services.CollectionObjectService;
-import org.collectionspace.services.collectionobject.*;
-import org.collectionspace.services.collectionobject.CollectionObjectList.*;
-import org.collectionspace.services.CollectionObjectJAXBSchema;
-
-import org.dom4j.Document;
-import org.dom4j.Element;
-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);
-
- // This should be a DI wired by a container like Spring, Seam, or EJB3
- final static CollectionObjectService service = new CollectionObjectServiceNuxeoImpl();
-
- public CollectionObjectResource() {
- // do nothing
- }
-
- @GET
- public CollectionObjectList getCollectionObjectList(@Context UriInfo ui) {
- CollectionObjectList p = new CollectionObjectList();
- try {
- Document document = service.getCollectionObjectList();
- Element root = document.getRootElement();
-
- // debug
- System.err.println(document.asXML());
-
- List<CollectionObjectList.CollectionObjectListItem> list = p
- .getCollectionObjectListItem();
- for (Iterator i = root.elementIterator(); i.hasNext();) {
- Element element = (Element) i.next();
- // debug
- System.err.println();
- element.asXML();
-
- // set the CollectionObject list item entity elements
- CollectionObjectListItem pli = new CollectionObjectListItem();
- pli.setObjectNumber(element.attributeValue("title"));
- pli.setUri(element.attributeValue("url"));
- pli.setCsid(element.attributeValue("id"));
- list.add(pli);
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return p;
- }
-
- @POST
- public Response createCollectionObject(CollectionObject co) {
-
- String csid = null;
- try {
-
- Document document = service.postCollectionObject(co);
- Element root = document.getRootElement();
- for (Iterator i = root.elementIterator(); i.hasNext();) {
- Element element = (Element) i.next();
- if ("docRef".equals(element.getName())) {
- csid = (String) element.getData();
- co.setCsid(csid);
- }
- }
- } catch (Exception e) {
- Response response = Response.status(Response.Status.NOT_FOUND)
- .entity("Create failed").type("text/plain").build();
- throw new WebApplicationException(response);
- }
-
- verbose("createCollectionObject: ", co);
- UriBuilder path = UriBuilder
- .fromResource(CollectionObjectResource.class);
- path.path("" + csid);
- Response response = Response.created(path.build()).build();
-
- return response;
- }
-
- @GET
- @Path("{csid}")
- public CollectionObject getCollectionObject(@PathParam("csid") String csid) {
-
- CollectionObject co = null;
- try {
- Document document = service.getCollectionObject(csid);
- Element root = document.getRootElement();
- co = new CollectionObject();
-
- // TODO: recognize schema thru namespace uri
- // Namespace ns = new Namespace("collectionobject",
- // "http://collectionspace.org/collectionobject");
-
- Iterator<Element> siter = root.elementIterator("schema");
- while (siter.hasNext()) {
-
- Element schemaElement = siter.next();
- System.err
- .println("CollectionObject.getCollectionObject() called.");
-
- // TODO: recognize schema thru namespace uri
- if (CollectionObjectService.CO_SCHEMA_NAME.equals(schemaElement.attribute("name")
- .getValue())) {
- Element ele = schemaElement
- .element(CollectionObjectJAXBSchema.OBJECT_NUMBER);
- if (ele != null) {
- co.setObjectNumber((String) ele.getData());
- }
- ele = schemaElement
- .element(CollectionObjectJAXBSchema.OTHER_NUMBER);
- if (ele != null) {
- co.setOtherNumber((String) ele.getData());
- }
- ele = schemaElement
- .element(CollectionObjectJAXBSchema.BRIEF_DESCRIPTION);
- if (ele != null) {
- co.setBriefDescription((String) ele.getData());
- }
- ele = schemaElement
- .element(CollectionObjectJAXBSchema.COMMENTS);
- if (ele != null) {
- co.setComments((String) ele.getData());
- }
- ele = schemaElement
- .element(CollectionObjectJAXBSchema.DIST_FEATURES);
- if (ele != null) {
- co.setDistFeatures((String) ele.getData());
- }
- ele = schemaElement
- .element(CollectionObjectJAXBSchema.OBJECT_NAME);
- if (ele != null) {
- co.setObjectName((String) ele.getData());
- }
- ele = schemaElement
- .element(CollectionObjectJAXBSchema.RESPONSIBLE_DEPT);
- if (ele != null) {
- co.setResponsibleDept((String) ele.getData());
- }
- ele = schemaElement
- .element(CollectionObjectJAXBSchema.TITLE);
- if (ele != null) {
- co.setTitle((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("getCollectionObject: ", co);
-
- return co;
- }
-
- @PUT
- @Path("{csid}")
- public CollectionObject updateCollectionObject(
- @PathParam("csid") String csid, CollectionObject theUpdate) {
-
- verbose("updateCollectionObject with input: ", theUpdate);
-
- String status = null;
- try {
-
- Document document = service.putCollectionObject(csid, theUpdate);
- 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("updateCollectionObject 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 theUpdate;
- }
-
- @DELETE
- @Path("{csid}")
- public void deleteCollectionObject(@PathParam("csid") String csid) {
-
- verbose("deleteCollectionObject with csid=" + csid);
- try {
-
- Document document = service.deleteCollectionObject(csid);
- Element root = document.getRootElement();
- for (Iterator i = root.elementIterator(); i.hasNext();) {
- Element element = (Element) i.next();
- if ("docRef".equals(element.getName())) {
- String status = (String) element.getData();
- verbose("deleteCollectionObjectt 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 void verbose(String msg) {
- System.out.println("CollectionObjectResource. " + msg);
- }
-
-}
--- /dev/null
+package org.collectionspace.services.collectionobject;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+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.services.collectionobject.CollectionObjectList.*;
+
+import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectConstants;
+import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectHandlerFactory;
+import org.collectionspace.services.common.NuxeoClientType;
+import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.repository.DocumentNotFoundException;
+import org.collectionspace.services.common.repository.DocumentHandler;
+import org.collectionspace.services.common.repository.RepositoryClient;
+import org.collectionspace.services.common.repository.RepositoryClientFactory;
+import org.jboss.resteasy.util.HttpResponseCodes;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Path("/collectionobjects")
+@Consumes("application/xml")
+@Produces("application/xml")
+public class CollectionObjectResource {
+
+ public final static String CO_SERVICE_NAME = "collectionobjects";
+ final Logger logger = LoggerFactory.getLogger(CollectionObjectResource.class);
+ //FIXME retrieve client type from configuration
+ final static NuxeoClientType CLIENT_TYPE = ServiceMain.getInstance().getNuxeoClientType();
+
+ public CollectionObjectResource() {
+ // do nothing
+ }
+
+ @POST
+ public Response createCollectionObject(
+ CollectionObject co) {
+
+ String csid = null;
+ try{
+ RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
+ RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
+ CollectionObjectHandlerFactory handlerFactory = CollectionObjectHandlerFactory.getInstance();
+ DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
+ handler.setCommonObject(co);
+ csid = client.create(CO_SERVICE_NAME, CollectionObjectConstants.CO_NUXEO_DOCTYPE, handler);
+ co.setCsid(csid);
+ if(logger.isDebugEnabled()){
+ verbose("createCollectionObject: ", co);
+ }
+ UriBuilder path = UriBuilder.fromResource(CollectionObjectResource.class);
+ path.path("" + csid);
+ Response response = Response.created(path.build()).build();
+ return response;
+ }catch(Exception e){
+ if(logger.isDebugEnabled()){
+ logger.debug("Caught exception in createCollectionObject", e);
+ }
+ Response response = Response.status(
+ Response.Status.INTERNAL_SERVER_ERROR).entity("Crate failed").type("text/plain").build();
+ throw new WebApplicationException(response);
+ }
+ }
+
+ @GET
+ @Path("{csid}")
+ public CollectionObject getCollectionObject(
+ @PathParam("csid") String csid) {
+ if(logger.isDebugEnabled()){
+ verbose("getCollectionObject with csid=" + csid);
+ }
+ if(csid == null || "".equals(csid)){
+ logger.error("getCollectionObject: missing csid!");
+ Response response = Response.status(Response.Status.BAD_REQUEST).entity(
+ "get failed on CollectionObject csid=" + csid).type(
+ "text/plain").build();
+ throw new WebApplicationException(response);
+ }
+ CollectionObject co = null;
+ try{
+ RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
+ RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
+ CollectionObjectHandlerFactory handlerFactory = CollectionObjectHandlerFactory.getInstance();
+ DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
+ client.get(csid, handler);
+ co = (CollectionObject) handler.getCommonObject();
+ }catch(DocumentNotFoundException dnfe){
+ if(logger.isDebugEnabled()){
+ logger.debug("getCollectionObject", dnfe);
+ }
+ Response response = Response.status(Response.Status.NOT_FOUND).entity(
+ "Get failed on CollectionObject csid=" + csid).type(
+ "text/plain").build();
+ throw new WebApplicationException(response);
+ }catch(Exception e){
+ if(logger.isDebugEnabled()){
+ logger.debug("getCollectionObject", e);
+ }
+ 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);
+ }
+ if(logger.isDebugEnabled()){
+ verbose("getCollectionObject: ", co);
+ }
+ return co;
+ }
+
+ @GET
+ public CollectionObjectList getCollectionObjectList(@Context UriInfo ui) {
+ CollectionObjectList coList = new CollectionObjectList();
+ try{
+ RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
+ RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
+ CollectionObjectHandlerFactory handlerFactory = CollectionObjectHandlerFactory.getInstance();
+ DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
+ client.getAll(CO_SERVICE_NAME, handler);
+ coList = (CollectionObjectList) handler.getCommonObjectList();
+ }catch(Exception e){
+ if(logger.isDebugEnabled()){
+ logger.debug("Caught exception in getCollectionObjectList", e);
+ }
+ Response response = Response.status(
+ Response.Status.INTERNAL_SERVER_ERROR).entity("index failed").type("text/plain").build();
+ throw new WebApplicationException(response);
+ }
+ return coList;
+ }
+
+ @PUT
+ @Path("{csid}")
+ public CollectionObject updateCollectionObject(
+ @PathParam("csid") String csid,
+ CollectionObject theUpdate) {
+ if(logger.isDebugEnabled()){
+ verbose("updateCollectionObject with csid=" + csid);
+ }
+ if(csid == null || "".equals(csid)){
+ logger.error("updateCollectionObject: missing csid!");
+ Response response = Response.status(Response.Status.BAD_REQUEST).entity(
+ "update failed on CollectionObject csid=" + csid).type(
+ "text/plain").build();
+ throw new WebApplicationException(response);
+ }
+ if(logger.isDebugEnabled()){
+ verbose("updateCollectionObject with input: ", theUpdate);
+ }
+ try{
+ RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
+ RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
+ CollectionObjectHandlerFactory handlerFactory = CollectionObjectHandlerFactory.getInstance();
+ DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
+ handler.setCommonObject(theUpdate);
+ client.update(csid, handler);
+ }catch(DocumentNotFoundException dnfe){
+ if(logger.isDebugEnabled()){
+ logger.debug("caugth exception in updateCollectionObject", dnfe);
+ }
+ Response response = Response.status(Response.Status.NOT_FOUND).entity(
+ "Update failed on CollectionObject csid=" + csid).type(
+ "text/plain").build();
+ throw new WebApplicationException(response);
+ }catch(Exception e){
+ Response response = Response.status(
+ Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
+ throw new WebApplicationException(response);
+ }
+ return theUpdate;
+ }
+
+ @DELETE
+ @Path("{csid}")
+ public Response deleteCollectionObject(@PathParam("csid") String csid) {
+
+ if(logger.isDebugEnabled()){
+ verbose("deleteCollectionObject with csid=" + csid);
+ }
+ if(csid == null || "".equals(csid)){
+ logger.error("deleteCollectionObject: missing csid!");
+ Response response = Response.status(Response.Status.BAD_REQUEST).entity(
+ "delete failed on CollectionObject csid=" + csid).type(
+ "text/plain").build();
+ throw new WebApplicationException(response);
+ }
+ try{
+ RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
+ RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
+ client.delete(csid);
+ return Response.status(HttpResponseCodes.SC_OK).build();
+ }catch(DocumentNotFoundException dnfe){
+ if(logger.isDebugEnabled()){
+ logger.debug("caught exception in deleteCollectionObject", dnfe);
+ }
+ Response response = Response.status(Response.Status.NOT_FOUND).entity(
+ "Delete failed on CollectionObject csid=" + csid).type(
+ "text/plain").build();
+ throw new WebApplicationException(response);
+ }catch(Exception e){
+ Response response = Response.status(
+ Response.Status.INTERNAL_SERVER_ERROR).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 void verbose(String msg) {
+ System.out.println("CollectionObjectResource. " + msg);
+ }
+}
/**\r
* \r
*/\r
-package org.collectionspace.services;\r
+package org.collectionspace.services.collectionobject;\r
\r
import java.io.IOException;\r
import org.dom4j.Document;\r
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.collectionspace.services.collectionobject.nuxeo;
+
+/**
+ * CollectionObjectConstants processes CollectionObject document
+ *
+ */
+public class CollectionObjectConstants {
+
+ public final static String CO_NUXEO_DOCTYPE = "CollectionObject";
+ public final static String CO_NUXEO_SCHEMA_NAME = "collectionobject";
+ public final static String CO_NUXEO_DC_TITLE = "CollectionSpace-CollectionObject";
+
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.collectionspace.services.collectionobject.nuxeo;
+
+import java.util.Iterator;
+import java.util.List;
+import org.collectionspace.services.CollectionObjectJAXBSchema;
+import org.collectionspace.services.collectionobject.CollectionObject;
+import org.collectionspace.services.collectionobject.CollectionObjectList;
+import org.collectionspace.services.collectionobject.CollectionObjectList.CollectionObjectListItem;
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler;
+import org.nuxeo.ecm.core.api.DocumentModel;
+import org.nuxeo.ecm.core.api.DocumentModelList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * CollectionObjectDocumentModelHandler
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class CollectionObjectDocumentModelHandler
+ extends DocumentModelHandler<CollectionObject, CollectionObjectList> {
+
+ private final Logger logger = LoggerFactory.getLogger(CollectionObjectDocumentModelHandler.class);
+ /**
+ * collectionObject is used to stash JAXB object to use when handle is called
+ * for Action.CREATE, Action.UPDATE or Action.GET
+ */
+ private CollectionObject collectionObject;
+ /**
+ * collectionObjectList is stashed when handle is called
+ * for ACTION.GET_ALL
+ */
+ private CollectionObjectList collectionObjectList;
+
+ @Override
+ public void prepare(Action action) throws Exception {
+ //no specific action needed
+ }
+
+ @Override
+ public void handle(Action action, DocumentWrapper wrapDoc) throws Exception {
+ switch(action){
+ case CREATE:
+ handleCreate(wrapDoc);
+ break;
+ case UPDATE:
+ handleUpdate(wrapDoc);
+ break;
+ case GET:
+ handleGet(wrapDoc);
+ break;
+ case GET_ALL:
+ handleGetAll(wrapDoc);
+ break;
+ }
+ }
+
+ /**
+ * handleCreate processes create operation response
+ * @param wrapDoc
+ * @throws Exception
+ */
+ public void handleCreate(DocumentWrapper wrapDoc) throws Exception {
+ CollectionObject co = getCommonObject();
+ if(co == null){
+ String msg = "Error creating document: Missing input data";
+ logger.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ //FIXME set other parts as well
+ fillCommonObject(co, wrapDoc);
+ }
+
+ /**
+ * handleUpdate processes update operation response
+ * @param wrapDoc
+ * @throws Exception
+ */
+ public void handleUpdate(DocumentWrapper wrapDoc) throws Exception {
+ CollectionObject co = getCommonObject();
+ if(co == null){
+ String msg = "Error updating document: Missing input data";
+ logger.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ //FIXME set other parts as well
+ fillCommonObject(co, wrapDoc);
+ }
+
+ /**
+ * handleGet processes get operation response
+ * @param wrapDoc
+ * @throws Exception
+ */
+ public void handleGet(DocumentWrapper wrapDoc) throws Exception {
+ CollectionObject co = extractCommonObject(wrapDoc);
+ setCommonObject(co);
+
+ //FIXME retrive other parts as well
+ }
+
+ /**
+ * handleGetAll processes index operation response
+ * @param wrapDoc
+ * @throws Exception
+ */
+ public void handleGetAll(DocumentWrapper wrapDoc) throws Exception {
+ CollectionObjectList coList = extractCommonObjectList(wrapDoc);
+ //FIXME, this is unncessarily called on each call from client
+ setCommonObjectList(coList);
+ }
+
+ /**
+ * getCommonObject get associated CollectionObject
+ * @return
+ */
+ @Override
+ public CollectionObject getCommonObject() {
+ return collectionObject;
+ }
+
+ /**
+ * setCommonObject set associated collectionobject
+ * @param collectionObject
+ */
+ @Override
+ public void setCommonObject(CollectionObject collectionObject) {
+ this.collectionObject = collectionObject;
+ }
+
+ /**
+ * getCollectionObjectList get associated CollectionObject (for index/GET_ALL)
+ * @return
+ */
+ @Override
+ public CollectionObjectList getCommonObjectList() {
+ return collectionObjectList;
+ }
+
+ @Override
+ public void setCommonObjectList(CollectionObjectList collectionObjectList) {
+ this.collectionObjectList = collectionObjectList;
+ }
+
+ @Override
+ public CollectionObject extractCommonObject(DocumentWrapper wrapDoc)
+ throws Exception {
+ DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
+ CollectionObject co = new CollectionObject();
+
+ //FIXME property get should be dynamically set using schema inspection
+ //so it does not require hard coding
+
+ // CollectionObject core values
+ co.setObjectNumber((String) docModel.getPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.OBJECT_NUMBER)));
+ co.setOtherNumber((String) docModel.getPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.OTHER_NUMBER)));
+ co.setBriefDescription((String) docModel.getPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.BRIEF_DESCRIPTION)));
+ co.setComments((String) docModel.getPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.COMMENTS)));
+ co.setDistFeatures((String) docModel.getPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.DIST_FEATURES)));
+ co.setObjectName((String) docModel.getPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.OBJECT_NAME)));
+ co.setResponsibleDept((String) docModel.getPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.RESPONSIBLE_DEPT)));
+ co.setTitle((String) docModel.getPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.TITLE)));
+
+ return co;
+ }
+
+ @Override
+ public void fillCommonObject(CollectionObject co, DocumentWrapper wrapDoc) throws Exception {
+ DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
+ //FIXME property setter should be dynamically set using schema inspection
+ //so it does not require hard coding
+
+ // a default title for the Dublin Core schema
+ docModel.setPropertyValue("dublincore:title", CollectionObjectConstants.CO_NUXEO_DC_TITLE);
+
+ // CollectionObject core values
+ if(co.getObjectNumber() != null){
+ docModel.setPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.OBJECT_NUMBER),
+ co.getObjectNumber());
+ }
+ if(co.getOtherNumber() != null){
+ docModel.setPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.OTHER_NUMBER),
+ co.getOtherNumber());
+ }
+ if(co.getBriefDescription() != null){
+ docModel.setPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.BRIEF_DESCRIPTION),
+ co.getBriefDescription());
+ }
+ if(co.getComments() != null){
+ docModel.setPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.COMMENTS),
+ co.getComments());
+ }
+ if(co.getDistFeatures() != null){
+ docModel.setPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.DIST_FEATURES),
+ co.getDistFeatures());
+ }
+ if(co.getObjectName() != null){
+ docModel.setPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.OBJECT_NAME),
+ co.getObjectName());
+ }
+ if(co.getResponsibleDept() != null){
+ docModel.setPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.RESPONSIBLE_DEPT),
+ co.getResponsibleDept());
+ }
+ if(co.getTitle() != null){
+ docModel.setPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.TITLE),
+ co.getTitle());
+ }
+ }
+
+ @Override
+ public CollectionObjectList extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception {
+ DocumentModelList docList = (DocumentModelList) wrapDoc.getWrappedObject();
+
+ CollectionObjectList coList = new CollectionObjectList();
+ List<CollectionObjectList.CollectionObjectListItem> list = coList.getCollectionObjectListItem();
+
+ //FIXME: iterating over a long list of documents is not a long term
+ //strategy...need to change to more efficient iterating in future
+ Iterator<DocumentModel> iter = docList.iterator();
+ while(iter.hasNext()){
+ DocumentModel docModel = iter.next();
+ CollectionObjectListItem coListItem = new CollectionObjectListItem();
+ coListItem.setObjectNumber((String) docModel.getPropertyValue(
+ getQProperty(CollectionObjectJAXBSchema.OBJECT_NUMBER)));
+ //need fully qualified context for URI
+ coListItem.setUri("/collectionobjects/" + docModel.getId());
+ coListItem.setCsid(docModel.getId());
+ list.add(coListItem);
+ }
+
+ return coList;
+ }
+
+ @Override
+ public void fillCommonObjectList(CollectionObjectList obj, DocumentWrapper wrapDoc) throws Exception {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * getQProperty converts the given property to qualified schema property
+ * @param prop
+ * @return
+ */
+ private String getQProperty(String prop) {
+ return CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME + ":" + prop;
+ }
+}
+
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.collectionspace.services.collectionobject.nuxeo;
+
+import org.collectionspace.services.common.NuxeoClientType;
+import org.collectionspace.services.common.repository.DocumentHandler;
+
+/**
+ * CollectionObjectHandlerFactory creates handlers for collectionobject based
+ * on type of Nuxeo client used
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class CollectionObjectHandlerFactory {
+
+ private static final CollectionObjectHandlerFactory self = new CollectionObjectHandlerFactory();
+
+ private CollectionObjectHandlerFactory() {
+ }
+
+ public static CollectionObjectHandlerFactory getInstance() {
+ return self;
+ }
+
+ public DocumentHandler getHandler(String clientType) {
+ if(NuxeoClientType.JAVA.toString().equals(clientType)){
+ return new CollectionObjectDocumentModelHandler();
+ } else if(NuxeoClientType.REST.toString().equals(clientType)) {
+ return new CollectionObjectRepresenationHandler();
+ }
+ throw new IllegalArgumentException("Not supported client=" + clientType);
+ }
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.collectionspace.services.collectionobject.nuxeo;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.collectionspace.services.CollectionObjectJAXBSchema;
+import org.collectionspace.services.collectionobject.CollectionObject;
+import org.collectionspace.services.collectionobject.CollectionObjectList;
+import org.collectionspace.services.collectionobject.CollectionObjectList.CollectionObjectListItem;
+import org.collectionspace.services.collectionobject.CollectionObjectService;
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.collectionspace.services.nuxeo.client.rest.RepresentationHandler;
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.nuxeo.ecm.core.api.DocumentModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * CollectionObjectDocumentModelHandler
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class CollectionObjectRepresenationHandler
+ extends RepresentationHandler<CollectionObject, CollectionObjectList>
+{
+
+ private final Logger logger = LoggerFactory.getLogger(CollectionObjectRepresenationHandler.class);
+ /**
+ * collectionObject is used to stash JAXB object to use when handle is called
+ * for Action.CREATE, Action.UPDATE or Action.GET
+ */
+ private CollectionObject collectionObject;
+ /**
+ * collectionObjectList is stashed when handle is called
+ * for ACTION.GET_ALL
+ */
+ private CollectionObjectList collectionObjectList;
+
+ @Override
+ public void prepare(Action action) throws Exception {
+ switch(action){
+ case CREATE:
+ case UPDATE:
+ prepare();
+ }
+ }
+
+ @Override
+ public void handle(Action action, DocumentWrapper wrapDoc)
+ throws Exception {
+ switch(action){
+ case CREATE:
+ handleCreate(wrapDoc);
+ break;
+ case UPDATE:
+ handleUpdate(wrapDoc);
+ break;
+ case GET:
+ handleGet(wrapDoc);
+ break;
+ case GET_ALL:
+ handleGetAll(wrapDoc);
+ break;
+ }
+ }
+
+ /**
+ * handleCreate processes create operation response
+ * @param wrapDoc
+ * @throws Exception
+ */
+ public void handleCreate(DocumentWrapper wrapDoc) throws Exception {
+ CollectionObject co = getCommonObject();
+ if(co == null){
+ String msg = "Error creating document: Missing input data";
+ logger.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ //FIXME set other parts as well
+ fillCommonObject(co, wrapDoc);
+ }
+
+ /**
+ * handleUpdate processes update operation response
+ * @param wrapDoc
+ * @throws Exception
+ */
+ public void handleUpdate(DocumentWrapper wrapDoc) throws Exception {
+ CollectionObject co = getCommonObject();
+ if(co == null){
+ String msg = "Error updating document: Missing input data";
+ logger.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ //FIXME set other parts as well
+ fillCommonObject(co, wrapDoc);
+ }
+
+ /**
+ * handleGet processes get operation response
+ * @param wrapDoc
+ * @throws Exception
+ */
+ public void handleGet(DocumentWrapper wrapDoc) throws Exception {
+ CollectionObject co = extractCommonObject(wrapDoc);
+ setCommonObject(co);
+ //FIXME retrive other parts as well
+ }
+
+ /**
+ * handleGetAll processes index operation response
+ * @param wrapDoc
+ * @throws Exception
+ */
+ public void handleGetAll(DocumentWrapper wrapDoc) throws Exception {
+ CollectionObjectList coList = extractCommonObjectList(wrapDoc);
+ setCommonObjectList(coList);
+ }
+
+ private void prepare() {
+ Map<String, String> queryParams = getQueryParams();
+ CollectionObject co = getCommonObject();
+ // todo: intelligent merge needed
+ if(co.getObjectNumber() != null){
+ queryParams.put(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME +
+ ":" + CollectionObjectJAXBSchema.OBJECT_NUMBER, co.getObjectNumber());
+ }
+
+ if(co.getOtherNumber() != null){
+ queryParams.put(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME +
+ ":" + CollectionObjectJAXBSchema.OTHER_NUMBER, co.getOtherNumber());
+ }
+
+ if(co.getBriefDescription() != null){
+ queryParams.put(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME +
+ ":" + CollectionObjectJAXBSchema.BRIEF_DESCRIPTION, co.getBriefDescription());
+ }
+
+ if(co.getComments() != null){
+ queryParams.put(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME +
+ ":" + CollectionObjectJAXBSchema.COMMENTS, co.getComments());
+ }
+
+ if(co.getDistFeatures() != null){
+ queryParams.put(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME +
+ ":" + CollectionObjectJAXBSchema.DIST_FEATURES, co.getDistFeatures());
+ }
+
+ if(co.getObjectName() != null){
+ queryParams.put(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME +
+ ":" + CollectionObjectJAXBSchema.OBJECT_NAME, co.getObjectName());
+ }
+
+ if(co.getResponsibleDept() != null){
+ queryParams.put(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME +
+ ":" + CollectionObjectJAXBSchema.RESPONSIBLE_DEPT, co.getResponsibleDept());
+ }
+
+ if(co.getTitle() != null){
+ queryParams.put(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME +
+ ":" + CollectionObjectJAXBSchema.TITLE, co.getTitle());
+ }
+ }
+
+ @Override
+ public CollectionObject extractCommonObject(DocumentWrapper wrapDoc)
+ throws Exception {
+ Document document = (Document) wrapDoc.getWrappedObject();
+ CollectionObject co = new CollectionObject();
+
+ //FIXME property get should be dynamically set using schema inspection
+ //so it does not require hard coding
+ Element root = document.getRootElement();
+
+ // TODO: recognize schema thru namespace uri
+ // Namespace ns = new Namespace("collectionobject",
+ // "http://collectionspace.org/collectionobject");
+
+ Iterator<Element> siter = root.elementIterator("schema");
+ while(siter.hasNext()){
+
+ Element schemaElement = siter.next();
+ if(logger.isDebugEnabled()){
+ logger.debug("getCommonObject() populating Common Object");
+ }
+ // TODO: recognize schema thru namespace uri
+ if(CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME.equals(schemaElement.attribute("name").getValue())){
+ Element ele = schemaElement.element(CollectionObjectJAXBSchema.OBJECT_NUMBER);
+ if(ele != null){
+ co.setObjectNumber((String) ele.getData());
+ }
+ ele = schemaElement.element(CollectionObjectJAXBSchema.OTHER_NUMBER);
+ if(ele != null){
+ co.setOtherNumber((String) ele.getData());
+ }
+ ele = schemaElement.element(CollectionObjectJAXBSchema.BRIEF_DESCRIPTION);
+ if(ele != null){
+ co.setBriefDescription((String) ele.getData());
+ }
+ ele = schemaElement.element(CollectionObjectJAXBSchema.COMMENTS);
+ if(ele != null){
+ co.setComments((String) ele.getData());
+ }
+ ele = schemaElement.element(CollectionObjectJAXBSchema.DIST_FEATURES);
+ if(ele != null){
+ co.setDistFeatures((String) ele.getData());
+ }
+ ele = schemaElement.element(CollectionObjectJAXBSchema.OBJECT_NAME);
+ if(ele != null){
+ co.setObjectName((String) ele.getData());
+ }
+ ele = schemaElement.element(CollectionObjectJAXBSchema.RESPONSIBLE_DEPT);
+ if(ele != null){
+ co.setResponsibleDept((String) ele.getData());
+ }
+ ele = schemaElement.element(CollectionObjectJAXBSchema.TITLE);
+ if(ele != null){
+ co.setTitle((String) ele.getData());
+ }
+ }
+ }
+ return co;
+ }
+
+ @Override
+ public void fillCommonObject(CollectionObject co, DocumentWrapper wrapDoc)
+ throws Exception {
+ //Nuxeo REST takes create/update through queryParams, nothing to do here
+ }
+
+ @Override
+ public CollectionObjectList extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception {
+ Document document = (Document) wrapDoc.getWrappedObject();
+ // debug
+ if(logger.isDebugEnabled()){
+ logger.debug(document.asXML());
+ }
+ CollectionObjectList coList = new CollectionObjectList();
+ List<CollectionObjectList.CollectionObjectListItem> list = coList.getCollectionObjectListItem();
+ Element root = document.getRootElement();
+ for(Iterator i = root.elementIterator(); i.hasNext();){
+
+ Element element = (Element) i.next();
+ if(logger.isDebugEnabled()){
+ logger.debug(element.asXML());
+ }
+ // set the CollectionObject list item entity elements
+ CollectionObjectListItem coListItem = new CollectionObjectListItem();
+ coListItem.setObjectNumber(element.attributeValue("title"));
+ String id = element.attributeValue("id");
+ coListItem.setCsid(id);
+ coListItem.setUri("/collectionobjects/" + id);
+
+ list.add(coListItem);
+ }
+ return coList;
+ }
+
+ @Override
+ public void fillCommonObjectList(CollectionObjectList obj, DocumentWrapper wrapDoc)
+ throws Exception {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CollectionObject getCommonObject() {
+ return collectionObject;
+ }
+
+ @Override
+ public void setCommonObject(CollectionObject obj) {
+ this.collectionObject = obj;
+ }
+
+ @Override
+ public CollectionObjectList getCommonObjectList() {
+ return collectionObjectList;
+ }
+
+ @Override
+ public void setCommonObjectList(CollectionObjectList obj) {
+ this.collectionObjectList = obj;
+ }
+
+ /**
+ * getQProperty converts the given property to qualified schema property
+ * @param prop
+ * @return
+ */
+ private String getQProperty(String prop) {
+ return CollectionObjectConstants.CO_NUXEO_SCHEMA_NAME + ":" + prop;
+ }
+}
+
/**\r
* \r
*/\r
-package org.collectionspace.services;\r
+package org.collectionspace.services.collectionobject.nuxeo;\r
\r
+import org.collectionspace.services.collectionobject.CollectionObjectService;\r
+import org.collectionspace.services.*;\r
import java.io.ByteArrayInputStream;\r
import java.io.IOException;\r
import java.util.ArrayList;\r
import java.util.List;\r
import java.util.Map;\r
\r
-import org.collectionspace.services.nuxeo.NuxeoRESTClient;\r
+import org.collectionspace.services.nuxeo.client.rest.NuxeoRESTClient;\r
import org.collectionspace.services.nuxeo.CollectionSpaceServiceNuxeoImpl;\r
import org.collectionspace.services.collectionobject.CollectionObject;\r
import org.collectionspace.services.CollectionObjectJAXBSchema;\r
-import org.collectionspace.services.nuxeo.NuxeoUtils;\r
+import org.collectionspace.services.nuxeo.util.NuxeoUtils;\r
\r
import org.dom4j.Document;\r
import org.dom4j.DocumentException;\r
return document;\r
}\r
\r
- /*\r
- * Prototype method for calling the Nuxeo Java API\r
- */\r
- private Document getCollectionObjectViaJavaAPI(String csid)\r
- throws DocumentException, IOException {\r
- Document result = null;\r
- RepositoryInstance repoSession = null;\r
- \r
- try {\r
- repoSession = getRepositorySession();\r
- DocumentRef documentRef = new IdRef(csid);\r
- DocumentModel documentModel = repoSession.getDocument(documentRef);\r
- result = NuxeoUtils.getDocument(repoSession, documentModel);\r
- } catch (Exception e) {\r
- if (logger.isDebugEnabled()) {\r
- e.printStackTrace();\r
- }\r
- } finally {\r
- if (repoSession != null) {\r
- releaseRepositorySession(repoSession);\r
- }\r
- }\r
- \r
- // Dump out the contents of the result to stdout\r
- System.out.println(result.asXML());\r
- \r
- return result;\r
- }\r
-\r
+ \r
public Document getCollectionObjectList() throws DocumentException,\r
IOException {\r
Document result = null;\r
<nuxeo-client-config>
<!-- ip of network interface to which Nuxeo server is listening on -->
<host>127.0.0.1</host>
- <port>62474</port>
+ <port>62474</port> <!-- java -->
+ <!--port>8080</port--> <!-- rest -->
+ <client-type>java</client-type>
<user>Administrator</user>
<password>Administrator</password>
</nuxeo-client-config>
<workspace>
<service-name>persons</service-name>
<workspace-name>People</workspace-name>
+ <!-- use hard-coded workspace id for REST client -->
+ <!--workspace-id></workspace-id-->
</workspace>
- <workspace>
+ <workspace>
<service-name>collectionobjects</service-name>
<workspace-name>CollectionObjects</workspace-name>
+ <!-- use hard-coded workspace id for REST client -->
+ <!--workspace-id></workspace-id-->
</workspace>
<workspace>
<service-name>intakes</service-name>
<workspace-name>Intakes</workspace-name>
- </workspace>
+ <!-- use hard-coded workspace id for REST client -->
+ <!--workspace-id></workspace-id-->
+ </workspace>
</nuxeo-workspace>
</ns1:service-config>
import javax.xml.bind.Unmarshaller;
import org.collectionspace.services.common.ServiceConfig.NuxeoWorkspace;
import org.collectionspace.services.common.ServiceConfig.NuxeoWorkspace.Workspace;
-import org.collectionspace.services.nuxeo.NuxeoConnector;
+import org.collectionspace.services.nuxeo.client.java.NuxeoConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private Hashtable<String, String> serviceWorkspaces = new Hashtable<String, String>();
private NuxeoConnector nuxeoConnector;
private String serverRootDir = null;
+ private NuxeoClientType nuxeoClientType = null;
private ServiceMain() {
}
private void initialize() throws Exception {
setServerRootDir();
serviceConfig = readConfig();
- nuxeoConnector = NuxeoConnector.getInstance();
- nuxeoConnector.initialize(serviceConfig.getNuxeoClientConfig());
+ if(getNuxeoClientType().equals(NuxeoClientType.JAVA)){
+ nuxeoConnector = NuxeoConnector.getInstance();
+ nuxeoConnector.initialize(serviceConfig.getNuxeoClientConfig());
+ }
}
/**
instance = null;
}catch(Exception e){
e.printStackTrace();
- //gobble it
+ //gobble it
}
}
if(logger.isDebugEnabled()){
logger.debug("readConfig() read config file " + configFile.getAbsolutePath());
}
+ nuxeoClientType = sconfig.getNuxeoClientConfig().getClientType();
+ if(logger.isDebugEnabled()) {
+ logger.debug("using Nuxeo client=" + nuxeoClientType.toString());
+ }
return sconfig;
}
synchronized public void getWorkspaceIds() throws Exception {
- Hashtable<String, String> workspaceIds = nuxeoConnector.retrieveWorkspaceIds();
+ Hashtable<String, String> workspaceIds = new Hashtable<String, String>();
+
+ if(getNuxeoClientType().equals(NuxeoClientType.JAVA)){
+ workspaceIds = nuxeoConnector.retrieveWorkspaceIds();
+ }
NuxeoWorkspace nuxeoWorkspace = serviceConfig.getNuxeoWorkspace();
List<Workspace> workspaces = nuxeoWorkspace.getWorkspace();
+ String workspaceId = null;
for(Workspace workspace : workspaces){
- String workspaceId = workspaceIds.get(workspace.getWorkspaceName().toLowerCase());
- if(workspaceId == null){
- logger.error("failed to retrieve workspace id for " + workspace.getWorkspaceName());
- //FIXME: should we throw an exception here?
- continue;
+ if(getNuxeoClientType().equals(NuxeoClientType.JAVA)){
+ workspaceId = workspaceIds.get(workspace.getWorkspaceName().toLowerCase());
+ if(workspaceId == null){
+ logger.warn("failed to retrieve workspace id for " + workspace.getWorkspaceName());
+ //FIXME: should we throw an exception here?
+ continue;
+ }
+ }else{
+ workspaceId = workspace.getWorkspaceId();
+ if(workspaceId == null || "".equals(workspaceId)){
+ logger.error("could not find workspace id for " + workspace.getWorkspaceName());
+ //FIXME: should we throw an exception here?
+ continue;
+ }
}
+
serviceWorkspaces.put(workspace.getServiceName(), workspaceId);
if(logger.isDebugEnabled()){
logger.debug("retrieved workspace id=" + workspaceId +
public String getServerRootDir() {
return serverRootDir;
}
+
+ /**
+ * @return the nuxeoClientType
+ */
+ public NuxeoClientType getNuxeoClientType() {
+ return nuxeoClientType;
+ }
}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.collectionspace.services.common.repository;
+
+/**
+ * BadRequestException
+ *
+ */
+public class BadRequestException extends Exception {
+
+ /**
+ * Creates a new instance of <code>BadRequestException</code> without detail message.
+ */
+ public BadRequestException() {
+ }
+
+
+ /**
+ * Constructs an instance of <code>BadRequestException</code> with the specified detail message.
+ * @param msg the detail message.
+ */
+ public BadRequestException(String msg) {
+ super(msg);
+ }
+
+
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause. <p>Note that the detail message associated with
+ * <code>cause</code> is <i>not</i> automatically incorporated in
+ * this exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public BadRequestException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified cause and a detail
+ * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+ * typically contains the class and detail message of <tt>cause</tt>).
+ * This constructor is useful for exceptions that are little more than
+ * wrappers for other throwables (for example, {@link
+ * java.security.PrivilegedActionException}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public BadRequestException(Throwable cause) {
+ super(cause);
+ }
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+
+package org.collectionspace.services.common.repository;
+
+/**
+ * DocumentException
+ * Nuxeo document handling exception
+ */
+public class DocumentException extends Exception {
+
+ /**
+ * collectionspace specific error code
+ */
+ private int errorCode;
+
+ /**
+ * Creates a new instance of <code>DocumentException</code> without detail message.
+ */
+ public DocumentException() {
+ }
+
+ /**
+ * Constructs an instance of <code>DocumentException</code> with the specified detail message.
+ * @param msg the detail message.
+ */
+ public DocumentException(String msg) {
+ super(msg);
+ }
+
+
+ /**
+ * DocumentException with application specific code and message
+ * @param code
+ * @param msg
+ */
+ public DocumentException(int code, String msg) {
+ super(msg);
+ this.errorCode = code;
+ }
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause. <p>Note that the detail message associated with
+ * <code>cause</code> is <i>not</i> automatically incorporated in
+ * this exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public DocumentException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified cause and a detail
+ * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+ * typically contains the class and detail message of <tt>cause</tt>).
+ * This constructor is useful for exceptions that are little more than
+ * wrappers for other throwables (for example, {@link
+ * java.security.PrivilegedActionException}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public DocumentException(Throwable cause) {
+ super(cause);
+ }
+
+
+ /**
+ * @return the collectionspace errorCode
+ */
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+ /**
+ * @param errorCode the errorCode to set
+ */
+ public void setErrorCode(int errorCode) {
+ this.errorCode = errorCode;
+ }
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+package org.collectionspace.services.common.repository;
+
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.collectionspace.services.common.repository.DocumentException;
+import java.util.Map;
+import org.dom4j.Document;
+
+/**
+ *
+ * DocumentHandler provides document processing methods. It is an interface
+ * between Nuxeo repository client and CollectionSpace service resource. It provides
+ * methods to setup request via repository client and handle its response.
+ *
+ * Typical call sequence is:
+ * Create handler and repository client
+ * Call XXX operation on the repository client and pass the handler
+ * repository client calls prepare on the handler
+ * The repository client then calls handle on the handler
+ *
+ */
+public interface DocumentHandler<T, TL> {
+
+ public enum Action {
+
+ CREATE, GET, GET_ALL, UPDATE, DELETE
+ }
+
+ /**
+ * prepare is called by the Nuxeo client to prepare required parameters to set
+ * before invoking repository operation. this is mainly useful for create and
+ * update kind of actions
+ * @param action
+ * @throws Exception
+ */
+ public void prepare(Action action) throws Exception;
+
+ /**
+ * handle is called by the Nuxeo client to hand over the document processing on create
+ * function to the CollectionSpace service
+ * @param action
+ * @param doc wrapped Nuxeo doc
+ * @throws Exception
+ */
+ public void handle(Action action, DocumentWrapper docWrap) throws Exception;
+
+ /**
+ * extractCommonObject extracts common part of a CS document from given Nuxeo document.
+ * @param docWrap nuxeo document
+ * @return common part of CS object
+ * @throws Exception
+ */
+ public T extractCommonObject(DocumentWrapper docWrap) throws Exception;
+
+ /**
+ * fillCommonObject sets common part of CS object into given Nuxeo document
+ * @param obj input object
+ * @param docWrap target Nuxeo document
+ * @throws Exception
+ */
+ public void fillCommonObject(T obj, DocumentWrapper docWrap) throws Exception;
+
+ /**
+ * extractCommonObject extracts common part of a CS document from given Nuxeo document.
+ * @param docWrap nuxeo document
+ * @return common part of CS object
+ * @throws Exception
+ */
+ public TL extractCommonObjectList(DocumentWrapper docWrap) throws Exception;
+
+ /**
+ * fillCommonObject sets common part of CS object into given Nuxeo document
+ * @param obj input object
+ * @param docWrap target Nuxeo document
+ * @throws Exception
+ */
+ public void fillCommonObjectList(TL obj, DocumentWrapper docWrap) throws Exception;
+
+ /**
+ * getCommonObject provides the common part of a CS document.
+ * @return common part of CS document
+ */
+ public T getCommonObject();
+
+ /**
+ * setCommonObject sets common part of CS document as input for operation on
+ * Nuxeo repository
+ * @param obj input object
+ */
+ public void setCommonObject(T obj);
+
+ /**
+ * getCommonObjectList provides the default list object of a CS document.
+ * @return default list of CS document
+ */
+ public TL getCommonObjectList();
+
+ /**
+ * setCommonObjectList sets default list object for CS document as input for operation on
+ * Nuxeo repository
+ * @param default list of CS document
+ */
+ public void setCommonObjectList(TL obj);
+
+ /**
+ * getDocument get org.dom4j.Document from given DocumentModel
+ * @param Nuxeo document wrapper
+ * @return
+ * @throws DocumentException
+ */
+ public Document getDocument(DocumentWrapper docWrap) throws DocumentException;
+
+ /**
+ * getProperties
+ * @return
+ */
+ public Map<String, Object> getProperties();
+
+ /**
+ * setProperties provides means to the CollectionSpace service resource to
+ * set up parameters before invoking create request via the Nuxeo client.
+ * @param properties
+ */
+ public void setProperties(Map<String, Object> properties);
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+
+package org.collectionspace.services.common.repository;
+
+/**
+ * DocumentNotFoundException
+ *
+ */
+public class DocumentNotFoundException extends DocumentException {
+
+ /**
+ * Creates a new instance of <code>DocumentNotFoundException</code> without detail message.
+ */
+ public DocumentNotFoundException() {
+ }
+
+
+ /**
+ * Constructs an instance of <code>DocumentNotFoundException</code> with the specified detail message.
+ * @param msg the detail message.
+ */
+ public DocumentNotFoundException(String msg) {
+ super(msg);
+ }
+
+
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause. <p>Note that the detail message associated with
+ * <code>cause</code> is <i>not</i> automatically incorporated in
+ * this exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public DocumentNotFoundException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified cause and a detail
+ * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+ * typically contains the class and detail message of <tt>cause</tt>).
+ * This constructor is useful for exceptions that are little more than
+ * wrappers for other throwables (for example, {@link
+ * java.security.PrivilegedActionException}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public DocumentNotFoundException(Throwable cause) {
+ super(cause);
+ }
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.collectionspace.services.common.repository;
+
+/**
+ *
+ * DocumentWrapper wraps DocumentModel (java) or Representation (REST)
+ *
+ */
+public interface DocumentWrapper {
+
+ /**
+ * getWrappedObject
+ * @return wrapped object
+ */
+ public Object getWrappedObject();
+
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.collectionspace.services.common.repository;
+
+
+/**
+ * RepositoryClient is a generic Document Repository client
+ *
+ * Typical call sequence is:
+ * Create handler and repository client
+ * Call XXX operation on the repository client and pass the handler
+ * repository client calls prepare on the handler
+ * The repository client then calls handle on the handler
+ *
+ */
+public interface RepositoryClient {
+
+ /**
+ * create document in the Document repository
+ * @param serviceName entity service for which document is created. for example
+ * this is used to find mapping
+ * to a Nuxeo workspace using service-config.xml
+ * @param docType of the document created
+ * @param handler should be used by the caller to provide and transform the document
+ * @return id in repository of the newly created document
+ * @throws BadRequestException data input is bad
+ * @throws DocumentException
+ */
+ String create(String serviceName, String docType, DocumentHandler handler) throws BadRequestException, DocumentException;
+
+ /**
+ * delete a document from the Document repository
+ * @param id of the document
+ * @throws DocumentNotFoundException if document not found
+ * @throws DocumentException
+ */
+ void delete(String id) throws DocumentNotFoundException, DocumentException;
+
+ /**
+ * get document from the Document repository
+ * @param id of the document to retrieve
+ * @param handler should be used by the caller to provide and transform the document
+ * @throws DocumentNotFoundException if document not found
+ * @throws DocumentException
+ */
+ void get(String id, DocumentHandler handler) throws DocumentNotFoundException, DocumentException;
+
+ /**
+ * getAll get all documents for an entity entity service from the Document repository
+ * @param serviceName entity service for which documents are retrieved. this is used to find mapping
+ * to a Nuxeo workspace using service-config.xml
+ * @param handler should be used by the caller to provide and transform the document
+ * @throws DocumentNotFoundException if workspace not found
+ * @throws DocumentException
+ */
+ void getAll(String serviceName, DocumentHandler handler) throws DocumentNotFoundException, DocumentException;
+
+ /**
+ * update given document in the Document repository
+ * @param id of the document
+ * @param handler should be used by the caller to provide and transform the document
+ * @throws BadRequestException data input is bad
+ * @throws DocumentNotFoundException if document not found
+ * @throws DocumentException
+ */
+ void update(String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException;
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.collectionspace.services.common.repository;
+
+import java.util.Hashtable;
+import org.collectionspace.services.common.NuxeoClientType;
+
+/**
+ * RepositoryClientFactory is a singleton factory that provides required Nuxeo client
+ * it does not create clients as the clients are singletons
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class RepositoryClientFactory {
+
+
+ private static final RepositoryClientFactory self = new RepositoryClientFactory();
+ private Hashtable<String, RepositoryClient> clients = new Hashtable<String, RepositoryClient>();
+
+ private RepositoryClientFactory() {
+ try{
+ ClassLoader cloader = Thread.currentThread().getContextClassLoader();
+
+ Class jclazz = cloader.loadClass("org.collectionspace.services.nuxeo.client.java.RepositoryJavaClient");
+ Object jclient = jclazz.newInstance();
+ clients.put(NuxeoClientType.JAVA.toString(), (RepositoryClient) jclient);
+
+ Class rclazz = cloader.loadClass("org.collectionspace.services.nuxeo.client.rest.RepositoryRESTClient");
+ Object rclient = rclazz.newInstance();
+ clients.put(NuxeoClientType.REST.toString(), (RepositoryClient) rclient);
+
+ }catch(Exception e){
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static RepositoryClientFactory getInstance() {
+ return self;
+ }
+
+ public RepositoryClient getClient(String clientType) {
+ return clients.get(clientType);
+ }
+}
*/\r
package org.collectionspace.services.nuxeo;\r
\r
-import org.nuxeo.ecm.core.api.repository.RepositoryInstance;\r
-import org.nuxeo.ecm.core.client.NuxeoClient;\r
+import org.collectionspace.services.nuxeo.client.rest.NuxeoRESTClient;\r
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
\r
return nxClient;\r
}\r
\r
- protected RepositoryInstance getRepositorySession() throws Exception {\r
- //FIXME: is it possible to reuse repository session?\r
- //Authentication failures happen while trying to reuse the session\r
- NuxeoConnector nuxeoConnector = NuxeoConnector.getInstance();\r
- return nuxeoConnector.getRepositorySession();\r
- }\r
-\r
- protected void releaseRepositorySession(RepositoryInstance repoSession) {\r
- try{\r
- //release session\r
- NuxeoConnector nuxeoConnector = NuxeoConnector.getInstance();\r
- nuxeoConnector.releaseRepositorySession(repoSession);\r
- }catch(Exception e){\r
- logger.error("Could not close the repository session", e);\r
- //no need to throw this service specific exception\r
- }\r
- }\r
}\r
+++ /dev/null
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-
-package org.collectionspace.services.nuxeo;
-
-
-import javax.security.auth.callback.Callback;
-
-/**
- * Copied from jbossx
- *
- * An implementation of Callback that simply obtains an Object to be used
- * as the authentication credential. Interpretation of the Object is up to
- * the LoginModules that validate the credential.
- *
- * @author Scott.Stark@jboss.org
- */
-public class NuxeoCallback implements Callback {
-
- private final String prompt;
-
- private Object credential;
-
- public NuxeoCallback() {
- this("");
- }
-
- public NuxeoCallback(String prompt) {
- this.prompt = prompt;
- }
-
- public String getPrompt() {
- return prompt;
- }
-
- public Object getCredential() {
- return credential;
- }
-
- public void setCredential(Object credential) {
- this.credential = credential;
- }
-
- public void clearCredential() {
- credential = null;
- }
-
-}
+++ /dev/null
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.collectionspace.services.nuxeo;
-
-/**
- *
- * @author sanjaydalal
- */
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-/**
- * Copied from jbossx.
- *
- * @author Scott.Stark@jboss.org
- */
-public class NuxeoCallbackHandler implements CallbackHandler {
-
- private final String username;
- private char[] password;
- private final Object credential;
-
- /**
- * Initializes the UsernamePasswordHandler with the username and password to
- * use.
- *
- * @param username the user name
- * @param password the password for this user
- */
- public NuxeoCallbackHandler(String username, char[] password) {
- this.username = username;
- this.password = password;
- credential = password;
- }
-
- public NuxeoCallbackHandler(String username, Object credential) {
- this.username = username;
- this.credential = credential;
- if (credential instanceof char[]) {
- password = (char[]) credential;
- } else if (credential instanceof CharSequence) {
- password = credential.toString().toCharArray();
- }
- }
-
- /**
- * Sets any NameCallback name property to the instance username, sets any
- * PasswordCallback password property to the instance, and any password.
- *
- * @exception UnsupportedCallbackException,
- * thrown if any callback of type other than NameCallback or
- * PasswordCallback are seen.
- */
- public void handle(Callback[] callbacks)
- throws UnsupportedCallbackException {
- for (Callback c : callbacks) {
- if (c instanceof NameCallback) {
- NameCallback nc = (NameCallback) c;
- nc.setName(username);
- } else if (c instanceof PasswordCallback) {
- PasswordCallback pc = (PasswordCallback) c;
- if (password == null) {
- // We were given an opaque Object credential but a char[] is
- // requested?
- if (credential != null) {
- String tmp = credential.toString();
- password = tmp.toCharArray();
- }
- }
- pc.setPassword(password);
- } else if (c instanceof NuxeoCallback) {
- NuxeoCallback oc = (NuxeoCallback) c;
- oc.setCredential(credential);
- } else {
- throw new UnsupportedCallbackException(c,
- "Unrecognized Callback");
- }
- }
- }
-}
+++ /dev/null
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.collectionspace.services.nuxeo;
-
-/**
- *
- * @author sanjaydalal
- */
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.security.auth.login.AppConfigurationEntry;
-import javax.security.auth.login.Configuration;
-import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
-
-public class NuxeoLoginConfiguration extends Configuration {
-
- private final Configuration parent;
- public static final String LOGIN_DOMAIN = "nuxeo-client-login";
-
- public NuxeoLoginConfiguration(Configuration parent) {
- this.parent = parent;
- }
-
- @Override
- public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
-
- if (LOGIN_DOMAIN.equals(name)) {
- AppConfigurationEntry[] entries = new AppConfigurationEntry[1];
-
- Map<String, Object> options = new HashMap<String, Object>();
-
- options.put("restore-login-identity", "True");
- options.put("multi-threaded", "True");
-
- entries[0] = new AppConfigurationEntry("org.jboss.security.ClientLoginModule", LoginModuleControlFlag.REQUIRED, options);
-
-
- return entries;
- } else {
- return parent.getAppConfigurationEntry(name);
- }
- }
-
- @Override
- public void refresh() {
- if (parent != null) {
- parent.refresh();
- }
- }
-}
+++ /dev/null
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-
-package org.collectionspace.services.nuxeo;
-
-/**
- *
- * @author sanjaydalal
- */
-
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.login.Configuration;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-
-public class NuxeoLoginContextFactory {
-
-
- private static boolean initDone=false;
-
- private static void initLoginConfig()
- {
- if (initDone)
- return;
-
- Configuration parentConfig = null;
- try {
- parentConfig = Configuration.getConfiguration();
- } catch (Exception e) {
- // do nothing - this can happen if default configuration provider is not correctly configured
- // for examnple FileConfig fails if no config file was defined
- }
- Configuration config = new NuxeoLoginConfiguration(parentConfig);
- Configuration.setConfiguration(config);
-
- initDone=true;
-
- }
-
-
- public static LoginContext getLoginContext(CallbackHandler handler) throws LoginException
- {
- initLoginConfig();
- return new LoginContext(NuxeoLoginConfiguration.LOGIN_DOMAIN, handler);
- }
-}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.collectionspace.services.nuxeo.client.java;
+
+import org.collectionspace.services.common.repository.DocumentHandler;
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.collectionspace.services.common.repository.DocumentException;
+import java.util.HashMap;
+import java.util.Map;
+import org.collectionspace.services.nuxeo.client.*;
+import org.collectionspace.services.nuxeo.util.NuxeoUtils;
+import org.dom4j.Document;
+import org.nuxeo.ecm.core.api.DocumentModel;
+import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
+
+/**
+ * DocumentModelHandler is a base abstract Nuxeo document handler
+ * using Nuxeo Java Remote APIs for CollectionSpace services
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public abstract class DocumentModelHandler<T, TL>
+ implements DocumentHandler<T, TL> {
+
+ private Map<String, Object> properties = new HashMap<String, Object>();
+ private RepositoryInstance repositorySession;
+
+ @Override
+ public abstract void prepare(Action action) throws Exception;
+
+ @Override
+ public abstract void handle(Action action, DocumentWrapper wrap) throws Exception;
+
+ /**
+ * getRepositorySession returns Nuxeo Repository Session
+ * @return
+ */
+ public RepositoryInstance getRepositorySession() {
+ return repositorySession;
+ }
+
+ /**
+ * setRepositorySession sets repository session
+ * @param repoSession
+ */
+ public void setRepositorySession(RepositoryInstance repoSession) {
+ this.repositorySession = repoSession;
+ }
+
+ @Override
+ public abstract T extractCommonObject(DocumentWrapper wrapDoc) throws Exception;
+
+ @Override
+ public abstract void fillCommonObject(T obj, DocumentWrapper wrapDoc) throws Exception;
+
+ @Override
+ public abstract TL extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception;
+
+ @Override
+ public abstract void fillCommonObjectList(TL obj, DocumentWrapper wrapDoc) throws Exception;
+
+ @Override
+ public abstract T getCommonObject();
+
+ @Override
+ public abstract void setCommonObject(T obj);
+
+ @Override
+ public abstract TL getCommonObjectList();
+
+ @Override
+ public abstract void setCommonObjectList(TL obj);
+
+ @Override
+ public Document getDocument(DocumentWrapper wrapDoc) throws DocumentException {
+ DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
+ return NuxeoUtils.getDocument(getRepositorySession(), docModel);
+ }
+
+ /**
+ * @return the properties
+ */
+ @Override
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+ /**
+ * @param properties the properties to set
+ */
+ @Override
+ public void setProperties(Map<String, Object> properties) {
+ this.properties = properties;
+ }
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.collectionspace.services.nuxeo.client.java;
+
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.nuxeo.ecm.core.api.DocumentModelList;
+
+/**
+* DocumentModelListWrapper wraps Nuxeo DocumentModel
+*
+* $LastChangedRevision: $
+* $LastChangedDate: $
+*/
+public class DocumentModelListWrapper implements DocumentWrapper {
+
+ private DocumentModelList docModelList;
+
+ public DocumentModelListWrapper(DocumentModelList docModelList) {
+ this.docModelList = docModelList;
+ }
+
+ @Override
+ public Object getWrappedObject() {
+ return docModelList;
+ }
+
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.collectionspace.services.nuxeo.client.java;
+
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.nuxeo.ecm.core.api.DocumentModel;
+
+/**
+* DocumentModelWrapper wraps Nuxeo DocumentModel
+*
+* $LastChangedRevision: $
+* $LastChangedDate: $
+*/
+public class DocumentModelWrapper implements DocumentWrapper {
+
+ private DocumentModel docModel;
+
+ public DocumentModelWrapper(DocumentModel docModel) {
+ this.docModel = docModel;
+ }
+
+ @Override
+ public Object getWrappedObject() {
+ return docModel;
+ }
+
+}
/**
- * Copyright 2009 University of California at Berkeley
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
-package org.collectionspace.services.nuxeo;
+package org.collectionspace.services.nuxeo.client.java;
import java.io.File;
import java.util.Collection;
initialized = true;
}catch(Exception e){
if(logger.isDebugEnabled()){
- e.printStackTrace();
+ logger.debug("Caught exception while initializing", e);
}
}
}
// return client;
// }else{
//authentication failure error comes when reusing the client
- //fore connect for now
+ //force connect for now
client.forceConnect(nuxeoClientConfig.getHost(), nuxeoClientConfig.getPort());
if(logger.isDebugEnabled()){
logger.debug("getClient(): connection successful port=" +
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+package org.collectionspace.services.nuxeo.client.java;
+
+import org.collectionspace.services.common.repository.RepositoryClient;
+import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.repository.BadRequestException;
+import org.collectionspace.services.common.repository.DocumentNotFoundException;
+import org.collectionspace.services.common.repository.DocumentHandler;
+import org.collectionspace.services.common.repository.DocumentException;
+import org.collectionspace.services.common.repository.DocumentHandler.Action;
+import org.nuxeo.common.utils.IdUtils;
+import org.nuxeo.ecm.core.api.ClientException;
+import org.nuxeo.ecm.core.api.DocumentModel;
+import org.nuxeo.ecm.core.api.DocumentModelList;
+import org.nuxeo.ecm.core.api.DocumentRef;
+import org.nuxeo.ecm.core.api.IdRef;
+import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
+import org.nuxeo.ecm.core.client.NuxeoClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * RepositoryJavaClient is used to perform CRUD operations on documents
+ * in Nuxeo repository using Remote Java APIs. It uses @see DocumentHandler
+ * as IOHandler with the client.
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class RepositoryJavaClient implements RepositoryClient {
+
+ private final Logger logger = LoggerFactory.getLogger(RepositoryJavaClient.class);
+
+ public RepositoryJavaClient() {
+ }
+
+ /**
+ * create document in the Nuxeo repository
+ * @param serviceName entity service for which document is created. this is used to find mapping
+ * to a Nuxeo workspace using service-config.xml
+ * @param docType of the document created
+ * @param handler should be used by the caller to provide and transform the document
+ * @return id in repository of the newly created document
+ * @throws DocumentException
+ */
+ @Override
+ public String create(String serviceName, String docType, DocumentHandler handler) throws BadRequestException, DocumentException {
+
+ if(serviceName == null){
+ throw new IllegalArgumentException("RemoteRepositoryClient.create: serviceName is missing");
+ }
+ if(docType == null){
+ throw new IllegalArgumentException("RemoteRepositoryClient.create: docType is missing");
+ }
+ if(handler == null){
+ throw new IllegalArgumentException("RemoteRepositoryClient.create: handler is missing");
+ }
+ ServiceMain smain = ServiceMain.getInstance();
+ String nuxeoWspaceId = smain.getWorkspaceId(serviceName);
+ if(nuxeoWspaceId == null){
+ throw new DocumentNotFoundException("Unable to find workspace for service " + serviceName +
+ " check if the mapping exists in service-config.xml or " +
+ " the the mapped workspace exists in the Nuxeo repository");
+ }
+ RepositoryInstance repoSession = null;
+ try{
+ handler.prepare(Action.CREATE);
+ repoSession = getRepositorySession();
+
+ DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId);
+ DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace);
+ String wspacePath = wspaceDoc.getPathAsString();
+ String id = IdUtils.generateId("New " + docType);
+ //create document model
+ DocumentModel doc = repoSession.createDocumentModel(wspacePath, id, docType);
+ ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+ DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
+ handler.handle(Action.CREATE, wrapDoc);
+ //create document with documentmodel
+ doc = repoSession.createDocument(doc);
+ repoSession.save();
+ return doc.getId();
+ }catch(Exception e){
+ if(logger.isDebugEnabled()){
+ logger.debug("Caught exception ", e);
+ }
+ throw new DocumentException(e);
+ }finally{
+ if(repoSession != null){
+ releaseRepositorySession(repoSession);
+ }
+ }
+
+ }
+
+ /**
+ * get document from the Nuxeo repository
+ * @param id of the document to retrieve
+ * @param handler should be used by the caller to provide and transform the document
+ * @throws DocumentException
+ */
+ @Override
+ public void get(String id, DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
+
+ if(handler == null){
+ throw new IllegalArgumentException("RemoteRepositoryClient.get: handler is missing");
+ }
+ RepositoryInstance repoSession = null;
+
+ try{
+ handler.prepare(Action.GET);
+ repoSession = getRepositorySession();
+ DocumentRef docRef = new IdRef(id);
+ DocumentModel doc = null;
+ try{
+ doc = repoSession.getDocument(docRef);
+ }catch(ClientException ce){
+ String msg = "could not find document with id=" + id;
+ logger.error(msg, ce);
+ throw new DocumentNotFoundException(msg, ce);
+ }
+ ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+ DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
+ handler.handle(Action.GET, wrapDoc);
+ }catch(IllegalArgumentException iae) {
+ throw iae;
+ }catch(DocumentException de){
+ throw de;
+ }catch(Exception e){
+ if(logger.isDebugEnabled()){
+ logger.debug("Caught exception ", e);
+ }
+ throw new DocumentException(e);
+ }finally{
+ if(repoSession != null){
+ releaseRepositorySession(repoSession);
+ }
+ }
+ }
+
+ /**
+ * getAll get all documents for an entity entity service from the Nuxeo repository
+ * @param serviceName entity service for which documents are retrieved. this is used to find mapping
+ * to a Nuxeo workspace using service-config.xml
+ * @param handler should be used by the caller to provide and transform the document
+ * @throws DocumentException
+ */
+ @Override
+ public void getAll(String serviceName, DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
+ if(serviceName == null){
+ throw new IllegalArgumentException("RemoteRepositoryClient.getAll: serviceName is missing");
+ }
+ if(handler == null){
+ throw new IllegalArgumentException("RemoteRepositoryClient.getAll: handler is missing");
+ }
+ ServiceMain smain = ServiceMain.getInstance();
+ String nuxeoWspaceId = smain.getWorkspaceId(serviceName);
+ if(nuxeoWspaceId == null){
+ throw new DocumentNotFoundException("Unable to find workspace for service " + serviceName +
+ " check if the mapping exists in service-config.xml or " +
+ " the the mapped workspace exists in the Nuxeo repository");
+ }
+ RepositoryInstance repoSession = null;
+
+ try{
+ handler.prepare(Action.GET_ALL);
+ repoSession = getRepositorySession();
+ DocumentRef wsDocRef = new IdRef(nuxeoWspaceId);
+ DocumentModelList docList = repoSession.getChildren(wsDocRef);
+
+ ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+ DocumentModelListWrapper wrapDoc = new DocumentModelListWrapper(docList);
+ handler.handle(Action.GET_ALL, wrapDoc);
+
+ }catch(DocumentException de){
+ throw de;
+ }catch(Exception e){
+ if(logger.isDebugEnabled()){
+ logger.debug("Caught exception ", e);
+ }
+ throw new DocumentException(e);
+ }finally{
+ if(repoSession != null){
+ releaseRepositorySession(repoSession);
+ }
+ }
+ }
+
+ /**
+ * update given document in the Nuxeo repository
+ * @param id of the document
+ * @param handler should be used by the caller to provide and transform the document
+ * @throws DocumentException
+ */
+ @Override
+ public void update(String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException {
+ if(id == null){
+ throw new BadRequestException("RemoteRepositoryClient.update: id is missing");
+ }
+ if(handler == null){
+ throw new IllegalArgumentException("RemoteRepositoryClient.update: handler is missing");
+ }
+ RepositoryInstance repoSession = null;
+ try{
+ handler.prepare(Action.UPDATE);
+ repoSession = getRepositorySession();
+ DocumentRef docRef = new IdRef(id);
+ DocumentModel doc = null;
+ try{
+ doc = repoSession.getDocument(docRef);
+ }catch(ClientException ce){
+ String msg = "Could not find document to update with id=" + id;
+ logger.error(msg, ce);
+ throw new DocumentNotFoundException(msg, ce);
+ }
+ ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+ DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
+ handler.handle(Action.UPDATE, wrapDoc);
+ repoSession.saveDocument(doc);
+ repoSession.save();
+ }catch(DocumentException de){
+ throw de;
+ }catch(Exception e){
+ if(logger.isDebugEnabled()){
+ logger.debug("Caught exception ", e);
+ }
+ throw new DocumentException(e);
+ }finally{
+ if(repoSession != null){
+ releaseRepositorySession(repoSession);
+ }
+ }
+ }
+
+ /**
+ * delete a document from the Nuxeo repository
+ * @param id of the document
+ * @throws DocumentException
+ */
+ @Override
+ public void delete(String id) throws DocumentNotFoundException, DocumentException {
+
+ if(logger.isDebugEnabled()){
+ logger.debug("deleting document with id=" + id);
+ }
+ RepositoryInstance repoSession = null;
+ try{
+ repoSession = getRepositorySession();
+ DocumentRef docRef = new IdRef(id);
+ try{
+ repoSession.removeDocument(docRef);
+ }catch(ClientException ce){
+ String msg = "could not find document to delete with id=" + id;
+ logger.error(msg, ce);
+ throw new DocumentNotFoundException(msg, ce);
+ }
+ repoSession.save();
+ }catch(DocumentException de){
+ throw de;
+ }catch(Exception e){
+ if(logger.isDebugEnabled()){
+ logger.debug("Caught exception ", e);
+ }
+ throw new DocumentException(e);
+ }finally{
+ if(repoSession != null){
+ releaseRepositorySession(repoSession);
+ }
+ }
+ }
+
+ private RepositoryInstance getRepositorySession() throws Exception {
+ //FIXME: is it possible to reuse repository session?
+ //Authentication failures happen while trying to reuse the session
+ NuxeoClient client = NuxeoConnector.getInstance().getClient();
+ RepositoryInstance repoSession = client.openRepository();
+ if(logger.isDebugEnabled()){
+ logger.debug("getRepository() repository root: " +
+ repoSession.getRootDocument());
+ }
+ return repoSession;
+ }
+
+ private void releaseRepositorySession(RepositoryInstance repoSession) {
+ try{
+ NuxeoClient client = NuxeoConnector.getInstance().getClient();
+ //release session
+ client.releaseRepository(repoSession);
+ }catch(Exception e){
+ logger.error("Could not close the repository session", e);
+ //no need to throw this service specific exception
+ }
+ }
+}
*
* $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $
*/
-package org.collectionspace.services.nuxeo;
+package org.collectionspace.services.nuxeo.client.rest;
import java.io.IOException;
import java.io.InputStream;
sb.append(protocol);
sb.append("://");
sb.append(serverIP);
- if (serverPort != null && !serverIP.equals("80")) {
+ if(serverPort != null && !serverIP.equals("80")){
sb.append(':');
sb.append(serverPort);
}
- sb.append(servletPath);
sb.append('/');
- baseURL = sb.toString();
+ sb.append(servletPath);
+ this.baseURL = sb.toString();
}
public void setBasicAuthentication(String userName, String password) {
String path = "";
StringBuffer pathBuffer = new StringBuffer();
- if (pathParams != null) {
- for (String p : pathParams) {
+ if(pathParams != null){
+ for(String p : pathParams){
pathBuffer.append(p);
pathBuffer.append('/');
}
Map<String, String> queryParams, InputStream istream) {
StringBuffer urlBuffer = new StringBuffer();
- if (subPath.startsWith("/")) {
+ if(subPath.startsWith("/")){
subPath = subPath.substring(1);
}
- if (subPath.endsWith("/")) {
+ if(subPath.endsWith("/")){
subPath = subPath.substring(0, subPath.length() - 1);
}
urlBuffer.append('/');
urlBuffer.append(subPath);
- if (queryParams != null) {
+ if(queryParams != null){
urlBuffer.append('?');
-
+
String qpValue = null;
- for (String qpName : queryParams.keySet()) {
+ for(String qpName : queryParams.keySet()){
urlBuffer.append(qpName);
urlBuffer.append('=');
qpValue = queryParams.get(qpName);
- if (qpValue != null) {
- urlBuffer.append(qpValue.replaceAll(" ", "%20"));
+ if(qpValue != null){
+ urlBuffer.append(qpValue.replaceAll(" ", "%20"));
}
urlBuffer.append('&');
}
public void write(OutputStream outputStream) throws IOException {
byte[] buffer = new byte[1024 * 64];
int read;
- while ((read = in.read(buffer)) != -1) {
+ while((read = in.read(buffer)) != -1){
outputStream.write(buffer, 0, read);
}
String path = "";
StringBuffer pathBuffer = new StringBuffer();
- if (pathParams != null) {
- for (String p : pathParams) {
+ if(pathParams != null){
+ for(String p : pathParams){
pathBuffer.append(p);
pathBuffer.append('/');
}
Map<String, String> queryParams) {
StringBuffer urlBuffer = new StringBuffer();
- if (subPath.startsWith("/")) {
+ if(subPath.startsWith("/")){
subPath = subPath.substring(1);
}
- if (subPath.endsWith("/")) {
+ if(subPath.endsWith("/")){
subPath = subPath.substring(0, subPath.length() - 1);
}
urlBuffer.append('/');
urlBuffer.append(subPath);
- if (queryParams != null) {
+ if(queryParams != null){
urlBuffer.append('?');
- for (String qpName : queryParams.keySet()) {
+ for(String qpName : queryParams.keySet()){
urlBuffer.append(qpName);
urlBuffer.append('=');
urlBuffer.append(queryParams.get(qpName).replaceAll(" ", "%20"));
protected void setupAuth(Request request) {
- if (authType == AUTH_TYPE_BASIC) {
+ if(authType == AUTH_TYPE_BASIC){
ChallengeScheme scheme = ChallengeScheme.HTTP_BASIC;
ChallengeResponse authentication = new ChallengeResponse(scheme,
userName, password);
request.setChallengeResponse(authentication);
- } else if (authType == AUTH_TYPE_SECRET) {
+ }else if(authType == AUTH_TYPE_SECRET){
Series<Parameter> additionnalHeaders = new Form();
Map<String, String> securityHeaders = PortalSSOAuthenticationProvider.getHeaders(
secretToken, userName);
- for (String hn : securityHeaders.keySet()) {
+ for(String hn : securityHeaders.keySet()){
additionnalHeaders.add(hn, securityHeaders.get(hn));
}
}
protected void setupCookies(Request request) {
- if (cookies != null) {
+ if(cookies != null){
request.getCookies().clear();
- for (Cookie cookie : cookies) {
+ for(Cookie cookie : cookies){
request.getCookies().add(cookie);
}
}
}
- protected Client getRestClient() {
- if (restClient == null) {
- if (baseURL.startsWith("https")) {
+ Client getRestClient() {
+ if(restClient == null){
+ if(baseURL.startsWith("https")){
restClient = new Client(Protocol.HTTPS);
- } else {
+ }else{
restClient = new Client(Protocol.HTTP);
}
}
public void setUserName(String userName) {
this.userName = userName;
}
+
+ /**
+ * buildUrl build URL from given path and query parameters
+ * @param pathParams
+ * @param queryParams
+ * @return
+ */
+ String buildUrl(List<String> pathParams,
+ Map<String, String> queryParams) {
+ String subPath = "";
+ StringBuffer pathBuffer = new StringBuffer();
+
+ if(pathParams != null){
+ for(String p : pathParams){
+ pathBuffer.append(p);
+ pathBuffer.append('/');
+ }
+ subPath = pathBuffer.toString();
+ }
+
+ StringBuffer urlBuffer = new StringBuffer();
+
+ if(subPath.startsWith("/")){
+ subPath = subPath.substring(1);
+ }
+ if(subPath.endsWith("/")){
+ subPath = subPath.substring(0, subPath.length() - 1);
+ }
+
+ urlBuffer.append(baseURL);
+ urlBuffer.append('/');
+ urlBuffer.append(restPrefix);
+ urlBuffer.append('/');
+ urlBuffer.append(subPath);
+
+ if(queryParams != null){
+ urlBuffer.append('?');
+
+ String qpValue = null;
+ for(String qpName : queryParams.keySet()){
+ urlBuffer.append(qpName);
+ urlBuffer.append('=');
+ qpValue = queryParams.get(qpName);
+ if(qpValue != null){
+ urlBuffer.append(qpValue.replaceAll(" ", "%20"));
+ }
+ urlBuffer.append('&');
+ }
+ }
+
+ return urlBuffer.toString();
+ }
}
* $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $
*/
-package org.collectionspace.services.nuxeo;
+package org.collectionspace.services.nuxeo.client.rest;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.collectionspace.services.nuxeo.client.rest;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import org.collectionspace.services.common.repository.DocumentException;
+import org.collectionspace.services.common.repository.DocumentHandler;
+import org.collectionspace.services.common.repository.RepositoryClient;
+
+import org.restlet.data.Request;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Map;
+
+import org.collectionspace.services.common.ServiceConfig;
+import org.collectionspace.services.common.ServiceConfig.NuxeoClientConfig;
+import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.repository.BadRequestException;
+import org.collectionspace.services.common.repository.DocumentNotFoundException;
+import org.collectionspace.services.common.repository.DocumentHandler.Action;
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+import org.dom4j.tree.DefaultDocument;
+import org.restlet.data.MediaType;
+import org.restlet.data.Method;
+import org.restlet.data.Response;
+import org.restlet.data.Status;
+import org.restlet.resource.OutputRepresentation;
+import org.restlet.resource.Representation;
+
+/**
+ * RepositoryRESTClient is used to perform CRUD operations on documents
+ * in Nuxeo repository using Nuxeo RESTful APIs. It uses @see DocumentHandler
+ * as IOHandler with the client.
+ *
+ * v2 NuxeoClient
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class RepositoryRESTClient implements RepositoryClient {
+
+ private final Logger logger = LoggerFactory.getLogger(RepositoryRESTClient.class);
+ private NuxeoRESTClient nuxeoRestClient;
+
+ public RepositoryRESTClient() {
+ }
+
+ @Override
+ public String create(String serviceName, String docType, DocumentHandler handler) throws BadRequestException, DocumentException {
+ if(serviceName == null){
+ throw new IllegalArgumentException("RepositoryRESTClient.create: serviceName is missing");
+ }
+ if(docType == null){
+ throw new IllegalArgumentException("RepositoryRESTClient.create: docType is missing");
+ }
+ if(handler == null){
+ throw new IllegalArgumentException("RepositoryRESTClient.create: handler is missing");
+ }
+ ServiceMain smain = ServiceMain.getInstance();
+ String nuxeoWspaceId = smain.getWorkspaceId(serviceName);
+ if(nuxeoWspaceId == null){
+ throw new DocumentNotFoundException("Unable to find workspace for service " + serviceName +
+ " check if the mapping exists in service-config.xml or " +
+ " the the mapped workspace exists in the Nuxeo repository");
+ }
+ try{
+ RepresentationHandler repHandler = (RepresentationHandler) handler;
+ repHandler.prepare(Action.CREATE);
+ List<String> pathParams = new ArrayList<String>();
+ pathParams.add("default");
+ pathParams.add(nuxeoWspaceId);
+ pathParams.add("createDocument");
+ if(repHandler.getPathParams().size() > 0){
+ pathParams.addAll(repHandler.getPathParams());
+ }
+ Map<String, String> queryParams = new HashMap<String, String>();
+ queryParams.put("docType", docType);
+ // a default title for the Dublin Core schema
+ queryParams.put("dublincore:title", "CollectionSpace-" + docType);
+ if(repHandler.getQueryParams().size() > 0){
+ queryParams.putAll(repHandler.getQueryParams());
+ }
+
+ String completeURL = getNuxeoRestClient().buildUrl(pathParams, queryParams);
+ if(logger.isDebugEnabled()){
+ logger.debug("create using url=" + completeURL);
+ }
+ Request request = buildRequest(Method.POST, completeURL);
+
+ //write out create stream, this is not needed as queryParams
+ //contain the document
+ final InputStream in = new ByteArrayInputStream(new byte[0]);
+ request.setEntity(new OutputRepresentation(
+ MediaType.MULTIPART_FORM_DATA) {
+
+ @Override
+ public void write(OutputStream outputStream) throws IOException {
+ byte[] buffer = new byte[1024 * 64];
+ int read;
+ while((read = in.read(buffer)) != -1){
+ outputStream.write(buffer, 0, read);
+ }
+ }
+ });
+ //following call to handler.handle is not needed as queryparams
+ //contains the real data
+ RepresentationWrapper wrapDoc = new RepresentationWrapper(new DefaultDocument());
+ repHandler.handle(Action.CREATE, wrapDoc);
+ //read response
+ //Nuxeo does not set 201 SUCCESS_CREATED on successful creation
+ Document document = executeRequest(request, completeURL, Status.SUCCESS_OK);
+ //handle is not needed on create as queryparams have all data
+ return extractId(document);
+
+ }catch(Exception e){
+ if(logger.isDebugEnabled()){
+ logger.debug("Caught exception ", e);
+ }
+ throw new DocumentException(e);
+ }finally{
+ }
+ }
+
+ @Override
+ public void get(String id, DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
+
+ if(handler == null){
+ throw new IllegalArgumentException("RepositoryRESTClient.get: handler is missing");
+ }
+
+ try{
+ RepresentationHandler repHandler = (RepresentationHandler) handler;
+ repHandler.prepare(Action.GET);
+ ArrayList pathParams = new ArrayList();
+ pathParams.add("default");
+ pathParams.add(id);
+ pathParams.add("export");
+ if(repHandler.getPathParams().size() > 0){
+ pathParams.addAll(repHandler.getPathParams());
+ }
+ HashMap<String, String> queryParams = new HashMap<String, String>();
+ queryParams.put("format", "XML");
+ if(repHandler.getQueryParams().size() > 0){
+ queryParams.putAll(repHandler.getQueryParams());
+ }
+ String completeURL = getNuxeoRestClient().buildUrl(pathParams, queryParams);
+ if(logger.isDebugEnabled()){
+ logger.debug("get using url=" + completeURL);
+ }
+ Request request = buildRequest(Method.GET, completeURL);
+ Document document = executeRequest(request, completeURL, Status.SUCCESS_OK);
+ RepresentationWrapper wrapDoc = new RepresentationWrapper(document);
+ repHandler.handle(Action.GET, wrapDoc);
+ }catch(Exception e){
+ if(logger.isDebugEnabled()){
+ logger.debug("Caught exception ", e);
+ }
+ throw new DocumentException(e);
+ }finally{
+ }
+ }
+
+ @Override
+ public void getAll(String serviceName, DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
+ if(serviceName == null){
+ throw new IllegalArgumentException("RepositoryRESTClient.getAll: serviceName is missing");
+ }
+ if(handler == null){
+ throw new IllegalArgumentException("RepositoryRESTClient.getAll: handler is missing");
+ }
+ ServiceMain smain = ServiceMain.getInstance();
+ String nuxeoWspaceId = smain.getWorkspaceId(serviceName);
+ if(nuxeoWspaceId == null){
+ throw new DocumentNotFoundException("Unable to find workspace for service " + serviceName +
+ " check if the mapping exists in service-config.xml or " +
+ " the the mapped workspace exists in the Nuxeo repository");
+ }
+ try{
+ RepresentationHandler repHandler = (RepresentationHandler) handler;
+ repHandler.prepare(Action.GET_ALL);
+ ArrayList pathParams = new ArrayList();
+ pathParams.add("default");
+ pathParams.add(nuxeoWspaceId);
+ pathParams.add("browse");
+ if(repHandler.getPathParams().size() > 0){
+ pathParams.addAll(repHandler.getPathParams());
+ }
+ String completeURL = getNuxeoRestClient().buildUrl(pathParams, repHandler.getQueryParams());
+ if(logger.isDebugEnabled()){
+ logger.debug("getAll using url=" + completeURL);
+ }
+ Request request = buildRequest(Method.GET, completeURL);
+ Document document = executeRequest(request, completeURL, Status.SUCCESS_OK);
+ RepresentationWrapper wrapDoc = new RepresentationWrapper(document);
+ repHandler.handle(Action.GET_ALL, wrapDoc);
+ }catch(Exception e){
+ if(logger.isDebugEnabled()){
+ logger.debug("Caught exception ", e);
+ }
+ throw new DocumentException(e);
+ }finally{
+ }
+ }
+
+ @Override
+ public void update(String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException {
+ if(handler == null){
+ throw new IllegalArgumentException("RepositoryRESTClient.update: handler is missing");
+ }
+
+ try{
+ RepresentationHandler repHandler = (RepresentationHandler) handler;
+ repHandler.prepare(Action.UPDATE);
+ List<String> pathParams = new ArrayList<String>();
+ pathParams.add("default");
+ pathParams.add(id);
+ pathParams.add("updateDocumentRestlet");
+ if(repHandler.getPathParams().size() > 0){
+ pathParams.addAll(repHandler.getPathParams());
+ }
+ String completeURL = getNuxeoRestClient().buildUrl(pathParams, repHandler.getQueryParams());
+ if(logger.isDebugEnabled()){
+ logger.debug("update using url=" + completeURL);
+ }
+ //repHandler.handle is not needed as queryParams contain all the data
+ RepresentationWrapper wrapDoc = new RepresentationWrapper(new DefaultDocument());
+ repHandler.handle(Action.UPDATE, wrapDoc);
+ Request request = buildRequest(Method.PUT, completeURL);
+ Document document = executeRequest(request, completeURL, Status.SUCCESS_OK);
+
+ }catch(Exception e){
+ if(logger.isDebugEnabled()){
+ logger.debug("Caught exception ", e);
+ }
+ throw new DocumentException(e);
+ }finally{
+ }
+ }
+
+ @Override
+ public void delete(String id) throws DocumentNotFoundException, DocumentException {
+
+ if(logger.isDebugEnabled()){
+ logger.debug("deleting document with id=" + id);
+ }
+
+ try{
+ List<String> pathParams = new ArrayList<String>();
+ pathParams.add("default");
+ pathParams.add(id);
+ pathParams.add("deleteDocumentRestlet");
+
+ Map<String, String> queryParams = new HashMap<String, String>();
+ String completeURL = getNuxeoRestClient().buildUrl(pathParams, queryParams);
+ if(logger.isDebugEnabled()){
+ logger.debug("delete using url=" + completeURL);
+ }
+ Request request = buildRequest(Method.DELETE, completeURL);
+ Document document = executeRequest(request, completeURL, Status.SUCCESS_OK);
+ //FIXME error handling?
+ // Document document = service.deleteCollectionObject(csid);
+// Element root = document.getRootElement();
+// for(Iterator i = root.elementIterator(); i.hasNext();){
+// Element element = (Element) i.next();
+// if("docRef".equals(element.getName())){
+// String status = (String) element.getData();
+// verbose("deleteCollectionObjectt response: " + status);
+// }
+// }
+
+ }catch(Exception e){
+ if(logger.isDebugEnabled()){
+ logger.debug("Caught exception ", e);
+ }
+ throw new DocumentException(e);
+ }finally{
+ }
+ }
+
+ /**
+ * buildRequest build HTTP request given parameters
+ * @param method
+ * @param completeURL
+ * @return
+ */
+ private Request buildRequest(Method method, String completeURL) {
+ Request request = new Request(method, completeURL);
+ getNuxeoRestClient().setupAuth(request);
+ getNuxeoRestClient().setupCookies(request);
+ return request;
+ }
+
+ /**
+ * executeRequest execute given HTTP request
+ * @param request
+ * @param completeURL
+ * @return
+ * @throws Exception
+ */
+ private Document executeRequest(Request request, String completeURL, Status expected) throws Exception {
+ //execute
+ Response res = getNuxeoRestClient().getRestClient().handle(request);
+ Status status = res.getStatus();
+ if(status.getCode() != expected.getCode()){
+ logger.error("failed to execute request=" + request.getMethod() +
+ " with error status=" + status +
+ " url=" + completeURL +
+ " response=" + res.toString());
+ throw new DocumentException(status.getCode(), status.getDescription());
+ }
+ Representation rep = res.getEntity();
+
+ //read response
+ return retrieveResponse(rep);
+ }
+
+ /**
+ * retrieveResponse retrieves DOM document from Restlet Represeantion
+ * @param request
+ * @return
+ * @throws Exception
+ */
+ private Document retrieveResponse(Representation rep) throws Exception {
+ SAXReader reader = new SAXReader();
+ Document document = reader.read(rep.getStream());
+ return document;
+ }
+
+ /**
+ * extractId extract document id from response
+ * @param document
+ * @return
+ */
+ private String extractId(Document document) {
+ String csid = null;
+ Element root = document.getRootElement();
+ for(Iterator i = root.elementIterator(); i.hasNext();){
+ Element element = (Element) i.next();
+ if("docRef".equals(element.getName())){
+ csid = (String) element.getData();
+ break;
+ }
+ }
+ return csid;
+ }
+
+ private NuxeoRESTClient getNuxeoRestClient() {
+ if(nuxeoRestClient == null){
+ ServiceConfig sconfig = ServiceMain.getInstance().getServiceConfig();
+ NuxeoClientConfig nxConfig = sconfig.getNuxeoClientConfig();
+ String protocol = "http";
+ if(nxConfig.getProtocol() != null && !"".equals(nxConfig.getProtocol())){
+ protocol = nxConfig.getProtocol();
+ }
+ NuxeoRESTClient tempClient = new NuxeoRESTClient(protocol,
+ nxConfig.getHost(), "" + nxConfig.getPort());
+
+ tempClient.setBasicAuthentication(nxConfig.getUser(), nxConfig.getPassword());
+
+ nuxeoRestClient = tempClient;
+
+ }
+ return nuxeoRestClient;
+ }
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.collectionspace.services.nuxeo.client.rest;
+
+import org.collectionspace.services.common.repository.DocumentHandler;
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.collectionspace.services.common.repository.DocumentException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.collectionspace.services.nuxeo.client.*;
+import org.dom4j.Document;
+
+/**
+ * RepresentationHandler is a base abstract Nuxeo document handler
+ * using Nuxeo RESTful APIs for CollectionSpace services
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public abstract class RepresentationHandler<T, TL>
+ implements DocumentHandler<T, TL> {
+
+ private Map<String, Object> properties = new HashMap<String, Object>();
+ private List<String> pathParams = new ArrayList<String>();
+ private Map<String, String> queryParams = new HashMap<String, String>();
+ private Document document;
+ private InputStream inputStream = null;
+
+ @Override
+ public abstract void prepare(Action action) throws Exception;
+
+ @Override
+ public abstract void handle(Action action, DocumentWrapper wrapDoc) throws Exception;
+
+ @Override
+ public abstract T extractCommonObject(DocumentWrapper wrapDoc) throws Exception;
+
+ @Override
+ public abstract void fillCommonObject(T obj, DocumentWrapper wrapDoc) throws Exception;
+
+ @Override
+ public abstract TL extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception;
+
+ @Override
+ public abstract void fillCommonObjectList(TL obj, DocumentWrapper wrapDoc) throws Exception;
+
+ @Override
+ public abstract T getCommonObject();
+
+ @Override
+ public abstract void setCommonObject(T obj);
+
+ @Override
+ public abstract TL getCommonObjectList();
+
+ @Override
+ public abstract void setCommonObjectList(TL obj);
+
+ @Override
+ public Document getDocument(DocumentWrapper wrapDoc) throws DocumentException {
+ throw new UnsupportedOperationException("DocumentHandler.getDocument(wrapDoc)");
+ }
+
+ /**
+ * @return the pathParams
+ */
+ public List<String> getPathParams() {
+ return pathParams;
+ }
+
+ /**
+ * @param pathParams the pathParams to set
+ */
+ public void setPathParams(List<String> pathParams) {
+ this.pathParams = pathParams;
+ }
+
+ /**
+ * @return the queryParams
+ */
+ public Map<String, String> getQueryParams() {
+ return queryParams;
+ }
+
+ /**
+ * @param queryParams the queryParams to set
+ */
+ public void setQueryParams(Map<String, String> queryParams) {
+ this.queryParams = queryParams;
+ }
+
+ /**
+ * getInputStream to retrieve input stream by client for posting a document
+ * @return the inputStream
+ */
+ public InputStream getInputStream() {
+ return inputStream;
+ }
+
+ /**
+ * setInputStream to set input stream to read for posting document
+ * @param inputStream the inputStream to set
+ */
+ public void setInputStream(InputStream inputStream) {
+ this.inputStream = inputStream;
+ }
+
+ /**
+ * @return the document
+ */
+ public Document getDocument() {
+ return document;
+ }
+
+ /**
+ * @param document the document to set
+ */
+ public void setDocument(Document document) {
+ this.document = document;
+ }
+
+ /**
+ * @return the properties
+ */
+ @Override
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+ /**
+ * @param properties the properties to set
+ */
+ @Override
+ public void setProperties(Map<String, Object> properties) {
+ this.properties = properties;
+ }
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.collectionspace.services.nuxeo.client.rest;
+
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.dom4j.Document;
+
+/**
+ * RepresentationWrapper wraps RESTful representation (Restlet)
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class RepresentationWrapper implements DocumentWrapper {
+
+ private Document document;
+
+ public RepresentationWrapper(Document doc) {
+ document = doc;
+ }
+
+ @Override
+ public Object getWrappedObject() {
+ return document;
+ }
+}
/**
- * Copyright 2009 University of California at Berkeley
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
*/
-package org.collectionspace.services.nuxeo;
+package org.collectionspace.services.nuxeo.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import javax.ws.rs.WebApplicationException;
+import org.collectionspace.services.common.repository.DocumentException;
import org.dom4j.Document;
import org.dom4j.io.SAXReader;
import org.nuxeo.ecm.core.api.DocumentModel;
/**
* Various utilities related to Nuxeo
- * @author
*/
public class NuxeoUtils {
private static Logger logger = LoggerFactory.getLogger(NuxeoUtils.class);
- public static Document getDocument(RepositoryInstance repoSession, DocumentModel helloDoc)
- throws Exception {
+ /**
+ * getDocument retrieve org.dom4j.Document from Nuxeo DocumentModel
+ * @param repoSession
+ * @param nuxeoDoc
+ * @return
+ * @throws DocumentException
+ */
+ public static Document getDocument(RepositoryInstance repoSession, DocumentModel nuxeoDoc)
+ throws DocumentException {
Document doc = null;
DocumentWriter writer = null;
DocumentReader reader = null;
try{
baos = new ByteArrayOutputStream();
//nuxeo io.impl begin
- reader = new SingleDocumentReader(repoSession, helloDoc);
+ reader = new SingleDocumentReader(repoSession, nuxeoDoc);
writer = new XMLDocumentWriter(baos);
DocumentPipe pipe = new DocumentPipeImpl();
//nuxeo io.impl end
bais = new ByteArrayInputStream(baos.toByteArray());
SAXReader saxReader = new SAXReader();
doc = saxReader.read(bais);
+ }catch(Exception e){
+ if(logger.isDebugEnabled()){
+ logger.debug("Caught exception while processing document ", e);
+ }
+ throw new DocumentException(e);
}finally{
if(reader != null){
reader.close();
baos.close();
}
}catch(IOException ioe){
- logger.error("Failed to close io streams with {}", ioe);
- throw new WebApplicationException();
+ String msg = "Failed to close io streams";
+ logger.error(msg + " {}", ioe);
+ throw new DocumentException(ioe);
}
}
return doc;
<xs:sequence>
<xs:element name="host" type="xs:string" minOccurs="1" maxOccurs="1" />
<xs:element name="port" type="xs:int" minOccurs="1" maxOccurs="1" />
+ <!-- protocol (http/https) is only applicable for rest client -->
+ <xs:element name="protocol" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <!-- default client is java -->
+ <xs:element name="client-type" type="NuxeoClientType" minOccurs="0" maxOccurs="1" />
+
<xs:element name="user" type="xs:string" minOccurs="1" maxOccurs="1" />
<!-- password should not be in cleartext -->
<xs:element name="password" type="xs:string" minOccurs="1" maxOccurs="1" />
+
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType>
<xs:sequence>
<xs:element name="service-name" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <!-- workspace name is required for Nuxeo Java client -->
<xs:element name="workspace-name" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <!-- workspace ids are required only for Nuxeo REST client -->
+ <xs:element name="workspace-id" type="xs:string" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:complexType>
</xs:element>
+ <!-- enumeration defining the type nuxeo client -->
+ <xs:simpleType name="NuxeoClientType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="java" />
+ <xs:enumeration value="rest" />
+ </xs:restriction>
+ </xs:simpleType>
+
</xs:schema>
import java.util.List;\r
import java.util.Map;\r
\r
-import org.collectionspace.services.nuxeo.NuxeoRESTClient;\r
+import org.collectionspace.services.nuxeo.client.rest.NuxeoRESTClient;\r
import org.collectionspace.services.nuxeo.CollectionSpaceServiceNuxeoImpl;\r
import org.collectionspace.services.intake.Intake;\r
import org.collectionspace.services.IntakeJAXBSchema;\r