CSPACE-81,394 schema extension supported between consumer and service using multipart messaging, between service and repository using nuxeo repository. metadata-driven using service binding. collectionobject schema extended for testing for natural history domain
CSPACE-43 use of JAXB is minimized to consumer side and restricted to just common part on the service side
CSPACE-371 nuxeo binding is externalized into tenant binding.
CSPACE-395 multi tenancy first cut. example binding for movingimages.us.
M services/authentication/client/src/test/java/org/collectionspace/services/authentication/client/AuthenticationServiceTest.java
M services/sdk/sample/src/main/java/org/collectionspace/services/sdk/sample/Sample.java
D services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/CollectionObjectService.java
M services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/CollectionObjectResource.java
M services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectRepresenationHandler.java
M services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectDocumentModelHandler.java
D services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectServiceNuxeoImpl.java
M services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/nuxeo/CollectionObjectHandlerFactory.java
M services/collectionobject/service/pom.xml
D services/collectionobject/jaxb/src/main/resources/collectionobject.xsd
A + services/collectionobject/jaxb/src/main/resources/collectionobjects-common.xsd
A services/collectionobject/jaxb/src/main/resources/collectionobjects-naturalhistory.xsd
M services/collectionobject/jaxb/pom.xml
D services/collectionobject/3rdparty/nuxeo-platform-cs-collectionobject/src/main/resources/schemas/collectionobject.xsd
A + services/collectionobject/3rdparty/nuxeo-platform-cs-collectionobject/src/main/resources/schemas/collectionobjects-common.xsd
A services/collectionobject/3rdparty/nuxeo-platform-cs-collectionobject/src/main/resources/schemas/collectionobjects-naturalhistory.xsd
M services/collectionobject/3rdparty/nuxeo-platform-cs-collectionobject/src/main/resources/OSGI-INF/core-types-contrib.xml
A services/collectionobject/3rdparty/pom.xml~
A services/collectionobject/client/received.xml~
A services/collectionobject/client/received.xml
A services/collectionobject/client/sent.xml~
M services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java
M services/collectionobject/client/src/main/java/org/collectionspace/services/client/CollectionObjectClient.java
M services/collectionobject/client/src/main/java/org/collectionspace/services/client/CollectionObjectProxy.java
A services/collectionobject/client/sent.xml
M services/collectionobject/client/pom.xml
A services/collectionobject/client/test.xml
M services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CollectionSpaceJaxRsApplication.java
M services/JaxRsServiceProvider/src/main/webapp/WEB-INF/web.xml
M services/JaxRsServiceProvider/pom.xml
A services/common/profiles.xml
A services/common/src/main/java/org/collectionspace/services/common/repository/DocumentUtils.java
A services/common/src/main/java/org/collectionspace/services/common/repository/AbstractDocumentHandler.java
M services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClientFactory.java
M services/common/src/main/java/org/collectionspace/services/common/repository/DocumentHandler.java
M services/common/src/main/java/org/collectionspace/services/common/repository/DocumentException.java
M services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClient.java
M services/common/src/main/java/org/collectionspace/services/common/CollectionSpaceResource.java
A + services/common/src/main/java/org/collectionspace/services/common/CollectionSpaceServiceContextListener.java
A + services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResource.java
A services/common/src/main/java/org/collectionspace/services/common/context
A services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java
A services/common/src/main/java/org/collectionspace/services/common/context/ServiceContextImpl.java
M services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java
A services/common/src/main/java/org/collectionspace/services/common/config
A services/common/src/main/java/org/collectionspace/services/common/config/ConfigReader.java
A services/common/src/main/java/org/collectionspace/services/common/config/AbstractConfigReader.java
A services/common/src/main/java/org/collectionspace/services/common/config/ServicesConfigReader.java
A services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReader.java
D services/common/src/main/java/org/collectionspace/services/common/ServiceContextListener.java
M services/common/src/main/java/org/collectionspace/services/common/CollectionSpaceHandlerFactory.java
A services/common/src/main/java/org/collectionspace/services/svn-commit.tmp~
M services/common/src/main/java/org/collectionspace/services/nuxeo/util/NuxeoUtils.java
M services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClient.java
M services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnector.java
M services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelHandler.java
M services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/RepresentationHandler.java
M services/common/src/main/java/org/collectionspace/services/nuxeo/client/rest/RepositoryRESTClient.java
M services/common/src/main/config/service-config.xml
A services/common/src/main/config/tenant-bindings.xml
A services/common/src/main/svn-commit.tmp~
M services/common/src/main/resources/service-config.xsd
A services/common/src/main/resources/types.xsd
A services/common/src/main/resources/tenant.xsd
A services/common/src/main/resources/service.xsd
M services/common/pom.xml
M services/common/build.xml
_M services/acquisition/service
M services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/AcquisitionResource.java
D services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/AcquisitionService.java
M services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/nuxeo/AcquisitionDocumentModelHandler.java
M services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/nuxeo/AcquisitionHandlerFactory.java
_M services/acquisition/jaxb
D services/acquisition/jaxb/src/main/resources/acquisition.xsd
A + services/acquisition/jaxb/src/main/resources/acquisitions-common.xsd
_M services/acquisition/3rdparty/nuxeo-platform-cs-acquisition
D services/acquisition/3rdparty/nuxeo-platform-cs-acquisition/src/main/resources/schemas/acquisition.xsd
A + services/acquisition/3rdparty/nuxeo-platform-cs-acquisition/src/main/resources/schemas/acquisitions-common.xsd
M services/acquisition/3rdparty/nuxeo-platform-cs-acquisition/src/main/resources/OSGI-INF/core-types-contrib.xml
_M services/acquisition/client
M services/acquisition/client/src/test/java/org/collectionspace/services/client/test/AcquisitionServiceTest.java
M services/acquisition/client/src/main/java/org/collectionspace/services/client/AcquisitionClient.java
M services/acquisition/client/src/main/java/org/collectionspace/services/client/AcquisitionProxy.java
M services/pom.xml
M services/id/service/pom.xml
M services/id/jaxb/pom.xml
_M services/query/service
_M services/IntegrationTests
A services/intake/service/profiles.xml
M services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeResource.java
D services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeService.java
D services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeServiceNuxeoImpl.java
M services/intake/service/src/main/java/org/collectionspace/services/intake/nuxeo/IntakeHandlerFactory.java
M services/intake/service/src/main/java/org/collectionspace/services/intake/nuxeo/IntakeRepresenationHandler.java
M services/intake/service/src/main/java/org/collectionspace/services/intake/nuxeo/IntakeDocumentModelHandler.java
A + services/intake/jaxb/src/main/resources/intakes-common.xsd
D services/intake/jaxb/src/main/resources/intake.xsd
M services/intake/jaxb/pom.xml
A + services/intake/3rdparty/nuxeo-platform-cs-intake/src/main/resources/schemas/intakes-common.xsd
D services/intake/3rdparty/nuxeo-platform-cs-intake/src/main/resources/schemas/intake.xsd
M services/intake/3rdparty/nuxeo-platform-cs-intake/src/main/resources/OSGI-INF/core-types-contrib.xml
M services/intake/client/src/test/java/org/collectionspace/services/client/test/IntakeServiceTest.java
M services/intake/client/src/main/java/org/collectionspace/services/client/IntakeClient.java
M services/intake/client/src/main/java/org/collectionspace/services/client/IntakeProxy.java
M services/relation/service/src/main/java/org/collectionspace/services/relation/NewRelationResource.java
M services/client/src/main/java/org/collectionspace/services/client/test/ServiceTest.java
M services/client/src/main/java/org/collectionspace/services/client/test/AbstractServiceTest.java
<artifactId>org.collectionspace.services.acquisition.service</artifactId>\r
<version>1.0</version>\r
</dependency>\r
- <dependency>\r
+ <!--dependency>\r
<groupId>org.collectionspace.services</groupId>\r
<artifactId>org.collectionspace.services.relation.service</artifactId>\r
<version>1.0</version>\r
<groupId>org.collectionspace.services</groupId>\r
<artifactId>org.collectionspace.services.query.service</artifactId>\r
<version>1.0</version>\r
- </dependency>\r
+ </dependency-->\r
<dependency>\r
<groupId>commons-io</groupId>\r
<artifactId>commons-io</artifactId>\r
<dependency>\r
<groupId>org.jboss.resteasy</groupId>\r
<artifactId>resteasy-jaxb-provider</artifactId>\r
- <version>1.0.2.GA</version>\r
+ <version>1.1.GA</version>\r
</dependency>\r
<dependency>\r
<groupId>org.jboss.resteasy</groupId>\r
<artifactId>resteasy-multipart-provider</artifactId>\r
- <version>1.0.2.GA</version>\r
+ <version>1.1.GA</version>\r
</dependency>\r
<dependency>\r
<groupId>junit</groupId>\r
import org.collectionspace.services.collectionobject.CollectionObjectResource;
import org.collectionspace.services.id.IDResource;
import org.collectionspace.services.intake.IntakeResource;
-//import org.collectionspace.services.relation.RelationResource;
-import org.collectionspace.services.relation.NewRelationResource;
+////import org.collectionspace.services.relation.RelationResource;
+//import org.collectionspace.services.relation.NewRelationResource;
import org.collectionspace.services.acquisition.AcquisitionResource;
-import org.collectionspace.services.query.QueryResource;
+//import org.collectionspace.services.query.QueryResource;
import javax.ws.rs.core.Application;
import java.util.HashSet;
singletons.add(new IntakeResource());
singletons.add(new AcquisitionResource());
// singletons.add(new RelationResource());
- singletons.add(new NewRelationResource());
- singletons.add(new QueryResource());
+ //singletons.add(new NewRelationResource());
+// singletons.add(new QueryResource());
// singletons.add(new DomainIdentifierResource());
// singletons.add(new PingResource());
}
<listener>
<listener-class>
- org.collectionspace.services.common.ServiceContextListener
+ org.collectionspace.services.common.CollectionSpaceServiceContextListener
</listener-class>
</listener>
<?xml version="1.0"?>
<component name="org.collectionspace.acquisition.coreTypes">
<extension target="org.nuxeo.ecm.core.schema.TypeService" point="schema">
- <schema name="acquisition" prefix="acquisition" src="schemas/acquisition.xsd"/>
+ <schema name="acquisitions-common" prefix="acquisitions-common" src="schemas/acquisitions-common.xsd"/>
</extension>
<extension target="org.nuxeo.ecm.core.schema.TypeService" point="doctype">
<doctype name="Acquisition" extends="Document">
<schema name="common"/>
<schema name="dublincore"/>
- <schema name="acquisition"/>
+ <schema name="acquisitions-common"/>
</doctype>
</extension>
</component>
import javax.ws.rs.core.Response;
-import org.collectionspace.services.acquisition.Acquisition;
-import org.collectionspace.services.acquisition.AcquisitionList;
-
+import org.collectionspace.services.acquisition.AcquisitionsCommonList;
import org.jboss.resteasy.client.ProxyFactory;
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
/**
* @return
* @see org.collectionspace.hello.client.IntakeProxy#getIntake()
*/
- public ClientResponse<AcquisitionList> readList() {
+ public ClientResponse<AcquisitionsCommonList> readList() {
return acquisitionProxy.readList();
}
* @return
* @see org.collectionspace.hello.client.IntakeProxy#getIntake(java.lang.String)
*/
- public ClientResponse<Acquisition> read(String csid) {
+ public ClientResponse<MultipartInput> read(String csid) {
return acquisitionProxy.read(csid);
}
* @return
* @see org.collectionspace.hello.client.IntakeProxy#createIntake(org.collectionspace.hello.Intake)
*/
- public ClientResponse<Response> create(Acquisition intake) {
- return acquisitionProxy.create(intake);
+ public ClientResponse<Response> create(MultipartOutput multipart) {
+ return acquisitionProxy.create(multipart);
}
/**
* @return
* @see org.collectionspace.hello.client.IntakeProxy#updateIntake(java.lang.Long, org.collectionspace.hello.Intake)
*/
- public ClientResponse<Acquisition> update(String csid, Acquisition intake) {
- return acquisitionProxy.update(csid, intake);
+ public ClientResponse<MultipartInput> update(String csid, MultipartOutput multipart) {
+ return acquisitionProxy.update(csid, multipart);
}
/**
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
-import org.collectionspace.services.acquisition.Acquisition;
-import org.collectionspace.services.acquisition.AcquisitionList;
+import org.collectionspace.services.acquisition.AcquisitionsCommonList;
import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
/**
* @version $Revision:$
*/
@Path("/acquisitions/")
-@Produces({"application/xml"})
-@Consumes({"application/xml"})
+@Produces({"multipart/mixed"})
+@Consumes({"multipart/mixed"})
public interface AcquisitionProxy {
@GET
- ClientResponse<AcquisitionList> readList();
+ @Produces({"application/xml"})
+ ClientResponse<AcquisitionsCommonList> readList();
//(C)reate
@POST
- ClientResponse<Response> create(Acquisition co);
+ ClientResponse<Response> create(MultipartOutput multipart);
//(R)ead
@GET
@Path("/{csid}")
- ClientResponse<Acquisition> read(@PathParam("csid") String csid);
+ ClientResponse<MultipartInput> read(@PathParam("csid") String csid);
//(U)pdate
@PUT
@Path("/{csid}")
- ClientResponse<Acquisition> update(@PathParam("csid") String csid, Acquisition co);
+ ClientResponse<MultipartInput> update(@PathParam("csid") String csid, MultipartOutput multipart);
//(D)elete
@DELETE
@Path("/{csid}")
ClientResponse<Response> delete(@PathParam("csid") String csid);
-}
\ No newline at end of file
+}
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
- package org.collectionspace.services.client.test;
+package org.collectionspace.services.client.test;
import java.util.List;
+import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
import org.collectionspace.services.client.AcquisitionClient;
-import org.collectionspace.services.client.test.ServiceRequestType;
-import org.collectionspace.services.acquisition.Acquisition;
-import org.collectionspace.services.acquisition.AcquisitionList;
+import org.collectionspace.services.acquisition.AcquisitionsCommon;
+import org.collectionspace.services.acquisition.AcquisitionsCommonList;
import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
+import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
import org.testng.Assert;
import org.testng.annotations.Test;
final String SERVICE_PATH_COMPONENT = "acquisitions";
private String knownResourceId = null;
-
// ---------------------------------------------------------------
// CRUD tests : CREATE tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
@Test
public void create() {
// Submit the request to the service and store the response.
String identifier = createIdentifier();
- Acquisition acquisition = createAcquisitionInstance(identifier);
- ClientResponse<Response> res = client.create(acquisition);
+
+ MultipartOutput multipart = createAcquisitionInstance(identifier);
+ ClientResponse<Response> res = client.create(multipart);
+
int statusCode = res.getStatus();
// Check the status code of the response: does it match
// Does it exactly match the expected status code?
verbose("create: status = " + statusCode);
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
// Store the ID returned from this create operation for
// additional tests below.
knownResourceId = extractId(res);
+ verbose("create: knownResourceId=" + knownResourceId);
}
@Override
}
// Failure outcomes
-
// Placeholders until the three tests below can be uncommented.
// See Issue CSPACE-401.
- public void createWithEmptyEntityBody() {}
- public void createWithMalformedXml() {}
- public void createWithWrongXmlSchema() {}
+ public void createWithEmptyEntityBody() {
+ }
-/*
+ public void createWithMalformedXml() {
+ }
+
+ public void createWithWrongXmlSchema() {
+ }
+
+ /*
@Override
@Test(dependsOnMethods = {"create", "testSubmitRequest"})
public void createWithMalformedXml() {
- // Perform setup.
- setupCreateWithMalformedXml();
-
- // Submit the request to the service and store the response.
- String method = REQUEST_TYPE.httpMethodName();
- String url = getServiceRootURL();
- final String entity = MALFORMED_XML_DATA; // Constant from base class.
- int statusCode = submitRequest(method, url, entity);
-
- // Check the status code of the response: does it match
- // the expected response(s)?
- verbose("createWithMalformedXml url=" + url + " status=" + statusCode);
- Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
- Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+ // Perform setup.
+ setupCreateWithMalformedXml();
+
+ // Submit the request to the service and store the response.
+ String method = REQUEST_TYPE.httpMethodName();
+ String url = getServiceRootURL();
+ final String entity = MALFORMED_XML_DATA; // Constant from base class.
+ int statusCode = submitRequest(method, url, entity);
+
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ verbose("createWithMalformedXml url=" + url + " status=" + statusCode);
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
@Override
@Test(dependsOnMethods = {"create", "testSubmitRequest"})
public void createWithWrongXmlSchema() {
- // Perform setup.
- setupCreateWithWrongXmlSchema();
-
- // Submit the request to the service and store the response.
- String method = REQUEST_TYPE.httpMethodName();
- String url = getServiceRootURL();
- final String entity = WRONG_XML_SCHEMA_DATA;
- int statusCode = submitRequest(method, url, entity);
-
- // Check the status code of the response: does it match
- // the expected response(s)?
- verbose("createWithWrongSchema url=" + url + " status=" + statusCode);
- Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
- Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+ // Perform setup.
+ setupCreateWithWrongXmlSchema();
+
+ // Submit the request to the service and store the response.
+ String method = REQUEST_TYPE.httpMethodName();
+ String url = getServiceRootURL();
+ final String entity = WRONG_XML_SCHEMA_DATA;
+ int statusCode = submitRequest(method, url, entity);
+
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ verbose("createWithWrongSchema url=" + url + " status=" + statusCode);
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
-*/
-
+ */
// ---------------------------------------------------------------
// CRUD tests : READ tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
@Test(dependsOnMethods = {"create"})
public void read() {
-
+
// Perform setup.
setupRead();
// Submit the request to the service and store the response.
- ClientResponse<Acquisition> res = client.read(knownResourceId);
+ ClientResponse<MultipartInput> res = client.read(knownResourceId);
int statusCode = res.getStatus();
-
+
// Check the status code of the response: does it match
// the expected response(s)?
verbose("read: status = " + statusCode);
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+ //FIXME: remove the following try catch once Aron fixes signatures
+ try{
+ MultipartInput input = (MultipartInput) res.getEntity();
+ AcquisitionsCommon acquistionObject = (AcquisitionsCommon) extractPart(input,
+ getCommonPartName(), AcquisitionsCommon.class);
+ Assert.assertNotNull(acquistionObject);
+ }catch(Exception e){
+ throw new RuntimeException(e);
+ }
}
// Failure outcomes
-
@Override
@Test(dependsOnMethods = {"read"})
public void readNonExistent() {
// Perform setup.
setupReadNonExistent();
-
+
// Submit the request to the service and store the response.
- ClientResponse<Acquisition> res = client.read(NON_EXISTENT_ID);
+ ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
int statusCode = res.getStatus();
// Check the status code of the response: does it match
// the expected response(s)?
verbose("readNonExistent: status = " + res.getStatus());
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
-
// ---------------------------------------------------------------
// CRUD tests : READ_LIST tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
- @Test(dependsOnMethods = {"createList"})
+ @Test(dependsOnMethods = {"createList", "read"})
public void readList() {
-
+
// Perform setup.
setupReadList();
// Submit the request to the service and store the response.
- ClientResponse<AcquisitionList> res = client.readList();
- AcquisitionList list = res.getEntity();
+ ClientResponse<AcquisitionsCommonList> res = client.readList();
+ AcquisitionsCommonList list = res.getEntity();
int statusCode = res.getStatus();
// Check the status code of the response: does it match
// the expected response(s)?
verbose("readList: status = " + res.getStatus());
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
// Optionally output additional data about list members for debugging.
boolean iterateThroughList = false;
- if (iterateThroughList && logger.isDebugEnabled()) {
- List<AcquisitionList.AcquisitionListItem> items =
- list.getAcquisitionListItem();
+ if(iterateThroughList && logger.isDebugEnabled()){
+ List<AcquisitionsCommonList.AcquisitionListItem> items =
+ list.getAcquisitionListItem();
int i = 0;
- for(AcquisitionList.AcquisitionListItem item : items){
+ for(AcquisitionsCommonList.AcquisitionListItem item : items){
verbose("readList: list-item[" + i + "] csid=" +
- item.getCsid());
+ item.getCsid());
verbose("readList: list-item[" + i + "] objectNumber=" +
- item.getAccessiondate());
+ item.getAccessiondate());
verbose("readList: list-item[" + i + "] URI=" +
- item.getUri());
+ item.getUri());
i++;
}
}
-
+
}
// Failure outcomes
-
// None at present.
-
-
// ---------------------------------------------------------------
// CRUD tests : UPDATE tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
- @Test(dependsOnMethods = {"create"})
+ @Test(dependsOnMethods = {"read"})
public void update() {
-
+
// Perform setup.
setupUpdate();
-
- // Retrieve an existing resource that we can update.
- ClientResponse<Acquisition> res = client.read(knownResourceId);
- verbose("read: status = " + res.getStatus());
- Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
- Acquisition acquisition = res.getEntity();
- verbose("Got object to update with ID: " + knownResourceId,
- acquisition, Acquisition.class);
-
- // Update the content of this resource.
- acquisition.setAccessiondate("updated-" + acquisition.getAccessiondate());
-// acquisition.setEntryDate("updated-" + acquisition.getEntryDate());
-
- // Submit the request to the service and store the response.
- res = client.update(knownResourceId, acquisition);
- int statusCode = res.getStatus();
- Acquisition updatedObject = res.getEntity();
-
- // Check the status code of the response: does it match
- // the expected response(s)?
- verbose("update: status = " + res.getStatus());
- Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
- Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
-
- // Check the contents of the response: does it match
- // what was submitted?
- verbose("update: ", updatedObject, Acquisition.class);
- Assert.assertEquals(updatedObject.getAccessiondate(),
- acquisition.getAccessiondate(),
- "Data in updated object did not match submitted data.");
+ try{ //ideally, just remove try-catch and let the exception bubble up
+ // Retrieve an existing resource that we can update.
+ ClientResponse<MultipartInput> res =
+ client.read(knownResourceId);
+ verbose("update: read status = " + res.getStatus());
+ Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
+
+ verbose("got object to update with ID: " + knownResourceId);
+ MultipartInput input = (MultipartInput) res.getEntity();
+ AcquisitionsCommon acquisition = (AcquisitionsCommon) extractPart(input,
+ getCommonPartName(), AcquisitionsCommon.class);
+ Assert.assertNotNull(acquisition);
+
+ // Update the content of this resource.
+ acquisition.setAccessiondate("updated-" + acquisition.getAccessiondate());
+ verbose("updated object", acquisition, AcquisitionsCommon.class);
+ // Submit the request to the service and store the response.
+ MultipartOutput output = new MultipartOutput();
+ OutputPart commonPart = output.addPart(acquisition, MediaType.APPLICATION_XML_TYPE);
+ commonPart.getHeaders().add("label", getCommonPartName());
+
+ res = client.update(knownResourceId, output);
+ int statusCode = res.getStatus();
+ // Check the status code of the response: does it match the expected response(s)?
+ verbose("update: status = " + res.getStatus());
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+
+
+ input = (MultipartInput) res.getEntity();
+ AcquisitionsCommon updatedAcquisition =
+ (AcquisitionsCommon) extractPart(input,
+ getCommonPartName(), AcquisitionsCommon.class);
+ Assert.assertNotNull(updatedAcquisition);
+
+ Assert.assertEquals(updatedAcquisition.getAccessiondate(),
+ acquisition.getAccessiondate(),
+ "Data in updated object did not match submitted data.");
+ }catch(Exception e){
+ e.printStackTrace();
+ }
}
// Failure outcomes
-
// Placeholders until the three tests below can be uncommented.
// See Issue CSPACE-401.
- public void updateWithEmptyEntityBody() {}
- public void updateWithMalformedXml() {}
- public void updateWithWrongXmlSchema() {}
+ public void updateWithEmptyEntityBody() {
+ }
-/*
+ public void updateWithMalformedXml() {
+ }
+
+ public void updateWithWrongXmlSchema() {
+ }
+
+ /*
@Override
@Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
public void updateWithEmptyEntityBody() {
- // Perform setup.
- setupUpdateWithEmptyEntityBody();
-
- // Submit the request to the service and store the response.
- String method = REQUEST_TYPE.httpMethodName();
- String url = getResourceURL(knownResourceId);
- String mediaType = MediaType.APPLICATION_XML;
- final String entity = "";
- int statusCode = submitRequest(method, url, mediaType, entity);
-
- // Check the status code of the response: does it match
- // the expected response(s)?
- verbose("updateWithEmptyEntityBody url=" + url + " status=" + statusCode);
- Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
- Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+ // Perform setup.
+ setupUpdateWithEmptyEntityBody();
+
+ // Submit the request to the service and store the response.
+ String method = REQUEST_TYPE.httpMethodName();
+ String url = getResourceURL(knownResourceId);
+ String mediaType = MediaType.APPLICATION_XML;
+ final String entity = "";
+ int statusCode = submitRequest(method, url, mediaType, entity);
+
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ verbose("updateWithEmptyEntityBody url=" + url + " status=" + statusCode);
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
@Override
@Test(dependsOnMethods = {"create", "testSubmitRequest"})
public void createWithEmptyEntityBody() {
- // Perform setup.
- setupCreateWithEmptyEntityBody();
-
- // Submit the request to the service and store the response.
- String method = REQUEST_TYPE.httpMethodName();
- String url = getServiceRootURL();
- String mediaType = MediaType.APPLICATION_XML;
- final String entity = "";
- int statusCode = submitRequest(method, url, mediaType, entity);
-
- // Check the status code of the response: does it match
- // the expected response(s)?
- verbose("createWithEmptyEntityBody url=" + url + " status=" + statusCode);
- Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
- Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+ // Perform setup.
+ setupCreateWithEmptyEntityBody();
+
+ // Submit the request to the service and store the response.
+ String method = REQUEST_TYPE.httpMethodName();
+ String url = getServiceRootURL();
+ String mediaType = MediaType.APPLICATION_XML;
+ final String entity = "";
+ int statusCode = submitRequest(method, url, mediaType, entity);
+
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ verbose("createWithEmptyEntityBody url=" + url + " status=" + statusCode);
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
@Override
@Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
public void updateWithMalformedXml() {
- // Perform setup.
- setupUpdateWithMalformedXml();
-
- // Submit the request to the service and store the response.
- String method = REQUEST_TYPE.httpMethodName();
- String url = getResourceURL(knownResourceId);
- final String entity = MALFORMED_XML_DATA;
- int statusCode = submitRequest(method, url, entity);
-
- // Check the status code of the response: does it match
- // the expected response(s)?
- verbose("updateWithMalformedXml: url=" + url + " status=" + statusCode);
- Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
- Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+ // Perform setup.
+ setupUpdateWithMalformedXml();
+
+ // Submit the request to the service and store the response.
+ String method = REQUEST_TYPE.httpMethodName();
+ String url = getResourceURL(knownResourceId);
+ final String entity = MALFORMED_XML_DATA;
+ int statusCode = submitRequest(method, url, entity);
+
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ verbose("updateWithMalformedXml: url=" + url + " status=" + statusCode);
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
@Override
@Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
public void updateWithWrongXmlSchema() {
- // Perform setup.
- setupUpdateWithWrongXmlSchema();
-
- // Submit the request to the service and store the response.
- String method = REQUEST_TYPE.httpMethodName();
- String url = getResourceURL(knownResourceId);
- final String entity = WRONG_XML_SCHEMA_DATA;
- int statusCode = submitRequest(method, url, entity);
-
- // Check the status code of the response: does it match
- // the expected response(s)?
- verbose("updateWithWrongSchema: url=" + url + " status=" + statusCode);
- Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
- Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+ // Perform setup.
+ setupUpdateWithWrongXmlSchema();
+
+ // Submit the request to the service and store the response.
+ String method = REQUEST_TYPE.httpMethodName();
+ String url = getResourceURL(knownResourceId);
+ final String entity = WRONG_XML_SCHEMA_DATA;
+ int statusCode = submitRequest(method, url, entity);
+
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ verbose("updateWithWrongSchema: url=" + url + " status=" + statusCode);
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
-*/
-
+ */
@Override
@Test(dependsOnMethods = {"update", "testSubmitRequest"})
public void updateNonExistent() {
// Submit the request to the service and store the response.
// Note: The ID used in this 'create' call may be arbitrary.
// The only relevant ID may be the one used in update(), below.
- Acquisition acquisition = createAcquisitionInstance(NON_EXISTENT_ID);
- ClientResponse<Acquisition> res =
- client.update(NON_EXISTENT_ID, acquisition);
+ MultipartOutput multipart = createAcquisitionInstance(NON_EXISTENT_ID);
+ ClientResponse<MultipartInput> res =
+ client.update(NON_EXISTENT_ID, multipart);
int statusCode = res.getStatus();
// Check the status code of the response: does it match
// the expected response(s)?
verbose("updateNonExistent: status = " + res.getStatus());
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
// ---------------------------------------------------------------
// CRUD tests : DELETE tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
- @Test(dependsOnMethods =
- {"create", "read", "update"})
+ @Test(dependsOnMethods = {"create", "read", "update"})
public void delete() {
// Perform setup.
// the expected response(s)?
verbose("delete: status = " + res.getStatus());
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
// Failure outcomes
-
@Override
@Test(dependsOnMethods = {"delete"})
public void deleteNonExistent() {
// the expected response(s)?
verbose("deleteNonExistent: status = " + res.getStatus());
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
-
// ---------------------------------------------------------------
// Utility tests : tests of code used in tests above
// ---------------------------------------------------------------
-
/**
* Tests the code for manually submitting data that is used by several
* of the methods above.
String method = ServiceRequestType.READ.httpMethodName();
String url = getResourceURL(knownResourceId);
int statusCode = submitRequest(method, url);
-
+
// Check the status code of the response: does it match
// the expected response(s)?
verbose("testSubmitRequest: url=" + url + " status=" + statusCode);
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
- }
+ }
// ---------------------------------------------------------------
// Utility methods used by tests above
// ---------------------------------------------------------------
-
@Override
public String getServicePathComponent() {
return SERVICE_PATH_COMPONENT;
}
-
- private Acquisition createAcquisitionInstance(String identifier) {
- Acquisition acquisition =
- createAcquisitionInstance(
- "entryNumber-" + identifier,
- "entryDate-" + identifier);
- return acquisition;
- }
-
- private Acquisition createAcquisitionInstance(String entryNumber, String entryDate) {
- Acquisition acquisition = new Acquisition();
-// acquisition.setEntryNumber(entryNumber);
- acquisition.setAccessiondate(entryDate);
- return acquisition;
- }
+
+ private MultipartOutput createAcquisitionInstance(String identifier) {
+ AcquisitionsCommon acquisition = new AcquisitionsCommon();
+ acquisition.setAccessiondate("accessionDate-" + identifier);
+ MultipartOutput multipart = new MultipartOutput();
+ OutputPart commonPart = multipart.addPart(acquisition, MediaType.APPLICATION_XML_TYPE);
+ commonPart.getHeaders().add("label", getCommonPartName());
+
+ verbose("to be created, collectionobject common ", acquisition, AcquisitionsCommon.class);
+ return multipart;
+ }
}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:ns="http://collectionspace.org/acquisition"
- xmlns="http://collectionspace.org/acquisition"
- targetNamespace="http://services.collectionspace.org/acquisition"
+ xmlns:ns="http://collectionspace.org/services/acquisition"
+ xmlns="http://collectionspace.org/services/acquisition"
+ targetNamespace="http://collectionspace.org/services/acquisition"
version="0.1"
>
<!-- See http://wiki.collectionspace.org/display/collectionspace/Acquisition+Schema -->
<!-- acquisition -->
- <xs:element name="acquisition">
+ <xs:element name="acquisitions-common">
<xs:complexType>
<xs:sequence>
<xs:element name="csid" type="xs:string" />
</xs:element>
<!-- acquisition records, as in nuxeo repository -->
- <xs:element name="acquisition-list">
+ <xs:element name="acquisitions-common-list">
<xs:complexType>
<xs:sequence>
<xs:element name="acquisition-list-item" maxOccurs="unbounded">
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.acquisition.AcquisitionList.*;
-
-import org.collectionspace.services.acquisition.nuxeo.AcquisitionConstants;
import org.collectionspace.services.acquisition.nuxeo.AcquisitionHandlerFactory;
-import org.collectionspace.services.common.NuxeoClientType;
-import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.AbstractCollectionSpaceResource;
+import org.collectionspace.services.common.context.ServiceContext;
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.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
import org.jboss.resteasy.util.HttpResponseCodes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Path("/acquisitions")
-@Consumes("application/xml")
-@Produces("application/xml")
-public class AcquisitionResource {
+@Consumes("multipart/mixed")
+@Produces("multipart/mixed")
+public class AcquisitionResource
+ extends AbstractCollectionSpaceResource {
- public final static String ACQUISITION_SERVICE_NAME = "acquisitions";
+ final private String serviceName = "acquisitions";
final Logger logger = LoggerFactory.getLogger(AcquisitionResource.class);
- //FIXME retrieve client type from configuration
- final static NuxeoClientType CLIENT_TYPE = ServiceMain.getInstance().getNuxeoClientType();
+
+ @Override
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ @Override
+ public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception {
+ DocumentHandler docHandler = AcquisitionHandlerFactory.getInstance().getHandler(
+ ctx.getRepositoryClientType().toString());
+ docHandler.setServiceContext(ctx);
+ if(ctx.getInput() != null){
+ Object obj = ctx.getInputPart(ctx.getCommonPartLabel(), AcquisitionsCommon.class);
+ if(obj != null){
+ docHandler.setCommonPart((AcquisitionsCommon) obj);
+ }
+ }
+ return docHandler;
+ }
public AcquisitionResource() {
// do nothing
}
@POST
- public Response createAcquisition(
- Acquisition acquisitionObject) {
+ public Response createAcquisition(MultipartInput input) {
- String csid = null;
try{
- RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
- RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
- AcquisitionHandlerFactory handlerFactory = AcquisitionHandlerFactory.getInstance();
- DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
- handler.setCommonObject(acquisitionObject);
- csid = client.create(ACQUISITION_SERVICE_NAME, handler);
- acquisitionObject.setCsid(csid);
- if(logger.isDebugEnabled()){
- verbose("createAcquisition: ", acquisitionObject);
- }
+ ServiceContext ctx = createServiceContext(input);
+ DocumentHandler handler = createDocumentHandler(ctx);
+ String csid = getRepositoryClient(ctx).create(ctx, handler);
UriBuilder path = UriBuilder.fromResource(AcquisitionResource.class);
path.path("" + csid);
Response response = Response.created(path.build()).build();
@GET
@Path("{csid}")
- public Acquisition getAcquisition(
+ public MultipartOutput getAcquisition(
@PathParam("csid") String csid) {
if(logger.isDebugEnabled()){
- verbose("getAcquisition with csid=" + csid);
+ logger.debug("getAcquisition with csid=" + csid);
}
if(csid == null || "".equals(csid)){
logger.error("getAcquisition: missing csid!");
"text/plain").build();
throw new WebApplicationException(response);
}
- Acquisition acquisitionObject = null;
+ MultipartOutput result = null;
try{
- RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
- RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
- AcquisitionHandlerFactory handlerFactory = AcquisitionHandlerFactory.getInstance();
- DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
- client.get(csid, handler);
- acquisitionObject = (Acquisition) handler.getCommonObject();
+ ServiceContext ctx = createServiceContext(null);
+ DocumentHandler handler = createDocumentHandler(ctx);
+ getRepositoryClient(ctx).get(ctx, csid, handler);
+ result = ctx.getOutput();
}catch(DocumentNotFoundException dnfe){
if(logger.isDebugEnabled()){
logger.debug("getAcquisition", dnfe);
throw new WebApplicationException(response);
}
- if(acquisitionObject == null){
+ if(result == null){
Response response = Response.status(Response.Status.NOT_FOUND).entity(
"Get failed, the requested Acquisition CSID:" + csid + ": was not found.").type(
"text/plain").build();
throw new WebApplicationException(response);
}
- if(logger.isDebugEnabled()){
- verbose("getAcquisition: ", acquisitionObject);
- }
- return acquisitionObject;
+ return result;
}
@GET
- public AcquisitionList getAcquisitionList(@Context UriInfo ui) {
- AcquisitionList acquisitionObjectList = new AcquisitionList();
+ @Produces("application/xml")
+ public AcquisitionsCommonList getAcquisitionList(@Context UriInfo ui) {
+ AcquisitionsCommonList acquisitionObjectList = new AcquisitionsCommonList();
try{
- RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
- RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
- AcquisitionHandlerFactory handlerFactory = AcquisitionHandlerFactory.getInstance();
- DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
- client.getAll(ACQUISITION_SERVICE_NAME, handler);
- acquisitionObjectList = (AcquisitionList) handler.getCommonObjectList();
+ ServiceContext ctx = createServiceContext(null);
+ DocumentHandler handler = createDocumentHandler(ctx);
+ getRepositoryClient(ctx).getAll(ctx, handler);
+ acquisitionObjectList = (AcquisitionsCommonList) handler.getCommonPartList();
}catch(Exception e){
if(logger.isDebugEnabled()){
logger.debug("Caught exception in getAcquisitionList", e);
@PUT
@Path("{csid}")
- public Acquisition updateAcquisition(
+ public MultipartOutput updateAcquisition(
@PathParam("csid") String csid,
- Acquisition theUpdate) {
+ MultipartInput theUpdate) {
if(logger.isDebugEnabled()){
- verbose("updateAcquisition with csid=" + csid);
+ logger.debug("updateAcquisition with csid=" + csid);
}
if(csid == null || "".equals(csid)){
logger.error("updateAcquisition: missing csid!");
throw new WebApplicationException(response);
}
if(logger.isDebugEnabled()){
- verbose("updateAcquisition with input: ", theUpdate);
+ logger.debug("updateAcquisition with input: ", theUpdate);
}
+ MultipartOutput result = null;
try{
- RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
- RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
- AcquisitionHandlerFactory handlerFactory = AcquisitionHandlerFactory.getInstance();
- DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
- handler.setCommonObject(theUpdate);
- client.update(csid, handler);
+ ServiceContext ctx = createServiceContext(theUpdate);
+ DocumentHandler handler = createDocumentHandler(ctx);
+ getRepositoryClient(ctx).update(ctx, csid, handler);
+ result = ctx.getOutput();
}catch(DocumentNotFoundException dnfe){
if(logger.isDebugEnabled()){
logger.debug("caugth exception in updateAcquisition", dnfe);
Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
throw new WebApplicationException(response);
}
- return theUpdate;
+ return result;
}
@DELETE
public Response deleteAcquisition(@PathParam("csid") String csid) {
if(logger.isDebugEnabled()){
- verbose("deleteAcquisition with csid=" + csid);
+ logger.debug("deleteAcquisition with csid=" + csid);
}
if(csid == null || "".equals(csid)){
logger.error("deleteAcquisition: missing csid!");
throw new WebApplicationException(response);
}
try{
- RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
- RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
- client.delete(csid);
+ ServiceContext ctx = createServiceContext(null);
+ getRepositoryClient(ctx).delete(ctx, csid);
return Response.status(HttpResponseCodes.SC_OK).build();
}catch(DocumentNotFoundException dnfe){
if(logger.isDebugEnabled()){
}
- private void verbose(String msg, Acquisition acquisitionObject) {
- try{
- verbose(msg);
- JAXBContext jc = JAXBContext.newInstance(
- Acquisition.class);
-
- Marshaller m = jc.createMarshaller();
- m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
- m.marshal(acquisitionObject, System.out);
- }catch(Exception e){
- e.printStackTrace();
- }
-
- }
-
- private void verbose(String msg) {
- System.out.println("AcquisitionResource. " + msg);
- }
}
+++ /dev/null
-/**\r
- * \r
- */\r
-package org.collectionspace.services.acquisition;\r
-\r
-import java.io.IOException;\r
-import org.dom4j.Document;\r
-import org.dom4j.DocumentException;\r
-\r
-import org.collectionspace.services.acquisition.Acquisition;\r
-\r
-/**\r
- * @author remillet\r
- * \r
- */\r
-public interface AcquisitionService {\r
-\r
- public final static String ACQUISITION_SCHEMA_NAME = "acquisition";\r
-\r
- // Create\r
- Document postAcquisition(Acquisition co)\r
- throws DocumentException, IOException;\r
-\r
- // Read single object\r
- Document getAcquisition(String csid) throws DocumentException,\r
- IOException;\r
-\r
- // Read a list of objects\r
- Document getAcquisitionList() throws DocumentException, IOException;\r
-\r
- // Update\r
- Document putAcquisition(String csid, Acquisition theUpdate)\r
- throws DocumentException, IOException;\r
-\r
- // Delete\r
- Document deleteAcquisition(String csid) throws DocumentException,\r
- IOException;\r
-}\r
import org.collectionspace.services.AcquisitionJAXBSchema;
import org.collectionspace.services.common.repository.DocumentWrapper;
-import org.collectionspace.services.acquisition.Acquisition;
-import org.collectionspace.services.acquisition.AcquisitionList;
-import org.collectionspace.services.acquisition.AcquisitionList.AcquisitionListItem;
+import org.collectionspace.services.acquisition.AcquisitionsCommon;
+import org.collectionspace.services.acquisition.AcquisitionsCommonList;
+import org.collectionspace.services.acquisition.AcquisitionsCommonList.AcquisitionListItem;
import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler;
-import org.collectionspace.services.acquisition.nuxeo.AcquisitionConstants;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentModelList;
* $LastChangedDate: $
*/
public class AcquisitionDocumentModelHandler
- extends DocumentModelHandler<Acquisition, AcquisitionList> {
+ extends DocumentModelHandler<AcquisitionsCommon, AcquisitionsCommonList> {
private final Logger logger = LoggerFactory.getLogger(AcquisitionDocumentModelHandler.class);
/**
* acquisition is used to stash JAXB object to use when handle is called
* for Action.CREATE, Action.UPDATE or Action.GET
*/
- private Acquisition acquisition;
+ private AcquisitionsCommon acquisition;
/**
* acquisitionList is stashed when handle is called
* for ACTION.GET_ALL
*/
- private AcquisitionList acquisitionList;
+ private AcquisitionsCommonList acquisitionList;
@Override
public void prepare(Action action) throws Exception {
}
/**
- * getCommonObject get associated acquisition
+ * getCommonPart get associated acquisition
* @return
*/
@Override
- public Acquisition getCommonObject() {
+ public AcquisitionsCommon getCommonPart() {
return acquisition;
}
/**
- * setCommonObject set associated acquisition
+ * setCommonPart set associated acquisition
* @param acquisition
*/
@Override
- public void setCommonObject(Acquisition acquisition) {
+ public void setCommonPart(AcquisitionsCommon acquisition) {
this.acquisition = acquisition;
}
* @return
*/
@Override
- public AcquisitionList getCommonObjectList() {
+ public AcquisitionsCommonList getCommonPartList() {
return acquisitionList;
}
@Override
- public void setCommonObjectList(AcquisitionList acquisitionList) {
+ public void setCommonPartList(AcquisitionsCommonList acquisitionList) {
this.acquisitionList = acquisitionList;
}
@Override
- public Acquisition extractCommonObject(DocumentWrapper wrapDoc)
+ public AcquisitionsCommon extractCommonPart(DocumentWrapper wrapDoc)
throws Exception {
- DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
- Acquisition acquisitionObject = new Acquisition();
-
- //FIXME property get should be dynamically set using schema inspection
- //so it does not require hard coding
-
- // acquisition core values
- acquisitionObject.setAccessiondate((String)docModel.getPropertyValue(
- getQProperty(AcquisitionJAXBSchema.ACCESSIONDATE)));
-
- return acquisitionObject;
+ throw new UnsupportedOperationException();
}
@Override
- public void fillCommonObject(Acquisition acquisitionObject, 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", AcquisitionConstants.NUXEO_DC_TITLE);
-
- // acquisition core values
- if(acquisitionObject.getAccessiondate() != null){
- docModel.setPropertyValue(getQProperty(
- AcquisitionJAXBSchema.ACCESSIONDATE), acquisitionObject.getAccessiondate());
- }
+ public void fillCommonPart(AcquisitionsCommon acquisitionObject, DocumentWrapper wrapDoc) throws Exception {
+ throw new UnsupportedOperationException();
}
@Override
- public AcquisitionList extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception {
+ public AcquisitionsCommonList extractCommonPartList(DocumentWrapper wrapDoc) throws Exception {
DocumentModelList docList = (DocumentModelList) wrapDoc.getWrappedObject();
- AcquisitionList coList = new AcquisitionList();
- List<AcquisitionList.AcquisitionListItem> list = coList.getAcquisitionListItem();
+ AcquisitionsCommonList coList = new AcquisitionsCommonList();
+ List<AcquisitionsCommonList.AcquisitionListItem> list = coList.getAcquisitionListItem();
//FIXME: iterating over a long list of documents is not a long term
//strategy...need to change to more efficient iterating in future
while(iter.hasNext()){
DocumentModel docModel = iter.next();
AcquisitionListItem listItem = new AcquisitionListItem();
- listItem.setAccessiondate((String)docModel.getPropertyValue(
- getQProperty(AcquisitionJAXBSchema.ACCESSIONDATE)));
+ listItem.setAccessiondate((String) docModel.getProperty(getServiceContext().getCommonPartLabel(),
+ AcquisitionJAXBSchema.ACCESSIONDATE));
//need fully qualified context for URI
String id = docModel.getId();
- listItem.setUri("/acquisitions/" + id);
+ listItem.setUri(getServiceContextPath() + id);
listItem.setCsid(id);
list.add(listItem);
}
}
@Override
- public void fillCommonObjectList(AcquisitionList obj, DocumentWrapper wrapDoc) throws Exception {
- throw new UnsupportedOperationException();
+ public void fillAllParts(DocumentWrapper wrapDoc) throws Exception {
+
+ super.fillAllParts(wrapDoc);
+ fillDublinCoreObject(wrapDoc); //dublincore might not be needed in future
}
+ private void fillDublinCoreObject(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", AcquisitionConstants.NUXEO_DC_TITLE);
+ }
+
+
/* (non-Javadoc)
* @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#getDocumentType()
*/
public String getDocumentType() {
- return AcquisitionConstants.NUXEO_DOCTYPE;
+ return AcquisitionConstants.NUXEO_DOCTYPE;
}
-
+
/**
* getQProperty converts the given property to qualified schema property
* @param prop
* @return
*/
- private String getQProperty(String prop) {
+ @Override
+ public String getQProperty(String prop) {
return AcquisitionConstants.NUXEO_SCHEMA_NAME + ":" + prop;
}
}
*/
package org.collectionspace.services.acquisition.nuxeo;
-import org.collectionspace.services.common.NuxeoClientType;
+import org.collectionspace.services.common.ClientType;
import org.collectionspace.services.common.repository.DocumentHandler;
/**
}
public DocumentHandler getHandler(String clientType) {
- if(NuxeoClientType.JAVA.toString().equals(clientType)){
+ if(ClientType.JAVA.toString().equals(clientType)){
return new AcquisitionDocumentModelHandler();
}
*/
package org.collectionspace.services.authentication.client;
-import java.util.ArrayList;
-import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.Marshaller;
import org.jboss.resteasy.client.ClientResponse;
import org.testng.Assert;
import org.testng.annotations.Test;
-import org.collectionspace.services.collectionobject.CollectionObject;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommon;
import org.collectionspace.services.client.CollectionObjectClient;
import org.collectionspace.services.client.CollectionSpaceClient;
+import org.collectionspace.services.client.test.AbstractServiceTest;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
+import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* $LastChangedRevision: 434 $
* $LastChangedDate: 2009-07-28 14:34:15 -0700 (Tue, 28 Jul 2009) $
*/
-public class AuthenticationServiceTest {
+public class AuthenticationServiceTest extends AbstractServiceTest {
- private String knownCollectionObjectId = null;
+ final String SERVICE_PATH_COMPONENT = "collectionobjects";
+ private String knownResourceId = null;
final Logger logger = LoggerFactory.getLogger(AuthenticationServiceTest.class);
+ @Override
+ public String getServicePathComponent() {
+ // @TODO Determine if it is possible to obtain this
+ // value programmatically.
+ //
+ // We set this in an annotation in the CollectionObjectProxy
+ // interface, for instance. We also set service-specific
+ // constants in each service module, which might also
+ // return this value.
+ return SERVICE_PATH_COMPONENT;
+ }
+
@Test
- public void auth_createCollectionObject() {
+ @Override
+ public void create() {
String identifier = this.createIdentifier();
- CollectionObject collectionObject = createCollectionObject(identifier);
+ MultipartOutput multipart = createCollectionObjectInstance(identifier);
CollectionObjectClient collectionObjectClient = new CollectionObjectClient();
if(!collectionObjectClient.isServerSecure()){
logger.warn("set -Dcspace.server.secure=true to run security tests");
collectionObjectClient.setupHttpClient();
collectionObjectClient.setProxy();
}catch(Exception e){
- logger.error("auth_createCollectionObject: caught " + e.getMessage());
+ logger.error("create: caught " + e.getMessage());
return;
}
- ClientResponse<Response> res = collectionObjectClient.create(collectionObject);
- verbose("auth_createCollectionObject: status = " + res.getStatus());
+ ClientResponse<Response> res = collectionObjectClient.create(multipart);
+ verbose("create: status = " + res.getStatus());
Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode(),
"expected " + Response.Status.CREATED.getStatusCode());
// Store the ID returned from this create operation for additional tests below.
- knownCollectionObjectId = extractId(res);
+ knownResourceId = extractId(res);
}
- @Test(dependsOnMethods = {"auth_createCollectionObject"})
- public void auth_createCollectionObjectWithoutUser() {
+ @Test(dependsOnMethods = {"create"})
+ public void createWithoutUser() {
String identifier = this.createIdentifier();
- CollectionObject collectionObject = createCollectionObject(identifier);
+ MultipartOutput multipart = createCollectionObjectInstance(identifier);
CollectionObjectClient collectionObjectClient = new CollectionObjectClient();
if(!collectionObjectClient.isServerSecure()){
logger.warn("set -Dcspace.server.secure=true to run security tests");
collectionObjectClient.setupHttpClient();
collectionObjectClient.setProxy();
}catch(Exception e){
- logger.error("auth_createCollectionObjectWithoutUser: caught " + e.getMessage());
+ logger.error("createWithoutUser: caught " + e.getMessage());
return;
}
- ClientResponse<Response> res = collectionObjectClient.create(collectionObject);
- verbose("auth_createCollectionObjectWithoutUser: status = " + res.getStatus());
+ ClientResponse<Response> res = collectionObjectClient.create(multipart);
+ verbose("createWithoutUser: status = " + res.getStatus());
Assert.assertEquals(res.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode(),
"expected " + Response.Status.UNAUTHORIZED.getStatusCode());
}
- @Test(dependsOnMethods = {"auth_createCollectionObjectWithoutUser"})
- public void auth_createCollectionObjectWithoutPassword() {
+ @Test(dependsOnMethods = {"createWithoutUser"})
+ public void createWithoutPassword() {
String identifier = this.createIdentifier();
- CollectionObject collectionObject = createCollectionObject(identifier);
+ MultipartOutput multipart = createCollectionObjectInstance(identifier);
CollectionObjectClient collectionObjectClient = new CollectionObjectClient();
if(!collectionObjectClient.isServerSecure()){
logger.warn("set -Dcspace.server.secure=true to run security tests");
collectionObjectClient.setupHttpClient();
collectionObjectClient.setProxy();
}catch(Exception e){
- logger.error("auth_createCollectionObjectWithoutPassword: caught " + e.getMessage());
+ logger.error("createWithoutPassword: caught " + e.getMessage());
return;
}
- ClientResponse<Response> res = collectionObjectClient.create(collectionObject);
- verbose("auth_createCollectionObjectWithoutPassword: status = " + res.getStatus());
+ ClientResponse<Response> res = collectionObjectClient.create(multipart);
+ verbose("createWithoutPassword: status = " + res.getStatus());
Assert.assertEquals(res.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode(),
"expected " + Response.Status.UNAUTHORIZED.getStatusCode());
}
- @Test(dependsOnMethods = {"auth_createCollectionObjectWithoutPassword"})
- public void auth_createCollectionObjectWithIncorrectPassword() {
+ @Test(dependsOnMethods = {"createWithoutPassword"})
+ public void createWithIncorrectPassword() {
String identifier = this.createIdentifier();
- CollectionObject collectionObject = createCollectionObject(identifier);
+ MultipartOutput multipart = createCollectionObjectInstance(identifier);
CollectionObjectClient collectionObjectClient = new CollectionObjectClient();
if(!collectionObjectClient.isServerSecure()){
logger.warn("set -Dcspace.server.secure=true to run security tests");
collectionObjectClient.setupHttpClient();
collectionObjectClient.setProxy();
}catch(Exception e){
- logger.error("auth_createCollectionObjectWithIncorrectPassword: caught " + e.getMessage());
+ logger.error("createWithIncorrectPassword: caught " + e.getMessage());
return;
}
- ClientResponse<Response> res = collectionObjectClient.create(collectionObject);
- verbose("auth_createCollectionObjectWithIncorrectPassword: status = " + res.getStatus());
+ ClientResponse<Response> res = collectionObjectClient.create(multipart);
+ verbose("createWithIncorrectPassword: status = " + res.getStatus());
Assert.assertEquals(res.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode(),
"expected " + Response.Status.UNAUTHORIZED.getStatusCode());
}
- @Test(dependsOnMethods = {"auth_createCollectionObjectWithoutPassword"})
- public void auth_createCollectionObjectWithoutUserPassword() {
+ @Test(dependsOnMethods = {"createWithoutPassword"})
+ public void createWithoutUserPassword() {
String identifier = this.createIdentifier();
- CollectionObject collectionObject = createCollectionObject(identifier);
+ MultipartOutput multipart = createCollectionObjectInstance(identifier);
CollectionObjectClient collectionObjectClient = new CollectionObjectClient();
if(!collectionObjectClient.isServerSecure()){
logger.warn("set -Dcspace.server.secure=true to run security tests");
collectionObjectClient.setupHttpClient();
collectionObjectClient.setProxy();
}catch(Exception e){
- logger.error("auth_createCollectionObjectWithoutUserPassword: caught " + e.getMessage());
+ logger.error("createWithoutUserPassword: caught " + e.getMessage());
return;
}
- ClientResponse<Response> res = collectionObjectClient.create(collectionObject);
- verbose("auth_createCollectionObjectWithoutUserPassword: status = " + res.getStatus());
+ ClientResponse<Response> res = collectionObjectClient.create(multipart);
+ verbose("createWithoutUserPassword: status = " + res.getStatus());
Assert.assertEquals(res.getStatus(), Response.Status.FORBIDDEN.getStatusCode(),
"expected " + Response.Status.FORBIDDEN.getStatusCode());
}
- @Test(dependsOnMethods = {"auth_createCollectionObjectWithoutPassword"})
- public void auth_createCollectionObjectWithIncorrectUserPassword() {
+ @Test(dependsOnMethods = {"createWithoutPassword"})
+ public void createWithIncorrectUserPassword() {
String identifier = this.createIdentifier();
- CollectionObject collectionObject = createCollectionObject(identifier);
+ MultipartOutput multipart = createCollectionObjectInstance(identifier);
CollectionObjectClient collectionObjectClient = new CollectionObjectClient();
if(!collectionObjectClient.isServerSecure()){
logger.warn("set -Dcspace.server.secure=true to run security tests");
collectionObjectClient.setupHttpClient();
collectionObjectClient.setProxy();
}catch(Exception e){
- logger.error("auth_createCollectionObjectWithIncorrectUserPassword: caught " + e.getMessage());
+ logger.error("createWithIncorrectUserPassword: caught " + e.getMessage());
return;
}
- ClientResponse<Response> res = collectionObjectClient.create(collectionObject);
- verbose("auth_createCollectionObjectWithIncorrectUserPassword: status = " + res.getStatus());
+ ClientResponse<Response> res = collectionObjectClient.create(multipart);
+ verbose("createWithIncorrectUserPassword: status = " + res.getStatus());
Assert.assertEquals(res.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode(),
"expected " + Response.Status.UNAUTHORIZED.getStatusCode());
}
- @Test(dependsOnMethods = {"auth_createCollectionObjectWithIncorrectUserPassword"})
- public void auth_deleteCollectionObject() {
+ @Override
+ @Test(dependsOnMethods = {"createWithIncorrectUserPassword"})
+ public void delete() {
CollectionObjectClient collectionObjectClient = new CollectionObjectClient();
collectionObjectClient = new CollectionObjectClient();
if(!collectionObjectClient.isServerSecure()){
collectionObjectClient.setupHttpClient();
collectionObjectClient.setProxy();
}catch(Exception e){
- logger.error("auth_deleteCollectionObject: caught " + e.getMessage());
+ logger.error("deleteCollectionObject: caught " + e.getMessage());
return;
}
- verbose("Calling deleteCollectionObject:" + knownCollectionObjectId);
- ClientResponse<Response> res = collectionObjectClient.delete(knownCollectionObjectId);
- verbose("auth_deleteCollectionObject: status = " + res.getStatus());
+ verbose("Calling deleteCollectionObject:" + knownResourceId);
+ ClientResponse<Response> res = collectionObjectClient.delete(knownResourceId);
+ verbose("deleteCollectionObject: status = " + res.getStatus());
Assert.assertEquals(res.getStatus(), Response.Status.OK.getStatusCode(),
"expected " + Response.Status.OK.getStatusCode());
}
// ---------------------------------------------------------------
// Utility methods used by tests above
// ---------------------------------------------------------------
- private CollectionObject createCollectionObject(String identifier) {
- CollectionObject collectionObject = createCollectionObject("objectNumber-" + identifier,
+ private MultipartOutput createCollectionObjectInstance(String identifier) {
+ return createCollectionObjectInstance("objectNumber-" + identifier,
"objectName-" + identifier);
-
- return collectionObject;
}
- private CollectionObject createCollectionObject(String objectNumber, String objectName) {
- CollectionObject collectionObject = new CollectionObject();
+ private MultipartOutput createCollectionObjectInstance(String objectNumber, String objectName) {
+ CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
collectionObject.setObjectNumber(objectNumber);
collectionObject.setObjectName(objectName);
+ MultipartOutput multipart = new MultipartOutput();
+ OutputPart commonPart = multipart.addPart(collectionObject, MediaType.APPLICATION_XML_TYPE);
+ commonPart.getHeaders().add("label", getCommonPartName());
- return collectionObject;
+ verbose("to be created, collectionobject common ", collectionObject, CollectionobjectsCommon.class);
+ return multipart;
}
- private String extractId(ClientResponse<Response> res) {
- MultivaluedMap mvm = res.getMetadata();
- String uri = (String) ((ArrayList) mvm.get("Location")).get(0);
- verbose("extractId:uri=" + uri);
- String[] segments = uri.split("/");
- String id = segments[segments.length - 1];
- verbose("id=" + id);
- return id;
+ @Override
+ public void createList() {
}
- private void verbose(String msg) {
- if(logger.isInfoEnabled()){
- logger.debug(msg);
- }
+ @Override
+ public void createWithEmptyEntityBody() {
}
- private void verbose(String msg, Object o, Class clazz) {
- try{
- verbose(msg);
- JAXBContext jc = JAXBContext.newInstance(clazz);
- Marshaller m = jc.createMarshaller();
- m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
- Boolean.TRUE);
- m.marshal(o, System.out);
- }catch(Exception e){
- e.printStackTrace();
- }
+ @Override
+ public void createWithMalformedXml() {
+ }
+
+ @Override
+ public void createWithWrongXmlSchema() {
+ }
+
+ @Override
+ public void read() {
+ }
+
+ @Override
+ public void readNonExistent() {
+ }
+
+ @Override
+ public void readList() {
+ }
+
+ @Override
+ public void update() {
+ }
+
+ @Override
+ public void updateWithEmptyEntityBody() {
+ }
+
+ @Override
+ public void updateWithMalformedXml() {
+ }
+
+ @Override
+ public void updateWithWrongXmlSchema() {
+ }
+
+ @Override
+ public void updateNonExistent() {
}
- private String createIdentifier() {
- long identifier = System.currentTimeMillis();
- return Long.toString(identifier);
+ @Override
+ public void deleteNonExistent() {
}
}
*/
package org.collectionspace.services.client.test;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
+import java.io.ByteArrayInputStream;
import java.util.ArrayList;
-import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
import org.collectionspace.services.client.TestServiceClient;
-import org.collectionspace.services.client.test.ServiceRequestType;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.InputPart;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractServiceTest implements ServiceTest {
final Logger logger = LoggerFactory.getLogger(AbstractServiceTest.class);
-
// A base-level client, used (only) to obtain the base service URL.
private static final TestServiceClient serviceClient = new TestServiceClient();
-
// A resource identifier believed to be non-existent in actual use,
// used when testing service calls that reference non-existent resources.
protected final String NON_EXISTENT_ID = createNonExistentIdentifier();
-
// The HTTP status code expected to be returned in the response,
// from a request made to a service (where relevant).
int EXPECTED_STATUS_CODE = 0;
-
// The generic type of service request being tested (e.g. CREATE, UPDATE, DELETE).
//
// This makes it possible to check behavior specific to that type of request,
//
// Note that the default value is set to a guard value.
protected ServiceRequestType REQUEST_TYPE = ServiceRequestType.NON_EXISTENT;
-
// Static data to be submitted in various tests
protected final static String XML_DECLARATION =
- "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
-
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
// Note: this constant is intentionally missing its last angle bracket.
protected final static String MALFORMED_XML_DATA =
- XML_DECLARATION +
- "<malformed_xml>wrong schema contents</malformed_xml";
-
+ XML_DECLARATION +
+ "<malformed_xml>wrong schema contents</malformed_xml";
protected final String WRONG_XML_SCHEMA_DATA =
- XML_DECLARATION +
- "<wrong_schema>wrong schema contents</wrong_schema>";
+ XML_DECLARATION +
+ "<wrong_schema>wrong schema contents</wrong_schema>";
// ---------------------------------------------------------------
// CRUD tests : CREATE tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
- public abstract void create();
-
+ public void create() {
+
+ }
+
protected void setupCreate() {
- clearSetup();
+ clearSetup("Create");
// Expected status code: 201 Created
EXPECTED_STATUS_CODE = Response.Status.CREATED.getStatusCode();
// Type of service request being tested
@Override
public abstract void createList();
-
- // No setup required for createList()
+ // No setup required for createList()
// Failure outcomes
-
@Override
public abstract void createWithEmptyEntityBody();
protected void setupCreateWithEmptyEntityBody() {
- clearSetup();
+ clearSetup("CreateWithEmptyEntityBody");
EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
REQUEST_TYPE = ServiceRequestType.CREATE;
}
public abstract void createWithMalformedXml();
protected void setupCreateWithMalformedXml() {
- clearSetup();
+ clearSetup("CreateWithMalformedXml");
// Expected status code: 400 Bad Request
EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
REQUEST_TYPE = ServiceRequestType.CREATE;
public abstract void createWithWrongXmlSchema();
protected void setupCreateWithWrongXmlSchema() {
- clearSetup();
+ clearSetup("CreateWithWrongXmlSchema");
// Expected status code: 400 Bad Request
EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
REQUEST_TYPE = ServiceRequestType.CREATE;
}
-
// ---------------------------------------------------------------
// CRUD tests : READ tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
public abstract void read();
protected void setupRead() {
- clearSetup();
+ clearSetup("Read");
// Expected status code: 200 OK
EXPECTED_STATUS_CODE = Response.Status.OK.getStatusCode();
REQUEST_TYPE = ServiceRequestType.READ;
}
// Failure outcomes
-
@Override
public abstract void readNonExistent();
protected void setupReadNonExistent() {
- clearSetup();
+ clearSetup("ReadNonExistent");
// Expected status code: 404 Not Found
EXPECTED_STATUS_CODE = Response.Status.NOT_FOUND.getStatusCode();
REQUEST_TYPE = ServiceRequestType.READ;
}
-
// ---------------------------------------------------------------
// CRUD tests : READ (list, or multiple) tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
public abstract void readList();
protected void setupReadList() {
- clearSetup();
+ clearSetup("ReadList");
// Expected status code: 200 OK
EXPECTED_STATUS_CODE = Response.Status.OK.getStatusCode();
REQUEST_TYPE = ServiceRequestType.READ_LIST;
}
// Failure outcomes
-
// None tested at present.
-
-
// ---------------------------------------------------------------
// CRUD tests : UPDATE tests
// ---------------------------------------------------------------
-
// Success outcomes
// ----------------
-
@Override
public abstract void update();
protected void setupUpdate() {
- clearSetup();
+ clearSetup("Update");
// Expected status code: 200 OK
EXPECTED_STATUS_CODE = Response.Status.OK.getStatusCode();
REQUEST_TYPE = ServiceRequestType.UPDATE;
}
// Failure outcomes
-
@Override
public abstract void updateWithEmptyEntityBody();
protected void setupUpdateWithEmptyEntityBody() {
- clearSetup();
+ clearSetup("UpdateWithEmptyEntityBody");
EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
REQUEST_TYPE = ServiceRequestType.UPDATE;
}
public abstract void updateWithMalformedXml();
protected void setupUpdateWithMalformedXml() {
- clearSetup();
+ clearSetup("UpdateWithMalformedXml");
// Expected status code: 400 Bad Request
EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
REQUEST_TYPE = ServiceRequestType.UPDATE;
public abstract void updateWithWrongXmlSchema();
protected void setupUpdateWithWrongXmlSchema() {
- clearSetup();
+ clearSetup("UpdateWithWrongXmlSchema");
// Expected status code: 400 Bad Request
EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
REQUEST_TYPE = ServiceRequestType.UPDATE;
public abstract void updateNonExistent();
protected void setupUpdateNonExistent() {
- clearSetup();
+ clearSetup("UpdateNonExistent");
// Expected status code: 404 Not Found
EXPECTED_STATUS_CODE = Response.Status.NOT_FOUND.getStatusCode();
REQUEST_TYPE = ServiceRequestType.UPDATE;
}
-
// ---------------------------------------------------------------
// CRUD tests : DELETE tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
public abstract void delete();
-
+
protected void setupDelete() {
- clearSetup();
+ clearSetup("Delete");
// Expected status code: 200 OK
EXPECTED_STATUS_CODE = Response.Status.OK.getStatusCode();
REQUEST_TYPE = ServiceRequestType.DELETE;
}
-
+
// Failure outcomes
-
@Override
public abstract void deleteNonExistent();
protected void setupDeleteNonExistent() {
- clearSetup();
+ clearSetup("DeleteNonExistent");
// Expected status code: 404 Not Found
EXPECTED_STATUS_CODE = Response.Status.NOT_FOUND.getStatusCode();
REQUEST_TYPE = ServiceRequestType.DELETE;
}
-
// ---------------------------------------------------------------
// Abstract utility methods
//
// Must be implemented by classes that extend
// this abstract base class.
// ---------------------------------------------------------------
-
/**
* Returns the URL path component of the service.
*
* This component will follow directly after the
* base path, if any.
*/
- protected abstract String getServicePathComponent();
+ @Override
+ public abstract String getServicePathComponent();
+ @Override
+ public String getCommonPartName() {
+ return getServicePathComponent() + "-common";
+ }
// ---------------------------------------------------------------
// Utility methods
// ---------------------------------------------------------------
-
/**
* Reinitializes setup values, to help expose any unintended reuse
* of those values between tests.
*/
- protected void clearSetup() {
+ protected void clearSetup(String testName) {
EXPECTED_STATUS_CODE = 0;
REQUEST_TYPE = ServiceRequestType.NON_EXISTENT;
+ logger.debug("========================================================");
+ logger.debug(" Test = " + testName);
+ logger.debug("========================================================");
}
/**
* @return An error message.
*/
protected String invalidStatusCodeMessage(ServiceRequestType requestType, int statusCode) {
- return
- "Status code '" + statusCode + "' in response is NOT within the expected set: " +
- requestType.validStatusCodesAsString();
+ return "Status code '" + statusCode + "' in response is NOT within the expected set: " +
+ requestType.validStatusCodesAsString();
}
-
+
/**
* Returns the root URL for a service.
*
*
* @return The root URL for a service.
*/
- protected String getServiceRootURL() {
+ protected String getServiceRootURL() {
return serviceClient.getBaseURL() + getServicePathComponent();
}
*/
protected int submitRequest(String method, String url) {
int statusCode = 0;
- try {
+ try{
ClientRequest request = new ClientRequest(url);
- if (method.equals(javax.ws.rs.HttpMethod.DELETE)) {
+ if(method.equals(javax.ws.rs.HttpMethod.DELETE)){
ClientResponse res = request.delete();
- statusCode = res.getStatus();
- } else if (method.equals(javax.ws.rs.HttpMethod.GET)) {
+ statusCode = res.getStatus();
+ }else if(method.equals(javax.ws.rs.HttpMethod.GET)){
ClientResponse res = request.get();
- statusCode = res.getStatus();
- } else {
+ statusCode = res.getStatus();
+ }else{
// Do nothing - leave status code at default value.
}
- } catch (Exception e) {
- logger.error(
- "Exception during HTTP " + method + " request to " + url + ":",
- e);
+ }catch(Exception e){
+ logger.error(
+ "Exception during HTTP " + method + " request to " + url + ":",
+ e);
}
return statusCode;
- }
+ }
/**
* Submits an HTTP request to a specified URL, with the submitted
* @return The status code received in the HTTP response.
*/
protected int submitRequest(String method, String url,
- String mediaType, String entityStr) {
+ String mediaType, String entityStr) {
int statusCode = 0;
- try {
+ try{
ClientRequest request = new ClientRequest(url);
request.body(mediaType, entityStr);
- if (method.equals(javax.ws.rs.HttpMethod.POST)) {
+ if(method.equals(javax.ws.rs.HttpMethod.POST)){
ClientResponse res = request.post(java.lang.String.class);
- statusCode = res.getStatus();
- } else if (method.equals(javax.ws.rs.HttpMethod.PUT)) {
+ statusCode = res.getStatus();
+ }else if(method.equals(javax.ws.rs.HttpMethod.PUT)){
ClientResponse res = request.put(java.lang.String.class);
- statusCode = res.getStatus();
- } else {
+ statusCode = res.getStatus();
+ }else{
// Do nothing - leave status code at default value.
}
- } catch (Exception e) {
- logger.error(
- "Exception during HTTP " + method + " request to " + url + ":",
- e);
+ }catch(Exception e){
+ logger.error(
+ "Exception during HTTP " + method + " request to " + url + ":",
+ e);
}
return statusCode;
- }
+ }
// @TODO Add Javadoc comments to all methods requiring them, below.
-
-
protected String extractId(ClientResponse<Response> res) {
MultivaluedMap mvm = res.getMetadata();
String uri = (String) ((ArrayList) mvm.get("Location")).get(0);
}
protected void verbose(String msg) {
- if (logger.isDebugEnabled()) {
+ if(logger.isDebugEnabled()){
logger.debug(msg);
}
}
protected String createNonExistentIdentifier() {
return Long.toString(Long.MAX_VALUE);
}
-
+
+ protected Object extractPart(MultipartInput input, String label, Class clazz) throws Exception {
+ Object obj = null;
+ for(InputPart part : input.getParts()){
+ String partLabel = part.getHeaders().getFirst("label");
+ if(label.equalsIgnoreCase(partLabel)){
+ String partStr = part.getBodyAsString();
+ verbose("extracted part str=\n" + partStr);
+ obj = part.getBody(clazz, null);
+ verbose("extracted part obj=\n", obj, clazz);
+ break;
+ }
+ }
+ return obj;
+ }
+
+ protected Object getPartObject(String partStr, Class clazz) throws JAXBException {
+ JAXBContext jc = JAXBContext.newInstance(clazz);
+ ByteArrayInputStream bais = null;
+ Object obj = null;
+ try{
+ bais = new ByteArrayInputStream(partStr.getBytes());
+ Unmarshaller um = jc.createUnmarshaller();
+ obj = um.unmarshal(bais);
+ }finally{
+ if(bais != null){
+ try{
+ bais.close();
+ }catch(Exception e){
+ }
+ }
+ }
+ return obj;
+ }
}
*/
public interface ServiceTest {
+
+ /**
+ * Returns the URL path component of the service.
+ *
+ * This component will follow directly after the
+ * base path, if any.
+ */
+ public String getServicePathComponent();
+
+ /**
+ * getCommonPartName get common part name for the service request
+ * @return
+ */
+ public String getCommonPartName();
+
// ---------------------------------------------------------------
// CRUD tests : CREATE tests
// ---------------------------------------------------------------
*
* Relied upon by 'read', 'update' and 'delete' tests, below.
*/
- public void create();
+ public void create();
/**
* Tests creation of a list of two or more new resources by repeatedly
/**
* Tests creation of a resource by submitting
- * an empty entity body (aka empty payload).
+ * an empty entity body (aka empty payload).
*/
public void createWithEmptyEntityBody();
/**
* Tests creation of a resource by submitting
- * a representation with malformed XML data.
+ * a representation with malformed XML data.
*/
public void createWithMalformedXml();
/**
* Tests creation of a resource by submitting
* a representation in the wrong XML schema
- * (e.g. not matching the object's schema).
+ * (e.g. not matching the object's schema).
*/
public void createWithWrongXmlSchema();
-
+
// @TODO If feasible, implement a negative (failure)
// test for creation of duplicate resources.
// ---------------------------------------------------------------
// Success outcomes
-
+
/**
- * Tests reading (i.e. retrieval) of a resource.
+ * Tests reading (i.e. retrieval) of a resource.
*/
public void read();
* resource, whose resource identifier does not exist
* at the specified URL.
*/
- public void readNonExistent();
+ public void readNonExistent();
// ---------------------------------------------------------------
* Tests reading (i.e. retrieval) of a list of
* multiple resources.
*/
- public void readList();
+ public void readList();
// If feasible, implement a test for reading
// an empty list returned by the service.
// Failure outcomes
-
+
// If feasible, implement a negative (failure) test
// of handling of unrecognized query parameters
// (e.g. other than filtering or chunking parameters, etc.
// ----------------
/**
- * Tests updating the content of a resource.
+ * Tests updating the content of a resource.
*/
public void update();
public void updateWithEmptyEntityBody();
/**
- * Tests updating the content of a resource
+ * Tests updating the content of a resource
* by submitting a representation with malformed
- * XML data.
+ * XML data.
*/
public void updateWithMalformedXml();
/**
* Tests updating the content of a resource
* by submitting a representation in the wrong
- * XML schema (e.g. not matching the object's schema).
+ * XML schema (e.g. not matching the object's schema).
*/
public void updateWithWrongXmlSchema();
/**
* Tests deleting a resource.
*/
- public void delete();
-
+ public void delete();
+
// Failure outcomes
-
+
/**
* Tests deleting a non-existent resource, whose resource
* identifier does not exist at the specified URL.
*/
public void deleteNonExistent();
-
+
}
<?xml version="1.0"?>
<component name="org.collectionspace.collectionobject.coreTypes">
- <extension target="org.nuxeo.ecm.core.schema.TypeService" point="schema">
- <schema name="collectionobject" prefix="collectionobject" src="schemas/collectionobject.xsd"/>
- </extension>
- <extension target="org.nuxeo.ecm.core.schema.TypeService" point="doctype">
- <doctype name="CollectionObject" extends="Document">
- <schema name="common"/>
- <schema name="dublincore"/>
- <schema name="collectionobject"/>
- </doctype>
- </extension>
+ <extension target="org.nuxeo.ecm.core.schema.TypeService" point="schema">
+ <schema name="collectionobjects-common" prefix="collectionobjects-common" src="schemas/collectionobjects-common.xsd"/>
+ <schema name="collectionobjects-naturalhistory" prefix="collectionobjects-naturalhistory" src="schemas/collectionobjects-naturalhistory.xsd"/>
+ </extension>
+ <extension target="org.nuxeo.ecm.core.schema.TypeService" point="doctype">
+ <doctype name="CollectionObject" extends="Document">
+ <schema name="common"/>
+ <schema name="dublincore"/>
+ <schema name="collectionobjects-common"/>
+ <schema name="collectionobjects-naturalhistory"/>
+ </doctype>
+ </extension>
</component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
+<xs:schema \r
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"\r
+ xmlns:ns="http://collectionspace.org/collectionobject/"\r
+ xmlns="http://collectionspace.org/collectionobject/"\r
+ targetNamespace="http://collectionspace.org/collectionobject/"\r
+ version="0.1">\r
+\r
+ <xs:element name="nh-string" type="xs:string" />\r
+ <xs:element name="nh-int" type="xs:int"/>\r
+ <xs:element name="nh-long" type="xs:long"/>\r
+ <xs:element name="nh-date" type="xs:dateTime"/>\r
+ <xs:element name="nh-note" type="xs:string"/>\r
+ \r
+</xs:schema>\r
--- /dev/null
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>org.collectionspace.services.collectionobject</artifactId>
+ <groupId>org.collectionspace.services</groupId>
+ <version>1.0</version>
+ </parent>
+
+ <artifactId>org.collectionspace.services.collectionobject.doctype</artifactId>
+ <packaging>jar</packaging>
+ <name>collectionobject.doctype</name>
+ <description>
+ CollectionObject Nuxeo document type
+ </description>
+ <properties>
+ <nuxeo.version.5.2>5.2-SNAPSHOT</nuxeo.version.5.2>
+ <nuxeo.version.1.5>1.5-SNAPSHOT</nuxeo.version.1.5>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.nuxeo.ecm.core</groupId>
+ <artifactId>nuxeo-core-schema</artifactId>
+ <version>${nuxeo.version.1.5}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.nuxeo.ecm.platform</groupId>
+ <artifactId>nuxeo-platform-types-core</artifactId>
+ <version>${nuxeo.version.5.2}</version>
+ </dependency>
+ </dependencies>
+
+</project>
<dependency>\r
<groupId>org.jboss.resteasy</groupId>\r
<artifactId>resteasy-jaxrs</artifactId>\r
- <version>1.0.2.GA</version>\r
+ <version>1.1.GA</version>\r
<!-- filter out unwanted jars -->\r
<exclusions>\r
<exclusion>\r
<dependency>\r
<groupId>org.jboss.resteasy</groupId>\r
<artifactId>resteasy-jaxb-provider</artifactId>\r
- <version>1.0.2.GA</version>\r
+ <version>1.1.GA</version>\r
</dependency>\r
<dependency>\r
<groupId>org.jboss.resteasy</groupId>\r
<artifactId>resteasy-multipart-provider</artifactId>\r
- <version>1.0.2.GA</version>\r
+ <version>1.1.GA</version>\r
</dependency>\r
<dependency>\r
<groupId>commons-httpclient</groupId>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<collectionobjects-common xmlns="http://collectionspace.org/services/collectionobject" xmlns:collectionobjects-common="http://collectionspace.org/services/collectionobject" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://collectionspace.org/services/collectionobject http://services.collectionspace.org/collectionobject/collectionobjects-common.xsd">\r
+<collectionobjects-common:objectNumber>objectNumber-1252961305700</collectionobjects-common:objectNumber>\r
+<collectionobjects-common:objectName>objectName-1252961305700</collectionobjects-common:objectName>\r
+</collectionobjects-common>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<collectionobjects-common xmlns="http://collectionspace.org/services/collectiono\r
+bject">\r
+<objectNumber>objectNumber-1252960223850</objectNumber>\r
+<objectName>objectName-1252960223850</objectName>\r
+</collectionobjects-common>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
+<ns2:collectionobjects-common xmlns:ns2="http://collectionspace.org/services/collectionobject">\r
+<objectNumber>objectNumber-1252960222412</objectNumber>\r
+<objectName>objectName-1252960222412</objectName>\r
+</ns2:collectionobjects-common>\r
+\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"\r
+ standalone="yes"?><ns2:collectionobjects-common xmlns:ns2="http://collectionspace.org/services/collectionobject"><objectNumber>objectNumber-1252960222412</objectNumber><objectName>objectName-1252960222412</objectName></ns2:collectionobjects-common>\r
+\r
import javax.ws.rs.core.Response;
-import org.collectionspace.services.collectionobject.CollectionObject;
-import org.collectionspace.services.collectionobject.CollectionObjectList;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
import org.jboss.resteasy.client.ProxyFactory;
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
/**
/**
* @return
- * @see org.collectionspace.hello.client.CollectionObjectProxy#getCollectionObject()
+ * @see org.collectionspace.hello.client.CollectionObjectProxy#readList()
*/
- public ClientResponse<CollectionObjectList> readList() {
+ public ClientResponse<CollectionobjectsCommonList> readList() {
return collectionObjectProxy.readList();
+
}
/**
* @return
* @see org.collectionspace.hello.client.CollectionObjectProxy#getCollectionObject(java.lang.String)
*/
- public ClientResponse<CollectionObject> read(String csid) {
+ public ClientResponse<MultipartInput> read(String csid) {
return collectionObjectProxy.read(csid);
}
/**
* @param collectionobject
* @return
- * @see org.collectionspace.hello.client.CollectionObjectProxy#createCollectionObject(org.collectionspace.hello.CollectionObject)
+ * @see org.collectionspace.hello.client.CollectionObjectProxy#create(org.collectionspace.services.collectionobject.CollectionobjectsCommon)
*/
- public ClientResponse<Response> create(CollectionObject collectionObject) {
- return collectionObjectProxy.create(collectionObject);
+ public ClientResponse<Response> create(MultipartOutput multipart) {
+ return collectionObjectProxy.create(multipart);
}
/**
* @param csid
* @param collectionobject
* @return
- * @see org.collectionspace.hello.client.CollectionObjectProxy#updateCollectionObject(java.lang.Long, org.collectionspace.hello.CollectionObject)
+ * @see org.collectionspace.hello.client.CollectionObjectProxy#updateCollectionObject(java.lang.Long, org.collectionspace.services.collectionobject.CollectionobjectsCommon)
*/
- public ClientResponse<CollectionObject> update(String csid, CollectionObject collectionObject) {
- return collectionObjectProxy.update(csid, collectionObject);
+ public ClientResponse<MultipartInput> update(String csid, MultipartOutput multipart) {
+ return collectionObjectProxy.update(csid, multipart);
}
/**
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
-import org.collectionspace.services.collectionobject.CollectionObject;
-import org.collectionspace.services.collectionobject.CollectionObjectList;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
+
/**
* @version $Revision:$
*/
@Path("/collectionobjects/")
-@Produces({"application/xml"})
-@Consumes({"application/xml"})
+@Produces({"multipart/mixed"})
+@Consumes({"multipart/mixed"})
public interface CollectionObjectProxy {
@GET
- ClientResponse<CollectionObjectList> readList();
+ @Produces({"application/xml"})
+ ClientResponse<CollectionobjectsCommonList> readList();
//(C)reate
@POST
- ClientResponse<Response> create(CollectionObject co);
+ ClientResponse<Response> create(MultipartOutput multipart);
//(R)ead
@GET
@Path("/{csid}")
- ClientResponse<CollectionObject> read(@PathParam("csid") String csid);
+ ClientResponse<MultipartInput> read(@PathParam("csid") String csid);
//(U)pdate
@PUT
@Path("/{csid}")
- ClientResponse<CollectionObject> update(@PathParam("csid") String csid, CollectionObject co);
+ ClientResponse<MultipartInput> update(@PathParam("csid") String csid, MultipartOutput multipart);
//(D)elete
@DELETE
@Path("/{csid}")
ClientResponse<Response> delete(@PathParam("csid") String csid);
-}
\ No newline at end of file
+}
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.collectionspace.services.client.test;
import java.util.List;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
import org.collectionspace.services.client.CollectionObjectClient;
-import org.collectionspace.services.client.test.ServiceRequestType;
-import org.collectionspace.services.collectionobject.CollectionObject;
-import org.collectionspace.services.collectionobject.CollectionObjectList;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommon;
+import org.collectionspace.services.collectionobject.domain.naturalhistory.CollectionObjectNaturalhistory;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
+import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
import org.testng.Assert;
import org.testng.annotations.Test;
private CollectionObjectClient client = new CollectionObjectClient();
final String SERVICE_PATH_COMPONENT = "collectionobjects";
private String knownResourceId = null;
-
+
// ---------------------------------------------------------------
// CRUD tests : CREATE tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
@Test
public void create() {
// Submit the request to the service and store the response.
String identifier = createIdentifier();
- CollectionObject collectionObject =
- createCollectionObjectInstance(identifier);
- ClientResponse<Response> res = client.create(collectionObject);
+
+ MultipartOutput multipart = createCollectionObjectInstance(identifier);
+ ClientResponse<Response> res = client.create(multipart);
+
int statusCode = res.getStatus();
// Check the status code of the response: does it match
// Does it exactly match the expected status code?
verbose("create: status = " + statusCode);
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
// Store the ID returned from this create operation
// for additional tests below.
knownResourceId = extractId(res);
+ verbose("create: knownResourceId=" + knownResourceId);
}
@Override
}
// Failure outcomes
-
// Placeholders until the three tests below can be uncommented.
// See Issue CSPACE-401.
public void createWithEmptyEntityBody() {}
// ---------------------------------------------------------------
// CRUD tests : READ tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
@Test(dependsOnMethods = {"create"})
public void read() {
-
+
// Perform setup.
setupRead();
// Submit the request to the service and store the response.
- ClientResponse<CollectionObject> res = client.read(knownResourceId);
+ ClientResponse<MultipartInput> res = client.read(knownResourceId);
int statusCode = res.getStatus();
-
+
// Check the status code of the response: does it match
// the expected response(s)?
verbose("read: status = " + statusCode);
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+ //FIXME: remove the following try catch once Aron fixes signatures
+ try{
+ MultipartInput input = (MultipartInput) res.getEntity();
+ CollectionobjectsCommon collectionObject = (CollectionobjectsCommon) extractPart(input,
+ getCommonPartName(), CollectionobjectsCommon.class);
+ Assert.assertNotNull(collectionObject);
+ }catch(Exception e){
+ throw new RuntimeException(e);
+ }
}
// Failure outcomes
// Perform setup.
setupReadNonExistent();
-
+
// Submit the request to the service and store the response.
- ClientResponse<CollectionObject> res = client.read(NON_EXISTENT_ID);
+ ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
int statusCode = res.getStatus();
// Check the status code of the response: does it match
// the expected response(s)?
verbose("readNonExistent: status = " + res.getStatus());
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
-
// ---------------------------------------------------------------
// CRUD tests : READ_LIST tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
- @Test(dependsOnMethods = {"createList"})
+ @Test(dependsOnMethods = {"createList", "read"})
public void readList() {
-
// Perform setup.
setupReadList();
// Submit the request to the service and store the response.
- ClientResponse<CollectionObjectList> res = client.readList();
- CollectionObjectList list = res.getEntity();
+ ClientResponse<CollectionobjectsCommonList> res = client.readList();
+ CollectionobjectsCommonList list = res.getEntity();
+
int statusCode = res.getStatus();
// Check the status code of the response: does it match
// the expected response(s)?
verbose("readList: status = " + res.getStatus());
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
// Optionally output additional data about list members for debugging.
boolean iterateThroughList = false;
if (iterateThroughList && logger.isDebugEnabled()) {
- List<CollectionObjectList.CollectionObjectListItem> items =
+ List<CollectionobjectsCommonList.CollectionObjectListItem> items =
list.getCollectionObjectListItem();
int i = 0;
- for(CollectionObjectList.CollectionObjectListItem item : items){
+
+ for(CollectionobjectsCommonList.CollectionObjectListItem item : items){
verbose("readList: list-item[" + i + "] csid=" +
item.getCsid());
verbose("readList: list-item[" + i + "] objectNumber=" +
i++;
}
}
-
}
// Failure outcomes
-
// None at present.
-
-
// ---------------------------------------------------------------
// CRUD tests : UPDATE tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
- @Test(dependsOnMethods = {"create"})
+ @Test(dependsOnMethods = {"read"})
public void update() {
-
+
// Perform setup.
setupUpdate();
-
- // Retrieve an existing resource that we can update.
- ClientResponse<CollectionObject> res = client.read(knownResourceId);
- verbose("read: status = " + res.getStatus());
- Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
- CollectionObject collectionObject = res.getEntity();
- verbose("Got object to update with ID: " + knownResourceId,
- collectionObject, CollectionObject.class);
-
- // Update the content of this resource.
- collectionObject.setObjectNumber("updated-" +
- collectionObject.getObjectNumber());
- collectionObject.setObjectName("updated-" +
- collectionObject.getObjectName());
-
- // Submit the request to the service and store the response.
- res = client.update(knownResourceId, collectionObject);
- int statusCode = res.getStatus();
-
- // Check the status code of the response: does it match
- // the expected response(s)?
- verbose("update: status = " + res.getStatus());
- Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
- Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
-
- // Check the contents of the response: does it match
- // what was submitted?
- CollectionObject updatedObject = res.getEntity();
- verbose("update: ", updatedObject, CollectionObject.class);
- Assert.assertEquals(updatedObject.getObjectName(),
- collectionObject.getObjectName(),
- "Data in updated object did not match submitted data.");
+ try{ //ideally, just remove try-catch and let the exception bubble up
+ // Retrieve an existing resource that we can update.
+ ClientResponse<MultipartInput> res =
+ client.read(knownResourceId);
+ verbose("update: read status = " + res.getStatus());
+ Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
+
+ verbose("got object to update with ID: " + knownResourceId);
+ MultipartInput input = (MultipartInput) res.getEntity();
+ CollectionobjectsCommon collectionObject = (CollectionobjectsCommon) extractPart(input,
+ getCommonPartName(), CollectionobjectsCommon.class);
+ Assert.assertNotNull(collectionObject);
+
+ // Update the content of this resource.
+ collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber());
+ collectionObject.setObjectName("updated-" + collectionObject.getObjectName());
+ verbose("updated object", collectionObject, CollectionobjectsCommon.class);
+ // Submit the request to the service and store the response.
+ MultipartOutput output = new MultipartOutput();
+ OutputPart commonPart = output.addPart(collectionObject, MediaType.APPLICATION_XML_TYPE);
+ commonPart.getHeaders().add("label", getCommonPartName());
+
+ res = client.update(knownResourceId, output);
+ int statusCode = res.getStatus();
+ // Check the status code of the response: does it match the expected response(s)?
+ verbose("update: status = " + res.getStatus());
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+
+
+ input = (MultipartInput) res.getEntity();
+ CollectionobjectsCommon updatedCollectionObject =
+ (CollectionobjectsCommon) extractPart(input,
+ getCommonPartName(), CollectionobjectsCommon.class);
+ Assert.assertNotNull(updatedCollectionObject);
+
+ Assert.assertEquals(updatedCollectionObject.getObjectName(),
+ collectionObject.getObjectName(),
+ "Data in updated object did not match submitted data.");
+ }catch(Exception e){
+ e.printStackTrace();
+ }
}
// Failure outcomes
/*
@Override
+
@Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
public void updateWithEmptyEntityBody() {
// Submit the request to the service and store the response.
// Note: The ID used in this 'create' call may be arbitrary.
- // The only relevant ID may be the one used in update(), below.
- CollectionObject collectionObject = createCollectionObjectInstance(NON_EXISTENT_ID);
- ClientResponse<CollectionObject> res =
- client.update(NON_EXISTENT_ID, collectionObject);
+
+ // The only relevant ID may be the one used in updateCollectionObject(), below.
+ MultipartOutput multipart = createCollectionObjectInstance(NON_EXISTENT_ID);
+ ClientResponse<MultipartInput> res =
+ client.update(NON_EXISTENT_ID, multipart);
+
int statusCode = res.getStatus();
// Check the status code of the response: does it match
// the expected response(s)?
verbose("updateNonExistent: status = " + res.getStatus());
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
// ---------------------------------------------------------------
// CRUD tests : DELETE tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
- @Test(dependsOnMethods =
- {"create", "read", "update"})
+ @Test(dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
public void delete() {
// Perform setup.
// the expected response(s)?
verbose("delete: status = " + res.getStatus());
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
// Failure outcomes
-
@Override
@Test(dependsOnMethods = {"delete"})
public void deleteNonExistent() {
// the expected response(s)?
verbose("deleteNonExistent: status = " + res.getStatus());
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
-
// ---------------------------------------------------------------
// Utility tests : tests of code used in tests above
// ---------------------------------------------------------------
-
/**
* Tests the code for manually submitting data that is used by several
* of the methods above.
String method = ServiceRequestType.READ.httpMethodName();
String url = getResourceURL(knownResourceId);
int statusCode = submitRequest(method, url);
-
+
// Check the status code of the response: does it match
// the expected response(s)?
verbose("testSubmitRequest: url=" + url + " status=" + statusCode);
// ---------------------------------------------------------------
// Utility methods used by tests above
// ---------------------------------------------------------------
-
@Override
public String getServicePathComponent() {
// @TODO Determine if it is possible to obtain this
// return this value.
return SERVICE_PATH_COMPONENT;
}
-
- private CollectionObject createCollectionObjectInstance(String identifier) {
- CollectionObject collectionObject =
- createCollectionObjectInstance(
- "objectNumber-" + identifier,
- "objectName-" + identifier);
- return collectionObject;
+
+ private MultipartOutput createCollectionObjectInstance(String identifier) {
+ return createCollectionObjectInstance("objectNumber-" + identifier,
+ "objectName-" + identifier);
}
- private CollectionObject createCollectionObjectInstance(
- String objectNumber, String objectName) {
- CollectionObject collectionObject = new CollectionObject();
+ private MultipartOutput createCollectionObjectInstance(String objectNumber, String objectName) {
+ CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
+
collectionObject.setObjectNumber(objectNumber);
collectionObject.setObjectName(objectName);
- return collectionObject;
+ MultipartOutput multipart = new MultipartOutput();
+ OutputPart commonPart = multipart.addPart(collectionObject, MediaType.APPLICATION_XML_TYPE);
+ commonPart.getHeaders().add("label", getCommonPartName());
+
+ verbose("to be created, collectionobject common ", collectionObject, CollectionobjectsCommon.class);
+
+ CollectionObjectNaturalhistory conh = new CollectionObjectNaturalhistory();
+ conh.setNhString("test-string");
+ conh.setNhInt(999);
+ conh.setNhLong(9999);
+ OutputPart nhPart = multipart.addPart(conh, MediaType.APPLICATION_XML_TYPE);
+ nhPart.getHeaders().add("label", getNHPartName());
+
+ verbose("to be created, collectionobject nhistory", conh, CollectionObjectNaturalhistory.class);
+ return multipart;
+
+ }
+
+ private String getNHPartName() {
+ return "collectionobjects-naturalhistory";
}
-
-
}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<collectionobjects-common xmlns="http://collectionspace.org/services/collectiono\r
+bject" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=\r
+"http://collectionspace.org/services/collectionobject http://services.collection\r
+space.org/collectionobject/collectionobjects-common.xsd">\r
+<objectNumber>objectNumber-1252955075364</objectNumber>\r
+<objectName>objectName-1252955075364</objectName>\r
+</collectionobjects-common>\r
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
- <version>2.1.2</version>
+ <version>2.1.9</version>
</dependency>
</dependencies>
<configuration>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:ns="http://collectionspace.org/collectionobject"
- xmlns="http://collectionspace.org/collectionobject"
- targetNamespace="http://services.collectionspace.org/collectionobject"
+ xmlns:ns="http://collectionspace.org/servics/collectionobject"
+ xmlns="http://collectionspace.org/services/collectionobject"
+ targetNamespace="http://collectionspace.org/services/collectionobject"
version="0.1"
>
<!-- avoid XmlRootElement nightnmare, see http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html-->
-
- <!-- collection-object -->
- <xs:element name="collection-object">
+
+ <!-- collectionobjects-common -->
+ <!-- convention: <servicename>-common -->
+ <xs:element name="collectionobjects-common">
<xs:complexType>
<xs:sequence>
- <xs:element name="csid" type="xs:string" />
- <xs:element name="objectNumber" type="xs:string"/>
- <xs:element name="otherNumber" type="xs:string"/>
- <xs:element name="briefDescription" type="xs:string"/>
- <xs:element name="comments" type="xs:string"/>
- <xs:element name="distFeatures" type="xs:string"/>
- <xs:element name="objectName" type="xs:string"/>
- <xs:element name="responsibleDept" type="xs:string"/>
- <xs:element name="title" type="xs:string"/>
+ <xs:element name="csid" type="xs:string" />
+ <xs:element name="objectNumber" type="xs:string"/>
+ <xs:element name="otherNumber" type="xs:string"/>
+ <xs:element name="briefDescription" type="xs:string"/>
+ <xs:element name="comments" type="xs:string"/>
+ <xs:element name="distFeatures" type="xs:string"/>
+ <xs:element name="objectName" type="xs:string"/>
+ <xs:element name="responsibleDept" type="xs:string"/>
+ <xs:element name="title" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- collection objects as in nuxeo repository -->
- <xs:element name="collection-object-list">
+ <xs:element name="collectionobjects-common-list">
<xs:complexType>
<xs:sequence>
<xs:element name="collection-object-list-item" maxOccurs="unbounded">
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ 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
+
+ Document : collectionobject-naturalhistory.xsd
+ Revision : $LastChangedRevision: $
+ Created on : $LastChangedDate: $
+ Author : $LastChangedBy: $
+ Description:
+-->
+<xs:schema
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:ns="http://collectionspace.org/services/collectionobject/domain/naturalhistory"
+ xmlns="http://collectionspace.org/services/collectionobject/domain/naturalhistory"
+ targetNamespace="http://collectionspace.org/services/collectionobject/domain/naturalhistory"
+ version="0.1"
+>
+ <!-- collection-object for museum of natural history -->
+ <xs:element name="collection-object-naturalhistory">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="nh-string" type="xs:string" />
+ <xs:element name="nh-int" type="xs:int"/>
+ <xs:element name="nh-long" type="xs:long"/>
+ <xs:element name="nh-date" type="xs:dateTime"/>
+ <xs:element name="nh-note" type="xs:string"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+</xs:schema>
+
<dependency>\r
<groupId>org.jboss.resteasy</groupId>\r
<artifactId>resteasy-jaxrs</artifactId>\r
- <version>1.0.2.GA</version>\r
+ <version>1.1.GA</version>\r
<exclusions>\r
<exclusion>\r
<groupId>tjws</groupId>\r
<dependency>\r
<groupId>org.jboss.resteasy</groupId>\r
<artifactId>resteasy-jaxb-provider</artifactId>\r
- <version>1.0.2.GA</version>\r
+ <version>1.1.GA</version>\r
</dependency>\r
<dependency>\r
<groupId>org.jboss.resteasy</groupId>\r
<artifactId>resteasy-multipart-provider</artifactId>\r
- <version>1.0.2.GA</version>\r
+ <version>1.1.GA</version>\r
</dependency>\r
\r
<!-- nuxeo -->\r
+/**
+ * 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;
import javax.ws.rs.Consumes;
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.AbstractCollectionSpaceResource;
+import org.collectionspace.services.common.context.ServiceContext;
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.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
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 {
+@Consumes("multipart/mixed")
+@Produces("multipart/mixed")
+public class CollectionObjectResource
+ extends AbstractCollectionSpaceResource {
- public final static String CO_SERVICE_NAME = "collectionobjects";
+ final private String serviceName = "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
+ @Override
+ public String getServiceName() {
+ return serviceName;
}
- @POST
- public Response createCollectionObject(
- CollectionObject collectionObject) {
+ @Override
+ public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception {
+ DocumentHandler docHandler = CollectionObjectHandlerFactory.getInstance().getHandler(
+ ctx.getRepositoryClientType().toString());
+ docHandler.setServiceContext(ctx);
+ if(ctx.getInput() != null){
+ Object obj = ctx.getInputPart(ctx.getCommonPartLabel(), CollectionobjectsCommon.class);
+ if(obj != null){
+ docHandler.setCommonPart((CollectionobjectsCommon) obj);
+ }
+ }
+ return docHandler;
+ }
- String csid = null;
+ @POST
+ public Response createCollectionObject(MultipartInput input) {
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(collectionObject);
- csid = client.create(CO_SERVICE_NAME, handler);
- collectionObject.setCsid(csid);
- if(logger.isDebugEnabled()){
- verbose("createCollectionObject: ", collectionObject);
- }
+ ServiceContext ctx = createServiceContext(input);
+ DocumentHandler handler = createDocumentHandler(ctx);
+ String csid = getRepositoryClient(ctx).create(ctx, handler);
UriBuilder path = UriBuilder.fromResource(CollectionObjectResource.class);
path.path("" + csid);
Response response = Response.created(path.build()).build();
@GET
@Path("{csid}")
- public CollectionObject getCollectionObject(
+ public MultipartOutput getCollectionObject(
@PathParam("csid") String csid) {
if(logger.isDebugEnabled()){
- verbose("getCollectionObject with csid=" + csid);
+ logger.debug("getCollectionObject with csid=" + csid);
}
if(csid == null || "".equals(csid)){
logger.error("getCollectionObject: missing csid!");
"text/plain").build();
throw new WebApplicationException(response);
}
- CollectionObject collectionObject = null;
+ MultipartOutput result = 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);
- collectionObject = (CollectionObject) handler.getCommonObject();
+ ServiceContext ctx = createServiceContext(null);
+ DocumentHandler handler = createDocumentHandler(ctx);
+ getRepositoryClient(ctx).get(ctx, csid, handler);
+ result = ctx.getOutput();
}catch(DocumentNotFoundException dnfe){
if(logger.isDebugEnabled()){
logger.debug("getCollectionObject", dnfe);
throw new WebApplicationException(response);
}
- if(collectionObject == null){
+ if(result == 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: ", collectionObject);
- }
- return collectionObject;
+ return result;
}
@GET
- public CollectionObjectList getCollectionObjectList(@Context UriInfo ui) {
- CollectionObjectList collectionObjectList = new CollectionObjectList();
+ @Produces("application/xml")
+ public CollectionobjectsCommonList getCollectionObjectList(@Context UriInfo ui) {
+ CollectionobjectsCommonList collectionObjectList = new CollectionobjectsCommonList();
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);
- collectionObjectList = (CollectionObjectList) handler.getCommonObjectList();
+ ServiceContext ctx = createServiceContext(null);
+ DocumentHandler handler = createDocumentHandler(ctx);
+ getRepositoryClient(ctx).getAll(ctx, handler);
+ collectionObjectList = (CollectionobjectsCommonList) handler.getCommonPartList();
}catch(Exception e){
if(logger.isDebugEnabled()){
logger.debug("Caught exception in getCollectionObjectList", e);
@PUT
@Path("{csid}")
- public CollectionObject updateCollectionObject(
+ public MultipartOutput updateCollectionObject(
@PathParam("csid") String csid,
- CollectionObject theUpdate) {
+ MultipartInput theUpdate) {
if(logger.isDebugEnabled()){
- verbose("updateCollectionObject with csid=" + csid);
+ logger.debug("updateCollectionObject with csid=" + csid);
}
if(csid == null || "".equals(csid)){
logger.error("updateCollectionObject: missing csid!");
"text/plain").build();
throw new WebApplicationException(response);
}
- if(logger.isDebugEnabled()){
- verbose("updateCollectionObject with input: ", theUpdate);
- }
+ MultipartOutput result = 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(theUpdate);
- client.update(csid, handler);
+ ServiceContext ctx = createServiceContext(theUpdate);
+ DocumentHandler handler = createDocumentHandler(ctx);
+ getRepositoryClient(ctx).update(ctx, csid, handler);
+ result = ctx.getOutput();
}catch(DocumentNotFoundException dnfe){
if(logger.isDebugEnabled()){
logger.debug("caugth exception in updateCollectionObject", dnfe);
Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
throw new WebApplicationException(response);
}
- return theUpdate;
+ return result;
}
@DELETE
public Response deleteCollectionObject(@PathParam("csid") String csid) {
if(logger.isDebugEnabled()){
- verbose("deleteCollectionObject with csid=" + csid);
+ logger.debug("deleteCollectionObject with csid=" + csid);
}
if(csid == null || "".equals(csid)){
logger.error("deleteCollectionObject: missing csid!");
throw new WebApplicationException(response);
}
try{
- RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
- RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
- client.delete(csid);
+ ServiceContext ctx = createServiceContext(null);
+ getRepositoryClient(ctx).delete(ctx, csid);
return Response.status(HttpResponseCodes.SC_OK).build();
}catch(DocumentNotFoundException dnfe){
if(logger.isDebugEnabled()){
}
}
-
- private void verbose(String msg, CollectionObject collectionObject) {
- try{
- verbose(msg);
- JAXBContext jc = JAXBContext.newInstance(
- CollectionObject.class);
-
- Marshaller m = jc.createMarshaller();
- m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
- m.marshal(collectionObject, System.out);
- }catch(Exception e){
- e.printStackTrace();
- }
-
- }
-
- private void verbose(String msg) {
- System.out.println("CollectionObjectResource. " + msg);
- }
}
+++ /dev/null
-/**\r
- * \r
- */\r
-package org.collectionspace.services.collectionobject;\r
-\r
-import java.io.IOException;\r
-import org.dom4j.Document;\r
-import org.dom4j.DocumentException;\r
-\r
-import org.collectionspace.services.collectionobject.CollectionObject;\r
-\r
-/**\r
- * @author remillet\r
- * \r
- */\r
-public interface CollectionObjectService {\r
-\r
- public final static String CO_SCHEMA_NAME = "collectionobject";\r
-\r
- // Create\r
- Document postCollectionObject(CollectionObject co)\r
- throws DocumentException, IOException;\r
-\r
- // Read single object\r
- Document getCollectionObject(String csid) throws DocumentException,\r
- IOException;\r
-\r
- // Read a list of objects\r
- Document getCollectionObjectList() throws DocumentException, IOException;\r
-\r
- // Update\r
- Document putCollectionObject(String csid, CollectionObject theUpdate)\r
- throws DocumentException, IOException;\r
-\r
- // Delete\r
- Document deleteCollectionObject(String csid) throws DocumentException,\r
- IOException;\r
-}\r
import java.util.Iterator;
import java.util.List;
-import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectConstants;
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.CollectionobjectsCommon;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommonList.CollectionObjectListItem;
import org.collectionspace.services.common.repository.DocumentWrapper;
import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler;
import org.nuxeo.ecm.core.api.DocumentModel;
* $LastChangedDate: $
*/
public class CollectionObjectDocumentModelHandler
- extends DocumentModelHandler<CollectionObject, CollectionObjectList> {
+ extends DocumentModelHandler<CollectionobjectsCommon, CollectionobjectsCommonList> {
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;
+ private CollectionobjectsCommon 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
- }
-
+ private CollectionobjectsCommonList collectionObjectList;
/**
- * getCommonObject get associated CollectionObject
+ * getCommonPart get associated CollectionobjectsCommon
* @return
*/
@Override
- public CollectionObject getCommonObject() {
+ public CollectionobjectsCommon getCommonPart() {
return collectionObject;
}
/**
- * setCommonObject set associated collectionobject
+ * setCommonPart set associated collectionobject
* @param collectionObject
*/
@Override
- public void setCommonObject(CollectionObject collectionObject) {
+ public void setCommonPart(CollectionobjectsCommon collectionObject) {
this.collectionObject = collectionObject;
}
/**
- * getCollectionObjectList get associated CollectionObject (for index/GET_ALL)
+ * getCollectionobjectsCommonList get associated CollectionobjectsCommon (for index/GET_ALL)
* @return
*/
@Override
- public CollectionObjectList getCommonObjectList() {
+ public CollectionobjectsCommonList getCommonPartList() {
return collectionObjectList;
}
@Override
- public void setCommonObjectList(CollectionObjectList collectionObjectList) {
+ public void setCommonPartList(CollectionobjectsCommonList collectionObjectList) {
this.collectionObjectList = collectionObjectList;
}
@Override
- public CollectionObject extractCommonObject(DocumentWrapper wrapDoc)
+ public CollectionobjectsCommon extractCommonPart(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;
+ throw new UnsupportedOperationException();
}
@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.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());
- }
+ public void fillCommonPart(CollectionobjectsCommon co, DocumentWrapper wrapDoc) throws Exception {
+ throw new UnsupportedOperationException();
}
@Override
- public CollectionObjectList extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception {
+ public CollectionobjectsCommonList extractCommonPartList(DocumentWrapper wrapDoc) throws Exception {
DocumentModelList docList = (DocumentModelList) wrapDoc.getWrappedObject();
- CollectionObjectList coList = new CollectionObjectList();
- List<CollectionObjectList.CollectionObjectListItem> list = coList.getCollectionObjectListItem();
+ CollectionobjectsCommonList coList = new CollectionobjectsCommonList();
+ List<CollectionobjectsCommonList.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
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.setObjectNumber((String) docModel.getProperty(getServiceContext().getCommonPartLabel(),
+ CollectionObjectJAXBSchema.OBJECT_NUMBER));
+ coListItem.setUri(getServiceContextPath() + docModel.getId());
coListItem.setCsid(docModel.getId());
list.add(coListItem);
}
}
@Override
- public void fillCommonObjectList(CollectionObjectList obj, DocumentWrapper wrapDoc) throws Exception {
- throw new UnsupportedOperationException();
+ public void fillAllParts(DocumentWrapper wrapDoc) throws Exception {
+
+ super.fillAllParts(wrapDoc);
+ fillDublinCoreObject(wrapDoc); //dublincore might not be needed in future
}
-
+
+ private void fillDublinCoreObject(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.NUXEO_DC_TITLE);
+ }
+
public String getDocumentType() {
- return CollectionObjectConstants.NUXEO_DOCTYPE;
+ return CollectionObjectConstants.NUXEO_DOCTYPE;
}
- /**
- * getQProperty converts the given property to qualified schema property
- * @param prop
- * @return
- */
- private String getQProperty(String prop) {
+ @Override
+ public String getQProperty(String prop) {
return CollectionObjectConstants.NUXEO_SCHEMA_NAME + ":" + prop;
}
}
*/
package org.collectionspace.services.collectionobject.nuxeo;
-import org.collectionspace.services.common.NuxeoClientType;
+import org.collectionspace.services.common.ClientType;
import org.collectionspace.services.common.repository.DocumentHandler;
/**
}
public DocumentHandler getHandler(String clientType) {
- if(NuxeoClientType.JAVA.toString().equals(clientType)){
+ if(ClientType.JAVA.toString().equals(clientType)){
return new CollectionObjectDocumentModelHandler();
- } else if(NuxeoClientType.REST.toString().equals(clientType)) {
+ } else if(ClientType.REST.toString().equals(clientType)) {
return new CollectionObjectRepresenationHandler();
}
throw new IllegalArgumentException("Not supported client=" + clientType);
import java.util.List;
import java.util.Map;
+import java.util.StringTokenizer;
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.CollectionobjectsCommon;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
+import org.collectionspace.services.collectionobject.CollectionobjectsCommonList.CollectionObjectListItem;
import org.collectionspace.services.common.repository.DocumentWrapper;
import org.collectionspace.services.nuxeo.client.rest.RepresentationHandler;
-import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectConstants;
import org.dom4j.Document;
import org.dom4j.Element;
* $LastChangedDate: $
*/
public class CollectionObjectRepresenationHandler
- extends RepresentationHandler<CollectionObject, CollectionObjectList>
+ extends RepresentationHandler<CollectionobjectsCommon, CollectionobjectsCommonList>
{
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;
+ private CollectionobjectsCommon collectionObject;
/**
* collectionObjectList is stashed when handle is called
* for ACTION.GET_ALL
*/
- private CollectionObjectList collectionObjectList;
+ private CollectionobjectsCommonList collectionObjectList;
@Override
public void prepare(Action action) throws Exception {
private void prepare() {
Map<String, String> queryParams = getQueryParams();
- CollectionObject co = getCommonObject();
+ CollectionobjectsCommon co = getCommonPart();
// todo: intelligent merge needed
if(co.getObjectNumber() != null){
queryParams.put(CollectionObjectConstants.NUXEO_SCHEMA_NAME +
}
@Override
- public CollectionObject extractCommonObject(DocumentWrapper wrapDoc)
+ public CollectionobjectsCommon extractCommonPart(DocumentWrapper wrapDoc)
throws Exception {
Document document = (Document) wrapDoc.getWrappedObject();
- CollectionObject co = new CollectionObject();
+ CollectionobjectsCommon co = new CollectionobjectsCommon();
//FIXME property get should be dynamically set using schema inspection
//so it does not require hard coding
}
@Override
- public void fillCommonObject(CollectionObject co, DocumentWrapper wrapDoc)
+ public void fillCommonPart(CollectionobjectsCommon co, DocumentWrapper wrapDoc)
throws Exception {
//Nuxeo REST takes create/update through queryParams, nothing to do here
}
@Override
- public CollectionObjectList extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception {
+ public CollectionobjectsCommonList extractCommonPartList(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();
+ CollectionobjectsCommonList coList = new CollectionobjectsCommonList();
+ List<CollectionobjectsCommonList.CollectionObjectListItem> list = coList.getCollectionObjectListItem();
Element root = document.getRootElement();
for(Iterator i = root.elementIterator(); i.hasNext();){
return coList;
}
- @Override
- public void fillCommonObjectList(CollectionObjectList obj, DocumentWrapper wrapDoc)
- throws Exception {
- throw new UnsupportedOperationException();
- }
@Override
- public CollectionObject getCommonObject() {
+ public CollectionobjectsCommon getCommonPart() {
return collectionObject;
}
@Override
- public void setCommonObject(CollectionObject obj) {
+ public void setCommonPart(CollectionobjectsCommon obj) {
this.collectionObject = obj;
}
@Override
- public CollectionObjectList getCommonObjectList() {
+ public CollectionobjectsCommonList getCommonPartList() {
return collectionObjectList;
}
@Override
- public void setCommonObjectList(CollectionObjectList obj) {
+ public void setCommonPartList(CollectionobjectsCommonList obj) {
this.collectionObjectList = obj;
}
return CollectionObjectConstants.NUXEO_DOCTYPE;
}
- /**
- * getQProperty converts the given property to qualified schema property
- * @param prop
- * @return
- */
- private String getQProperty(String prop) {
+
+ @Override
+ public String getQProperty(String prop) {
return CollectionObjectConstants.NUXEO_SCHEMA_NAME + ":" + prop;
}
+
}
+++ /dev/null
-/**\r
- * \r
- */\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.Arrays;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-\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.util.NuxeoUtils;\r
-\r
-import org.dom4j.Document;\r
-import org.dom4j.DocumentException;\r
-import org.dom4j.io.SAXReader;\r
-import org.restlet.resource.Representation;\r
-\r
-import org.nuxeo.ecm.core.api.IdRef;\r
-import org.nuxeo.ecm.core.api.repository.RepositoryInstance;\r
-import org.nuxeo.ecm.core.api.DocumentModel;\r
-import org.nuxeo.ecm.core.api.DocumentRef;\r
-\r
-\r
-\r
-/**\r
- * @author remillet\r
- * \r
- */\r
-public class CollectionObjectServiceNuxeoImpl extends\r
- CollectionSpaceServiceNuxeoImpl implements CollectionObjectService {\r
-\r
- final static String CO_NUXEO_DOCTYPE = "CollectionObject";\r
- final static String CO_NUXEO_SCHEMA_NAME = "collectionobject";\r
- final static String CO_NUXEO_DC_TITLE = "CollectionSpace-CollectionObject";\r
-\r
- // replace WORKSPACE_UID for resource workspace\r
- static String CS_COLLECTIONOBJECT_WORKSPACE_UID = "9dd20955-fce7-4a87-8319-040ab9543f4f";\r
-\r
- public Document deleteCollectionObject(String csid)\r
- throws DocumentException, IOException {\r
-\r
- Document result = null;\r
- \r
-// NuxeoRESTClient nxClient = getClient();\r
-// List<String> pathParams = new ArrayList<String>();\r
-// Map<String, String> queryParams = new HashMap<String, String>();\r
-//\r
-// pathParams.add("default");\r
-// pathParams.add(csid);\r
-// pathParams.add("deleteDocumentRestlet");\r
-// Representation res = nxClient.get(pathParams, queryParams);\r
-// SAXReader reader = new SAXReader();\r
-// result = reader.read(res.getStream());\r
- \r
- return result;\r
- }\r
-\r
- public Document getCollectionObject(String csid) throws DocumentException,\r
- IOException {\r
- \r
- // Calling via Nuxeo Java API\r
- //getCollectionObjectViaJavaAPI(csid);\r
- \r
- // Return to normal Nuxeo REST call\r
- Document result = null;\r
-// \r
-// List<String> pathParams = new ArrayList<String>();\r
-// Map<String, String> queryParams = new HashMap<String, String>();\r
-//\r
-// pathParams.add("default");\r
-// pathParams.add(csid);\r
-// pathParams.add("export");\r
-// queryParams.put("format", "XML");\r
-//\r
-// NuxeoRESTClient nxClient = getClient();\r
-// Representation res = nxClient.get(pathParams, queryParams);\r
-//\r
-// SAXReader reader = new SAXReader();\r
-// result = reader.read(res.getStream());\r
-\r
- return result;\r
- }\r
- \r
- \r
- public Document getCollectionObjectList() throws DocumentException,\r
- IOException {\r
- Document result = null;\r
-\r
-// NuxeoRESTClient nxClient = getClient();\r
-// List<String> pathParams = new ArrayList<String>();\r
-// Map<String, String> queryParams = new HashMap<String, String>();\r
-// pathParams = Arrays.asList("default",\r
-// CS_COLLECTIONOBJECT_WORKSPACE_UID, "browse");\r
-// Representation res = nxClient.get(pathParams, queryParams);\r
-// SAXReader reader = new SAXReader();\r
-// result = reader.read(res.getStream());\r
-\r
- return result;\r
- }\r
-\r
- public Document postCollectionObject(CollectionObject co)\r
- throws DocumentException, IOException {\r
- Document result = null;\r
- \r
-// NuxeoRESTClient nxClient = getClient();\r
-//\r
-// List<String> pathParams = new ArrayList<String>();\r
-// Map<String, String> queryParams = new HashMap<String, String>();\r
-// pathParams.add("default");\r
-// pathParams.add(CS_COLLECTIONOBJECT_WORKSPACE_UID);\r
-// pathParams.add("createDocument");\r
-// queryParams.put("docType", CO_NUXEO_DOCTYPE);\r
-//\r
-// // a default title for the Dublin Core schema\r
-// queryParams.put("dublincore:title", CO_NUXEO_DC_TITLE);\r
-//\r
-// // CollectionObject core values\r
-// queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-// + CollectionObjectJAXBSchema.OBJECT_NUMBER, co\r
-// .getObjectNumber());\r
-// queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-// + CollectionObjectJAXBSchema.OTHER_NUMBER, co.getOtherNumber());\r
-// queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-// + CollectionObjectJAXBSchema.BRIEF_DESCRIPTION, co\r
-// .getBriefDescription());\r
-// queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-// + CollectionObjectJAXBSchema.COMMENTS, co.getComments());\r
-// queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-// + CollectionObjectJAXBSchema.DIST_FEATURES, co\r
-// .getDistFeatures());\r
-// queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-// + CollectionObjectJAXBSchema.OBJECT_NAME, co.getObjectName());\r
-// queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-// + CollectionObjectJAXBSchema.RESPONSIBLE_DEPT, co\r
-// .getResponsibleDept());\r
-// queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-// + CollectionObjectJAXBSchema.TITLE, co.getTitle());\r
-//\r
-// ByteArrayInputStream bais = new ByteArrayInputStream(new byte[0]);\r
-// Representation res = nxClient.post(pathParams, queryParams, bais);\r
-//\r
-// SAXReader reader = new SAXReader();\r
-// result = reader.read(res.getStream());\r
-\r
- return result;\r
- }\r
-\r
- public Document putCollectionObject(String csid, CollectionObject theUpdate)\r
- throws DocumentException, IOException {\r
- \r
- Document result = null;\r
- \r
-// List<String> pathParams = new ArrayList<String>();\r
-// Map<String, String> queryParams = new HashMap<String, String>();\r
-// pathParams.add("default");\r
-// pathParams.add(csid);\r
-// pathParams.add("updateDocumentRestlet");\r
-//\r
-// // todo: intelligent merge needed\r
-// if (theUpdate.getObjectNumber() != null) {\r
-// queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-// + CollectionObjectJAXBSchema.OBJECT_NUMBER, theUpdate\r
-// .getObjectNumber());\r
-// }\r
-//\r
-// if (theUpdate.getOtherNumber() != null) {\r
-// queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-// + CollectionObjectJAXBSchema.OTHER_NUMBER, theUpdate\r
-// .getOtherNumber());\r
-// }\r
-//\r
-// if (theUpdate.getBriefDescription() != null) {\r
-// queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-// + CollectionObjectJAXBSchema.BRIEF_DESCRIPTION, theUpdate\r
-// .getBriefDescription());\r
-// }\r
-//\r
-// if (theUpdate.getComments() != null) {\r
-// queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-// + CollectionObjectJAXBSchema.COMMENTS, theUpdate\r
-// .getComments());\r
-// }\r
-//\r
-// if (theUpdate.getDistFeatures() != null) {\r
-// queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-// + CollectionObjectJAXBSchema.DIST_FEATURES, theUpdate\r
-// .getDistFeatures());\r
-// }\r
-//\r
-// if (theUpdate.getObjectName() != null) {\r
-// queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-// + CollectionObjectJAXBSchema.OBJECT_NAME, theUpdate\r
-// .getObjectName());\r
-// }\r
-//\r
-// if (theUpdate.getResponsibleDept() != null) {\r
-// queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-// + CollectionObjectJAXBSchema.RESPONSIBLE_DEPT, theUpdate\r
-// .getResponsibleDept());\r
-// }\r
-//\r
-// if (theUpdate.getTitle() != null) {\r
-// queryParams.put(CO_NUXEO_SCHEMA_NAME + ":"\r
-// + CollectionObjectJAXBSchema.TITLE, theUpdate.getTitle());\r
-// }\r
-//\r
-// NuxeoRESTClient nxClient = getClient();\r
-// Representation res = nxClient.get(pathParams, queryParams);\r
-// SAXReader reader = new SAXReader();\r
-// result = reader.read(res.getStream());\r
-\r
- return result;\r
- }\r
-\r
-}\r
<target name="deploy" depends="package"
description="deploy common elements in ${jboss.server.cspace}">
- <copy file="${basedir}/src/main/config/service-config.xml"
- todir="${jboss.server.cspace}/cspace/config/services"/>
+ <copy todir="${jboss.server.cspace}/cspace/config/services">
+ <fileset dir="${basedir}/src/main/config"/>
+ </copy>
</target>
<target name="undeploy"
description="undeploy common elements from ${jboss.server.cspace}">
- <delete failonerror="false" file="${jboss.server.cspace}/cspace/config/services/service-config.xml"/>
+ <delete failonerror="false" dir="${jboss.server.cspace}/cspace/config/services"/>
</target>
<target name="dist"
description="generate distribution for common elements" depends="package">
<copy todir="${services.trunk}/${dist.server.cspace}/cspace/config/services">
- <fileset file="${basedir}/src/main/config/service-config.xml"/>
+ <fileset dir="${basedir}/src/main/config"/>
</copy>
</target>
<name>services.common</name>\r
\r
<dependencies>\r
+ <dependency>\r
+ <groupId>com.sun.xml.bind</groupId>\r
+ <artifactId>jaxb-impl</artifactId>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.jvnet.jaxb2-commons</groupId>\r
+ <artifactId>property-listener-injector</artifactId>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.jvnet.jaxb2_commons</groupId>\r
+ <artifactId>runtime</artifactId>\r
+ </dependency>\r
<dependency>\r
<groupId>org.jboss.resteasy</groupId>\r
<artifactId>resteasy-jaxrs</artifactId>\r
- <version>1.0.2.GA</version>\r
<exclusions>\r
<exclusion>\r
<groupId>tjws</groupId>\r
<dependency>\r
<groupId>org.jboss.resteasy</groupId>\r
<artifactId>resteasy-jaxb-provider</artifactId>\r
- <version>1.0.2.GA</version>\r
+ <version>1.1.GA</version>\r
</dependency>\r
<dependency>\r
<groupId>org.jboss.resteasy</groupId>\r
<artifactId>resteasy-multipart-provider</artifactId>\r
- <version>1.0.2.GA</version>\r
+ <version>1.1.GA</version>\r
</dependency>\r
\r
<!-- utilities -->\r
</dependency>\r
<!-- javax -->\r
\r
-\r
+ <dependency>\r
+ <groupId>javax.servlet</groupId>\r
+ <artifactId>servlet-api</artifactId>\r
+ <version>2.5</version>\r
+ <scope>provided</scope>\r
+ </dependency>\r
+ \r
<dependency>\r
<groupId>javax.security</groupId>\r
<artifactId>jaas</artifactId>\r
<version>1.1.1</version>\r
</dependency>\r
\r
- <dependency>\r
- <groupId>com.sun.xml.bind</groupId>\r
- <artifactId>jaxb-impl</artifactId>\r
- <version>2.0.2</version>\r
- </dependency>\r
- <dependency>\r
- <groupId>org.jvnet.jaxb2-commons</groupId>\r
- <artifactId>property-listener-injector</artifactId>\r
- <version>1.0</version>\r
- </dependency>\r
- <dependency>\r
- <groupId>org.jvnet.jaxb2_commons</groupId>\r
- <artifactId>runtime</artifactId>\r
- <version>0.4.1.4</version>\r
- </dependency>\r
+\r
</dependencies>\r
\r
<build>\r
</goals>\r
</execution>\r
</executions>\r
- <dependencies>\r
- <!-- javax.activation.DataSource provider is required by spec -->\r
- <dependency>\r
- <groupId>javax.activation</groupId>\r
- <artifactId>activation</artifactId>\r
- <version>1.1</version>\r
- </dependency>\r
- <dependency>\r
- <groupId>com.sun.xml.bind</groupId>\r
- <artifactId>jaxb-impl</artifactId>\r
- <version>2.1.2</version>\r
- </dependency>\r
- </dependencies>\r
+\r
<configuration>\r
<args>\r
<arg>-XtoString</arg>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<profilesXml xmlns="http://maven.apache.org/PROFILES/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/PROFILES/1.0.0 http://maven.apache.org/xsd/profiles-1.0.0.xsd">
+</profilesXml>
\ No newline at end of file
<ns1:service-config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:ns1='http://collectionspace.org/services/common'
xsi:schemaLocation='http://collectionspace.org/services/common ../resources/common.xsd'>
- <nuxeo-client-config>
+
+ <!-- name of the repository client is referred in each service binding -->
+ <repository-client name="nuxeo-java" default="true">
<!-- ip of network interface to which Nuxeo server is listening on -->
<host>127.0.0.1</host>
<port>62474</port> <!-- java -->
<!--port>8080</port--> <!-- rest -->
- <client-type>java</client-type>
<user>Administrator</user>
<password>Administrator</password>
- </nuxeo-client-config>
- <nuxeo-workspace>
- <workspace>
+ <client-type>java</client-type>
+ <client-class>org.collectionspace.services.nuxeo.client.java.RepositoryJavaClient</client-class>
+ </repository-client>
+
+ <!-- TODO: remove once all the services start using service bindings -->
+ <repository-workspace>
+ <!--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>
<workspace>
<service-name>intakes</service-name>
<workspace-name>Intakes</workspace-name>
- <!-- use hard-coded workspace id for REST client -->
- <!--workspace-id></workspace-id-->
</workspace>
<workspace>
<service-name>relations</service-name>
<workspace-name>Relations</workspace-name>
- </workspace>
+ </workspace>
<workspace>
<service-name>acquisitions</service-name>
<workspace-name>Acquisitions</workspace-name>
- </workspace>
- </nuxeo-workspace>
+ </workspace>
+ </repository-workspace>
</ns1:service-config>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Document : tenants-bindings.xml
+ Created on : August 31, 2009, 10:52 AM
+ Author :
+ Description:
+ tenant bindings
+-->
+<tenant:TenantBindingConfig xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns:tenant='http://collectionspace.org/services/common/tenant'
+ xsi:schemaLocation='http://collectionspace.org/services/common/tenant http://collectionspace.org/services/common/tenant.xsd'
+ >
+ <!-- begin movinimages.us tenant meta-data -->
+ <tenant:tenantBinding
+ id="1" name="movingimages.us" displayName="Museum of Moving Images" version="0.1" repositoryDomain="default-domain">
+ <tenant:serviceBindings name="CollectionObjects" version="0.1">
+ <!-- begin collectionobject service meta-data -->
+ <service:repositoryClient xmlns:service='http://collectionspace.org/services/common/service'>nuxeo-java</service:repositoryClient>
+ <service:object id="1" name="CollectionObject" version="0.1"
+ xmlns:service='http://collectionspace.org/services/common/service'>
+ <service:part id="0" control_group="Managed"
+ versionable="true" auditable="false"
+ label="collectionobjects-system" updated="" order="0">
+ <service:content contentType="application/xml">
+ <service:xmlContent
+ namespaceURI="http://collectionspace.org/services/common/system"
+ schemaLocation="http://collectionspace.org/services/common/system http://collectionspace.org/services/common/system/system-response.xsd">
+ </service:xmlContent>
+ </service:content>
+ </service:part>
+ <service:part id="1" control_group="Managed"
+ versionable="true" auditable="false"
+ label="collectionobjects-common" updated="" order="1">
+ <service:content contentType="application/xml">
+ <service:xmlContent
+ namespaceURI="http://collectionspace.org/services/collectionobject"
+ schemaLocation="http://collectionspace.org/services/collectionobject http://services.collectionspace.org/collectionobject/collectionobjects-common.xsd">
+ </service:xmlContent>
+ </service:content>
+ </service:part>
+ <service:part id="2" control_group="Managed"
+ versionable="true" auditable="false"
+ label="collectionobjects-naturalhistory" updated="" order="2">
+ <service:content contentType="application/xml">
+ <service:xmlContent
+ namespaceURI="http://collectionspace.org/services/collectionobject/domain/naturalhistory"
+ schemaLocation="http://collectionspace.org/services/collectionobject/domain/naturalhistory http://collectionspace.org/services/collectionobject/domain/collectionobjects-naturalhistory.xsd">
+ </service:xmlContent>
+ </service:content>
+ </service:part>
+ </service:object>
+ </tenant:serviceBindings>
+ <!--end collectionobject service meta-data -->
+ <!-- begin intake service meta-data -->
+ <tenant:serviceBindings name="Intakes" version="0.1">
+ <service:repositoryClient xmlns:service='http://collectionspace.org/services/common/service'>nuxeo-java</service:repositoryClient>
+ <service:object id="2" name="Intake" version="0.1"
+ xmlns:service='http://collectionspace.org/services/common/service'>
+ <service:part id="0" control_group="Managed"
+ versionable="true" auditable="false"
+ label="intakes-system" updated="" order="0">
+ <service:content contentType="application/xml">
+ <service:xmlContent
+ namespaceURI="http://collectionspace.org/services/common/system"
+ schemaLocation="http://collectionspace.org/services/common/system http://collectionspace.org/services/common/system/system-response.xsd">
+ </service:xmlContent>
+ </service:content>
+ </service:part>
+ <service:part id="1" control_group="Managed"
+ versionable="true" auditable="false"
+ label="intakes-common" updated="" order="1">
+ <service:content contentType="application/xml">
+ <service:xmlContent
+ namespaceURI="http://collectionspace.org/services/intake"
+ schemaLocation="http://collectionspace.org/services/intake http://services.collectionspace.org/intake/intakes-common.xsd">
+ </service:xmlContent>
+ </service:content>
+ </service:part>
+ </service:object>
+ </tenant:serviceBindings>
+ <!-- end intake service meta-data -->
+ <!-- begin acquisition service meta-data -->
+ <tenant:serviceBindings name="Acquisitions" version="0.1">
+ <service:repositoryClient xmlns:service='http://collectionspace.org/services/common/service'>nuxeo-java</service:repositoryClient>
+ <service:object id="2" name="Acquisition" version="0.1"
+ xmlns:service='http://collectionspace.org/services/common/service'>
+ <service:part id="0" control_group="Managed"
+ versionable="true" auditable="false"
+ label="acquisitions-system" updated="" order="0">
+ <service:content contentType="application/xml">
+ <service:xmlContent
+ namespaceURI="http://collectionspace.org/services/common/system"
+ schemaLocation="http://collectionspace.org/services/common/system http://collectionspace.org/services/common/system/system-response.xsd">
+ </service:xmlContent>
+ </service:content>
+ </service:part>
+ <service:part id="1" control_group="Managed"
+ versionable="true" auditable="false"
+ label="acquisitions-common" updated="" order="1">
+ <service:content contentType="application/xml">
+ <service:xmlContent
+ namespaceURI="http://collectionspace.org/services/acquisition"
+ schemaLocation="http://collectionspace.org/services/acquisition http://services.collectionspace.org/acquisition/acquisitions-common.xsd">
+ </service:xmlContent>
+ </service:content>
+ </service:part>
+ </service:object>
+ </tenant:serviceBindings>
+ <!-- end acquisition service meta-data -->
+ </tenant:tenantBinding>
+ <!-- end movinimages.us tenant meta-data -->
+</tenant:TenantBindingConfig>
--- /dev/null
+/**\r
+ * This document is a part of the source code and related artifacts\r
+ * for CollectionSpace, an open source collections management system\r
+ * for museums and related institutions:\r
+\r
+ * http://www.collectionspace.org\r
+ * http://wiki.collectionspace.org\r
+\r
+ * Copyright 2009 University of California at Berkeley\r
+\r
+ * Licensed under the Educational Community License (ECL), Version 2.0.\r
+ * You may not use this file except in compliance with this License.\r
+\r
+ * You may obtain a copy of the ECL 2.0 License at\r
+\r
+ * https://source.collectionspace.org/collection-space/LICENSE.txt\r
+\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.collectionspace.services.common;\r
+\r
+import org.collectionspace.services.common.context.ServiceContext;\r
+import org.collectionspace.services.common.context.ServiceContextImpl;\r
+import org.collectionspace.services.common.repository.DocumentHandler;\r
+import org.collectionspace.services.common.repository.RepositoryClient;\r
+import org.collectionspace.services.common.repository.RepositoryClientFactory;\r
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;\r
+\r
+public abstract class AbstractCollectionSpaceResource\r
+ implements CollectionSpaceResource {\r
+\r
+ // Fields for default client factory and client\r
+ private RepositoryClientFactory repositoryClientFactory;\r
+ private RepositoryClient repositoryClient;\r
+\r
+ public AbstractCollectionSpaceResource() {\r
+ repositoryClientFactory = RepositoryClientFactory.getInstance();\r
+ }\r
+\r
+ @Override\r
+ abstract public String getServiceName();\r
+\r
+ @Override\r
+ public RepositoryClientFactory getRepositoryClientFactory() {\r
+ return repositoryClientFactory;\r
+ }\r
+\r
+ @Override\r
+ synchronized public RepositoryClient getRepositoryClient(ServiceContext ctx) {\r
+ if(repositoryClient != null){\r
+ return repositoryClient;\r
+ }\r
+ repositoryClient = repositoryClientFactory.getClient(ctx.getRepositoryClientName());\r
+ return repositoryClient;\r
+ }\r
+\r
+ @Override\r
+ public ServiceContext createServiceContext(MultipartInput input) throws Exception {\r
+ ServiceContext ctx = new ServiceContextImpl(getServiceName());\r
+ ctx.setInput(input);\r
+ return ctx;\r
+ }\r
+\r
+ @Override\r
+ abstract public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception ;\r
+}\r
+/**\r
+ * This document is a part of the source code and related artifacts\r
+ * for CollectionSpace, an open source collections management system\r
+ * for museums and related institutions:\r
+\r
+ * http://www.collectionspace.org\r
+ * http://wiki.collectionspace.org\r
+\r
+ * Copyright 2009 University of California at Berkeley\r
+\r
+ * Licensed under the Educational Community License (ECL), Version 2.0.\r
+ * You may not use this file except in compliance with this License.\r
+\r
+ * You may obtain a copy of the ECL 2.0 License at\r
+\r
+ * https://source.collectionspace.org/collection-space/LICENSE.txt\r
+\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
package org.collectionspace.services.common;\r
\r
import org.collectionspace.services.common.repository.DocumentHandler;\r
-import org.collectionspace.services.common.NuxeoClientType;\r
\r
public interface CollectionSpaceHandlerFactory {\r
+ /**\r
+ * getHandler gets or creates a document handler per given client type\r
+ * @param clientType (java|rest)\r
+ * @return\r
+ * @throws IllegalArgumentException\r
+ */\r
public DocumentHandler getHandler(String clientType) throws IllegalArgumentException;\r
}\r
-package org.collectionspace.services.common;\r
-\r
-import org.collectionspace.services.common.repository.DocumentHandler;\r
-import org.collectionspace.services.common.repository.RepositoryClient;\r
-import org.collectionspace.services.common.repository.RepositoryClientFactory;\r
-import org.collectionspace.services.common.CollectionSpaceHandlerFactory;\r
-//import org.collectionspace.services.relation.nuxeo.RelationHandlerFactory;\r
-\r
-public abstract class CollectionSpaceResource {\r
-\r
- // Fields for default client factory and client\r
- private RepositoryClientFactory defaultClientFactory;\r
- private RepositoryClient defaultClient;\r
- \r
- // Fields for default document handler factory and handler\r
- private CollectionSpaceHandlerFactory defaultHandlerFactory;\r
- private DocumentHandler defaultHandler;\r
- \r
- // Methods that subclasses must implement\r
- abstract protected String getClientType();\r
- abstract protected RepositoryClientFactory getDefaultClientFactory();\r
- abstract protected CollectionSpaceHandlerFactory getDefaultHandlerFactory();\r
- \r
- protected RepositoryClient getDefaultClient() {\r
- return this.defaultClient;\r
- }\r
- \r
- protected DocumentHandler getDefaultHandler() {\r
- return this.defaultHandler;\r
- }\r
- \r
- public CollectionSpaceResource() {\r
- defaultClientFactory = getDefaultClientFactory(); //implemented by subclasses\r
- defaultClient = defaultClientFactory.getClient(getClientType());\r
- defaultHandlerFactory = getDefaultHandlerFactory(); //implemented by subclasses\r
- defaultHandler = defaultHandlerFactory.getHandler(getClientType());\r
- } \r
-}\r
+/**
+ * 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;
+
+import org.collectionspace.services.common.context.ServiceContext;
+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.plugins.providers.multipart.MultipartInput;
+
+/**
+ * CollectionSpaceResource is a resource interface implemented by every
+ * entity/service in CollectionSpace
+ */
+public interface CollectionSpaceResource {
+
+ /**
+ * getServiceName returns the name of the service
+ */
+ public String getServiceName();
+
+ /**
+ * getRepositoryClientFactory
+ * @return
+ */
+ public RepositoryClientFactory getRepositoryClientFactory();
+
+ /**
+ * getRepositoryClient
+ * @param ctx service context
+ */
+ public RepositoryClient getRepositoryClient(ServiceContext ctx);
+
+ /**
+ * createServiceContext is a facotry method to create a service context
+ * a service contex is created on every service request call
+ * @param input
+ * @return
+ */
+ public ServiceContext createServiceContext(MultipartInput input) throws Exception;
+
+ /**
+ * createDocumentHandler creates a document handler and populates it with given
+ * service context. document handler should never be used
+ * across service invocations. it is a stateful object that holds request,
+ * response and service context
+ * @param ctx
+ * @return
+ */
+ public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception ;
+}
import javax.servlet.ServletContextListener;
/**
- * ServiceContextListener is a ServletContextListener that helps initialize
+ * CollectionSpaceServiceContextListener is a ServletContextListener that helps initialize
* the services layer at deployment and undeployment times
*/
-public class ServiceContextListener implements ServletContextListener {
+public class CollectionSpaceServiceContextListener implements ServletContextListener {
+ @Override
public void contextInitialized(ServletContextEvent event) {
try{
- ServletContext sc = event.getServletContext();
- ServiceMain svcMain = ServiceMain.getInstance(); //first access initializes as well
- svcMain.getWorkspaceIds();
- }catch(Exception e) {
+ ServletContext sc = event.getServletContext();
+ ServiceMain svcMain = ServiceMain.getInstance(); //first access initializes as well
+ svcMain.retrieveAllWorkspaceIds();
+ }catch(Exception e){
e.printStackTrace();
//fail here
throw new RuntimeException(e);
}
}
+ @Override
public void contextDestroyed(ServletContextEvent event) {
ServiceMain.getInstance().release();
}
*/
package org.collectionspace.services.common;
-import java.io.File;
import java.util.Hashtable;
-import java.util.List;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.Unmarshaller;
-import org.collectionspace.services.common.ServiceConfig.NuxeoWorkspace;
-import org.collectionspace.services.common.ServiceConfig.NuxeoWorkspace.Workspace;
+import org.collectionspace.services.common.config.ServicesConfigReader;
+import org.collectionspace.services.common.config.TenantBindingConfigReader;
import org.collectionspace.services.nuxeo.client.java.NuxeoConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
*/
public class ServiceMain {
+ /**
+ * volatile is used here to assume about ordering (post JDK 1.5)
+ */
private static volatile ServiceMain instance = null;
- final public static String CSPACE_DIR_NAME = "cspace";
- final public static String CONFIG_DIR_NAME = "config" + File.separator + "services";
- final private static String CONFIG_FILE_NAME = "service-config.xml";
final Logger logger = LoggerFactory.getLogger(ServiceMain.class);
- private ServiceConfig serviceConfig;
- private Hashtable<String, String> serviceWorkspaces = new Hashtable<String, String>();
private NuxeoConnector nuxeoConnector;
private String serverRootDir = null;
- private NuxeoClientType nuxeoClientType = null;
+ private ServicesConfigReader servicesConfigReader;
+ private TenantBindingConfigReader tenantBindingConfigReader;
private ServiceMain() {
}
private void initialize() throws Exception {
setServerRootDir();
- serviceConfig = readConfig();
- if(getNuxeoClientType().equals(NuxeoClientType.JAVA)){
+ readConfig();
+ if(getClientType().equals(ClientType.JAVA)){
nuxeoConnector = NuxeoConnector.getInstance();
- nuxeoConnector.initialize(serviceConfig.getNuxeoClientConfig());
+ nuxeoConnector.initialize(
+ getServicesConfigReader().getConfiguration().getRepositoryClient());
}
}
if(nuxeoConnector != null){
nuxeoConnector.release();
}
- serviceWorkspaces.clear();
instance = null;
}catch(Exception e){
e.printStackTrace();
}
}
- private ServiceConfig readConfig() throws Exception {
- JAXBContext jc = JAXBContext.newInstance(ServiceConfig.class);
- Unmarshaller um = jc.createUnmarshaller();
- String configFileName = getServerRootDir() +
- File.separator + CSPACE_DIR_NAME +
- File.separator + CONFIG_DIR_NAME +
- File.separator + CONFIG_FILE_NAME;
- File configFile = new File(configFileName);
- if(!configFile.exists()){
- String msg = "Could not find configuration file " + configFileName;
- logger.error(msg);
- throw new RuntimeException(msg);
- }
- ServiceConfig sconfig = (ServiceConfig) um.unmarshal(configFile);
- 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 = new Hashtable<String, String>();
+ private void readConfig() throws Exception {
+ //read service config
+ servicesConfigReader = new ServicesConfigReader(getServerRootDir());
+ getServicesConfigReader().read();
- if(getNuxeoClientType().equals(NuxeoClientType.JAVA)){
- workspaceIds = nuxeoConnector.retrieveWorkspaceIds();
- }
- NuxeoWorkspace nuxeoWorkspace = serviceConfig.getNuxeoWorkspace();
- List<Workspace> workspaces = nuxeoWorkspace.getWorkspace();
- String workspaceId = null;
- for(Workspace workspace : workspaces){
- 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;
- }
- }
+ tenantBindingConfigReader = new TenantBindingConfigReader(getServerRootDir());
+ getTenantBindingConfigReader().read();
+ }
- serviceWorkspaces.put(workspace.getServiceName(), workspaceId);
- if(logger.isDebugEnabled()){
- logger.debug("retrieved workspace id=" + workspaceId +
- " service=" + workspace.getServiceName() +
- " workspace=" + workspace.getWorkspaceName());
- }
- }
+ void retrieveAllWorkspaceIds() throws Exception {
+ //all configs are read, connector is initialized, retrieve workspaceids
+ getTenantBindingConfigReader().retrieveAllWorkspaceIds();
}
/**
- * @return the serviceConfig
+ * retrieveWorkspaceIds for given tenant domain.
+ * @param tenantDomain
+ * @return Hashtable<String, String> key=workspace name, value=workspace id
+ * @throws Exception
*/
- public ServiceConfig getServiceConfig() {
- return serviceConfig;
- }
-
- synchronized public String getWorkspaceId(String serviceName) {
- return serviceWorkspaces.get(serviceName);
+ public Hashtable<String, String> retrieveWorkspaceIds(String tenantDomain) throws Exception {
+ return nuxeoConnector.retrieveWorkspaceIds(tenantDomain);
}
/**
}
/**
- * @return the nuxeoClientType
+ * @return the serviceConfig
+ */
+ public ServiceConfig getServiceConfig() {
+ return getServicesConfigReader().getConfiguration();
+ }
+
+ /**
+ * @return the clientType
+ */
+ public ClientType getClientType() {
+ return getServicesConfigReader().getClientType();
+ }
+
+ /**
+ * @return the servicesConfigReader
+ */
+ public ServicesConfigReader getServicesConfigReader() {
+ return servicesConfigReader;
+ }
+
+ /**
+ * @return the tenantBindingConfigReader
*/
- public NuxeoClientType getNuxeoClientType() {
- return nuxeoClientType;
+ public TenantBindingConfigReader getTenantBindingConfigReader() {
+ return tenantBindingConfigReader;
}
}
--- /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.config;
+
+import java.io.File;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * AbstractConfigReader
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public abstract class AbstractConfigReader<T>
+ implements ConfigReader<T> {
+
+ private final Logger logger = LoggerFactory.getLogger(AbstractConfigReader.class);
+ private String serverRootDir;
+
+ AbstractConfigReader(String serverRootDir) {
+ this.serverRootDir = serverRootDir;
+ }
+
+ @Override
+ abstract public String getFileName();
+
+ @Override
+ abstract public void read() throws Exception;
+
+ @Override
+ abstract public T getConfiguration();
+
+
+ /**
+ * parse parses given configuration file from the disk based on given class
+ * definition
+ * @param configFile
+ * @param clazz
+ * @return A JAXB object
+ * @throws Exception
+ */
+ protected Object parse(File configFile, Class clazz) throws Exception {
+ JAXBContext jc = JAXBContext.newInstance(clazz);
+ Unmarshaller um = jc.createUnmarshaller();
+ Object readObject = um.unmarshal(configFile);
+ if(logger.isDebugEnabled()){
+ logger.debug("read() read file " + configFile.getAbsolutePath());
+ }
+ return readObject;
+ }
+
+ protected String getAbsoluteFileName(String configFileName) {
+ return serverRootDir +
+ File.separator + CSPACE_DIR_NAME +
+ File.separator + CONFIG_DIR_NAME +
+ File.separator + configFileName;
+ }
+
+ protected String getServerRootDir() {
+ return serverRootDir;
+ }
+}
--- /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.config;
+
+import java.io.File;
+
+/**
+ * ConfigReader is an interface for a configuration reader
+ */
+public interface ConfigReader<T> {
+
+ final public static String CSPACE_DIR_NAME = "cspace";
+ final public static String CONFIG_DIR_NAME = "config" + File.separator + "services";
+
+ /**
+ * getFileName - get configuration file name
+ * @return
+ */
+ public String getFileName();
+
+ /**
+ * read parse and read the configruation file.
+ * @throws Exception
+ */
+ public void read() throws Exception;
+
+ /**
+ * getConfig get configuration binding
+ * @return
+ */
+ public T getConfiguration();
+}
--- /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.config;
+
+import java.io.File;
+import org.collectionspace.services.common.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ServicesConfigReader reads service layer specific configuration
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class ServicesConfigReader
+ extends AbstractConfigReader<ServiceConfig> {
+
+ final private static String CONFIG_FILE_NAME = "service-config.xml";
+ final Logger logger = LoggerFactory.getLogger(ServicesConfigReader.class);
+ private ServiceConfig serviceConfig;
+ private ClientType clientType;
+ private String clientClassName;
+
+ public ServicesConfigReader(String serverRootDir) {
+ super(serverRootDir);
+ }
+
+ @Override
+ public String getFileName() {
+ return CONFIG_FILE_NAME;
+ }
+
+ @Override
+ public void read() throws Exception {
+ String configFileName = getAbsoluteFileName(CONFIG_FILE_NAME);
+ File configFile = new File(configFileName);
+ if(!configFile.exists()){
+ String msg = "Could not find configuration file " + configFileName;
+ logger.error(msg);
+ throw new RuntimeException(msg);
+ }
+ serviceConfig = (ServiceConfig) parse(configFile, ServiceConfig.class);
+ clientType = serviceConfig.getRepositoryClient().getClientType();
+ if(clientType == null){
+ String msg = "Missing <client-type> in <repository-client>";
+ logger.error(msg);
+ throw new IllegalArgumentException(msg);
+ }
+ clientClassName = serviceConfig.getRepositoryClient().getClientClass();
+ if(clientClassName == null){
+ String msg = "Missing <client-class> in <repository-client>";
+ logger.error(msg);
+ throw new IllegalArgumentException(msg);
+ }
+ if(logger.isDebugEnabled()){
+ logger.debug("using client=" + clientType.toString() + " class=" + clientClassName);
+ }
+ }
+
+ @Override
+ public ServiceConfig getConfiguration() {
+ return serviceConfig;
+ }
+
+ public ClientType getClientType() {
+ return clientType;
+ }
+
+ public String getClientClass() {
+ return clientClassName;
+ }
+}
--- /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.config;
+
+import java.io.File;
+import java.util.Hashtable;
+import java.util.List;
+import org.collectionspace.services.common.ClientType;
+import org.collectionspace.services.common.RepositoryWorkspaceType;
+import org.collectionspace.services.common.ServiceConfig;
+import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.service.ServiceBindingType;
+import org.collectionspace.services.common.tenant.TenantBindingType;
+import org.collectionspace.services.common.tenant.TenantBindingConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ServicesConfigReader reads service layer specific configuration
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class TenantBindingConfigReader
+ extends AbstractConfigReader<TenantBindingConfig> {
+
+ final private static String CONFIG_FILE_NAME = "tenant-bindings.xml";
+ final Logger logger = LoggerFactory.getLogger(TenantBindingConfigReader.class);
+ private TenantBindingConfig tenantBindingConfig;
+ //tenant name, tenant binding
+ private Hashtable<String, TenantBindingType> tenantBindings =
+ new Hashtable<String, TenantBindingType>();
+ //tenant-qualified servicename, service binding
+ private Hashtable<String, ServiceBindingType> serviceBindings =
+ new Hashtable<String, ServiceBindingType>();
+ //tenant-qualified service, workspace
+ private Hashtable<String, String> serviceWorkspaces = new Hashtable<String, String>();
+
+ public TenantBindingConfigReader(String serverRootDir) {
+ super(serverRootDir);
+ }
+
+ @Override
+ public String getFileName() {
+ return CONFIG_FILE_NAME;
+ }
+
+ @Override
+ public void read() throws Exception {
+ String configFileName = getAbsoluteFileName(CONFIG_FILE_NAME);
+ File configFile = new File(configFileName);
+ if(!configFile.exists()){
+ String msg = "Could not find configuration file " + configFileName;
+ logger.error(msg);
+ throw new RuntimeException(msg);
+ }
+ tenantBindingConfig = (TenantBindingConfig) parse(configFile, TenantBindingConfig.class);
+ for(TenantBindingType tenantBinding : tenantBindingConfig.getTenantBinding()){
+ tenantBindings.put(tenantBinding.getId(), tenantBinding);
+ readServiceBindings(tenantBinding);
+ if(logger.isDebugEnabled()){
+ logger.debug("read() added tenant id=" + tenantBinding.getId() +
+ " name=" + tenantBinding.getName());
+ }
+ }
+ }
+
+ private void readServiceBindings(TenantBindingType tenantBinding) throws Exception {
+ for(ServiceBindingType serviceBinding : tenantBinding.getServiceBindings()){
+ String key = getTenantQualifiedServiceName(tenantBinding.getId(),
+ serviceBinding.getName());
+ serviceBindings.put(key, serviceBinding);
+ if(logger.isDebugEnabled()){
+ logger.debug("readServiceBindings() added service " +
+ " name=" + key +
+ " workspace=" + serviceBinding.getName());
+ }
+ }
+ }
+
+ /**
+ * retrieveWorkspaceIds is called at initialization time to retrieve
+ * workspace ids of all the tenants
+ * @throws Exception
+ */
+ public void retrieveAllWorkspaceIds() throws Exception {
+ for(TenantBindingType tenantBinding : tenantBindings.values()){
+ retrieveWorkspaceIds(tenantBinding);
+ }
+ }
+
+ public void retrieveWorkspaceIds(TenantBindingType tenantBinding) throws Exception {
+ String tenantDomain = tenantBinding.getRepositoryDomain();
+ Hashtable<String, String> workspaceIds = new Hashtable<String, String>();
+ ServiceMain svcMain = ServiceMain.getInstance();
+ ClientType clientType = svcMain.getClientType();
+ if(clientType.equals(ClientType.JAVA)){
+ workspaceIds = svcMain.retrieveWorkspaceIds(tenantDomain);
+ }
+ for(ServiceBindingType serviceBinding : tenantBinding.getServiceBindings()){
+ String serviceName = serviceBinding.getName();
+ String workspaceId = null;
+ //workspace name is service name by convention
+ String workspace = serviceBinding.getName().toLowerCase();
+ if(clientType.equals(ClientType.JAVA)){
+ workspaceId = workspaceIds.get(workspace);
+ if(workspaceId == null){
+ logger.warn("failed to retrieve workspace id for " + workspace);
+ //FIXME: should we throw an exception here?
+ continue;
+ }
+ }else{
+ workspaceId = serviceBinding.getRepositoryWorkspaceId();
+ if(workspaceId == null || "".equals(workspaceId)){
+ logger.error("could not find workspace id for " + workspace);
+ //FIXME: should we throw an exception here?
+ continue;
+ }
+ }
+ String tenantService = getTenantQualifiedServiceName(tenantBinding.getId(), serviceName);
+ serviceWorkspaces.put(tenantService, workspaceId);
+ if(logger.isDebugEnabled()){
+ logger.debug("retrieved workspace id=" + workspaceId +
+ " service=" + serviceName +
+ " workspace=" + workspace);
+ }
+ }
+ }
+
+ @Override
+ public TenantBindingConfig getConfiguration() {
+ return tenantBindingConfig;
+ }
+
+ /**
+ * getTenantBinding gets tenant binding for given tenant
+ * @param tenantId
+ * @return
+ */
+ public TenantBindingType getTenantBinding(
+ String tenantId) {
+ return tenantBindings.get(tenantId);
+ }
+
+ /**
+ * getServiceBinding gets service binding for given tenant for a given service
+ * @param tenantId
+ * @param serviceName
+ * @return
+ */
+ public ServiceBindingType getServiceBinding(
+ String tenantId, String serviceName) {
+ String key = getTenantQualifiedServiceName(tenantId, serviceName);
+ return serviceBindings.get(key);
+ }
+
+ /**
+ * getWorkspaceId retrieves workspace id for given tenant for given service
+ * @param tenantId
+ * @param serviceName
+ * @return
+ */
+ public String getWorkspaceId(String tenantId, String serviceName) {
+ String tenantService = getTenantQualifiedServiceName(tenantId, serviceName);
+ return serviceWorkspaces.get(tenantService);
+ }
+
+ public static String getTenantQualifiedServiceName(
+ String tenantId, String serviceName) {
+ return tenantId + "." + serviceName.toLowerCase();
+ }
+}
--- /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.context;
+
+import java.io.IOException;
+import java.util.Map;
+import org.collectionspace.services.common.ClientType;
+import org.collectionspace.services.common.service.ObjectPartType;
+import org.collectionspace.services.common.service.ServiceBindingType;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
+import org.w3c.dom.Document;
+
+/**
+ *
+ * ServiceContext is used to pass along metadata and runtime context
+ * between various components of the service framework while processing
+ * a service request.
+ */
+public interface ServiceContext {
+
+ /**
+ * getTenantId get tenant id
+ * @return tenant id
+ */
+ public String getTenantId();
+
+ /**
+ * getTenantName get tenant name from the binding
+ * @return tenant name such as movingimage.us
+ */
+ public String getTenantName();
+
+ /**
+ * getServiceBinding gets service binding metadata
+ * @return service binding metadata
+ */
+ public ServiceBindingType getServiceBinding();
+
+ /**
+ * getServiceName returns the unqualified name of the service
+ * @return service name
+ */
+ public String getServiceName();
+
+ /**
+ * getQualifiedServiceName returns tenant id qualified service name
+ * @return tenant qualified service name
+ */
+ public String getQualifiedServiceName();
+
+ /**
+ * getRepositoryDomainName returns repository domain for the tenant
+ * @return repository domain for the tenant
+ */
+ public String getRepositoryDomainName();
+
+ /**
+ * getRepositoryClientName returns the repository client name as
+ * configured for the service
+ */
+ public String getRepositoryClientName();
+
+ /**
+ * getRepositoryClientType returns the type of client configured for the
+ * service layer
+ * @param ctx service context
+ * @return
+ */
+ public ClientType getRepositoryClientType();
+
+ /**
+ * getRepositoryWorkspaceName returns repository workspace for the service for
+ * the tenant. Not every service has a corresponding repository workspace.
+ * If the service does not have any repository workspace, this method
+ * returns null.
+ * @return repository workspace
+ */
+ public String getRepositoryWorkspaceName();
+
+ /**
+ * getRepositoryWorksapceId returns workspace id for the service for the
+ * tenant. Not every service has a corresponding repository workspace.
+ * If the service does not have any repository workspace, this method
+ * returns null.
+ * @return repository workspace
+ */
+ public String getRepositoryWorkspaceId();
+
+ /**
+ * setInput is used to set (multipart) request input before starting to
+ * process input data
+ * @param input multipart data input
+ * @exception IOException
+ */
+ public void setInput(MultipartInput input) throws IOException;
+
+ /**
+ * Get input parts as received over the wire from service consumer
+ * @return the input
+ */
+ public MultipartInput getInput();
+
+ /**
+ * Get output parts to send over the wire to service consumer
+ * @return the output
+ */
+ public MultipartOutput getOutput();
+
+ /**
+ * getInputPart returns part for given label from input
+ * @param label
+ * @param clazz class of the object
+ * @return part
+ */
+ public Object getInputPart(String label, Class clazz) throws IOException;
+
+ /**
+ * addOutputPart adds given XML part with given label and content type to output
+ * @param label
+ * @param document
+ * @param contentType media type
+ */
+ public void addOutputPart(String label, Document doc, String contentType) throws Exception;
+
+ /**
+ * getPartsMetadata returns metadata for object parts used by the service
+ * @return
+ */
+ public Map<String, ObjectPartType> getPartsMetadata();
+
+ /**
+ * getCommonPartLabel retruns label for common part of a service
+ * @return label
+ */
+ public String getCommonPartLabel();
+}
+
+
+
--- /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.context;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.core.MediaType;
+import org.collectionspace.services.common.ClientType;
+import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.config.TenantBindingConfigReader;
+import org.collectionspace.services.common.repository.DocumentUtils;
+import org.collectionspace.services.common.service.ObjectPartType;
+import org.collectionspace.services.common.service.ServiceBindingType;
+import org.collectionspace.services.common.service.ServiceObjectType;
+import org.collectionspace.services.common.tenant.TenantBindingType;
+import org.jboss.resteasy.plugins.providers.multipart.InputPart;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
+import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+
+/**
+ * ServiceContextImpl
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class ServiceContextImpl
+ implements ServiceContext {
+
+ final Logger logger = LoggerFactory.getLogger(ServiceContextImpl.class);
+ private TenantBindingType tenantBinding;
+ private ServiceBindingType serviceBinding;
+ //input stores original content as received over the wire
+ private MultipartInput input;
+ private MultipartOutput output;
+ Map<String, ObjectPartType> objectPartMap = new HashMap<String, ObjectPartType>();
+
+ @Override
+ public String toString() {
+ return "ServiceContextImpl [" +
+ "service name=" + serviceBinding.getName() + " " +
+ "service version=" + serviceBinding.getVersion() + " " +
+ "tenant id=" + tenantBinding.getId() + " " +
+ "tenant name=" + tenantBinding.getName() + " " + tenantBinding.getDisplayName() + " " +
+ "tenant repository domain=" + tenantBinding.getRepositoryDomain() + " " +
+ "]";
+ }
+
+ public ServiceContextImpl(String serviceName) {
+ TenantBindingConfigReader tReader =
+ ServiceMain.getInstance().getTenantBindingConfigReader();
+ //TODO: get tenant binding from security context (Subject.g
+ String tenantId = "1"; //hardcoded for movingimages.us
+ tenantBinding = tReader.getTenantBinding(tenantId);
+ if(tenantBinding == null){
+ String msg = "No tenant binding found while processing request for " +
+ serviceName;
+ logger.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ serviceBinding = tReader.getServiceBinding(tenantId, serviceName);
+ if(serviceBinding == null){
+ String msg = "No service binding found while processing request for " +
+ serviceName + " for tenant id=" + getTenantId() +
+ " name=" + getTenantName();
+ logger.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ if(logger.isDebugEnabled()){
+ logger.debug("tenantId=" + tenantId +
+ " service binding=" + serviceBinding.getName());
+ }
+ output = new MultipartOutput();
+ }
+
+ @Override
+ public String getTenantId() {
+ return tenantBinding.getId();
+ }
+
+ @Override
+ public String getTenantName() {
+ return tenantBinding.getName();
+ }
+
+ @Override
+ public ServiceBindingType getServiceBinding() {
+ return serviceBinding;
+ }
+
+ @Override
+ public String getServiceName() {
+ return serviceBinding.getName();
+ }
+
+ @Override
+ public String getQualifiedServiceName() {
+ return TenantBindingConfigReader.getTenantQualifiedServiceName(
+ getTenantId(), getServiceName());
+ }
+
+ @Override
+ public String getRepositoryDomainName() {
+ return tenantBinding.getRepositoryDomain();
+ }
+
+ @Override
+ public String getRepositoryClientName() {
+ return serviceBinding.getRepositoryClient();
+ }
+
+ @Override
+ public ClientType getRepositoryClientType() {
+ //assumption: there is only one repository client configured
+ return ServiceMain.getInstance().getClientType();
+ }
+
+ @Override
+ public String getRepositoryWorkspaceName() {
+ //service name is workspace name by convention
+ return serviceBinding.getName();
+ }
+
+ @Override
+ public String getRepositoryWorkspaceId() {
+ TenantBindingConfigReader tbConfigReader =
+ ServiceMain.getInstance().getTenantBindingConfigReader();
+ return tbConfigReader.getWorkspaceId(getTenantId(), getServiceName());
+ }
+
+ @Override
+ public MultipartInput getInput() {
+ return input;
+ }
+
+ @Override
+ public MultipartOutput getOutput() {
+ return output;
+ }
+
+ @Override
+ public Object getInputPart(String label, Class clazz) throws IOException {
+ Object obj = null;
+ if(getInput() != null){
+ MultipartInput fdip = getInput();
+
+ for(InputPart part : fdip.getParts()){
+ String partLabel = part.getHeaders().getFirst("label");
+ if(label.equalsIgnoreCase(partLabel)){
+ if(logger.isDebugEnabled()){
+ logger.debug("received part label=" + partLabel +
+ "\npayload=" + part.getBodyAsString());
+ }
+ obj = part.getBody(clazz, null);
+ break;
+ }
+ }
+ }
+ return obj;
+ }
+
+ @Override
+ public void addOutputPart(String label, Document doc, String contentType) throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try{
+ DocumentUtils.writeDocument(doc, baos);
+ baos.close();
+ OutputPart part = output.addPart(new String(baos.toByteArray()),
+ MediaType.valueOf(contentType));
+ part.getHeaders().add("label", label);
+ }finally{
+ if(baos != null){
+ try{
+ baos.close();
+ }catch(Exception e){
+ }
+ }
+ }
+ }
+
+ @Override
+ public void setInput(MultipartInput input) throws IOException {
+ this.input = input;
+ }
+
+ @Override
+ public Map<String, ObjectPartType> getPartsMetadata() {
+ if(objectPartMap.size() != 0){
+ return objectPartMap;
+ }
+
+ ServiceBindingType serviceBinding = getServiceBinding();
+ List<ServiceObjectType> objectTypes = serviceBinding.getObject();
+ for(ServiceObjectType objectType : objectTypes){
+ List<ObjectPartType> objectPartTypes = objectType.getPart();
+ for(ObjectPartType objectPartType : objectPartTypes){
+ objectPartMap.put(objectPartType.getLabel(), objectPartType);
+ }
+
+ }
+ return objectPartMap;
+ }
+
+ /**
+ * getCommonPartLabel get common part label
+ * @return
+ */
+ @Override
+ public String getCommonPartLabel() {
+ return getServiceName().toLowerCase() + "-common";
+ }
+}
--- /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.HashMap;
+import java.util.Map;
+
+import java.util.StringTokenizer;
+import org.collectionspace.services.common.context.ServiceContext;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * AbstractDocumentHandler
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public abstract class AbstractDocumentHandler<T, TL>
+ implements DocumentHandler<T, TL> {
+
+ private final Logger logger = LoggerFactory.getLogger(AbstractDocumentHandler.class);
+ private Map<String, Object> properties = new HashMap<String, Object>();
+ private ServiceContext serviceContext;
+
+ public AbstractDocumentHandler() {
+ }
+
+ @Override
+ public ServiceContext getServiceContext() {
+ return serviceContext;
+ }
+
+ @Override
+ public void setServiceContext(ServiceContext ctx) {
+ serviceContext = ctx;
+ }
+
+ /**
+ * @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;
+ }
+
+ @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;
+
+ }
+ }
+
+ @Override
+ public abstract void handleCreate(DocumentWrapper wrapDoc) throws Exception;
+
+ @Override
+ public abstract void handleUpdate(DocumentWrapper wrapDoc) throws Exception;
+
+ @Override
+ public abstract void handleGet(DocumentWrapper wrapDoc) throws Exception;
+
+ @Override
+ public abstract void handleGetAll(DocumentWrapper wrapDoc) throws Exception;
+
+ @Override
+ public void complete(Action action, DocumentWrapper wrapDoc) throws Exception {
+ switch(action){
+ //TODO: add more actions if needed
+ case UPDATE:
+ completeUpdate(wrapDoc);
+ break;
+ }
+ }
+
+ @Override
+ public void completeUpdate(DocumentWrapper wrapDoc) throws Exception {
+ //no specific action needed
+ }
+
+ @Override
+ public abstract void extractAllParts(DocumentWrapper wrapDoc)
+ throws Exception;
+
+ @Override
+ public abstract void fillAllParts(DocumentWrapper wrapDoc)
+ throws Exception;
+
+ @Override
+ public abstract T extractCommonPart(DocumentWrapper wrapDoc)
+ throws Exception;
+
+ @Override
+ public abstract void fillCommonPart(T obj, DocumentWrapper wrapDoc)
+ throws Exception;
+
+ @Override
+ public abstract TL extractCommonPartList(DocumentWrapper wrapDoc)
+ throws Exception;
+
+ @Override
+ final public void fillCommonPartList(TL obj, DocumentWrapper wrapDoc) throws Exception {
+ throw new UnsupportedOperationException("bulk create/update not yet supported");
+ }
+
+ @Override
+ public abstract T getCommonPart();
+
+ @Override
+ public abstract void setCommonPart(T obj);
+
+ @Override
+ public abstract TL getCommonPartList();
+
+ @Override
+ public abstract void setCommonPartList(TL obj);
+
+ @Override
+ public abstract String getQProperty(String prop);
+
+ @Override
+ public String getUnQProperty(String qProp) {
+ StringTokenizer tkz = new StringTokenizer(qProp, ":");
+ if(tkz.countTokens() != 2){
+ String msg = "Property must be in the form xxx:yyy, " +
+ "e.g. collectionobjects-common:objectNumber";
+ logger.error(msg);
+ throw new IllegalArgumentException(msg);
+ }
+ tkz.nextToken(); //skip
+ return tkz.nextToken();
+ }
+
+ @Override
+ public String getServiceContextPath() {
+ return "/" + getServiceContext().getServiceName().toLowerCase() + "/";
+ }
+}
/**
* DocumentException
- * Nuxeo document handling exception
+ * document handling exception
*/
public class DocumentException extends Exception {
*/
package org.collectionspace.services.common.repository;
-import org.collectionspace.services.common.repository.DocumentWrapper;
-import org.collectionspace.services.common.repository.DocumentException;
+import java.io.IOException;
import java.util.Map;
-import org.dom4j.Document;
+import org.collectionspace.services.common.context.ServiceContext;
+import org.w3c.dom.Document;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
/**
*
* DocumentHandler provides document processing methods. It is an interface
- * between Nuxeo repository client and CollectionSpace service resource. It provides
+ * between repository client and CollectionSpace service resource. It provides
* methods to setup request via repository client and handle its response.
*
* Typical call sequence is:
}
/**
- * prepare is called by the Nuxeo client to prepare required parameters to set
- * before invoking repository operation. this is mainly useful for create and
+ * getServiceContext returns service context
+ * @return
+ */
+ public ServiceContext getServiceContext();
+
+ /**
+ * getServiceContextPath such as "/collectionobjects/"
+ * @return
+ */
+ public String getServiceContextPath();
+
+ /**
+ * setServiceContext sets service contex to the handler
+ * @param ctx
+ */
+ public void setServiceContext(ServiceContext ctx);
+
+ /**
+ * prepare is called by the client for preparation of stuff 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
+ * handle is called by the client to hand over the document processing task
* @param action
- * @param doc wrapped Nuxeo doc
+ * @param doc wrapped doc
* @throws Exception
*/
public void handle(Action action, DocumentWrapper docWrap) throws Exception;
- /**
- * handleCreate processes create operation response
+ /**
+ * handleCreate processes documents before creating document in repository
* @param wrapDoc
* @throws Exception
*/
public void handleCreate(DocumentWrapper wrapDoc) throws Exception;
/**
- * handleUpdate processes update operation response
+ * handleUpdate processes documents for the update of document in repository
* @param wrapDoc
* @throws Exception
*/
public void handleUpdate(DocumentWrapper wrapDoc) throws Exception;
/**
- * handleGet processes get operation response
+ * handleGet processes documents from repository before responding to consumer
* @param wrapDoc
* @throws Exception
*/
public void handleGet(DocumentWrapper wrapDoc) throws Exception;
/**
- * handleGetAll processes index operation response
+ * handleGetAll processes documents from repository before responding to consumer
* @param wrapDoc
* @throws Exception
*/
public void handleGetAll(DocumentWrapper wrapDoc) throws Exception;
-
+
/**
- * extractCommonObject extracts common part of a CS document from given Nuxeo document.
- * @param docWrap nuxeo document
- * @return common part of CS object
+ * complete is called by the client to provide an opportunity to the handler
+ * to take care of stuff before closing session with the repository. example
+ * could be to reclaim resources or to populate response to the consumer
+ * @param wrapDoc
* @throws Exception
*/
- public T extractCommonObject(DocumentWrapper docWrap) throws Exception;
+ public void complete(Action action, DocumentWrapper wrapDoc) throws Exception;
/**
- * fillCommonObject sets common part of CS object into given Nuxeo document
- * @param obj input object
- * @param docWrap target Nuxeo document
+ * completeUpdate is called by the client to indicate completion of the update call.
+ * this gives opportunity to prepare updated object that should be sent back to the consumer
+ * @param wrapDoc
* @throws Exception
*/
- public void fillCommonObject(T obj, DocumentWrapper docWrap) throws Exception;
+ public void completeUpdate(DocumentWrapper wrapDoc) throws Exception;
- /**
- * extractCommonObject extracts common part of a CS document from given Nuxeo document.
- * @param docWrap nuxeo document
- * @return common part of CS object
+ /**
+ * extractAllParts extracts all parts of a CS object from given document.
+ * this is usually called AFTER the get operation is invoked on the repository
+ * Called in handle GET/GET_ALL actions.
+ * @param docWrap document
* @throws Exception
*/
- public TL extractCommonObjectList(DocumentWrapper docWrap) throws Exception;
+ public void extractAllParts(DocumentWrapper docWrap) throws Exception;
/**
- * fillCommonObject sets common part of CS object into given Nuxeo document
+ * fillAllParts sets parts of CS object into given document
+ * this is usually called BEFORE create/update operations are invoked on the
+ * repository. Called in handle CREATE/UPDATE actions.
* @param obj input object
- * @param docWrap target Nuxeo document
+ * @param docWrap target document
* @throws Exception
*/
- public void fillCommonObjectList(TL obj, DocumentWrapper docWrap) throws Exception;
+ public void fillAllParts(DocumentWrapper docWrap) throws Exception;
/**
- * getCommonObject provides the common part of a CS document.
- * @return common part of CS document
+ * extractCommonPart extracts common part of a CS object from given document.
+ * this is usually called AFTER the get operation is invoked on the repository.
+ * Called in handle GET/GET_ALL actions.
+ * @param docWrap document
+ * @return common part of CS object
+ * @throws Exception
*/
- public T getCommonObject();
+ public T extractCommonPart(DocumentWrapper docWrap) throws Exception;
/**
- * setCommonObject sets common part of CS document as input for operation on
- * Nuxeo repository
+ * fillCommonPart sets common part of CS object into given document
+ * this is usually called BEFORE create/update operations are invoked on the
+ * repository. Called in handle CREATE/UPDATE actions.
* @param obj input object
+ * @param docWrap target document
+ * @throws Exception
*/
- public void setCommonObject(T obj);
+ public void fillCommonPart(T obj, DocumentWrapper docWrap) throws Exception;
/**
- * getCommonObjectList provides the default list object of a CS document.
- * @return default list of CS document
+ * extractCommonPart extracts common part of a CS object from given document.
+ * this is usually called AFTER bulk get (index/list) operation is invoked on
+ * the repository
+ * @param docWrap document
+ * @return common part of CS object
+ * @throws Exception
*/
- public TL getCommonObjectList();
+ public TL extractCommonPartList(DocumentWrapper docWrap) throws Exception;
/**
- * setCommonObjectList sets default list object for CS document as input for operation on
- * Nuxeo repository
- * @param default list of CS document
+ * fillCommonPartList sets list common part of CS object into given document
+ * this is usually called BEFORE bulk create/update on the repository
+ * (not yet supported)
+ * @param obj input object
+ * @param docWrap target document
+ * @throws Exception
*/
- public void setCommonObjectList(TL obj);
+ public void fillCommonPartList(TL obj, DocumentWrapper docWrap) throws Exception;
- /**
- * getDocument get org.dom4j.Document from given DocumentModel
- * @param Nuxeo document wrapper
- * @return
- * @throws DocumentException
- */
- public Document getDocument(DocumentWrapper docWrap) throws DocumentException;
-
/**
* Gets the document type.
*
/**
* setProperties provides means to the CollectionSpace service resource to
- * set up parameters before invoking create request via the Nuxeo client.
+ * set up parameters before invoking any request via the client.
* @param properties
*/
public void setProperties(Map<String, Object> properties);
+
+ /**
+ * getCommonPart provides the common part of a CS object.
+ * @return common part of CS object
+ */
+ public T getCommonPart();
+
+ /**
+ * setCommonPart sets common part of CS object as input for operation on
+ * repository
+ * @param obj input object
+ */
+ public void setCommonPart(T obj);
+
+ /**
+ * getCommonPartList provides the default list object of a CS object.
+ * @return default list of CS object
+ */
+ public TL getCommonPartList();
+
+ /**
+ * setCommonPartList sets common part list entry for CS object as input for operation on
+ * repository
+ * @param default list of CS object
+ */
+ public void setCommonPartList(TL obj);
+
+ /**
+ * getQProperty get qualified property (useful for mapping to repository document property)
+ * @param prop
+ * @return
+ */
+ public String getQProperty(String prop);
+
+ /**
+ * getUnQProperty unqualifies document property from repository
+ * @param qProp qualifeid property
+ * @return unqualified property
+ */
+ public String getUnQProperty(String qProp);
}
--- /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.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.collectionspace.services.common.service.ObjectPartContentType;
+import org.collectionspace.services.common.service.ObjectPartType;
+import org.collectionspace.services.common.service.XmlContentType;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+* DocumentUtils is a collection of utilities related to document management
+*
+* $LastChangedRevision: $
+* $LastChangedDate: $
+*/
+public class DocumentUtils {
+
+ /**
+ * parseProperties given payload to create XML document. this
+ * method also closes given stream after parsing.
+ * @param payload stream
+ * @return parsed Document
+ * @throws Exception
+ */
+ public static Document parseDocument(InputStream payload)
+ throws Exception {
+ try{
+ // Create a builder factory
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setValidating(false);//TODO take validating value from meta
+
+ // Create the builder and parse the file
+ return factory.newDocumentBuilder().parse(payload);
+
+ }finally{
+ if(payload != null){
+ payload.close();
+ }
+
+ }
+ }
+
+ /**
+ * parseProperties extract given payload (XML) into Name-Value properties. this
+ * @param document to parse
+ * @return map key=property name, value=property value
+ * @throws Exception
+ */
+ public static Map<String, Object> parseProperties(Document document)
+ throws Exception {
+ HashMap<String, Object> objectProps = new HashMap<String, Object>();
+ // Get a list of all elements in the document
+ Node root = document.getFirstChild();
+ NodeList children = root.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++){
+ Node node = (Node) children.item(i);
+ if(node.getNodeType() == Node.ELEMENT_NODE){
+ Node cnode = node.getFirstChild();
+ if(cnode.getNodeType() != Node.TEXT_NODE){
+ continue;
+ }
+ Node textNode = (Text) cnode;
+ objectProps.put(node.getNodeName(),
+ textNode.getNodeValue());
+ }
+ }
+ return objectProps;
+ }
+
+ /**
+ * buildDocument builds org.w3c.dom.Document from given properties using
+ * given metadata for a part
+ * @param partMeta
+ * @param rootElementName
+ * @param objectProps
+ * @return
+ * @throws Exception
+ */
+ public static Document buildDocument(ObjectPartType partMeta, String rootElementName,
+ Map<String, Object> objectProps)
+ throws Exception {
+ ObjectPartContentType partContentMeta = partMeta.getContent();
+ XmlContentType xc = partContentMeta.getXmlContent();
+ if(xc == null){
+ return null;
+ }
+
+ DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ Document document = builder.newDocument();
+ document.setXmlStandalone(true);
+ //JAXB unmarshaller recognizes the following kind of namespace qualification
+ //only. More investigation is needed to use other prefix
+// <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+// <ns2:collectionobjects-common xmlns:ns2="http://collectionspace.org/services/collectionobject">
+// <objectNumber>objectNumber-1252960222412</objectNumber>
+// <objectName>objectName-1252960222412</objectName>
+// </ns2:collectionobjects-common>
+
+ String ns = "ns2";
+ Element root = document.createElementNS(xc.getNamespaceURI(), ns + ":" + rootElementName);
+ root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
+ root.setAttribute("xsi:schemaLocation", xc.getSchemaLocation());
+ root.setAttribute("xmlns:" + ns, xc.getNamespaceURI());
+ document.appendChild(root);
+
+ for(String prop : objectProps.keySet()){
+ Object value = objectProps.get(prop);
+ if(value != null){
+ //no need to qualify each element name as namespace is already added
+ Element e = document.createElement(prop);
+ root.appendChild(e);
+ String strValue = objectProps.get(prop).toString();
+ Text tNode = document.createTextNode(strValue);
+ e.appendChild(tNode);
+ }
+ }
+ return document;
+ }
+
+ /**
+ * writeDocument streams out given document to given output stream
+ * @param document
+ * @param os
+ * @throws Exception
+ */
+ public static void writeDocument(Document document, OutputStream os) throws Exception {
+ TransformerFactory tFactory =
+ TransformerFactory.newInstance();
+ Transformer transformer = tFactory.newTransformer();
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ DOMSource source = new DOMSource(document);
+ StreamResult result = new StreamResult(os);
+ transformer.transform(source, result);
+ }
+}
*/
package org.collectionspace.services.common.repository;
+import org.collectionspace.services.common.context.ServiceContext;
+
/**
* RepositoryClient is a generic Document Repository client
/**
* 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 serviceName entity service for which document is created. this is used to find mapping
- * to a Nuxeo workspace using service-config.xml
+ * @param ctx service context under which this method is invoked
* @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, DocumentHandler handler) throws BadRequestException, DocumentException;
+ String create(ServiceContext ctx, DocumentHandler handler) throws BadRequestException, DocumentException;
/**
* delete a document from the Document repository
+ * @param ctx service context under which this method is invoked
* @param id of the document
* @throws DocumentNotFoundException if document not found
* @throws DocumentException
*/
- void delete(String id) throws DocumentNotFoundException, DocumentException;
+ void delete(ServiceContext ctx, String id) throws DocumentNotFoundException, DocumentException;
/**
* get document from the Document repository
+ * @param ctx service context under which this method is invoked
* @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;
+ void get(ServiceContext ctx, 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 ctx service context under which this method is invoked
* @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;
+ void getAll(ServiceContext ctx, DocumentHandler handler) throws DocumentNotFoundException, DocumentException;
/**
* update given document in the Document repository
+ * @param ctx service context under which this method is invoked
* @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;
+ void update(ServiceContext ctx, String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException;
}
*/
package org.collectionspace.services.common.repository;
+import java.lang.ClassLoader;
import java.util.Hashtable;
-import org.collectionspace.services.common.NuxeoClientType;
+import org.collectionspace.services.common.RepositoryClientConfigType;
+import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.config.ServicesConfigReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
- * RepositoryClientFactory is a singleton factory that provides required Nuxeo client
- * it does not create clients as the clients are singletons
+ * RepositoryClientFactory is a singleton factory that creates required repository
+ * clients. Repository clients are singletons.
*
* $LastChangedRevision: $
* $LastChangedDate: $
*/
public class RepositoryClientFactory {
-
private static final RepositoryClientFactory self = new RepositoryClientFactory();
+ final Logger logger = LoggerFactory.getLogger(RepositoryClientFactory.class);
+ //clients key=client name, value=repository client
private Hashtable<String, RepositoryClient> clients = new Hashtable<String, RepositoryClient>();
private RepositoryClientFactory() {
try{
+ ServicesConfigReader scReader = ServiceMain.getInstance().getServicesConfigReader();
+ RepositoryClientConfigType repositoryClientConfig = scReader.getConfiguration().getRepositoryClient();
+ String clientClassName = repositoryClientConfig.getClientClass();
+ String clientName = repositoryClientConfig.getName();
ClassLoader cloader = Thread.currentThread().getContextClassLoader();
- Class jclazz = cloader.loadClass("org.collectionspace.services.nuxeo.client.java.RepositoryJavaClient");
+ Class jclazz = cloader.loadClass(clientClassName);
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);
+ clients.put(clientName, (RepositoryClient) jclient);
}catch(Exception e){
throw new RuntimeException(e);
return self;
}
- public RepositoryClient getClient(String clientType) {
- return clients.get(clientType);
+ /**
+ * get repository client
+ * @param clientName name of the client as found in service binding
+ * @return
+ */
+ public RepositoryClient getClient(String clientName) {
+ return clients.get(clientName);
}
}
*/
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.io.InputStream;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import javax.ws.rs.core.MediaType;
+import org.collectionspace.services.common.repository.DocumentWrapper;
+import org.collectionspace.services.common.repository.AbstractDocumentHandler;
+import org.collectionspace.services.common.repository.BadRequestException;
+import org.collectionspace.services.common.repository.DocumentUtils;
+import org.collectionspace.services.common.service.ObjectPartType;
import org.collectionspace.services.nuxeo.client.*;
-import org.collectionspace.services.nuxeo.util.NuxeoUtils;
-import org.dom4j.Document;
+import org.jboss.resteasy.plugins.providers.multipart.InputPart;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
/**
* DocumentModelHandler is a base abstract Nuxeo document handler
* $LastChangedDate: $
*/
public abstract class DocumentModelHandler<T, TL>
- implements DocumentHandler<T, TL> {
+ extends AbstractDocumentHandler<T, TL> {
private final Logger logger = LoggerFactory.getLogger(DocumentModelHandler.class);
- private Map<String, Object> properties = new HashMap<String, Object>();
private RepositoryInstance repositorySession;
+ //key=schema, value=documentpart
- @Override
- public abstract void prepare(Action action) throws Exception;
+ /**
+ * getRepositorySession returns Nuxeo Repository Session
+ * @return
+ */
+ public RepositoryInstance getRepositorySession() {
+ return repositorySession;
+ }
- @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;
- }
+ /**
+ * setRepositorySession sets repository session
+ * @param repoSession
+ */
+ public void setRepositorySession(RepositoryInstance repoSession) {
+ this.repositorySession = repoSession;
}
@Override
public void handleCreate(DocumentWrapper wrapDoc) throws Exception {
- if(getCommonObject() == null){
- String msg = "Error creating document: Missing input data";
- logger.error(msg);
- throw new IllegalStateException(msg);
- }
- //FIXME set other parts as well
- fillCommonObject(getCommonObject(), wrapDoc);
+ fillAllParts(wrapDoc);
}
@Override
public void handleUpdate(DocumentWrapper wrapDoc) throws Exception {
- if(getCommonObject() == null){
- String msg = "Error updating document: Missing input data";
- logger.error(msg);
- throw new IllegalStateException(msg);
- }
- //FIXME set other parts as well
- fillCommonObject(getCommonObject(), wrapDoc);
+ fillAllParts(wrapDoc);
}
@Override
public void handleGet(DocumentWrapper wrapDoc) throws Exception {
- setCommonObject(extractCommonObject(wrapDoc));
-
- //FIXME retrive other parts as well
+ extractAllParts(wrapDoc);
}
@Override
public void handleGetAll(DocumentWrapper wrapDoc) throws Exception {
- setCommonObjectList(extractCommonObjectList(wrapDoc));
+ setCommonPartList(extractCommonPartList(wrapDoc));
}
- /**
- * getRepositorySession returns Nuxeo Repository Session
- * @return
- */
- public RepositoryInstance getRepositorySession() {
- return repositorySession;
+ @Override
+ public void completeUpdate(DocumentWrapper wrapDoc) throws Exception {
+ DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
+ //return at least those document part(s) that were received
+ Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
+ List<InputPart> inputParts = getServiceContext().getInput().getParts();
+ for(InputPart part : inputParts){
+ String partLabel = part.getHeaders().getFirst("label");
+ ObjectPartType partMeta = partsMetaMap.get(partLabel);
+ extractObject(docModel, partLabel, partMeta);
+ }
}
- /**
- * setRepositorySession sets repository session
- * @param repoSession
- */
- public void setRepositorySession(RepositoryInstance repoSession) {
- this.repositorySession = repoSession;
+ @Override
+ public void extractAllParts(DocumentWrapper wrapDoc) throws Exception {
+
+ DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
+ String[] schemas = docModel.getDeclaredSchemas();
+ Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
+ for(String schema : schemas){
+ ObjectPartType partMeta = partsMetaMap.get(schema);
+ if(partMeta == null){
+ continue; //unknown part, ignore
+ }
+ extractObject(docModel, schema, partMeta);
+ }
}
@Override
- public abstract T extractCommonObject(DocumentWrapper wrapDoc) throws Exception;
+ public abstract T extractCommonPart(DocumentWrapper wrapDoc) throws Exception;
@Override
- public abstract void fillCommonObject(T obj, DocumentWrapper wrapDoc) throws Exception;
+ public void fillAllParts(DocumentWrapper wrapDoc) throws Exception {
- @Override
- public abstract TL extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception;
+ //TODO filling extension parts should be dynamic
+ //Nuxeo APIs lack to support stream/byte[] input, get/setting properties is
+ //not an ideal way of populating objects.
+ DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
+ MultipartInput input = getServiceContext().getInput();
+ if(input.getParts().isEmpty()){
+ String msg = "No payload found!";
+ logger.error(msg + "Ctx=" + getServiceContext().toString());
+ throw new BadRequestException(msg);
+ }
+
+ Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
+
+ //iterate over parts received and fill those parts
+ List<InputPart> inputParts = input.getParts();
+ for(InputPart part : inputParts){
+
+ String partLabel = part.getHeaders().getFirst("label");
+ //skip if the part is not in metadata
+ if(!partsMetaMap.containsKey(partLabel)){
+ continue;
+ }
+ InputStream payload = part.getBody(InputStream.class, null);
+
+ //check if this is an xml part
+ if(part.getMediaType().equals(MediaType.APPLICATION_XML_TYPE)){
+ if(payload != null){
+ Document document = DocumentUtils.parseDocument(payload);
+ //TODO: callback to handler if registered to validate the
+ //document
+ Map<String, Object> objectProps = DocumentUtils.parseProperties(document);
+ docModel.setProperties(partLabel, objectProps);
+ }
+ }
+ }//rof
+
+ }
@Override
- public abstract void fillCommonObjectList(TL obj, DocumentWrapper wrapDoc) throws Exception;
+ public abstract void fillCommonPart(T obj, DocumentWrapper wrapDoc) throws Exception;
@Override
- public abstract T getCommonObject();
+ public abstract TL extractCommonPartList(DocumentWrapper wrapDoc) throws Exception;
@Override
- public abstract void setCommonObject(T obj);
+ public abstract T getCommonPart();
@Override
- public abstract TL getCommonObjectList();
+ public abstract void setCommonPart(T obj);
@Override
- public abstract void setCommonObjectList(TL obj);
+ public abstract TL getCommonPartList();
@Override
- public Document getDocument(DocumentWrapper wrapDoc) throws DocumentException {
- DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
- return NuxeoUtils.getDocument(getRepositorySession(), docModel);
- }
-
+ public abstract void setCommonPartList(TL obj);
+
/* (non-Javadoc)
* @see org.collectionspace.services.common.repository.DocumentHandler#getDocumentType()
*/
@Override
public abstract String getDocumentType();
-
- /**
- * @return the properties
- */
- @Override
- public Map<String, Object> getProperties() {
- return properties;
- }
/**
- * @param properties the properties to set
+ * extractObject extracts an XML object from given DocumentModel
+ * @param docModel
+ * @param schema of the object to extract
+ * @param partMeta metadata for the object to extract
+ * @throws Exception
*/
- @Override
- public void setProperties(Map<String, Object> properties) {
- this.properties = properties;
+ protected void extractObject(DocumentModel docModel, String schema, ObjectPartType partMeta)
+ throws Exception {
+ MediaType mt = MediaType.valueOf(partMeta.getContent().getContentType());
+ if(mt.equals(MediaType.APPLICATION_XML_TYPE)){
+ Map<String, Object> objectProps = docModel.getProperties(schema);
+ //unqualify properties before sending the doc over the wire (to save bandwidh)
+ //FIXME: is there a better way to avoid duplication of a collection?
+ Map<String, Object> unQObjectProperties = new HashMap<String, Object>();
+ Set<Entry<String, Object>> qualifiedEntries = objectProps.entrySet();
+ for(Entry<String, Object> entry : qualifiedEntries){
+ String unqProp = getUnQProperty(entry.getKey());
+ unQObjectProperties.put(unqProp, entry.getValue());
+ }
+ Document doc = DocumentUtils.buildDocument(partMeta, schema, unQObjectProperties);
+ if(logger.isDebugEnabled()){
+ DocumentUtils.writeDocument(doc, System.out);
+ }
+ getServiceContext().addOutputPart(schema, doc, partMeta.getContent().getContentType());
+ } //TODO: handle other media types
}
+
}
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
-import org.collectionspace.services.common.ServiceConfig.NuxeoClientConfig;
+import org.collectionspace.services.common.RepositoryClientConfigType;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentModelList;
import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
private NuxeoApp app;
private NuxeoClient client;
private volatile boolean initialized = false; //use volatile for lazy initialization in singleton
- private NuxeoClientConfig nuxeoClientConfig;
+ private RepositoryClientConfigType repositoryClientConfig;
private NuxeoConnector() {
}
* is initialized in a thread-safe manner and not initialized more than once.
* Initialization involves starting Nuxeo runtime, loading Nuxeo APIs jars
* in OSGI container as well as establishing initial connection.
- * @param nuxeoClientConfig
+ * @param repositoryClientConfig
* @throws java.lang.Exception
*/
- public void initialize(NuxeoClientConfig nuxeoClientConfig) throws Exception {
+ public void initialize(RepositoryClientConfigType repositoryClientConfig) throws Exception {
if(initialized == false){
synchronized(this){
if(initialized == false){
try{
- this.nuxeoClientConfig = nuxeoClientConfig;
- setProperties(nuxeoClientConfig);
+ this.repositoryClientConfig = repositoryClientConfig;
+ setProperties(repositoryClientConfig);
app = new NuxeoApp();
app.start();
if(logger.isDebugEnabled()){
}
}
- private void setProperties(NuxeoClientConfig nuxeoClientConfig) {
+ private void setProperties(RepositoryClientConfigType repositoryClientConfig) {
System.setProperty("nuxeo.client.on.jboss", Boolean.TRUE.toString());
System.setProperty("org.nuxeo.runtime.server.enabled", Boolean.FALSE.toString());
- System.setProperty("org.nuxeo.runtime.server.port", "" + nuxeoClientConfig.getPort());
- System.setProperty("org.nuxeo.runtime.server.host", nuxeoClientConfig.getHost());
+ System.setProperty("org.nuxeo.runtime.server.port", "" + repositoryClientConfig.getPort());
+ System.setProperty("org.nuxeo.runtime.server.host", repositoryClientConfig.getHost());
//System.setProperty("org.nuxeo.runtime.1.3.3.streaming.port", "3233");
- System.setProperty("org.nuxeo.runtime.streaming.serverLocator", "socket://" + nuxeoClientConfig.getHost() + ":3233");
+ System.setProperty("org.nuxeo.runtime.streaming.serverLocator", "socket://" + repositoryClientConfig.getHost() + ":3233");
System.setProperty("org.nuxeo.runtime.streaming.isServer", Boolean.FALSE.toString());
//org.nuxeo.client.remote is part of the fix to Nuxeo Runtime to use Java Remote APIs
//from JBoss
// }else{
//authentication failure error comes when reusing the client
//force connect for now
- client.forceConnect(nuxeoClientConfig.getHost(), nuxeoClientConfig.getPort());
+ client.forceConnect(repositoryClientConfig.getHost(), repositoryClientConfig.getPort());
if(logger.isDebugEnabled()){
logger.debug("getClient(): connection successful port=" +
- nuxeoClientConfig.getPort());
+ repositoryClientConfig.getPort());
}
return client;
// }
/**
* retrieveWorkspaceIds retrieves all workspace ids from default repository
- * @return
+ * @param tenantDomain domain representing tenant
+ * @return
* @throws java.lang.Exception
*/
- public Hashtable<String, String> retrieveWorkspaceIds() throws Exception {
+ public Hashtable<String, String> retrieveWorkspaceIds(String tenantDomain) throws Exception {
RepositoryInstance repoSession = null;
Hashtable<String, String> workspaceIds = new Hashtable<String, String>();
try{
repoSession = getRepositorySession();
DocumentModel rootDoc = repoSession.getRootDocument();
DocumentModelList rootChildrenList = repoSession.getChildren(rootDoc.getRef());
- Iterator<DocumentModel> riter = rootChildrenList.iterator();
- if(riter.hasNext()){
- DocumentModel domain = riter.next();
+ Iterator<DocumentModel> diter = rootChildrenList.iterator();
+ while(diter.hasNext()){
+ DocumentModel domain = diter.next();
+ String domainPath = "/" + tenantDomain;
+ if(!domain.getPathAsString().equalsIgnoreCase(domainPath)) {
+ continue;
+ }
+ if(logger.isDebugEnabled()) {
+ logger.debug("domain=" + domain.toString());
+ }
DocumentModelList domainChildrenList = repoSession.getChildren(domain.getRef());
- Iterator<DocumentModel> diter = domainChildrenList.iterator();
- while(diter.hasNext()){
- DocumentModel childNode = diter.next();
+ Iterator<DocumentModel> witer = domainChildrenList.iterator();
+ while(witer.hasNext()){
+ DocumentModel childNode = witer.next();
if("Workspaces".equalsIgnoreCase(childNode.getName())){
DocumentModelList workspaceList = repoSession.getChildren(childNode.getRef());
Iterator<DocumentModel> wsiter = workspaceList.iterator();
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.context.ServiceContext;
import org.collectionspace.services.common.repository.BadRequestException;
import org.collectionspace.services.common.repository.DocumentNotFoundException;
import org.collectionspace.services.common.repository.DocumentHandler;
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.PathRef;
import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
import org.nuxeo.ecm.core.client.NuxeoClient;
import org.slf4j.Logger;
*/
public class RepositoryJavaClient implements RepositoryClient {
- private final Logger logger = LoggerFactory
- .getLogger(RepositoryJavaClient.class);
+ private final Logger logger = LoggerFactory.getLogger(RepositoryJavaClient.class);
- public RepositoryJavaClient() {
- }
+ 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,
- DocumentHandler handler) throws BadRequestException,
- DocumentException {
+ /**
+ * create document in the Nuxeo repository
+ *
+ * @param ctx service context under which this method is invoked
+ * @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(ServiceContext ctx,
+ DocumentHandler handler) throws BadRequestException,
+ DocumentException {
- if (serviceName == null) {
- throw new IllegalArgumentException(
- "RemoteRepositoryClient.create: serviceName is missing");
- }
- if (handler.getDocumentType() == 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();
+ if(handler.getDocumentType() == null){
+ throw new IllegalArgumentException(
+ "RemoteRepositoryClient.create: docType is missing");
+ }
+ if(handler == null){
+ throw new IllegalArgumentException(
+ "RemoteRepositoryClient.create: handler is missing");
+ }
+ String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
+ if(nuxeoWspaceId == null){
+ throw new DocumentNotFoundException(
+ "Unable to find workspace for service " + ctx.getServiceName() +
+ " 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 " + handler.getDocumentType());
+ // create document model
+ DocumentModel doc = repoSession.createDocumentModel(wspacePath, id,
+ handler.getDocumentType());
+ ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+ DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
+ handler.handle(Action.CREATE, wrapDoc);
+ // create document with documentmodel
+ doc = repoSession.createDocument(doc);
+ repoSession.save();
+ handler.complete(Action.CREATE, wrapDoc);
+ return doc.getId();
+ }catch(Exception e){
+ if(logger.isDebugEnabled()){
+ logger.debug("Caught exception ", e);
+ }
+ throw new DocumentException(e);
+ }finally{
+ if(repoSession != null){
+ releaseRepositorySession(repoSession);
+ }
+ }
- DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId);
- DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace);
- String wspacePath = wspaceDoc.getPathAsString();
- String id = IdUtils.generateId("New " + handler.getDocumentType());
- // create document model
- DocumentModel doc = repoSession.createDocumentModel(wspacePath, id,
- handler.getDocumentType());
- ((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 ctx service context under which this method is invoked
+ * @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(ServiceContext ctx, String id, DocumentHandler handler)
+ throws DocumentNotFoundException, DocumentException {
- /**
- * 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;
- if (handler == null) {
- throw new IllegalArgumentException(
- "RemoteRepositoryClient.get: handler is missing");
- }
- RepositoryInstance repoSession = null;
+ try{
+ handler.prepare(Action.GET);
+ repoSession = getRepositorySession();
+ //FIXME, there is a potential privacy violation here, one tenant could
+ //retrieve doc id of another tenant and could retrieve the document
+ //PathRef does not seem to come to rescue as expected. Needs more thoughts.
+ 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);
+ }
+ //set reposession to handle the document
+ ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+ DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
+ handler.handle(Action.GET, wrapDoc);
+ handler.complete(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);
+ }
+ }
+ }
- 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 ctx service context under which this method is invoked
+ * @param handler
+ * should be used by the caller to provide and transform the
+ * document
+ * @throws DocumentException
+ */
+ @Override
+ public void getAll(ServiceContext ctx, DocumentHandler handler)
+ throws DocumentNotFoundException, DocumentException {
+ if(handler == null){
+ throw new IllegalArgumentException(
+ "RemoteRepositoryClient.getAll: handler is missing");
+ }
+ String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
+ if(nuxeoWspaceId == null){
+ throw new DocumentNotFoundException(
+ "Unable to find workspace for service " +
+ ctx.getServiceName() + " check if the mapping exists in service-config.xml or " +
+ " the the mapped workspace exists in the Nuxeo repository");
+ }
+ RepositoryInstance repoSession = null;
- /**
- * 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);
+ //set reposession to handle the document
+ ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+ DocumentModelListWrapper wrapDoc = new DocumentModelListWrapper(
+ docList);
+ handler.handle(Action.GET_ALL, wrapDoc);
+ handler.complete(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);
+ }
+ }
+ }
- try {
- handler.prepare(Action.GET_ALL);
- repoSession = getRepositorySession();
- DocumentRef wsDocRef = new IdRef(nuxeoWspaceId);
- DocumentModelList docList = repoSession.getChildren(wsDocRef);
+ /**
+ * update given document in the Nuxeo repository
+ *
+ * @param ctx service context under which this method is invoked
+ * @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(ServiceContext ctx, 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();
+ //FIXME, there is a potential privacy violation here, one tenant could
+ //retrieve doc id of another tenant and could retrieve the document
+ //PathRef does not seem to come to rescue as expected. Needs more thoughts.
+ 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);
+ }
+ //set reposession to handle the document
+ ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+ DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
+ handler.handle(Action.UPDATE, wrapDoc);
+ repoSession.saveDocument(doc);
+ repoSession.save();
+ handler.complete(Action.UPDATE, 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);
+ }
+ }
+ }
- ((DocumentModelHandler) handler).setRepositorySession(repoSession);
- DocumentModelListWrapper wrapDoc = new DocumentModelListWrapper(
- docList);
- handler.handle(Action.GET_ALL, wrapDoc);
+ /**
+ * delete a document from the Nuxeo repository
+ * @param ctx service context under which this method is invoked
+ * @param id
+ * of the document
+ * @throws DocumentException
+ */
+ @Override
+ public void delete(ServiceContext ctx, String id) throws DocumentNotFoundException,
+ DocumentException {
- } 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);
- }
- }
- }
+ if(logger.isDebugEnabled()){
+ logger.debug("deleting document with id=" + id);
+ }
+ RepositoryInstance repoSession = null;
+ try{
+ repoSession = getRepositorySession();
+ //FIXME, there is a potential privacy violation here, one tenant could
+ //retrieve doc id of another tenant and could retrieve the document
+ //PathRef does not seem to come to rescue as expected. needs more thoughts.
+ 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);
+ }
+ }
+ }
- /**
- * 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);
- }
- }
- }
+ 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;
+ }
- /**
- * 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
- }
- }
+ 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
+ }
+ }
}
import java.util.Map;
import org.collectionspace.services.common.ServiceConfig;
-import org.collectionspace.services.common.ServiceConfig.NuxeoClientConfig;
+import org.collectionspace.services.common.RepositoryClientConfigType;
import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.config.TenantBindingConfigReader;
+import org.collectionspace.services.common.context.ServiceContext;
import org.collectionspace.services.common.repository.BadRequestException;
import org.collectionspace.services.common.repository.DocumentNotFoundException;
import org.collectionspace.services.common.repository.DocumentHandler.Action;
}
@Override
- public String create(String serviceName, DocumentHandler handler) throws BadRequestException, DocumentException {
- if(serviceName == null){
- throw new IllegalArgumentException("RepositoryRESTClient.create: serviceName is missing");
- }
+ public String create(ServiceContext ctx, DocumentHandler handler) throws BadRequestException, DocumentException {
+
if(handler.getDocumentType() == 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);
+ String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
if(nuxeoWspaceId == null){
- throw new DocumentNotFoundException("Unable to find workspace for service " + serviceName +
+ throw new DocumentNotFoundException("Unable to find workspace for service " + ctx.getServiceName() +
" check if the mapping exists in service-config.xml or " +
" the the mapped workspace exists in the Nuxeo repository");
}
//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
+ repHandler.complete(Action.CREATE, wrapDoc);
return extractId(document);
}catch(Exception e){
}
@Override
- public void get(String id, DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
+ public void get(ServiceContext ctx, String id, DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
if(handler == null){
throw new IllegalArgumentException("RepositoryRESTClient.get: handler is missing");
Document document = executeRequest(request, completeURL, Status.SUCCESS_OK);
RepresentationWrapper wrapDoc = new RepresentationWrapper(document);
repHandler.handle(Action.GET, wrapDoc);
+ repHandler.complete(Action.GET, wrapDoc);
}catch(Exception e){
if(logger.isDebugEnabled()){
logger.debug("Caught exception ", e);
}
@Override
- public void getAll(String serviceName, DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
- if(serviceName == null){
- throw new IllegalArgumentException("RepositoryRESTClient.getAll: serviceName is missing");
- }
+ public void getAll(ServiceContext ctx, DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
if(handler == null){
throw new IllegalArgumentException("RepositoryRESTClient.getAll: handler is missing");
}
- ServiceMain smain = ServiceMain.getInstance();
- String nuxeoWspaceId = smain.getWorkspaceId(serviceName);
+ String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
if(nuxeoWspaceId == null){
- throw new DocumentNotFoundException("Unable to find workspace for service " + serviceName +
+ throw new DocumentNotFoundException("Unable to find workspace for service " + ctx.getServiceName() +
" check if the mapping exists in service-config.xml or " +
" the the mapped workspace exists in the Nuxeo repository");
}
Document document = executeRequest(request, completeURL, Status.SUCCESS_OK);
RepresentationWrapper wrapDoc = new RepresentationWrapper(document);
repHandler.handle(Action.GET_ALL, wrapDoc);
+ repHandler.complete(Action.GET_ALL, wrapDoc);
}catch(Exception e){
if(logger.isDebugEnabled()){
logger.debug("Caught exception ", e);
}
@Override
- public void update(String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException {
+ public void update(ServiceContext ctx, String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException {
if(handler == null){
throw new IllegalArgumentException("RepositoryRESTClient.update: handler is missing");
}
repHandler.handle(Action.UPDATE, wrapDoc);
Request request = buildRequest(Method.PUT, completeURL);
Document document = executeRequest(request, completeURL, Status.SUCCESS_OK);
-
+ repHandler.complete(Action.UPDATE, wrapDoc);
}catch(Exception e){
if(logger.isDebugEnabled()){
logger.debug("Caught exception ", e);
}
@Override
- public void delete(String id) throws DocumentNotFoundException, DocumentException {
+ public void delete(ServiceContext ctx, String id) throws DocumentNotFoundException, DocumentException {
if(logger.isDebugEnabled()){
logger.debug("deleting document with id=" + id);
private NuxeoRESTClient getNuxeoRestClient() {
if(nuxeoRestClient == null){
ServiceConfig sconfig = ServiceMain.getInstance().getServiceConfig();
- NuxeoClientConfig nxConfig = sconfig.getNuxeoClientConfig();
+ //assumption: there is only one client and that also is rest
+ RepositoryClientConfigType repConfig = sconfig.getRepositoryClient();
String protocol = "http";
- if(nxConfig.getProtocol() != null && !"".equals(nxConfig.getProtocol())){
- protocol = nxConfig.getProtocol();
+ if(repConfig.getProtocol() != null && !"".equals(repConfig.getProtocol())){
+ protocol = repConfig.getProtocol();
}
NuxeoRESTClient tempClient = new NuxeoRESTClient(protocol,
- nxConfig.getHost(), "" + nxConfig.getPort());
+ repConfig.getHost(), "" + repConfig.getPort());
- tempClient.setBasicAuthentication(nxConfig.getUser(), nxConfig.getPassword());
+ tempClient.setBasicAuthentication(repConfig.getUser(), repConfig.getPassword());
nuxeoRestClient = tempClient;
*/
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.common.repository.AbstractDocumentHandler;
import org.collectionspace.services.nuxeo.client.*;
-import org.dom4j.Document;
+import org.w3c.dom.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* $LastChangedDate: $
*/
public abstract class RepresentationHandler<T, TL>
- implements DocumentHandler<T, TL> {
+ extends AbstractDocumentHandler<T, TL> {
private final Logger logger = LoggerFactory.getLogger(RepresentationHandler.class);
- 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 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;
- }
- }
-
@Override
public void handleCreate(DocumentWrapper wrapDoc) throws Exception {
- if(getCommonObject() == null){
- String msg = "Error creating document: Missing input data";
- logger.error(msg);
- throw new IllegalStateException(msg);
- }
- //FIXME set other parts as well
- fillCommonObject(getCommonObject(), wrapDoc);
+ fillAllParts(wrapDoc);
}
@Override
public void handleUpdate(DocumentWrapper wrapDoc) throws Exception {
- if(getCommonObject() == null){
- String msg = "Error updating document: Missing input data";
- logger.error(msg);
- throw new IllegalStateException(msg);
- }
- //FIXME set other parts as well
- fillCommonObject(getCommonObject(), wrapDoc);
+ fillAllParts(wrapDoc);
}
@Override
public void handleGet(DocumentWrapper wrapDoc) throws Exception {
- setCommonObject(extractCommonObject(wrapDoc));
-
- //FIXME retrive other parts as well
+ extractAllParts(wrapDoc);
}
@Override
public void handleGetAll(DocumentWrapper wrapDoc) throws Exception {
- setCommonObjectList(extractCommonObjectList(wrapDoc));
+ setCommonPartList(extractCommonPartList(wrapDoc));
}
@Override
- public abstract T extractCommonObject(DocumentWrapper wrapDoc) throws Exception;
+ public void extractAllParts(DocumentWrapper wrapDoc) throws Exception {
+ setCommonPart(extractCommonPart(wrapDoc));
+
+ //FIXME retrive other parts as well
+ }
@Override
- public abstract void fillCommonObject(T obj, DocumentWrapper wrapDoc) throws Exception;
+ public abstract T extractCommonPart(DocumentWrapper wrapDoc) throws Exception;
@Override
- public abstract TL extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception;
+ public void fillAllParts(DocumentWrapper wrapDoc) throws Exception {
+ if(getCommonPart() == null){
+ String msg = "Error creating document: Missing input data";
+ logger.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ //FIXME set other parts as well
+ fillCommonPart(getCommonPart(), wrapDoc);
+ }
@Override
- public abstract void fillCommonObjectList(TL obj, DocumentWrapper wrapDoc) throws Exception;
+ public abstract void fillCommonPart(T obj, DocumentWrapper wrapDoc) throws Exception;
@Override
- public abstract T getCommonObject();
+ public abstract TL extractCommonPartList(DocumentWrapper wrapDoc) throws Exception;
@Override
- public abstract void setCommonObject(T obj);
+ public abstract T getCommonPart();
@Override
- public abstract TL getCommonObjectList();
+ public abstract void setCommonPart(T obj);
@Override
- public abstract void setCommonObjectList(TL obj);
+ public abstract TL getCommonPartList();
@Override
- public Document getDocument(DocumentWrapper wrapDoc) throws DocumentException {
- throw new UnsupportedOperationException("DocumentHandler.getDocument(wrapDoc)");
- }
+ public abstract void setCommonPartList(TL obj);
/**
* @return the pathParams
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;
- }
}
}
return doc;
}
-
-/**
- * Gets the document.
- *
- * @param repoSession the repo session
- * @param csid the csid
- *
- * @return the document
- *
- * @throws DocumentException the document exception
- */
-public static Document getDocument(RepositoryInstance repoSession, String csid)
- throws DocumentException {
- Document result = null;
-
- DocumentModel docModel = getDocumentModel(repoSession, csid);
- result = getDocument(repoSession, docModel);
-
- return result;
- }
-
- /**
- * Gets the workspace model.
- *
- * @param repoSession the repo session
- * @param workspaceName the workspace name
- *
- * @return the workspace model
- *
- * @throws DocumentException the document exception
- * @throws IOException Signals that an I/O exception has occurred.
- * @throws ClientException the client exception
- */
- public static DocumentModel getWorkspaceModel(
- RepositoryInstance repoSession, String workspaceName)
- throws DocumentException, IOException, ClientException {
- DocumentModel result = null;
-
- String workspaceUUID = ServiceMain.getInstance().getWorkspaceId(
- workspaceName);
- DocumentRef workspaceRef = new IdRef(workspaceUUID);
- result = repoSession.getDocument(workspaceRef);
-
- return result;
- }
-
- /**
- * Gets the document model.
- *
- * @param repoSession the repo session
- * @param csid the csid
- *
- * @return the document model
- *
- * @throws DocumentException the document exception
- */
- public static DocumentModel getDocumentModel(
- RepositoryInstance repoSession, String csid)
- throws DocumentException {
- DocumentModel result = null;
-
- try {
- DocumentRef documentRef = new IdRef(csid);
- result = repoSession.getDocument(documentRef);
- } catch (ClientException e) {
- e.printStackTrace();
- }
-
- return result;
- }
-
+
+ /**
+ * Gets the document.
+ *
+ * @param repoSession the repo session
+ * @param csid the csid
+ *
+ * @return the document
+ *
+ * @throws DocumentException the document exception
+ */
+ public static Document getDocument(RepositoryInstance repoSession, String csid)
+ throws DocumentException {
+ Document result = null;
+
+ DocumentModel docModel = getDocumentModel(repoSession, csid);
+ result = getDocument(repoSession, docModel);
+
+ return result;
+ }
+
+ /**
+ * Gets the workspace model.
+ *
+ * @param repoSession the repo session
+ * @param workspaceName the workspace name
+ *
+ * @return the workspace model
+ *
+ * @throws DocumentException the document exception
+ * @throws IOException Signals that an I/O exception has occurred.
+ * @throws ClientException the client exception
+ */
+ public static DocumentModel getWorkspaceModel(
+ RepositoryInstance repoSession, String workspaceName)
+ throws DocumentException, IOException, ClientException {
+ DocumentModel result = null;
+ //FIXME: commented out as this does not work without tenant qualification
+ String workspaceUUID = null;
+// String workspaceUUID = ServiceMain.getInstance().getWorkspaceId(
+// workspaceName);
+ DocumentRef workspaceRef = new IdRef(workspaceUUID);
+ result = repoSession.getDocument(workspaceRef);
+
+ return result;
+ }
+
+ /**
+ * Gets the document model.
+ *
+ * @param repoSession the repo session
+ * @param csid the csid
+ *
+ * @return the document model
+ *
+ * @throws DocumentException the document exception
+ */
+ public static DocumentModel getDocumentModel(
+ RepositoryInstance repoSession, String csid)
+ throws DocumentException {
+ DocumentModel result = null;
+
+ try{
+ DocumentRef documentRef = new IdRef(csid);
+ result = repoSession.getDocument(documentRef);
+ }catch(ClientException e){
+ e.printStackTrace();
+ }
+
+ return result;
+ }
}
--- /dev/null
+\r
+--This line, and those below, will be ignored--\r
+\r
+M common/repository/RepositoryClient.java\r
<xs:element name="service-config">
<xs:complexType>
<xs:sequence>
- <xs:element name="nuxeo-client-config" minOccurs="1" maxOccurs="1">
- <xs:complexType>
- <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:element name="nuxeo-workspace" minOccurs="0" maxOccurs="1" >
- <xs:complexType>
- <xs:sequence>
- <xs:element name="workspace" maxOccurs="unbounded" >
- <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:sequence>
- </xs:complexType>
- </xs:element>
+ <!-- assumption: there is only one type of repository client used -->
+ <xs:element name="repository-client" type="RepositoryClientConfigType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="repository-workspace" type="RepositoryWorkspaceType" minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
- <!-- enumeration defining the type nuxeo client -->
- <xs:simpleType name="NuxeoClientType">
+ <xs:complexType name="RepositoryClientConfigType">
+ <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" />
+ <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" />
+ <!-- default client is java -->
+ <xs:element name="client-type" type="ClientType" minOccurs="1" maxOccurs="1" />
+ <!-- default client is org.collectionspace.services.nuxeo.client.java.RepositoryJavaClient -->
+ <xs:element name="client-class" type="xs:string" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ <!-- name of the client -->
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="default" type="xs:boolean" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="RepositoryWorkspaceType">
+ <xs:sequence>
+ <xs:element name="workspace" maxOccurs="unbounded" >
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="service-name" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <!-- workspace name is required for Repository Java client -->
+ <xs:element name="workspace-name" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <!-- workspace ids are required only for Repository REST client -->
+ <xs:element name="workspace-id" type="xs:string" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- enumeration defining the type repository client -->
+ <xs:simpleType name="ClientType">
<xs:restriction base="xs:string">
<xs:enumeration value="java" />
<xs:enumeration value="rest" />
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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
+
+ Document : service.xsd
+ Revision : $LastChangedRevision: $
+ Created on : $LastChangedDate: $
+ Author : $LastChangedBy: $
+ Description: ServiceBinding desribes how a possibly tenant-specific service is
+ bound to corresponding service framework at runtime
+ ServiceObjectType is used to describe the
+ structure of a CollectionSpace object - an entity or relation.
+ This is NOT used to encode or decode the stream in or out the
+ content over the wire or to the storage.
+ Derived from Fedora Digtial Object Model and MIME Multipart
+-->
+<xs:schema
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns="http://collectionspace.org/services/common/service"
+ xmlns:types="http://collectionspace.org/services/common/types"
+ targetNamespace="http://collectionspace.org/services/common/service"
+ version="0.1"
+ elementFormDefault="qualified"
+>
+
+ <xs:import namespace="http://collectionspace.org/services/common/types" schemaLocation="types.xsd" />
+
+ <xs:complexType name="ServiceBindingType">
+ <xs:sequence>
+ <!-- object(s) served by the service -->
+ <xs:element name="object" type="ServiceObjectType" minOccurs="1" maxOccurs="unbounded"/>
+
+ <!-- name of the repository client (from service-config.xml) -->
+ <xs:element name="repositoryClient" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <!-- repositoryWorkspaceId could be workspace id -->
+ <!-- used only for Nuxeo rest client -->
+ <xs:element name="repositoryWorkspaceId" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="version" type="types:VersionType" use="required"/>
+ </xs:complexType>
+
+ <!--
+ ServiceObjectType defines the manifest for a collectionspace
+ object. includes properties of the object as well as manifests
+ for zero or more parts of the object.
+ -->
+ <xs:complexType name="ServiceObjectType">
+ <xs:annotation>
+ <xs:documentation/>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="property" type="types:PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="part" type="ObjectPartType" minOccurs="0" maxOccurs="unbounded"/>
+ <!-- a handler Java class to process the content of this service -->
+ <xs:element name="serviceHandler" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute name="id" type="xs:ID" use="required"/>
+ <!-- the object name could be collectionobject|intake|location, etc. -->
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="version" type="types:VersionType" use="required"/>
+ </xs:complexType>
+
+
+ <!---
+ ObjectPartType describes a part of an object
+ -->
+ <xs:complexType name="ObjectPartType">
+ <xs:annotation>
+ <xs:documentation/>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="properties" type="types:PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="content" type="ObjectPartContentType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute name="id" type="xs:ID" use="required"/>
+ <!-- control group indicates where the content resides -->
+ <xs:attribute name="control_group" use="required">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <!-- managed by an external repository such as MediaVault -->
+ <xs:enumeration value="External"/>
+ <!-- managed by CollectionSpace -->
+ <xs:enumeration value="Managed"/>
+ <!-- inlined from this manifest -->
+ <xs:enumeration value="Inline"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="versionable" type="xs:boolean" use="optional" default="true"/>
+ <xs:attribute name="auditable" type="xs:boolean" use="optional" default="true"/>
+ <!-- application defined label to identify the part, e.g. collectionobject.ucmp.berkeley -->
+ <xs:attribute name="label" type="xs:string" use="optional"/>
+ <xs:attribute name="updated" type="xs:dateTime" use="optional"/>
+ <!-- order in the sequence of one or more parts -->
+ <xs:attribute name="order" type="xs:int" use="optional"/>
+ </xs:complexType>
+
+ <!--
+ ObjectPartContentType describes the content of a part as well as provides
+ information about how to handle the part
+ -->
+ <xs:complexType name="ObjectPartContentType">
+ <xs:sequence>
+ <xs:element name="contentDigest" type="ContentDigestType" minOccurs="0"/>
+ <xs:choice>
+ <xs:element name="xmlContent" type="XmlContentType"/>
+ <xs:element name="contentLocation" type="ContentLocationType"/>
+ <xs:element name="binaryContent" type="xs:base64Binary"/>
+ </xs:choice>
+ <!-- a handler Java class to process the content of this part -->
+ <xs:element name="partHandler" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ <!-- MIME content type -->
+ <xs:attribute name="contentType" type="xs:string" use="required"/>
+ </xs:complexType>
+
+ <!--
+ content digest provides information about the digest algorithm used
+ and the digest itself
+ -->
+ <xs:complexType name="ContentDigestType">
+ <xs:attribute name="algorithm" use="required">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="MD5"/>
+ <xs:enumeration value="SHA-1"/>
+ <xs:enumeration value="SHA-256"/>
+ <xs:enumeration value="SHA-384"/>
+ <xs:enumeration value="SHA-512"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="value" type="xs:string" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="XmlContentType">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="skip" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ <!-- location to retrieve the schema from -->
+ <!-- in fact, schema should be retrievable by the parser, validator -->
+ <xs:attribute name="schemaLocation" type="xs:string" use="optional"/>
+ <xs:attribute name="namespaceURI" type="xs:string" use="optional"/>
+ </xs:complexType>
+
+ <xs:complexType name="ContentLocationType">
+ <xs:attribute name="type" use="required">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="internalId"/>
+ <xs:enumeration value="URL"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="ref" use="required">
+ <xs:simpleType>
+ <xs:restriction base="xs:anyURI">
+ <xs:minLength value="1"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+
+</xs:schema>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ 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
+
+ Document : tenant-binding.xsd
+ Revision : $LastChangedRevision: $
+ Created on : $LastChangedDate: $
+ Description:
+
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns="http://collectionspace.org/services/common/tenant"
+ xmlns:types="http://collectionspace.org/services/common/types"
+ xmlns:service="http://collectionspace.org/services/common/service"
+ targetNamespace="http://collectionspace.org/services/common/tenant"
+ version="0.1"
+ elementFormDefault="qualified">
+
+ <xs:import namespace="http://collectionspace.org/services/common/types" schemaLocation="types.xsd" />
+ <xs:import namespace="http://collectionspace.org/services/common/service" schemaLocation="service.xsd" />
+
+ <xs:element name="TenantBindingConfig">
+ <xs:annotation>
+ <xs:documentation/>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="tenantBinding" type="TenantBindingType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <!--
+ TenantBindingType describes bindings for each tenant in CollectionSpace
+ -->
+ <xs:complexType name="TenantBindingType">
+ <xs:sequence>
+ <xs:element name="serviceBindings" type="service:ServiceBindingType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <!-- tenant id, a UUID -->
+ <xs:attribute name="id" type="xs:ID" use="required"/>
+ <!-- domain name including subdomain but not TLD -->
+ <!-- e.g. hearstmuseum.berkeley or movingimage.us -->
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ <!-- display name as Museum of Moving Images -->
+ <xs:attribute name="displayName" type="xs:string" use="required"/>
+ <xs:attribute name="version" type="types:VersionType" use="required"/>
+ <!-- repository domain -->
+ <xs:attribute name="repositoryDomain" type="xs:string" use="optional" default="default-domain"/>
+ </xs:complexType>
+
+</xs:schema>
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ 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
+
+ Document : types.xsd
+ Revision : $LastChangedRevision: $
+ Created on : $LastChangedDate: $
+ Description:
+
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns="http://collectionspace.org/services/common/types"
+ targetNamespace="http://collectionspace.org/services/common/types"
+ elementFormDefault="qualified"
+>
+ <!--
+ PropertyType defines the type for property in the property bag
+ -->
+ <xs:complexType name="PropertyType">
+ <xs:sequence>
+ <xs:element name="item" type="PropertyItemType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="PropertyItemType">
+ <xs:sequence>
+ <xs:element name="key" type="xs:string"/>
+ <xs:element name="value" type="xs:string"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="VersionType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="1.0"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+</xs:schema>
\ No newline at end of file
--- /dev/null
+\r
+--This line, and those below, will be ignored--\r
+\r
+D resources/common.xsd\r
+A resources/system-response.xsd\r
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
- <version>2.1.2</version>
</dependency>
</dependencies>
<configuration>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.3.2-SNAPSHOT</version>
- </dependency>
+ </dependency>
</dependencies>
<?xml version="1.0"?>
<component name="org.collectionspace.intake.coreTypes">
<extension target="org.nuxeo.ecm.core.schema.TypeService" point="schema">
- <schema name="intake" prefix="intake" src="schemas/intake.xsd"/>
+ <schema name="intakes-common" prefix="intakes-common" src="schemas/intakes-common.xsd"/>
</extension>
<extension target="org.nuxeo.ecm.core.schema.TypeService" point="doctype">
<doctype name="Intake" extends="Document">
<schema name="common"/>
<schema name="dublincore"/>
- <schema name="intake"/>
+ <schema name="intakes-common"/>
</doctype>
</extension>
</component>
import javax.ws.rs.core.Response;
-import org.collectionspace.services.intake.Intake;
-import org.collectionspace.services.intake.IntakeList;
+import org.collectionspace.services.intake.IntakesCommonList;
import org.jboss.resteasy.client.ProxyFactory;
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
/**
* @return
* @see org.collectionspace.hello.client.IntakeProxy#getIntake()
*/
- public ClientResponse<IntakeList> readList() {
+ public ClientResponse<IntakesCommonList> readList() {
return intakeProxy.readList();
}
* @return
* @see org.collectionspace.hello.client.IntakeProxy#getIntake(java.lang.String)
*/
- public ClientResponse<Intake> read(String csid) {
+
+ public ClientResponse<MultipartInput> read(String csid) {
return intakeProxy.read(csid);
}
* @return
* @see org.collectionspace.hello.client.IntakeProxy#createIntake(org.collectionspace.hello.Intake)
*/
- public ClientResponse<Response> create(Intake intake) {
- return intakeProxy.create(intake);
+ public ClientResponse<Response> create(MultipartOutput multipart) {
+ return intakeProxy.create(multipart);
}
/**
* @return
* @see org.collectionspace.hello.client.IntakeProxy#updateIntake(java.lang.Long, org.collectionspace.hello.Intake)
*/
- public ClientResponse<Intake> update(String csid, Intake intake) {
- return intakeProxy.update(csid, intake);
+ public ClientResponse<MultipartInput> update(String csid, MultipartOutput multipart) {
+ return intakeProxy.update(csid, multipart);
+
}
/**
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
-import org.collectionspace.services.intake.Intake;
-import org.collectionspace.services.intake.IntakeList;
+import org.collectionspace.services.intake.IntakesCommonList;
import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
/**
* @version $Revision:$
*/
@Path("/intakes/")
-@Produces({"application/xml"})
-@Consumes({"application/xml"})
+@Produces({"multipart/mixed"})
+@Consumes({"multipart/mixed"})
public interface IntakeProxy {
@GET
- ClientResponse<IntakeList> readList();
+ @Produces({"application/xml"})
+ ClientResponse<IntakesCommonList> readList();
//(C)reate
@POST
- ClientResponse<Response> create(Intake co);
+ ClientResponse<Response> create(MultipartOutput multipart);
//(R)ead
@GET
@Path("/{csid}")
- ClientResponse<Intake> read(@PathParam("csid") String csid);
+ ClientResponse<MultipartInput> read(@PathParam("csid") String csid);
//(U)pdate
@PUT
@Path("/{csid}")
- ClientResponse<Intake> update(@PathParam("csid") String csid, Intake co);
+ ClientResponse<MultipartInput> update(@PathParam("csid") String csid, MultipartOutput multipart);
//(D)elete
@DELETE
@Path("/{csid}")
ClientResponse<Response> delete(@PathParam("csid") String csid);
-}
\ No newline at end of file
+}
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
- package org.collectionspace.services.client.test;
+package org.collectionspace.services.client.test;
import java.util.List;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
import org.collectionspace.services.client.IntakeClient;
-import org.collectionspace.services.client.test.ServiceRequestType;
-import org.collectionspace.services.intake.Intake;
-import org.collectionspace.services.intake.IntakeList;
+import org.collectionspace.services.intake.IntakesCommon;
+import org.collectionspace.services.intake.IntakesCommonList;
import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
+import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
import org.testng.Assert;
import org.testng.annotations.Test;
/**
* IntakeServiceTest, carries out tests against a
* deployed and running Intake Service.
- *
+ *
* $LastChangedRevision$
* $LastChangedDate$
*/
final String SERVICE_PATH_COMPONENT = "intakes";
private String knownResourceId = null;
-
// ---------------------------------------------------------------
// CRUD tests : CREATE tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
@Test
public void create() {
// Submit the request to the service and store the response.
String identifier = createIdentifier();
- Intake intake = createIntakeInstance(identifier);
- ClientResponse<Response> res = client.create(intake);
+
+ MultipartOutput multipart = createIntakeInstance(identifier);
+ ClientResponse<Response> res = client.create(multipart);
+
int statusCode = res.getStatus();
// Check the status code of the response: does it match
// Does it exactly match the expected status code?
verbose("create: status = " + statusCode);
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
- // Store the ID returned from this create operation for
- // additional tests below.
+ // Store the ID returned from this create operation
+ // for additional tests below.
knownResourceId = extractId(res);
+ verbose("create: knownResourceId=" + knownResourceId);
}
@Override
}
// Failure outcomes
-
// Placeholders until the three tests below can be uncommented.
// See Issue CSPACE-401.
- public void createWithEmptyEntityBody() {}
- public void createWithMalformedXml() {}
- public void createWithWrongXmlSchema() {}
+ public void createWithEmptyEntityBody() {
+ }
+
+ public void createWithMalformedXml() {
+ }
+
+ public void createWithWrongXmlSchema() {
+ }
-/*
+ /*
@Override
@Test(dependsOnMethods = {"create", "testSubmitRequest"})
public void createWithEmptyEntityBody() {
-
- // Perform setup.
- setupCreateWithEmptyEntityBody();
- // Submit the request to the service and store the response.
- String method = REQUEST_TYPE.httpMethodName();
- String url = getServiceRootURL();
- String mediaType = MediaType.APPLICATION_XML;
- final String entity = "";
- int statusCode = submitRequest(method, url, mediaType, entity);
-
- // Check the status code of the response: does it match
- // the expected response(s)?
- verbose("createWithEmptyEntityBody url=" + url + " status=" + statusCode);
- Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
- Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+ // Perform setup.
+ setupCreateWithEmptyEntityBody();
+
+ // Submit the request to the service and store the response.
+ String method = REQUEST_TYPE.httpMethodName();
+ String url = getServiceRootURL();
+ String mediaType = MediaType.APPLICATION_XML;
+ final String entity = "";
+ int statusCode = submitRequest(method, url, mediaType, entity);
+
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ verbose("createWithEmptyEntityBody url=" + url + " status=" + statusCode);
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
@Override
@Test(dependsOnMethods = {"create", "testSubmitRequest"})
public void createWithMalformedXml() {
-
- // Perform setup.
- setupCreateWithMalformedXml();
- // Submit the request to the service and store the response.
- String method = REQUEST_TYPE.httpMethodName();
- String url = getServiceRootURL();
- String mediaType = MediaType.APPLICATION_XML;
- final String entity = MALFORMED_XML_DATA; // Constant from base class.
- int statusCode = submitRequest(method, url, mediaType, entity);
-
- // Check the status code of the response: does it match
- // the expected response(s)?
- verbose("createWithMalformedXml url=" + url + " status=" + statusCode);
- Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
- Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+ // Perform setup.
+ setupCreateWithMalformedXml();
+
+ // Submit the request to the service and store the response.
+ String method = REQUEST_TYPE.httpMethodName();
+ String url = getServiceRootURL();
+ String mediaType = MediaType.APPLICATION_XML;
+ final String entity = MALFORMED_XML_DATA; // Constant from base class.
+ int statusCode = submitRequest(method, url, mediaType, entity);
+
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ verbose("createWithMalformedXml url=" + url + " status=" + statusCode);
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
@Override
@Test(dependsOnMethods = {"create", "testSubmitRequest"})
public void createWithWrongXmlSchema() {
-
- // Perform setup.
- setupCreateWithWrongXmlSchema();
-
- // Submit the request to the service and store the response.
- String method = REQUEST_TYPE.httpMethodName();
- String url = getServiceRootURL();
- String mediaType = MediaType.APPLICATION_XML;
- final String entity = WRONG_XML_SCHEMA_DATA;
- int statusCode = submitRequest(method, url, mediaType, entity);
-
- // Check the status code of the response: does it match
- // the expected response(s)?
- verbose("createWithWrongSchema url=" + url + " status=" + statusCode);
- Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
- Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
- }
-*/
+ // Perform setup.
+ setupCreateWithWrongXmlSchema();
+
+ // Submit the request to the service and store the response.
+ String method = REQUEST_TYPE.httpMethodName();
+ String url = getServiceRootURL();
+ String mediaType = MediaType.APPLICATION_XML;
+ final String entity = WRONG_XML_SCHEMA_DATA;
+ int statusCode = submitRequest(method, url, mediaType, entity);
+
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ verbose("createWithWrongSchema url=" + url + " status=" + statusCode);
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+ }
+ */
// ---------------------------------------------------------------
// CRUD tests : READ tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
@Test(dependsOnMethods = {"create"})
public void read() {
-
+
// Perform setup.
setupRead();
// Submit the request to the service and store the response.
- ClientResponse<Intake> res = client.read(knownResourceId);
+ ClientResponse<MultipartInput> res = client.read(knownResourceId);
int statusCode = res.getStatus();
-
+
// Check the status code of the response: does it match
// the expected response(s)?
verbose("read: status = " + statusCode);
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+ //FIXME: remove the following try catch once Aron fixes signatures
+ try{
+ MultipartInput input = (MultipartInput) res.getEntity();
+ IntakesCommon intake = (IntakesCommon) extractPart(input,
+ getCommonPartName(), IntakesCommon.class);
+ Assert.assertNotNull(intake);
+ }catch(Exception e){
+ throw new RuntimeException(e);
+ }
}
// Failure outcomes
-
@Override
@Test(dependsOnMethods = {"read"})
public void readNonExistent() {
// Perform setup.
setupReadNonExistent();
-
+
// Submit the request to the service and store the response.
- ClientResponse<Intake> res = client.read(NON_EXISTENT_ID);
+ ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
int statusCode = res.getStatus();
// Check the status code of the response: does it match
// the expected response(s)?
verbose("readNonExistent: status = " + res.getStatus());
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
-
// ---------------------------------------------------------------
// CRUD tests : READ_LIST tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
- @Test(dependsOnMethods = {"createList"})
+ @Test(dependsOnMethods = {"read"})
public void readList() {
-
+
// Perform setup.
setupReadList();
// Submit the request to the service and store the response.
- ClientResponse<IntakeList> res = client.readList();
- IntakeList list = res.getEntity();
+ ClientResponse<IntakesCommonList> res = client.readList();
+ IntakesCommonList list = res.getEntity();
int statusCode = res.getStatus();
// Check the status code of the response: does it match
// the expected response(s)?
verbose("readList: status = " + res.getStatus());
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
// Optionally output additional data about list members for debugging.
boolean iterateThroughList = false;
- if (iterateThroughList && logger.isDebugEnabled()) {
- List<IntakeList.IntakeListItem> items =
- list.getIntakeListItem();
+ if(iterateThroughList && logger.isDebugEnabled()){
+ List<IntakesCommonList.IntakeListItem> items =
+ list.getIntakeListItem();
int i = 0;
- for(IntakeList.IntakeListItem item : items){
+ for(IntakesCommonList.IntakeListItem item : items){
verbose("readList: list-item[" + i + "] csid=" +
- item.getCsid());
+ item.getCsid());
verbose("readList: list-item[" + i + "] objectNumber=" +
- item.getEntryNumber());
+ item.getEntryNumber());
verbose("readList: list-item[" + i + "] URI=" +
- item.getUri());
+ item.getUri());
i++;
}
}
-
+
}
// Failure outcomes
-
// None at present.
-
-
// ---------------------------------------------------------------
// CRUD tests : UPDATE tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
- @Test(dependsOnMethods = {"create"})
+ @Test(dependsOnMethods = {"read"})
public void update() {
-
+
// Perform setup.
setupUpdate();
- // Retrieve an existing resource that we can update.
- ClientResponse<Intake> res = client.read(knownResourceId);
- verbose("read: status = " + res.getStatus());
- Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
- Intake intake = res.getEntity();
- verbose("Got object to update with ID: " + knownResourceId,
- intake, Intake.class);
-
- // Update the content of this resource.
- intake.setEntryNumber("updated-" + intake.getEntryNumber());
- intake.setEntryDate("updated-" + intake.getEntryDate());
-
- // Submit the request to the service and store the response.
- res = client.update(knownResourceId, intake);
- int statusCode = res.getStatus();
- Intake updatedObject = res.getEntity();
-
- // Check the status code of the response: does it match
- // the expected response(s)?
- verbose("update: status = " + res.getStatus());
- Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
- Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
-
- // Check the contents of the response: does it match
- // what was submitted?
- verbose("update: ", updatedObject, Intake.class);
- Assert.assertEquals(updatedObject.getEntryDate(),
- intake.getEntryDate(),
- "Data in updated object did not match submitted data.");
+ try{ //ideally, just remove try-catch and let the exception bubble up
+ // Retrieve an existing resource that we can update.
+ ClientResponse<MultipartInput> res =
+ client.read(knownResourceId);
+ verbose("update: read status = " + res.getStatus());
+ Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
+
+ verbose("got object to update with ID: " + knownResourceId);
+ MultipartInput input = (MultipartInput) res.getEntity();
+ IntakesCommon intake = (IntakesCommon) extractPart(input,
+ getCommonPartName(), IntakesCommon.class);
+ Assert.assertNotNull(intake);
+
+ // Update the content of this resource.
+ // Update the content of this resource.
+ intake.setEntryNumber("updated-" + intake.getEntryNumber());
+ intake.setEntryDate("updated-" + intake.getEntryDate());
+ verbose("to be updated object", intake, IntakesCommon.class);
+ // Submit the request to the service and store the response.
+ MultipartOutput output = new MultipartOutput();
+ OutputPart commonPart = output.addPart(intake, MediaType.APPLICATION_XML_TYPE);
+ commonPart.getHeaders().add("label", getCommonPartName());
+
+ res = client.update(knownResourceId, output);
+ int statusCode = res.getStatus();
+ // Check the status code of the response: does it match the expected response(s)?
+ verbose("update: status = " + res.getStatus());
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+
+
+ input = (MultipartInput) res.getEntity();
+ IntakesCommon updatedIntake =
+ (IntakesCommon) extractPart(input,
+ getCommonPartName(), IntakesCommon.class);
+ Assert.assertNotNull(updatedIntake);
+
+ Assert.assertEquals(updatedIntake.getEntryDate(),
+ intake.getEntryDate(),
+ "Data in updated object did not match submitted data.");
+ }catch(Exception e){
+ e.printStackTrace();
+ }
}
// Failure outcomes
-
// Placeholders until the three tests below can be uncommented.
// See Issue CSPACE-401.
- public void updateWithEmptyEntityBody() {}
- public void updateWithMalformedXml() {}
- public void updateWithWrongXmlSchema() {}
+ public void updateWithEmptyEntityBody() {
+ }
+
+ public void updateWithMalformedXml() {
+ }
+
+ public void updateWithWrongXmlSchema() {
+ }
-/*
+ /*
@Override
@Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
public void updateWithEmptyEntityBody() {
-
- // Perform setup.
- setupUpdateWithEmptyEntityBody();
- // Submit the request to the service and store the response.
- String method = REQUEST_TYPE.httpMethodName();
- String url = getResourceURL(knownResourceId);
- String mediaType = MediaType.APPLICATION_XML;
- final String entity = "";
- int statusCode = submitRequest(method, url, mediaType, entity);
-
- // Check the status code of the response: does it match
- // the expected response(s)?
- verbose("updateWithEmptyEntityBody url=" + url + " status=" + statusCode);
- Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
- Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+ // Perform setup.
+ setupUpdateWithEmptyEntityBody();
+
+ // Submit the request to the service and store the response.
+ String method = REQUEST_TYPE.httpMethodName();
+ String url = getResourceURL(knownResourceId);
+ String mediaType = MediaType.APPLICATION_XML;
+ final String entity = "";
+ int statusCode = submitRequest(method, url, mediaType, entity);
+
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ verbose("updateWithEmptyEntityBody url=" + url + " status=" + statusCode);
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
@Override
@Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
public void updateWithMalformedXml() {
- // Perform setup.
- setupUpdateWithMalformedXml();
-
- // Submit the request to the service and store the response.
- String method = REQUEST_TYPE.httpMethodName();
- String url = getResourceURL(knownResourceId);
- String mediaType = MediaType.APPLICATION_XML;
- final String entity = MALFORMED_XML_DATA;
- int statusCode = submitRequest(method, url, mediaType, entity);
-
- // Check the status code of the response: does it match
- // the expected response(s)?
- verbose("updateWithMalformedXml: url=" + url + " status=" + statusCode);
- Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
- Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+ // Perform setup.
+ setupUpdateWithMalformedXml();
+
+ // Submit the request to the service and store the response.
+ String method = REQUEST_TYPE.httpMethodName();
+ String url = getResourceURL(knownResourceId);
+ String mediaType = MediaType.APPLICATION_XML;
+ final String entity = MALFORMED_XML_DATA;
+ int statusCode = submitRequest(method, url, mediaType, entity);
+
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ verbose("updateWithMalformedXml: url=" + url + " status=" + statusCode);
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
@Override
@Test(dependsOnMethods = {"create", "update", "testSubmitRequest"})
public void updateWithWrongXmlSchema() {
-
- // Perform setup.
- setupUpdateWithWrongXmlSchema();
-
- // Submit the request to the service and store the response.
- String method = REQUEST_TYPE.httpMethodName();
- String url = getResourceURL(knownResourceId);
- String mediaType = MediaType.APPLICATION_XML;
- final String entity = WRONG_XML_SCHEMA_DATA;
- int statusCode = submitRequest(method, url, mediaType, entity);
-
- // Check the status code of the response: does it match
- // the expected response(s)?
- verbose("updateWithWrongSchema: url=" + url + " status=" + statusCode);
- Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
- Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
- }
-*/
+ // Perform setup.
+ setupUpdateWithWrongXmlSchema();
+
+ // Submit the request to the service and store the response.
+ String method = REQUEST_TYPE.httpMethodName();
+ String url = getResourceURL(knownResourceId);
+ String mediaType = MediaType.APPLICATION_XML;
+ final String entity = WRONG_XML_SCHEMA_DATA;
+ int statusCode = submitRequest(method, url, mediaType, entity);
+
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ verbose("updateWithWrongSchema: url=" + url + " status=" + statusCode);
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+ }
+ */
@Override
@Test(dependsOnMethods = {"update", "testSubmitRequest"})
public void updateNonExistent() {
// Submit the request to the service and store the response.
// Note: The ID used in this 'create' call may be arbitrary.
// The only relevant ID may be the one used in update(), below.
- Intake intake = createIntakeInstance(NON_EXISTENT_ID);
- ClientResponse<Intake> res =
- client.update(NON_EXISTENT_ID, intake);
+
+ // The only relevant ID may be the one used in update(), below.
+ MultipartOutput multipart = createIntakeInstance(NON_EXISTENT_ID);
+ ClientResponse<MultipartInput> res =
+ client.update(NON_EXISTENT_ID, multipart);
int statusCode = res.getStatus();
// Check the status code of the response: does it match
// the expected response(s)?
verbose("updateNonExistent: status = " + res.getStatus());
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
// ---------------------------------------------------------------
// CRUD tests : DELETE tests
// ---------------------------------------------------------------
-
// Success outcomes
-
@Override
- @Test(dependsOnMethods =
- {"create", "read", "update"})
+ @Test(dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
public void delete() {
// Perform setup.
// the expected response(s)?
verbose("delete: status = " + res.getStatus());
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
// Failure outcomes
-
@Override
@Test(dependsOnMethods = {"delete"})
public void deleteNonExistent() {
// the expected response(s)?
verbose("deleteNonExistent: status = " + res.getStatus());
Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
- invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
}
-
// ---------------------------------------------------------------
// Utility tests : tests of code used in tests above
// ---------------------------------------------------------------
-
/**
* Tests the code for manually submitting data that is used by several
* of the methods above.
String method = ServiceRequestType.READ.httpMethodName();
String url = getResourceURL(knownResourceId);
int statusCode = submitRequest(method, url);
-
+
// Check the status code of the response: does it match
// the expected response(s)?
verbose("testSubmitRequest: url=" + url + " status=" + statusCode);
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
- }
+ }
// ---------------------------------------------------------------
// Utility methods used by tests above
// ---------------------------------------------------------------
-
@Override
public String getServicePathComponent() {
return SERVICE_PATH_COMPONENT;
}
-
- private Intake createIntakeInstance(String identifier) {
- Intake intake =
- createIntakeInstance(
+
+ private MultipartOutput createIntakeInstance(String identifier) {
+ return createIntakeInstance(
"entryNumber-" + identifier,
"entryDate-" + identifier);
- return intake;
}
-
- private Intake createIntakeInstance(String entryNumber, String entryDate) {
- Intake intake = new Intake();
+
+ private MultipartOutput createIntakeInstance(String entryNumber, String entryDate) {
+ IntakesCommon intake = new IntakesCommon();
intake.setEntryNumber(entryNumber);
intake.setEntryDate(entryDate);
- return intake;
- }
+ MultipartOutput multipart = new MultipartOutput();
+ OutputPart commonPart = multipart.addPart(intake, MediaType.APPLICATION_XML_TYPE);
+ commonPart.getHeaders().add("label", getCommonPartName());
+
+ verbose("to be created, intake common ", intake, IntakesCommon.class);
+ return multipart;
+ }
}
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
- <version>2.1.2</version>
- </dependency>
+ <version>2.1.9</version>
+ </dependency>
</dependencies>
<configuration>
<args>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:ns="http://collectionspace.org/intake"
- xmlns="http://collectionspace.org/intake"
- targetNamespace="http://services.collectionspace.org/intake"
+ xmlns:ns="http://collectionspace.org/services/intake"
+ xmlns="http://collectionspace.org/services/intake"
+ targetNamespace="http://collectionspace.org/services/intake"
version="0.1"
>
<!-- See http://wiki.collectionspace.org/display/collectionspace/Intake+Schema -->
<!-- intake -->
- <xs:element name="intake">
+ <xs:element name="intakes-common">
<xs:complexType>
<xs:sequence>
<xs:element name="csid" type="xs:string" />
</xs:element>
<!-- intake records, as in nuxeo repository -->
- <xs:element name="intake-list">
+ <xs:element name="intakes-common-list">
<xs:complexType>
<xs:sequence>
<xs:element name="intake-list-item" maxOccurs="unbounded">
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<profilesXml xmlns="http://maven.apache.org/PROFILES/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/PROFILES/1.0.0 http://maven.apache.org/xsd/profiles-1.0.0.xsd">
+</profilesXml>
\ No newline at end of file
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.intake.IntakeList.*;
+import org.collectionspace.services.common.AbstractCollectionSpaceResource;
+import org.collectionspace.services.intake.IntakesCommonList.*;
-import org.collectionspace.services.intake.nuxeo.IntakeConstants;
import org.collectionspace.services.intake.nuxeo.IntakeHandlerFactory;
-import org.collectionspace.services.common.NuxeoClientType;
+import org.collectionspace.services.common.ClientType;
import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.context.ServiceContext;
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.plugins.providers.multipart.MultipartInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
import org.jboss.resteasy.util.HttpResponseCodes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Path("/intakes")
-@Consumes("application/xml")
-@Produces("application/xml")
-public class IntakeResource {
+@Consumes("multipart/mixed")
+@Produces("multipart/mixed")
+public class IntakeResource extends AbstractCollectionSpaceResource {
- public final static String INTAKE_SERVICE_NAME = "intakes";
+ private final static String serviceName = "intakes";
final Logger logger = LoggerFactory.getLogger(IntakeResource.class);
//FIXME retrieve client type from configuration
- final static NuxeoClientType CLIENT_TYPE = ServiceMain.getInstance().getNuxeoClientType();
+ final static ClientType CLIENT_TYPE = ServiceMain.getInstance().getClientType();
public IntakeResource() {
// do nothing
}
- @POST
- public Response createIntake(
- Intake intakeObject) {
+ @Override
+ public String getServiceName() {
+ return serviceName;
+ }
- String csid = null;
- try{
- RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
- RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
- IntakeHandlerFactory handlerFactory = IntakeHandlerFactory.getInstance();
- DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
- handler.setCommonObject(intakeObject);
- csid = client.create(INTAKE_SERVICE_NAME, handler);
- intakeObject.setCsid(csid);
- if(logger.isDebugEnabled()){
- verbose("createIntake: ", intakeObject);
+ @Override
+ public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception {
+ DocumentHandler docHandler = IntakeHandlerFactory.getInstance().getHandler(
+ ctx.getRepositoryClientType().toString());
+ docHandler.setServiceContext(ctx);
+ if(ctx.getInput() != null){
+ Object obj = ctx.getInputPart(ctx.getCommonPartLabel(), IntakesCommon.class);
+ if(obj != null){
+ docHandler.setCommonPart((IntakesCommon) obj);
}
+ }
+ return docHandler;
+ }
+
+ @POST
+ public Response createIntake(MultipartInput input) {
+ try{
+ ServiceContext ctx = createServiceContext(input);
+ DocumentHandler handler = createDocumentHandler(ctx);
+ String csid = getRepositoryClient(ctx).create(ctx, handler);
+ //intakeObject.setCsid(csid);
UriBuilder path = UriBuilder.fromResource(IntakeResource.class);
path.path("" + csid);
Response response = Response.created(path.build()).build();
@GET
@Path("{csid}")
- public Intake getIntake(
+ public MultipartOutput getIntake(
@PathParam("csid") String csid) {
if(logger.isDebugEnabled()){
- verbose("getIntake with csid=" + csid);
+ logger.debug("getIntake with csid=" + csid);
}
if(csid == null || "".equals(csid)){
logger.error("getIntake: missing csid!");
"text/plain").build();
throw new WebApplicationException(response);
}
- Intake intakeObject = null;
+ MultipartOutput result = null;
try{
- RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
- RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
- IntakeHandlerFactory handlerFactory = IntakeHandlerFactory.getInstance();
- DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
- client.get(csid, handler);
- intakeObject = (Intake) handler.getCommonObject();
+ ServiceContext ctx = createServiceContext(null);
+ DocumentHandler handler = createDocumentHandler(ctx);
+ getRepositoryClient(ctx).get(ctx, csid, handler);
+ result = ctx.getOutput();
}catch(DocumentNotFoundException dnfe){
if(logger.isDebugEnabled()){
logger.debug("getIntake", dnfe);
Response.Status.INTERNAL_SERVER_ERROR).entity("Get failed").type("text/plain").build();
throw new WebApplicationException(response);
}
-
- if(intakeObject == null){
+ if(result == null){
Response response = Response.status(Response.Status.NOT_FOUND).entity(
"Get failed, the requested Intake CSID:" + csid + ": was not found.").type(
"text/plain").build();
throw new WebApplicationException(response);
}
- if(logger.isDebugEnabled()){
- verbose("getIntake: ", intakeObject);
- }
- return intakeObject;
+ return result;
}
@GET
- public IntakeList getIntakeList(@Context UriInfo ui) {
- IntakeList intakeObjectList = new IntakeList();
+ @Produces("application/xml")
+ public IntakesCommonList getIntakeList(@Context UriInfo ui) {
+ IntakesCommonList intakeObjectList = new IntakesCommonList();
try{
- RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
- RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
- IntakeHandlerFactory handlerFactory = IntakeHandlerFactory.getInstance();
- DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
- client.getAll(INTAKE_SERVICE_NAME, handler);
- intakeObjectList = (IntakeList) handler.getCommonObjectList();
+ ServiceContext ctx = createServiceContext(null);
+ DocumentHandler handler = createDocumentHandler(ctx);
+ getRepositoryClient(ctx).getAll(ctx, handler);
+ intakeObjectList = (IntakesCommonList) handler.getCommonPartList();
}catch(Exception e){
if(logger.isDebugEnabled()){
logger.debug("Caught exception in getIntakeList", e);
@PUT
@Path("{csid}")
- public Intake updateIntake(
+ public MultipartOutput updateIntake(
@PathParam("csid") String csid,
- Intake theUpdate) {
+ MultipartInput theUpdate) {
if(logger.isDebugEnabled()){
- verbose("updateIntake with csid=" + csid);
+ logger.debug("updateIntake with csid=" + csid);
}
if(csid == null || "".equals(csid)){
logger.error("updateIntake: missing csid!");
"text/plain").build();
throw new WebApplicationException(response);
}
- if(logger.isDebugEnabled()){
- verbose("updateIntake with input: ", theUpdate);
- }
+ MultipartOutput result = null;
try{
- RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
- RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
- IntakeHandlerFactory handlerFactory = IntakeHandlerFactory.getInstance();
- DocumentHandler handler = (DocumentHandler) handlerFactory.getHandler(CLIENT_TYPE.toString());
- handler.setCommonObject(theUpdate);
- client.update(csid, handler);
+ ServiceContext ctx = createServiceContext(theUpdate);
+ DocumentHandler handler = createDocumentHandler(ctx);
+ getRepositoryClient(ctx).update(ctx, csid, handler);
+ result = ctx.getOutput();
}catch(DocumentNotFoundException dnfe){
if(logger.isDebugEnabled()){
logger.debug("caugth exception in updateIntake", dnfe);
Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
throw new WebApplicationException(response);
}
- return theUpdate;
+ return result;
}
@DELETE
public Response deleteIntake(@PathParam("csid") String csid) {
if(logger.isDebugEnabled()){
- verbose("deleteIntake with csid=" + csid);
+ logger.debug("deleteIntake with csid=" + csid);
}
if(csid == null || "".equals(csid)){
logger.error("deleteIntake: missing csid!");
throw new WebApplicationException(response);
}
try{
- RepositoryClientFactory clientFactory = RepositoryClientFactory.getInstance();
- RepositoryClient client = clientFactory.getClient(CLIENT_TYPE.toString());
- client.delete(csid);
+ ServiceContext ctx = createServiceContext(null);
+ getRepositoryClient(ctx).delete(ctx, csid);
return Response.status(HttpResponseCodes.SC_OK).build();
}catch(DocumentNotFoundException dnfe){
if(logger.isDebugEnabled()){
}
}
-
- private void verbose(String msg, Intake intakeObject) {
- try{
- verbose(msg);
- JAXBContext jc = JAXBContext.newInstance(
- Intake.class);
-
- Marshaller m = jc.createMarshaller();
- m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
- m.marshal(intakeObject, System.out);
- }catch(Exception e){
- e.printStackTrace();
- }
-
- }
-
- private void verbose(String msg) {
- System.out.println("IntakeResource. " + msg);
- }
}
+++ /dev/null
-/**\r
- * \r
- */\r
-package org.collectionspace.services.intake;\r
-\r
-import java.io.IOException;\r
-import org.dom4j.Document;\r
-import org.dom4j.DocumentException;\r
-\r
-import org.collectionspace.services.intake.Intake;\r
-\r
-/**\r
- * @author remillet\r
- * \r
- */\r
-public interface IntakeService {\r
-\r
- public final static String INTAKE_SCHEMA_NAME = "intake";\r
-\r
- // Create\r
- Document postIntake(Intake co)\r
- throws DocumentException, IOException;\r
-\r
- // Read single object\r
- Document getIntake(String csid) throws DocumentException,\r
- IOException;\r
-\r
- // Read a list of objects\r
- Document getIntakeList() throws DocumentException, IOException;\r
-\r
- // Update\r
- Document putIntake(String csid, Intake theUpdate)\r
- throws DocumentException, IOException;\r
-\r
- // Delete\r
- Document deleteIntake(String csid) throws DocumentException,\r
- IOException;\r
-}\r
+++ /dev/null
-/**\r
- * \r
- */\r
-package org.collectionspace.services.intake;\r
-\r
-import org.collectionspace.services.*;\r
-import java.io.ByteArrayInputStream;\r
-import java.io.IOException;\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-\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
-\r
-import org.dom4j.Document;\r
-import org.dom4j.DocumentException;\r
-import org.dom4j.io.SAXReader;\r
-import org.restlet.resource.Representation;\r
-\r
-/**\r
- * @author remillet\r
- * \r
- */\r
-public class IntakeServiceNuxeoImpl extends\r
- CollectionSpaceServiceNuxeoImpl implements IntakeService {\r
-\r
- final static String INTAKE_NUXEO_DOCTYPE = "Intake";\r
- final static String INTAKE_NUXEO_SCHEMA_NAME = "intake";\r
- final static String INTAKE_NUXEO_DC_TITLE = "CollectionSpace-Intake";\r
-\r
- // replace WORKSPACE_UID for resource workspace\r
- static String CS_INTAKE_WORKSPACE_UID = "c04210c4-9426-475f-b4ee-aa3d6aa4b97c";\r
-\r
- public Document deleteIntake(String csid)\r
- throws DocumentException, IOException {\r
-\r
- Document result = null;\r
- \r
-// NuxeoRESTClient nxClient = getClient();\r
-// List<String> pathParams = new ArrayList<String>();\r
-// Map<String, String> queryParams = new HashMap<String, String>();\r
-//\r
-// pathParams.add("default");\r
-// pathParams.add(csid);\r
-// pathParams.add("deleteDocumentRestlet");\r
-// Representation res = nxClient.get(pathParams, queryParams);\r
-// SAXReader reader = new SAXReader();\r
-// result = reader.read(res.getStream());\r
- \r
- return result;\r
- }\r
-\r
- public Document getIntake(String csid) throws DocumentException,\r
- IOException {\r
- Document result = null;\r
- \r
-// List<String> pathParams = new ArrayList<String>();\r
-// Map<String, String> queryParams = new HashMap<String, String>();\r
-//\r
-// pathParams.add("default");\r
-// pathParams.add(csid);\r
-// pathParams.add("export");\r
-// queryParams.put("format", "XML");\r
-//\r
-// NuxeoRESTClient nxClient = getClient();\r
-// Representation res = nxClient.get(pathParams, queryParams);\r
-//\r
-// SAXReader reader = new SAXReader();\r
-// result = reader.read(res.getStream());\r
-\r
- return result;\r
- }\r
-\r
- public Document getIntakeList() throws DocumentException,\r
- IOException {\r
- Document result = null;\r
-\r
-// NuxeoRESTClient nxClient = getClient();\r
-// List<String> pathParams = new ArrayList<String>();\r
-// Map<String, String> queryParams = new HashMap<String, String>();\r
-// pathParams = Arrays.asList("default",\r
-// CS_INTAKE_WORKSPACE_UID, "browse");\r
-// Representation res = nxClient.get(pathParams, queryParams);\r
-// SAXReader reader = new SAXReader();\r
-// result = reader.read(res.getStream());\r
-\r
- return result;\r
- }\r
-\r
- public Document postIntake(Intake co)\r
- throws DocumentException, IOException {\r
- Document result = null;\r
- \r
-// NuxeoRESTClient nxClient = getClient();\r
-//\r
-// List<String> pathParams = new ArrayList<String>();\r
-// Map<String, String> queryParams = new HashMap<String, String>();\r
-// pathParams.add("default");\r
-// pathParams.add(CS_INTAKE_WORKSPACE_UID);\r
-// pathParams.add("createDocument");\r
-// queryParams.put("docType", INTAKE_NUXEO_DOCTYPE);\r
-//\r
-// // a default title for the Dublin Core schema\r
-// queryParams.put("dublincore:title", INTAKE_NUXEO_DC_TITLE);\r
-//\r
-// // Intake core values\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.CURRENT_OWNER, co\r
-// .getCurrentOwner());\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.DEPOSITOR, co.getDepositor());\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.DEPOSITORS_REQUIREMENTS, co\r
-// .getDepositorsRequirements());\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.ENTRY_DATE, co.getEntryDate());\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.ENTRY_METHOD, co\r
-// .getEntryMethod());\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.ENTRY_NOTE, co.getEntryNote());\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.ENTRY_NUMBER, co\r
-// .getEntryNumber());\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.ENTRY_REASON, co.getEntryReason());\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.PACKING_NOTE, co.getPackingNote());\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.RETURN_DATE, co.getReturnDate());\r
-//\r
-// ByteArrayInputStream bais = new ByteArrayInputStream(new byte[0]);\r
-// Representation res = nxClient.post(pathParams, queryParams, bais);\r
-//\r
-// SAXReader reader = new SAXReader();\r
-// result = reader.read(res.getStream());\r
-\r
- return result;\r
- }\r
-\r
- public Document putIntake(String csid, Intake theUpdate)\r
- throws DocumentException, IOException {\r
- Document result = null;\r
- \r
-// List<String> pathParams = new ArrayList<String>();\r
-// Map<String, String> queryParams = new HashMap<String, String>();\r
-// pathParams.add("default");\r
-// pathParams.add(csid);\r
-// pathParams.add("updateDocumentRestlet");\r
-//\r
-// // todo: intelligent merge needed\r
-// if (theUpdate.getCurrentOwner() != null) {\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.CURRENT_OWNER, theUpdate.getCurrentOwner());\r
-// }\r
-//\r
-// if (theUpdate.getDepositor() != null) {\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.DEPOSITOR, theUpdate.getDepositor());\r
-// }\r
-//\r
-// if (theUpdate.getDepositorsRequirements() != null) {\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.DEPOSITORS_REQUIREMENTS, theUpdate.getDepositorsRequirements());\r
-// }\r
-//\r
-// if (theUpdate.getEntryDate() != null) {\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.ENTRY_DATE, theUpdate.getEntryDate());\r
-// }\r
-//\r
-// if (theUpdate.getEntryMethod() != null) {\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.ENTRY_METHOD, theUpdate.getEntryMethod());\r
-// }\r
-//\r
-// if (theUpdate.getEntryNote() != null) {\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.ENTRY_NOTE, theUpdate.getEntryNote());\r
-// }\r
-//\r
-// if (theUpdate.getEntryNumber() != null) {\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.ENTRY_NUMBER, theUpdate.getEntryNumber());\r
-// }\r
-//\r
-// if (theUpdate.getEntryReason() != null) {\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.ENTRY_REASON, theUpdate.getEntryReason());\r
-// }\r
-//\r
-// if (theUpdate.getPackingNote() != null) {\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.PACKING_NOTE, theUpdate.getPackingNote());\r
-// }\r
-//\r
-// if (theUpdate.getReturnDate() != null) {\r
-// queryParams.put(INTAKE_NUXEO_SCHEMA_NAME + ":"\r
-// + IntakeJAXBSchema.RETURN_DATE, theUpdate.getReturnDate());\r
-// }\r
-//\r
-// NuxeoRESTClient nxClient = getClient();\r
-// Representation res = nxClient.get(pathParams, queryParams);\r
-// SAXReader reader = new SAXReader();\r
-// result = reader.read(res.getStream());\r
-\r
- return result;\r
- }\r
-\r
-}\r
import org.collectionspace.services.IntakeJAXBSchema;
import org.collectionspace.services.common.repository.DocumentWrapper;
-import org.collectionspace.services.intake.Intake;
-import org.collectionspace.services.intake.IntakeList;
-import org.collectionspace.services.intake.IntakeList.IntakeListItem;
+import org.collectionspace.services.intake.IntakesCommon;
+import org.collectionspace.services.intake.IntakesCommonList;
+import org.collectionspace.services.intake.IntakesCommonList.IntakeListItem;
import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler;
-import org.collectionspace.services.intake.nuxeo.IntakeConstants;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentModelList;
* $LastChangedDate: $
*/
public class IntakeDocumentModelHandler
- extends DocumentModelHandler<Intake, IntakeList> {
+ extends DocumentModelHandler<IntakesCommon, IntakesCommonList> {
private final Logger logger = LoggerFactory.getLogger(IntakeDocumentModelHandler.class);
/**
* intake is used to stash JAXB object to use when handle is called
* for Action.CREATE, Action.UPDATE or Action.GET
*/
- private Intake intake;
+ private IntakesCommon intake;
/**
* intakeList is stashed when handle is called
* for ACTION.GET_ALL
*/
- private IntakeList intakeList;
+ private IntakesCommonList intakeList;
@Override
public void prepare(Action action) throws Exception {
}
/**
- * getCommonObject get associated intake
+ * getCommonPart get associated intake
* @return
*/
@Override
- public Intake getCommonObject() {
+ public IntakesCommon getCommonPart() {
return intake;
}
/**
- * setCommonObject set associated intake
+ * setCommonPart set associated intake
* @param intake
*/
@Override
- public void setCommonObject(Intake intake) {
+ public void setCommonPart(IntakesCommon intake) {
this.intake = intake;
}
/**
- * getIntakeList get associated intake (for index/GET_ALL)
+ * getCommonPartList get associated intake (for index/GET_ALL)
* @return
*/
@Override
- public IntakeList getCommonObjectList() {
+ public IntakesCommonList getCommonPartList() {
return intakeList;
}
@Override
- public void setCommonObjectList(IntakeList intakeList) {
+ public void setCommonPartList(IntakesCommonList intakeList) {
this.intakeList = intakeList;
}
@Override
- public Intake extractCommonObject(DocumentWrapper wrapDoc)
+ public IntakesCommon extractCommonPart(DocumentWrapper wrapDoc)
throws Exception {
- DocumentModel docModel = (DocumentModel) wrapDoc.getWrappedObject();
- Intake intakeObject = new Intake();
-
- //FIXME property get should be dynamically set using schema inspection
- //so it does not require hard coding
-
- // intake core values
- intakeObject.setCurrentOwner((String)docModel.getPropertyValue(
- getQProperty(IntakeJAXBSchema.CURRENT_OWNER)));
-
- intakeObject.setDepositor((String)docModel.getPropertyValue(getQProperty(
- IntakeJAXBSchema.DEPOSITOR)));
-
- intakeObject.setDepositorsRequirements((String)docModel.getPropertyValue(getQProperty(
- IntakeJAXBSchema.DEPOSITORS_REQUIREMENTS)));
-
- intakeObject.setEntryDate((String)docModel.getPropertyValue(getQProperty(
- IntakeJAXBSchema.ENTRY_DATE)));
-
- intakeObject.setEntryMethod((String)docModel.getPropertyValue(getQProperty(
- IntakeJAXBSchema.ENTRY_METHOD)));
-
- intakeObject.setEntryNote((String)docModel.getPropertyValue(getQProperty(
- IntakeJAXBSchema.ENTRY_NOTE)));
-
- intakeObject.setEntryNumber((String)docModel.getPropertyValue(getQProperty(
- IntakeJAXBSchema.ENTRY_NUMBER)));
-
- intakeObject.setEntryReason((String)docModel.getPropertyValue(getQProperty(
- IntakeJAXBSchema.ENTRY_REASON)));
-
- intakeObject.setPackingNote((String)docModel.getPropertyValue(getQProperty(
- IntakeJAXBSchema.PACKING_NOTE)));
-
- intakeObject.setReturnDate((String)docModel.getPropertyValue(getQProperty(
- IntakeJAXBSchema.RETURN_DATE)));
-
- return intakeObject;
+ throw new UnsupportedOperationException();
}
@Override
- public void fillCommonObject(Intake intakeObject, 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", IntakeConstants.NUXEO_DC_TITLE);
-
- // intake core values
- if(intakeObject.getCurrentOwner() != null){
- docModel.setPropertyValue(getQProperty(
- IntakeJAXBSchema.CURRENT_OWNER), intakeObject.getCurrentOwner());
- }
-
- if(intakeObject.getDepositor() != null){
- docModel.setPropertyValue(getQProperty(
- IntakeJAXBSchema.DEPOSITOR), intakeObject.getDepositor());
- }
-
- if(intakeObject.getDepositorsRequirements() != null){
- docModel.setPropertyValue(getQProperty(
- IntakeJAXBSchema.DEPOSITORS_REQUIREMENTS), intakeObject.getDepositorsRequirements());
- }
-
- if(intakeObject.getEntryDate() != null){
- docModel.setPropertyValue(getQProperty(
- IntakeJAXBSchema.ENTRY_DATE), intakeObject.getEntryDate());
- }
-
- if(intakeObject.getEntryMethod() != null){
- docModel.setPropertyValue(getQProperty(
- IntakeJAXBSchema.ENTRY_METHOD), intakeObject.getEntryMethod());
- }
-
- if(intakeObject.getEntryNote() != null){
- docModel.setPropertyValue(getQProperty(
- IntakeJAXBSchema.ENTRY_NOTE), intakeObject.getEntryNote());
- }
-
- if(intakeObject.getEntryNumber() != null){
- docModel.setPropertyValue(getQProperty(
- IntakeJAXBSchema.ENTRY_NUMBER), intakeObject.getEntryNumber());
- }
-
- if(intakeObject.getEntryReason() != null){
- docModel.setPropertyValue(getQProperty(
- IntakeJAXBSchema.ENTRY_REASON), intakeObject.getEntryReason());
- }
-
- if(intakeObject.getPackingNote() != null){
- docModel.setPropertyValue(getQProperty(
- IntakeJAXBSchema.PACKING_NOTE), intakeObject.getPackingNote());
- }
-
- if(intakeObject.getReturnDate() != null){
- docModel.setPropertyValue(getQProperty(
- IntakeJAXBSchema.RETURN_DATE), intakeObject.getReturnDate());
- }
-
+ public void fillCommonPart(IntakesCommon intakeObject, DocumentWrapper wrapDoc) throws Exception {
+ throw new UnsupportedOperationException();
}
@Override
- public IntakeList extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception {
+ public IntakesCommonList extractCommonPartList(DocumentWrapper wrapDoc) throws Exception {
DocumentModelList docList = (DocumentModelList) wrapDoc.getWrappedObject();
- IntakeList coList = new IntakeList();
- List<IntakeList.IntakeListItem> list = coList.getIntakeListItem();
+ IntakesCommonList coList = new IntakesCommonList();
+ List<IntakesCommonList.IntakeListItem> list = coList.getIntakeListItem();
//FIXME: iterating over a long list of documents is not a long term
//strategy...need to change to more efficient iterating in future
while(iter.hasNext()){
DocumentModel docModel = iter.next();
IntakeListItem ilistItem = new IntakeListItem();
- ilistItem.setEntryNumber((String)docModel.getPropertyValue(
- getQProperty(IntakeJAXBSchema.ENTRY_NUMBER)));
- //need fully qualified context for URI
+ ilistItem.setEntryNumber((String) docModel.getProperty(getServiceContext().getCommonPartLabel(),
+ IntakeJAXBSchema.ENTRY_NUMBER));
String id = docModel.getId();
- ilistItem.setUri("/intakes/" + id);
+ ilistItem.setUri(getServiceContextPath() + id);
ilistItem.setCsid(id);
list.add(ilistItem);
}
return coList;
}
- @Override
- public void fillCommonObjectList(IntakeList obj, DocumentWrapper wrapDoc) throws Exception {
- throw new UnsupportedOperationException();
- }
/* (non-Javadoc)
* @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#getDocumentType()
*/
+ @Override
public String getDocumentType() {
- return IntakeConstants.NUXEO_DOCTYPE;
+ return IntakeConstants.NUXEO_DOCTYPE;
}
-
+
/**
* getQProperty converts the given property to qualified schema property
* @param prop
* @return
*/
- private String getQProperty(String prop) {
+ @Override
+ public String getQProperty(String prop) {
return IntakeConstants.NUXEO_SCHEMA_NAME + ":" + prop;
}
}
*/
package org.collectionspace.services.intake.nuxeo;
-import org.collectionspace.services.common.NuxeoClientType;
+import org.collectionspace.services.common.ClientType;
import org.collectionspace.services.common.repository.DocumentHandler;
/**
}
public DocumentHandler getHandler(String clientType) {
- if(NuxeoClientType.JAVA.toString().equals(clientType)){
+ if(ClientType.JAVA.toString().equals(clientType)){
return new IntakeDocumentModelHandler();
- } else if(NuxeoClientType.REST.toString().equals(clientType)) {
+ } else if(ClientType.REST.toString().equals(clientType)) {
return new IntakeRepresenationHandler();
}
throw new IllegalArgumentException("Not supported client=" + clientType);
import org.collectionspace.services.IntakeJAXBSchema;
import org.collectionspace.services.common.repository.DocumentWrapper;
-import org.collectionspace.services.intake.Intake;
-import org.collectionspace.services.intake.IntakeList;
-import org.collectionspace.services.intake.IntakeList.IntakeListItem;
+import org.collectionspace.services.intake.IntakesCommon;
+import org.collectionspace.services.intake.IntakesCommonList;
+import org.collectionspace.services.intake.IntakesCommonList.IntakeListItem;
import org.collectionspace.services.nuxeo.client.rest.RepresentationHandler;
import org.dom4j.Document;
import org.dom4j.Element;
* $LastChangedDate: $
*/
public class IntakeRepresenationHandler
- extends RepresentationHandler<Intake, IntakeList> {
+ extends RepresentationHandler<IntakesCommon, IntakesCommonList> {
private final Logger logger = LoggerFactory.getLogger(IntakeRepresenationHandler.class);
/**
* intakeObj is used to stash JAXB object to use when handle is called
* for Action.CREATE, Action.UPDATE or Action.GET
*/
- private Intake intake;
+ private IntakesCommon intake;
/**
* intakeListObject is stashed when handle is called
* for ACTION.GET_ALL
*/
- private IntakeList intakeList;
+ private IntakesCommonList intakeList;
@Override
public void prepare(Action action) throws Exception {
private void prepare() {
Map<String, String> queryParams = getQueryParams();
- Intake intakeObject = getCommonObject();
+ IntakesCommon intakeObject = getCommonPart();
if(intakeObject.getCurrentOwner() != null){
queryParams.put(IntakeConstants.NUXEO_SCHEMA_NAME + ":" +
IntakeJAXBSchema.CURRENT_OWNER, intakeObject.getCurrentOwner());
}
@Override
- public Intake extractCommonObject(DocumentWrapper wrapDoc)
+ public IntakesCommon extractCommonPart(DocumentWrapper wrapDoc)
throws Exception {
Document document = (Document) wrapDoc.getWrappedObject();
- Intake intakeObj = new Intake();
+ IntakesCommon intakeObj = new IntakesCommon();
//FIXME property get should be dynamically set using schema inspection
//so it does not require hard coding
}
@Override
- public void fillCommonObject(Intake co, DocumentWrapper wrapDoc)
+ public void fillCommonPart(IntakesCommon co, DocumentWrapper wrapDoc)
throws Exception {
//Nuxeo REST takes create/update through queryParams, nothing to do here
}
@Override
- public IntakeList extractCommonObjectList(DocumentWrapper wrapDoc) throws Exception {
+ public IntakesCommonList extractCommonPartList(DocumentWrapper wrapDoc) throws Exception {
Document document = (Document) wrapDoc.getWrappedObject();
if(logger.isDebugEnabled()){
logger.debug(document.asXML());
}
- IntakeList intakeListObject = new IntakeList();
- List<IntakeList.IntakeListItem> list = intakeListObject.getIntakeListItem();
+ IntakesCommonList intakeListObject = new IntakesCommonList();
+ List<IntakesCommonList.IntakeListItem> list = intakeListObject.getIntakeListItem();
Element root = document.getRootElement();
for(Iterator i = root.elementIterator(); i.hasNext();){
return intakeListObject;
}
- @Override
- public void fillCommonObjectList(IntakeList obj, DocumentWrapper wrapDoc)
- throws Exception {
- throw new UnsupportedOperationException();
- }
@Override
- public Intake getCommonObject() {
+ public IntakesCommon getCommonPart() {
return intake;
}
@Override
- public void setCommonObject(Intake obj) {
+ public void setCommonPart(IntakesCommon obj) {
this.intake = obj;
}
@Override
- public IntakeList getCommonObjectList() {
+ public IntakesCommonList getCommonPartList() {
return intakeList;
}
@Override
- public void setCommonObjectList(IntakeList obj) {
+ public void setCommonPartList(IntakesCommonList obj) {
this.intakeList = obj;
}
/* (non-Javadoc)
* @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#getDocumentType()
*/
+ @Override
public String getDocumentType() {
- return IntakeConstants.NUXEO_DOCTYPE;
+ return IntakeConstants.NUXEO_DOCTYPE;
}
-
+
/**
* getQProperty converts the given property to qualified schema property
* @param prop
* @return
*/
- private String getQProperty(String prop) {
+ @Override
+ public String getQProperty(String prop) {
return IntakeConstants.NUXEO_SCHEMA_NAME + ":" + prop;
}
}
<!-- add modules below in the order based on dependencies -->\r
<module>common</module>\r
<module>authentication</module>\r
- <module>relation</module>\r
- <module>query</module>\r
+ <!--module>relation</module-->\r
+ <!--module>query</module-->\r
<module>acquisition</module>\r
<module>vocabulary</module>\r
<module>id</module>\r
<module>intake</module>\r
<module>JaxRsServiceProvider</module>\r
<module>client</module>\r
- <module>sdk</module>\r
- <module>IntegrationTests</module>\r
+ <!--module>sdk</module-->\r
+ <!--module>IntegrationTests</module-->\r
</modules>\r
\r
<repositories> </repositories>\r
<dependency>\r
<groupId>org.jboss.resteasy</groupId>\r
<artifactId>jaxrs-api</artifactId>\r
- <version>1.0.2.GA</version>\r
+ <version>1.1.GA</version>\r
</dependency>\r
<dependency>\r
<groupId>net.java.dev.jaxb2-commons</groupId>\r
<dependency>\r
<groupId>org.jboss.resteasy</groupId>\r
<artifactId>resteasy-jaxrs</artifactId>\r
- <version>1.0.2.GA</version>\r
+ <version>1.1.GA</version>\r
</dependency>\r
<dependency>\r
<groupId>commons-httpclient</groupId>\r
<dependency>\r
<groupId>com.sun.xml.bind</groupId>\r
<artifactId>jaxb-impl</artifactId>\r
- <version>2.1.7</version>\r
+ <version>2.1.9</version>\r
</dependency>\r
<dependency>\r
<groupId>org.slf4j</groupId>\r
* http://www.collectionspace.org
* http://wiki.collectionspace.org
*
- * Copyright © 2009 {Contributing Institution}
+ * Copyright � 2009 {Contributing Institution}
*
* Licensed under the Educational Community License (ECL), Version 2.0.
* You may not use this file except in compliance with this License.
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
-import org.collectionspace.services.relation.RelationList.RelationListItem;
-import org.collectionspace.services.common.CollectionSpaceResource;
-import org.collectionspace.services.relation.nuxeo.RelationNuxeoConstants;
-import org.collectionspace.services.relation.nuxeo.RelationHandlerFactory;
-import org.collectionspace.services.common.CollectionSpaceHandlerFactory;
+import org.collectionspace.services.common.AbstractCollectionSpaceResource;
import org.collectionspace.services.common.NuxeoClientType;
-import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.context.ServiceContext;
import org.collectionspace.services.common.relation.RelationsManager;
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("/relations")
-@Consumes("application/xml")
-@Produces("application/xml")
-public class NewRelationResource extends CollectionSpaceResource {
+@Consumes("multipart/mixed")
+@Produces("multipart/mixed")
+public class NewRelationResource extends AbstractCollectionSpaceResource {
- public final static String SERVICE_NAME = "relations";
+ public final static String serviceName = "relations";
final Logger logger = LoggerFactory.getLogger(NewRelationResource.class);
- // FIXME retrieve client type from configuration
-// final static NuxeoClientType CLIENT_TYPE = ServiceMain.getInstance()
-// .getNuxeoClientType();
- protected String getClientType() {
- return ServiceMain.getInstance().getNuxeoClientType().toString();
- }
-
- protected RepositoryClientFactory getDefaultClientFactory() {
- return RepositoryClientFactory.getInstance();
- }
-
- protected CollectionSpaceHandlerFactory getDefaultHandlerFactory() {
- return RelationHandlerFactory.getInstance();
- }
+
+ @Override
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ @Override
+ public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception {
+ DocumentHandler docHandler = RelationHandlerFactory.getInstance().getHandler(
+ ctx.getRepositoryClientType().toString());
+ docHandler.setServiceContext(ctx);
+ if(ctx.getInput() != null){
+ Object obj = ctx.getInputPart(ctx.getCommonPartLabel(), CollectionobjectsCommon.class);
+ if(obj != null){
+ docHandler.setCommonPart((CollectionobjectsCommon) obj);
+ }
+ }
+ return docHandler;
+ }
+
// public NewRelationResource() {
// }
import org.jboss.resteasy.client.ClientResponse;\r
\r
import org.collectionspace.services.client.CollectionObjectClient;\r
-import org.collectionspace.services.collectionobject.CollectionObject;\r
-import org.collectionspace.services.collectionobject.CollectionObjectList;\r
+import org.collectionspace.services.collectionobject.CollectionobjectsCommon;\r
+import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;\r
\r
public class Sample {\r
\r
String csid = createCollectionObject();\r
System.out.println("Created a new collection object with CSID=" + csid);\r
\r
- CollectionObject co = readCollectionObject(csid);\r
+ CollectionobjectsCommon co = readCollectionObject(csid);\r
System.out.println("Got a collection object with CSID=" + csid);\r
}\r
\r
static String createCollectionObject() {\r
String result = null;\r
\r
- CollectionObject co = new CollectionObject();\r
- co.setObjectName("Keiko CollectionObject");\r
+ CollectionobjectsCommon co = new CollectionobjectsCommon();\r
+ co.setObjectName("Keiko CollectionobjectsCommon");\r
\r
ClientResponse<Response> response = collectionObjectClient.create(co);\r
Assert.assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode());\r
return result;\r
}\r
\r
- static CollectionObject readCollectionObject(String csid) {\r
- CollectionObject result = null;\r
+ static CollectionobjectsCommon readCollectionObject(String csid) {\r
+ CollectionobjectsCommon result = null;\r
\r
- ClientResponse<CollectionObject> response = collectionObjectClient.read(csid);\r
+ ClientResponse<CollectionobjectsCommon> response = collectionObjectClient.read(csid);\r
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());\r
result = response.getEntity();\r
\r