\r
private static final String SCHEME = "http";\r
private static final String HOST = "localhost";\r
- private static final String PORT = "8080";\r
+ private static final String PORT = "8180";\r
private static final String URI = "/helloworld/cspace-nuxeo";\r
private static final String URL = SCHEME + "://" +\r
HOST + ":" +\r
--- /dev/null
+package org.collectionspace.hello.client;
+
+import javax.ws.rs.core.Response;
+
+import org.collectionspace.hello.PersonNuxeo;
+import org.collectionspace.hello.People;
+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.MultipartFormDataInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+
+/**
+ * A PersonNuxeoClient.
+
+ * @version $Revision:$
+ */
+public class MultischemaClient extends CollectionSpaceClient {
+
+ /**
+ *
+ */
+ private static final MultischemaClient instance = new MultischemaClient();
+ /**
+ *
+ */
+ private MultischemaProxy proxy;
+
+ /**
+ *
+ * Create a new PersonNuxeoClient.
+ *
+ */
+ private MultischemaClient() {
+ ResteasyProviderFactory factory = ResteasyProviderFactory.getInstance();
+ RegisterBuiltin.register(factory);
+ proxy = ProxyFactory.create(MultischemaProxy.class, getURL());
+ }
+
+ /**
+ * FIXME Comment this
+ *
+ * @return
+ */
+ public static MultischemaClient getInstance() {
+ return instance;
+ }
+
+ /**
+ * @param id
+ * @return
+ * @see org.collectionspace.hello.client.PersonNuxeoProxy#getPerson(java.lang.String)
+ */
+ public ClientResponse<MultipartFormDataInput> getPerson(String id) {
+ return proxy.getPerson(id);
+ }
+
+ /**
+ * @param person
+ * @return
+ * @see org.collectionspace.hello.client.PersonNuxeoProxy#createPerson(org.collectionspace.hello.PersonNuxeo)
+ */
+ public ClientResponse<Response> createPerson(MultipartFormDataOutput multipartPerson) {
+ return proxy.createPerson(multipartPerson);
+ }
+
+ /**
+ * @param id
+ * @param person
+ * @return
+ * @see org.collectionspace.hello.client.PersonNuxeoProxy#updatePerson(java.lang.Long, org.collectionspace.hello.PersonNuxeo)
+ */
+ public ClientResponse<PersonNuxeo> updatePerson(String id, PersonNuxeo person) {
+ return proxy.updatePerson(id, person);
+ }
+
+ /**
+ * @param id
+ * @return
+ * @see org.collectionspace.hello.client.PersonNuxeoProxy#deletePerson(java.lang.Long)
+ */
+ public ClientResponse<Response> deletePerson(String id) {
+ return proxy.deletePerson(id);
+ }
+}
--- /dev/null
+package org.collectionspace.hello.client;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+
+import org.collectionspace.hello.PersonNuxeo;
+import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput;
+
+/**
+ * @version $Revision:$
+ */
+@Path("/multischema/")
+@Produces({"application/xml"})
+@Consumes({"application/xml"})
+public interface MultischemaProxy {
+
+
+ @GET
+ @Path("/{id}")
+ @Produces("multipart/form-data")
+ ClientResponse<MultipartFormDataInput> getPerson(@PathParam("id") String id);
+
+ @POST
+ @Consumes("multipart/form-data")
+ ClientResponse<Response> createPerson(MultipartFormDataOutput multipartPerson);
+
+ @PUT
+ @Path("/{id}")
+ ClientResponse<PersonNuxeo> updatePerson(@PathParam("id") String id, PersonNuxeo so);
+
+ @DELETE
+ @Path("/{id}")
+ ClientResponse<Response> deletePerson(@PathParam("id") String id);
+}
\ No newline at end of file
--- /dev/null
+package org.collectionspace.hello.client.test;
+
+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.Marshaller;
+import org.collectionspace.hello.PersonNuxeo;
+import org.collectionspace.hello.client.MultischemaClient;
+import org.collectionspace.world.DublincoreNuxeo;
+import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * A MultipartTest.
+ *
+ * @version $Revision:$
+ */
+public class MultischemaServiceTest {
+
+ private MultischemaClient client = MultischemaClient.getInstance();
+ private String updateId = "";
+ private String deleteId = "";
+ final Logger logger = LoggerFactory.getLogger(MultischemaServiceTest.class);
+ @Test
+ public void createPerson() {
+ MultipartFormDataOutput multipartPerson = createPerson("Mr.", "Chris", "Hoffman");
+ ClientResponse<Response> res = client.createPerson(multipartPerson);
+ Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode());
+ //store updateId locally
+ updateId = extractId(res);
+ }
+
+ @Test
+ public void createTeam() {
+ MultipartFormDataOutput multipartPerson = createPerson("Mr.", "Sanjay", "Dalal");
+ ClientResponse<Response> res = client.createPerson(multipartPerson);
+ Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode());
+ deleteId = extractId(res);
+
+ multipartPerson = createPerson("Mr.", "Aron", "Roberts");
+ res = client.createPerson(multipartPerson);
+ Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode());
+
+ multipartPerson = createPerson("Mr.", "Richard", "Millet");
+ res = client.createPerson(multipartPerson);
+ Assert.assertEquals(res.getStatus(), Response.Status.CREATED.getStatusCode());
+ }
+
+ @Test(dependsOnMethods = {"createPerson"})
+ public void updatePerson() throws Exception {
+ MultipartFormDataInput mdip = client.getPerson(updateId).getEntity();
+ PersonNuxeo touPerson = mdip.getFormDataPart("hello", PersonNuxeo.class, null);
+ touPerson.setId(updateId);
+ verbose("got person to update", touPerson, PersonNuxeo.class);
+ touPerson.setFirstName("Patrick");
+ touPerson.setLastName("Schmitz");
+ PersonNuxeo uPerson = client.updatePerson(updateId, touPerson).getEntity();
+ verbose("updated person", uPerson, PersonNuxeo.class);
+ //Assert.assertNotSame(uPerson.getVersion(), initialVersion);
+ Assert.assertEquals(uPerson.getFirstName(), "Patrick");
+ }
+
+ @Test(dependsOnMethods = {"createTeam"})
+ public void deletePerson() {
+ ClientResponse<Response> res = client.deletePerson(deleteId);
+ verbose("deletePerson: id=" + deleteId);
+ verbose("deletePerson: status = " + res.getStatus());
+ Assert.assertEquals(res.getStatus(), Response.Status.NO_CONTENT.getStatusCode());
+ }
+
+ private MultipartFormDataOutput createPerson(String title, String firstName, String lastName) {
+ PersonNuxeo person = new PersonNuxeo();
+
+ person.setFirstName(firstName);
+ person.setLastName(lastName);
+ person.setStreet("2195 Hearst Ave.");
+ person.setCity("Berkeley");
+ person.setState("CA");
+ person.setZip("94704");
+ person.setCountry("US");
+ person.setVersion("1.0");
+
+ DublincoreNuxeo dublin = new DublincoreNuxeo();
+ dublin.setTitle(title);
+ MultipartFormDataOutput multipartPerson = new MultipartFormDataOutput();
+ multipartPerson.addFormData("hello", person, MediaType.APPLICATION_XML_TYPE);
+ multipartPerson.addFormData("dublincore", dublin, MediaType.APPLICATION_XML_TYPE);
+ return multipartPerson;
+ }
+
+ private String extractId(ClientResponse<Response> res) {
+ MultivaluedMap mvm = res.getMetadata();
+ String uri = (String) ((ArrayList) mvm.get("Location")).get(0);
+ String[] segments = uri.split("/");
+ String id = segments[segments.length - 1];
+ verbose("extractId: id=" + id);
+ return id;
+ }
+
+ private void verbose(String msg) {
+ logger.info(msg);
+ }
+
+ private void verbose(String msg, Object o, Class clazz) {
+ try{
+ verbose(msg);
+ JAXBContext jc = JAXBContext.newInstance(clazz);
+ Marshaller m = jc.createMarshaller();
+ m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
+ Boolean.TRUE);
+ m.marshal(o, System.out);
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+
+}
--- /dev/null
+Helloworld service interfacing with Nuxeo repository through Nuxeo
+REST apis.
+
+System Requirements:
+====================
+- Maven 2.0.9 or higher
+- Nuxeo CollectionSpace Extensions
+
+Building the project:
+====================
+In root directoy...
+1. customize build.properties for your environment
+2. mvn clean package
+3. ant
--- /dev/null
+jboss.dir=C:/dev/jboss-4.2.3.GA\r
+jboss.client.dir=${jboss.dir}/client\r
+nuxeo.dir=${jboss.dir}/server/default/deploy/nuxeo.ear/system\r
+nuxeo.local.repo.dir=file:///C:/dev/jboss-4.2.3.GA/server/default/deploy/nuxeo.ear/system\r
+nuxeo.local.repo.client.dir=file:///C:/dev/nuxeo/nuxeo-core/nuxeo-core-client/target\r
--- /dev/null
+<?xml version="1.0"?>
+<project name="helloworld" default="deploy" basedir=".">
+
+ <property file="build.properties" />
+
+
+ <target name="deploy" description="Deploy">
+ <copy todir="${jboss.dir}/server/default/deploy">
+ <fileset file="${basedir}/target/helloworld.war" />
+ </copy>
+ </target>
+
+</project>
--- /dev/null
+<?xml version='1.0' encoding='UTF-8' ?>\r
+\r
+<!-- The JBoss specific elements used to integrate the servlet 2.4 web.xml\r
+elements into a JBoss deployment. This version applies to the JBoss 4.2.x\r
+releases.\r
+\r
+$Id: jboss-web_4_0.dtd 60134 2007-01-31 13:14:47Z thomas.diesler@jboss.com $\r
+\r
+ <!DOCTYPE jboss-web PUBLIC\r
+ "-//JBoss//DTD Web Application 4.2//EN"\r
+ "http://www.jboss.org/j2ee/dtd/jboss-web_4_2.dtd">\r
+-->\r
+\r
+<!ENTITY % service-ref PUBLIC\r
+ "-//JBoss//DTD Web Service Reference 4.2//EN"\r
+ "http://www.jboss.org/j2ee/dtd/service-ref_4_2.dtd">\r
+ \r
+%service-ref;\r
+\r
+<!-- The jboss-web element is the root element.\r
+-->\r
+<!ELEMENT jboss-web (class-loading?, security-domain?, jacc-star-role-allow?, context-root?,\r
+ virtual-host*, use-session-cookies?, replication-config?, resource-env-ref*,\r
+ resource-ref*, security-role*, ejb-ref*, ejb-local-ref*, \r
+ message-destination-ref*, message-destination*, \r
+ webservice-description*, service-ref*, depends*, servlet*, authenticators*)>\r
+\r
+<!-- The class-loading element allows one to override the default class\r
+loading behavior of the web container. You can specify the\r
+Examples:\r
+ <class-loading java2ClassLoadingCompliance='false'/>\r
+\r
+ <class-loading java2ClassLoadingCompliance='false'>\r
+ <loader-repository loaderRepositoryClass='dot.com.LoaderRepository'>\r
+ ...\r
+ </loader-repository>\r
+ </class-loading>\r
+-->\r
+<!ELEMENT class-loading (loader-repository?)>\r
+<!-- The java2ClassLoadingCompliance attribute indicates if the normal Java2\r
+parent first class loading model should be used over the servlet 2.3 web\r
+container first model.\r
+-->\r
+<!ATTLIST class-loading java2ClassLoadingCompliance CDATA #IMPLIED>\r
+\r
+<!-- The loader-repository specifies the name of the UnifiedLoaderRepository\r
+ MBean to use for the ear to provide ear level scoping of classes deployed\r
+ in the ear. It is a unique JMX ObjectName string. It may also specify\r
+ an arbitrary configuration by including a loader-repository-config element.\r
+\r
+Examples:\r
+ <class-loading>\r
+ <loader-repository>jboss.test:loader=cts-cmp2v1-sar.ear</loader-repository>\r
+ </class-loading>\r
+\r
+ <class-loading java2ClassLoadingCompliance='false'>\r
+ <loader-repository loaderRepositoryClass='dot.com.LoaderRepository'>\r
+ dot.com:loader=unique-archive-name\r
+ <loader-repository-config configParserClass='dot.com.LoaderParser'>\r
+ java2ParentDelegaton=true\r
+ </loader-repository-config>\r
+ </loader-repository>\r
+ </class-loading>\r
+-->\r
+<!ELEMENT loader-repository (#PCDATA | loader-repository-config)*>\r
+<!-- The loaderRepositoryClass attribute gives the classname of the\r
+org.jboss.mx.loading.LoaderRepository implementation.\r
+-->\r
+<!ATTLIST loader-repository loaderRepositoryClass CDATA #IMPLIED>\r
+\r
+<!-- The loader-repository-config element specifies any arbitrary configuration\r
+fragment for use in configuring the loader-repository instance. The actual\r
+content of this element is specific to the loaderRepositoryClass and the\r
+code parsing the element.\r
+-->\r
+<!ELEMENT loader-repository-config (#PCDATA)>\r
+<!-- The configParserClass attribute gives the classname of the\r
+org.jboss.mx.loading.LoaderRepositoryFactory.LoaderRepositoryConfigParser\r
+implementation to use to parse the loader-repository-config content.\r
+-->\r
+<!ATTLIST loader-repository-config configParserClass CDATA #IMPLIED>\r
+\r
+<!-- The context-root element specifies the context root of a web\r
+application. This is normally specified at the ear level using the standard\r
+J2EE application.xml descriptor, but it may be given here for standalone wars.\r
+This should not override the application.xml level specification.\r
+-->\r
+<!ELEMENT context-root (#PCDATA)>\r
+
+<!-- (JBAS-1824) The jacc-star-role-allow element specifies whether the
+jacc permission generating agent in the web layer needs to generate a
+WebResourcePermission(url,null) permission such that the jacc provider can
+make a decision as to bypass authorization or not.
+-->
+<!ELEMENT jacc-star-role-allow (#PCDATA)>
+\r
+<!-- The security-domain element allows one to specify a module wide\r
+security manager domain. It specifies the JNDI name of the security\r
+manager that implements the org.jboss.security.AuthenticationManager and\r
+org.jboss.security.RealmMapping interfaces for the domain.\r
+-->\r
+<!ELEMENT security-domain (#PCDATA)>\r
+\r
+<!-- The flushOnSessionInvalidation attribute is a boolean indicating whether\r
+the associated security domain cache should be flushed when the web session is\r
+invalidated. If true, the security manager service \r
+flushAuthenticationCache(String, java.security.Principal) is called when the\r
+session is seen to be invalid due to expiration or explicit invalidation.\r
+-->\r
+<!ATTLIST security-domain flushOnSessionInvalidation (true|false) 'false'>\r
+\r
+<!-- The virtual-host element allows one to specify which virtual host the war\r
+should be deployed to. Example, to specify that a war should be deployed to the\r
+www.jboss-store.org virtual host add the following virtual-host element:\r
+ <virtual-host>www.jboss-store.org</virtual-host>\r
+-->\r
+<!ELEMENT virtual-host (#PCDATA)>\r
+\r
+<!--The resource-env-ref element maps from the servlet ENC relative name\r
+of the resource-env-ref to the deployment environment JNDI name of\r
+the administered object resource.\r
+Example:\r
+ <resource-env-ref>\r
+ <resource-env-ref-name>jms/NewsTopic</resource-env-ref-name>\r
+ <jndi-name>topic/NewsTopic</jndi-name>\r
+ </resource-env-ref>\r
+-->\r
+<!ELEMENT resource-env-ref (resource-env-ref-name , jndi-name)>\r
+\r
+<!-- The resource-env-ref-name specifies the name of the web.xml\r
+resource-env-ref-name element which this mapping applies.\r
+-->\r
+<!ELEMENT resource-env-ref-name (#PCDATA)>\r
+\r
+<!--The resource-ref element maps from the servlet ENC relative name\r
+of the resource-ref to the deployment environment JNDI name of\r
+the resource manager connection factory.\r
+Example:\r
+ <resource-ref>\r
+ <res-ref-name>jdbc/TheDataSource</res-ref-name>\r
+ <jndi-name>java:/DefaultDS</jndi-name>\r
+ </resource-ref>\r
+\r
+ <resource-ref>\r
+ <res-ref-name>jdbc/TheDataSource</res-ref-name>\r
+ <res-url>http://x.y.z</res-url>\r
+ </resource-ref>\r
+-->\r
+<!ELEMENT resource-ref (res-ref-name , (jndi-name | res-url))>\r
+\r
+<!-- The res-ref-name specifies the name of the web.xml res-ref-name element\r
+which this mapping applies.\r
+-->\r
+<!ELEMENT res-ref-name (#PCDATA)>\r
+\r
+<!--\r
+ The security-role element contains the definition of a security role.\r
+ The definition consists of an the security role name and principal name element(s).\r
+\r
+Used in: jboss-web\r
+\r
+Example:\r
+ <security-role>\r
+ <role-name>Manager</role-name>\r
+ <principal-name>j2ee</principal-name>\r
+ <principal-name>javajoe</principal-name>\r
+ </security-role>\r
+-->\r
+<!ELEMENT security-role (role-name, principal-name+)>\r
+\r
+<!--\r
+ The role-name element is the name of the role.\r
+\r
+ Used in: security-role\r
+-->\r
+<!ELEMENT role-name (#PCDATA)>\r
+\r
+<!--\r
+ The principal-name element is the name of the principal that is mapped\r
+ to the assembly role-name.\r
+\r
+ Used in: security-role\r
+-->\r
+<!ELEMENT principal-name (#PCDATA)>\r
+\r
+<!-- The ejb-ref element maps from the servlet ENC relative name\r
+of the ejb reference to the deployment environment JNDI name of\r
+the bean.\r
+Example:\r
+ <ejb-ref>\r
+ <ejb-ref-name>ejb/Bean0</ejb-ref-name>\r
+ <jndi-name>deployed/ejbs/Bean0</jndi-name>\r
+ </ejb-ref>\r
+-->\r
+<!ELEMENT ejb-ref (ejb-ref-name , jndi-name)>\r
+\r
+<!-- The ejb-local-ref element maps from the servlet ENC relative name\r
+of the ejb local reference to the deployment environment JNDI name of\r
+the bean.\r
+Example:\r
+ <ejb-local-ref>\r
+ <ejb-ref-name>ejb/Bean0</ejb-ref-name>\r
+ <local-jndi-name>deployed/ejbs/Bean0</local-jndi-name>\r
+ </ejb-local-ref>\r
+-->\r
+<!ELEMENT ejb-local-ref (ejb-ref-name , (local-jndi-name|jndi-name))>\r
+\r
+<!-- The ejb-ref-name element gives the ENC relative name used\r
+in the web.xml ejb-ref-name element.\r
+\r
+Used in: ejb-ref\r
+-->\r
+<!ELEMENT ejb-ref-name (#PCDATA)>\r
+\r
+<!-- The jndi-name element specifies the JNDI name of the deployed\r
+object to which the servlet ENC binding will link to via a JNDI\r
+LinkRef.\r
+\r
+Used in: resource-ref, resource-env-ref, ejb-ref, \r
+ message-destination-ref, message-destination\r
+-->\r
+<!ELEMENT jndi-name (#PCDATA)>\r
+\r
+<!--\r
+ The JNDI name under with the local home interface should be bound\r
+\r
+ Used in: ejb-local-ref\r
+-->\r
+<!ELEMENT local-jndi-name (#PCDATA)>\r
+\r
+<!-- The res-url element value is a URL string for a resource-ref of\r
+res-type = java.net.URL. Using a res-url creates a binding of the URL\r
+instance under the java:comp/env. If you want to link to another binding\r
+of a URL, you can use the jndi-name to do so.\r
+\r
+// Binds the URL(http://x.y.z) under java:comp/env/jdbc/XYZHome\r
+<resource-ref>\r
+ <res-ref-name>jdbc/XYZHome</res-ref-name>\r
+ <res-url>http://x.y.z</res-url>\r
+</resource-ref>\r
+// Binds a link to urls/XYZHomePage under java:comp/env/jdbc/XYZHome\r
+<resource-ref>\r
+ <res-ref-name>jdbc/XYZHome</res-ref-name>\r
+ <res-url>urls/XYZHomePage</res-url>\r
+</resource-ref>\r
+\r
+ Used in: resource-ref\r
+-->\r
+<!ELEMENT res-url (#PCDATA)>\r
+\r
+<!--\r
+ The message-destination-ref element is used to configure the\r
+ jndi-name for a message-destination-ref in ejb-jar.xml\r
+\r
+ Used in: jboss-web\r
+-->\r
+<!ELEMENT message-destination-ref (message-destination-ref-name, jndi-name)>\r
+\r
+<!--\r
+ The message-destination-ref-name element identifies the\r
+ message-destination-ref. It must match the name in ejb-jar.xml\r
+\r
+ Used in: message-destination-ref\r
+-->\r
+<!ELEMENT message-destination-ref-name (#PCDATA)>\r
+\r
+<!--\r
+ The message-destination element is used to configure the\r
+ jndi-name for a message-destination in ejb-jar.xml\r
+\r
+ Used in: jboss-web\r
+-->\r
+<!ELEMENT message-destination (message-destination-name, jndi-name)>\r
+\r
+<!--\r
+ The message-destination-name element identifies the\r
+ message-destination. It must match the name in ejb-jar.xml\r
+\r
+ Used in: message-destination\r
+-->\r
+<!ELEMENT message-destination-name (#PCDATA)>\r
+\r
+<!-- The depends element gives a JMX ObjectName of a service on which the\r
+container or ejb depends.\r
+-->\r
+<!ELEMENT depends (#PCDATA)>\r
+\r
+<!-- The use-session-cookies element controls wether this context uses session cookies\r
+ or not.\r
+\r
+Example:\r
+ <use-session-cookies>true</use-session-cookies>\r
+-->\r
+<!ELEMENT use-session-cookies (#PCDATA)>\r
+\r
+\r
+<!--\r
+ HTTP Session clustering configuration (optional tags)\r
+-->\r
+<!ELEMENT replication-config (replication-trigger?, replication-granularity, replication-field-batch-mode?)>\r
+\r
+<!--\r
+ Clustering only: Determines when the container should consider that a session\r
+ must be replicated accross the cluster.\r
+ Possible values are:\r
+ 1 - "SET_AND_GET"\r
+ 2 - "SET_AND_NON_PRIMITIVE_GET" (default value)\r
+ 3 - "SET"\r
+\r
+ The first option is conservative but not optimal (performance-wise): it will replicate the\r
+ session even if its content has not been modified but simply accessed. There is no deterministic\r
+ way to know if the content of an attribute is not itself modified. Consequently, by default, no\r
+ hypothesis can be done. It is up to the developer to tell us if we can trust this policy.\r
+\r
+ The second option is conservative but will only replicate if a non-primitive Object has been\r
+ accessed (Integer, Long, String, etc. which are immutables). It is the default value.\r
+\r
+ The third option considers that the developer will explicitely call setAttribute on the session\r
+ if it has to be replicated.\r
+\r
+Examples:\r
+ <replication-trigger>SET_AND_GET</replication-trigger>\r
+ or\r
+ <replication-trigger>SET_AND_NON_PRIMITIVE_GET</replication-trigger>\r
+ or\r
+ <replication-trigger>SET</replication-trigger>\r
+-->\r
+<!ELEMENT replication-trigger (#PCDATA)>\r
+\r
+<!--\r
+ Clustering only: Determines the session replication granularity level.\r
+ Possible values are:\r
+ 1 - "SESSION" (default)\r
+ 2 - "ATTRIBUTE"\r
+ 3 - "FIELD"\r
+\r
+ The first option indicates that replication is done per session instance, i.e. when\r
+ the session is considered modified, the whole session object will be serialized\r
+ and replicated. This is the preferred policy when the sessions are generally small.\r
+\r
+ The second option indicates that replication is performed only for the the dirty\r
+ attributes in the session, plus some session data, like lastAccessTime. For sessions\r
+ carrying large amounts of data, parts of which are infrequently accessed,\r
+ this option can increase replication performance.\r
+ \r
+Examples:\r
+ <replication-granularity>SESSION</replication-granularity>\r
+ or\r
+ <replication-granularity>ATTRIBUTE</replication-granularity>\r
+-->\r
+<!ELEMENT replication-granularity (#PCDATA)>\r
+\r
+<!--\r
+ Determine whether to batch the replication when the granularity level is set to FIELD.\r
+ Default is true.\r
+\r
+ If this is set to TRUE, that means we will replicate the pojo changes only during the\r
+ http request is finished. To use this, the JBossCacheAop transaction manager class will\r
+ need to be configured as BatchModeTransactionManager such that a user can still have\r
+ UserTransaction inside the http request. However, note that the cache will not particiapte\r
+ in the UserTransaction in this case.\r
+\r
+ If you want cache to participate in the UserTransaction, you can configure the transaction\r
+ manager class to JBossTransactionManager and set this option to FALSE. The result is for\r
+ those session attribute changes that are not under transaction will replicate instantaneously,\r
+ while those particiate under transaction will replicate only when the transaction is\r
+ completed.\r
+\r
+Examples:\r
+ <replication-field-batch-mode>TRUE</replication-field-batch-mode>\r
+ or\r
+ <replication-field-batch-mode>FALSE</replication-field-batch-mode>\r
+-->\r
+<!ELEMENT replication-field-batch-mode (true|false)>\r
+\r
+<!--\r
+Runtime information about a web service.\r
+\r
+wsdl-publish-location is optionally used to specify\r
+where the final wsdl and any dependent files should be stored. This location\r
+resides on the file system from which deployment is initiated.\r
+\r
+-->\r
+<!ELEMENT webservice-description ( webservice-description-name, config-name?, config-file?, wsdl-publish-location? )>\r
+\r
+<!--\r
+Unique name of a webservice within a module\r
+-->\r
+<!ELEMENT webservice-description-name ( #PCDATA )>\r
+\r
+<!--\r
+file: URL of a directory to which a web-service-description's wsdl should be\r
+published during deployment. Any required files will be published to this\r
+directory, preserving their location relative to the module-specific\r
+wsdl directory(META-INF/wsdl or WEB-INF/wsdl).\r
+\r
+Example :\r
+\r
+ For an ejb.jar whose webservices.xml wsdl-file element contains\r
+ META-INF/wsdl/a/Foo.wsdl\r
+\r
+ <wsdl-publish-location>file:/home/user1/publish\r
+ </wsdl-publish-location>\r
+\r
+ The final wsdl will be stored in /home/user1/publish/a/Foo.wsdl\r
+\r
+-->\r
+<!ELEMENT wsdl-publish-location ( #PCDATA )>\r
+\r
+<!-- The servlet element specifies servlet specific bindings. Currently this\r
+is only the run-as principal identity.\r
+\r
+ Used in: jboss-web\r
+-->\r
+<!ELEMENT servlet (servlet-name, run-as-principal?)>\r
+\r
+<!-- The servlet-name maps from the web.xml servlet/servlet-name to the\r
+jboss-web/servlet/servlet-name.\r
+ Used in: servlet\r
+-->\r
+<!ELEMENT servlet-name ( #PCDATA )>\r
+\r
+<!--\r
+ The run-as-principal element specifies whether a specific run-as identity is\r
+ to be used. If there is a run-as role defined for a servlet, there can also\r
+ be a run-as-principal defined here. If you don't define a run-as principal\r
+ the callee will see ctx.getUserPrincipal() == 'anonymous'\r
+\r
+ Used in: servlet\r
+-->\r
+<!ELEMENT run-as-principal ( #PCDATA )>\r
+\r
+<!--\r
+ Customize the tomcat authenticators at the context or web-app level.\r
+ These are keyed in by http-auth method specified in login-config in web.xml\r
+ \r
+ <authenticators>\r
+ <authenticator>\r
+ <key>BASIC</key>\r
+ <value>org.apache.catalina.authenticator.BasicAuthenticator</value>\r
+ </authenticator>\r
+ <authenticator>\r
+ <key>CLIENT-CERT</key>\r
+ <value>org.apache.catalina.authenticator.SSLAuthenticator</value>\r
+ </authenticator>\r
+ <authenticator>\r
+ <key>DIGEST</key>\r
+ <value>org.apache.catalina.authenticator.DigestAuthenticator</value>\r
+ </authenticator>\r
+ <authenticator>\r
+ <key>FORM</key>\r
+ <value>org.apache.catalina.authenticator.FormAuthenticator</value>\r
+ </authenticator>\r
+ <authenticator>\r
+ <key>NONE</key>\r
+ <value>org.apache.catalina.authenticator.NonLoginAuthenticator</value>\r
+ </authenticator>\r
+ </authenticators> \r
+-->\r
+\r
+<!ELEMENT authenticators (authenticator+)>\r
+<!ELEMENT authenticator ( key, value )>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<project-shared-configuration>\r
+ <!--
+This file contains additional configuration written by modules in the NetBeans IDE.
+The configuration is intended to be shared among all the users of project and
+therefore it is assumed to be part of version control checkout.
+Without this configuration present, some functionality in the IDE may be limited or fail altogether.
+-->\r
+ <properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">\r
+ <!--
+Properties that influence various parts of the IDE, especially code formatting and the like.
+You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
+That way multiple projects can share the same settings (useful for formatting rules for example).
+Any value defined here will override the pom.xml file value but is only applicable to the current project.
+-->\r
+ <org-netbeans-modules-editor-indent.CodeStyle.usedProfile>default</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>\r
+ <org-netbeans-modules-editor-indent.CodeStyle.project.tab-size>8</org-netbeans-modules-editor-indent.CodeStyle.project.tab-size>\r
+ <org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width>80</org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width>\r
+ <netbeans.hint.useExternalMaven>false</netbeans.hint.useExternalMaven>\r
+ </properties>\r
+</project-shared-configuration>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<actions>\r
+ <action>\r
+ <actionName>test</actionName>\r
+ <packagings>\r
+ <packaging>*</packaging>\r
+ </packagings>\r
+ <goals>\r
+ <goal>test</goal>\r
+ </goals>\r
+ </action>\r
+ <action>\r
+ <actionName>build</actionName>\r
+ <packagings>\r
+ <packaging>*</packaging>\r
+ </packagings>\r
+ <goals>\r
+ <goal>install</goal>\r
+ </goals>\r
+ </action>\r
+ <action>\r
+ <actionName>clean</actionName>\r
+ <packagings>\r
+ <packaging>*</packaging>\r
+ </packagings>\r
+ <goals>\r
+ <goal>clean</goal>\r
+ </goals>\r
+ </action>\r
+ <action>\r
+ <actionName>rebuild</actionName>\r
+ <packagings>\r
+ <packaging>*</packaging>\r
+ </packagings>\r
+ <goals>\r
+ <goal>clean</goal>\r
+ <goal>install</goal>\r
+ </goals>\r
+ <properties>\r
+ <maven.test.skip>true</maven.test.skip>\r
+ </properties>\r
+ </action>\r
+ <action>\r
+ <actionName>run</actionName>\r
+ <packagings>\r
+ <packaging>war</packaging>\r
+ <packaging>ear</packaging>\r
+ <packaging>ejb</packaging>\r
+ </packagings>\r
+ <goals>\r
+ <goal>package</goal>\r
+ </goals>\r
+ <properties>\r
+ \r
+ <netbeans.deploy>true</netbeans.deploy>\r
+ </properties>\r
+ </action>\r
+ <action>\r
+ <actionName>debug</actionName>\r
+ <packagings>\r
+ <packaging>war</packaging>\r
+ <packaging>ear</packaging>\r
+ <packaging>ejb</packaging>\r
+ </packagings>\r
+ <goals>\r
+ <goal>package</goal>\r
+ </goals>\r
+ <properties>\r
+ \r
+ <netbeans.deploy>true</netbeans.deploy>\r
+ <netbeans.deploy.debugmode>true</netbeans.deploy.debugmode>\r
+ </properties>\r
+ </action>\r
+ </actions>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<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">\r
+ <parent>\r
+ <artifactId>jaxrs-prototype</artifactId>\r
+ <groupId>org.collectionspace.hello.services</groupId>\r
+ <version>0.1</version>\r
+ </parent>\r
+ <modelVersion>4.0.0</modelVersion>\r
+ <groupId>org.collectionspace.hello.services</groupId>\r
+ <artifactId>jaxrs-nuxeo-javaapi-service</artifactId>\r
+ <packaging>war</packaging>\r
+ <version>0.1</version>\r
+ <name>jaxrs-nuxeo-javaapi-service</name>\r
+\r
+ <repositories>\r
+ <repository>\r
+ <id>java.net</id>\r
+ <url>http://download.java.net/maven/1</url>\r
+ <layout>legacy</layout>\r
+ </repository>\r
+ <repository>\r
+ <id>maven repo</id>\r
+ <name>maven repo</name>\r
+ <url>http://repo1.maven.org/maven2/</url>\r
+ </repository>\r
+ <!-- For resteasy -->\r
+ <repository>\r
+ <id>cspace.local.jboss.client</id>\r
+ <url>${jboss.client.dir}</url>\r
+ </repository>\r
+ <repository>\r
+ <id>jboss</id>\r
+ <name>jboss repo</name>\r
+ <url>http://repository.jboss.org/maven2</url>\r
+ </repository>\r
+ <repository>\r
+ <id>mojo</id>\r
+ <name>mojo repo</name>\r
+ <url>http://svn.codehaus.org/mojo/trunk/mojo/jboss-maven-plugin</url>\r
+ </repository>\r
+\r
+ <repository>\r
+ <id>cspace.local.nuxeo</id>\r
+ <url>${nuxeo.local.repo.dir}</url>\r
+ </repository>\r
+ <repository>\r
+ <id>cspace.local.nuxeo.client</id>\r
+ <url>${nuxeo.local.repo.client.dir}</url>\r
+ </repository>\r
+ <!--repository>\r
+ <id>public</id>\r
+ <url>http://maven.nuxeo.org/public</url>\r
+ <releases>\r
+ </releases>\r
+ <snapshots>\r
+ <enabled>false</enabled>\r
+ </snapshots>\r
+ </repository>\r
+ <repository>\r
+ <id>public-snapshot</id>\r
+ <url>http://maven.nuxeo.org/public-snapshot</url>\r
+ <releases>\r
+ <enabled>false</enabled>\r
+ </releases>\r
+ <snapshots>\r
+ </snapshots>\r
+ </repository-->\r
+\r
+\r
+ </repositories>\r
+\r
+ <pluginRepositories>\r
+ <pluginRepository>\r
+ <id>public</id>\r
+ <url>http://maven.nuxeo.org/public</url>\r
+ <name>Nuxeo virtual release repository</name>\r
+ <releases>\r
+ </releases>\r
+ <snapshots>\r
+ <enabled>false</enabled>\r
+ </snapshots>\r
+ </pluginRepository>\r
+ <pluginRepository>\r
+ <id>public-snapshot</id>\r
+ <url>http://maven.nuxeo.org/public-snapshot</url>\r
+ <name>Nuxeo virtual snapshot repository</name>\r
+ <releases>\r
+ <enabled>false</enabled>\r
+ </releases>\r
+ <snapshots>\r
+ </snapshots>\r
+ </pluginRepository>\r
+ </pluginRepositories>\r
+\r
+\r
+ <properties>\r
+ <jboss.version>4.2.3.GA</jboss.version>\r
+ <jboss.ejb.version>3.0</jboss.ejb.version>\r
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\r
+ <apacheds.version>1.5.1</apacheds.version>\r
+ <apachedshared.version>0.9.7</apachedshared.version>\r
+ <nuxeo.version.5.2>5.2-SNAPSHOT</nuxeo.version.5.2>\r
+ <nuxeo.version.1.5>1.5-SNAPSHOT</nuxeo.version.1.5>\r
+ </properties>\r
+\r
+\r
+ <dependencies>\r
+ <dependency>\r
+ <groupId>org.collectionspace.hello.services</groupId>\r
+ <artifactId>jaxrs-jaxb</artifactId>\r
+ <version>0.1</version>\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
+ <artifactId>webserver</artifactId>\r
+ </exclusion>\r
+ </exclusions>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.jboss.resteasy</groupId>\r
+ <artifactId>resteasy-jaxb-provider</artifactId>\r
+ <version>1.0.2.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
+ </dependency>\r
+ <dependency>\r
+ <groupId>junit</groupId>\r
+ <artifactId>junit</artifactId>\r
+ <version>4.1</version>\r
+ <scope>test</scope>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.slf4j</groupId>\r
+ <artifactId>slf4j-api</artifactId>\r
+ <version>1.5.2</version>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.slf4j</groupId>\r
+ <artifactId>slf4j-log4j12</artifactId>\r
+ <version>1.5.2</version>\r
+ </dependency>\r
+ <!-- javax -->\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.0.01</version>\r
+ <scope>provided</scope>\r
+ </dependency>\r
+\r
+ <!-- dom -->\r
+ <dependency>\r
+ <groupId>dom4j</groupId>\r
+ <artifactId>dom4j</artifactId>\r
+ <version>1.6.1</version>\r
+ <scope>provided</scope>\r
+ </dependency>\r
+ \r
+ <!-- jboss -->\r
+ <dependency>\r
+ <groupId>jboss</groupId>\r
+ <artifactId>jboss-remoting</artifactId>\r
+ <version>2.2.2.SP8</version>\r
+ <scope>provided</scope>\r
+ </dependency>\r
+ \r
+ <!-- nuxeo -->\r
+\r
+ <dependency>\r
+ <groupId>org.nuxeo.common</groupId>\r
+ <artifactId>nuxeo-common</artifactId>\r
+ <version>${nuxeo.version.1.5}</version>\r
+ <scope>provided</scope>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.nuxeo.runtime</groupId>\r
+ <artifactId>nuxeo-runtime</artifactId>\r
+ <version>${nuxeo.version.1.5}</version>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.nuxeo.ecm.core</groupId>\r
+ <artifactId>nuxeo-core-api</artifactId>\r
+ <version>${nuxeo.version.1.5}</version>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.nuxeo.ecm.core</groupId>\r
+ <artifactId>nuxeo-core-client</artifactId>\r
+ <version>${nuxeo.version.1.5}</version>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.nuxeo.ecm.core</groupId>\r
+ <artifactId>nuxeo-core-query</artifactId>\r
+ <version>${nuxeo.version.1.5}</version>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.nuxeo.ecm.core</groupId>\r
+ <artifactId>nuxeo-core-schema</artifactId>\r
+ <version>${nuxeo.version.1.5}</version>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.nuxeo.ecm.core</groupId>\r
+ <artifactId>nuxeo-core-io</artifactId>\r
+ <version>${nuxeo.version.1.5}</version>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.nuxeo.ecm.core</groupId>\r
+ <artifactId>nuxeo-core-facade</artifactId>\r
+ <version>${nuxeo.version.1.5}</version>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.nuxeo.runtime</groupId>\r
+ <artifactId>nuxeo-runtime-osgi</artifactId>\r
+ <version>${nuxeo.version.1.5}</version>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.osgi</groupId>\r
+ <artifactId>osgi-core</artifactId>\r
+ <version>4.1</version>\r
+ </dependency>\r
+\r
+\r
+ </dependencies>\r
+ \r
+ <build>\r
+ <finalName>helloworld</finalName>\r
+ <plugins>\r
+ <plugin>\r
+ <groupId>org.codehaus.mojo</groupId>\r
+ <artifactId>jboss-maven-plugin</artifactId>\r
+ <configuration>\r
+ <jbossHome>${jboss.dir}</jbossHome>\r
+ <port>8180</port>\r
+ </configuration>\r
+ <executions>\r
+ <execution>\r
+ <id>jboss-undeploy</id>\r
+ <phase>pre-integration-test</phase>\r
+ <goals>\r
+ <goal>undeploy</goal>\r
+ </goals>\r
+ <configuration>\r
+ <fileName>${basedir}/target/helloworld.war</fileName>\r
+ </configuration>\r
+ </execution>\r
+ <execution>\r
+ <id>jboss-deploy</id>\r
+ <phase>pre-integration-test</phase>\r
+ <goals>\r
+ <goal>deploy</goal>\r
+ </goals>\r
+ <configuration>\r
+ <fileName>${basedir}/target/helloworld.war</fileName>\r
+ </configuration>\r
+ </execution>\r
+\r
+ </executions>\r
+ </plugin>\r
+\r
+ <plugin>\r
+ <groupId>org.apache.maven.plugins</groupId>\r
+ <artifactId>maven-surefire-plugin</artifactId>\r
+ <configuration></configuration>\r
+ <executions>\r
+ <execution>\r
+ <id>surefire-it</id>\r
+ <phase>integration-test</phase>\r
+ <goals>\r
+ <goal>test</goal>\r
+ </goals>\r
+ <configuration>\r
+ <skip>false</skip>\r
+ </configuration>\r
+ </execution>\r
+ </executions>\r
+ </plugin>\r
+ <plugin>\r
+ <groupId>org.apache.maven.plugins</groupId>\r
+ <artifactId>maven-war-plugin</artifactId>\r
+ <version>2.0</version>\r
+ </plugin>\r
+ <plugin>\r
+ <groupId>org.apache.maven.plugins</groupId>\r
+ <artifactId>maven-compiler-plugin</artifactId>\r
+ <configuration>\r
+ <source>1.5</source>\r
+ <target>1.5</target>\r
+ </configuration>\r
+ </plugin>\r
+ </plugins>\r
+ </build>\r
+</project>\r
--- /dev/null
+package org.collectionspace.hello.services;
+
+import javax.ws.rs.core.Application;
+import java.util.HashSet;
+import java.util.Set;
+
+public class CollectionSpaceApplication extends Application {
+
+ private Set<Object> singletons = new HashSet<Object>();
+ private Set<Class<?>> empty = new HashSet<Class<?>>();
+
+ public CollectionSpaceApplication() {
+ singletons.add(new MultischemaResource());
+ }
+
+ @Override
+ public Set<Class<?>> getClasses() {
+ return empty;
+ }
+
+ @Override
+ public Set<Object> getSingletons() {
+ return singletons;
+ }
+}
--- /dev/null
+package org.collectionspace.hello.services;\r
+\r
+\r
+public abstract class CollectionSpaceResource {\r
+ //replace WORKSPACE_UID for resource workspace\r
+ static String CS_COLLECTIONOBJECT_WORKSPACE_UID = "5a37d40f-59c4-4d15-93ad-e0e6a0c33587";\r
+ //sanjay 6c7881fe-54c5-486e-b144-a025dee3a484\r
+ //demo eae0d7b6-580a-45a3-a0f3-e25e980e03bb\r
+ static String CS_PERSON_WORKSPACE_UID = "6c7881fe-54c5-486e-b144-a025dee3a484";\r
+ \r
+ //replace host if not running on localhost\r
+ //static String CS_NUXEO_HOST = "173.45.234.217";\r
+ static String CS_NUXEO_HOST = "localhost";\r
+ static String CS_NUXEO_URI = "http://" + CS_NUXEO_HOST + ":8080/nuxeo";\r
+\r
+}\r
--- /dev/null
+package org.collectionspace.hello.services;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+
+import org.collectionspace.hello.PersonNuxeo;
+
+import org.collectionspace.services.nuxeo.NuxeoConnector;
+import org.collectionspace.world.DublincoreNuxeo;
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput;
+
+
+import org.nuxeo.common.utils.IdUtils;
+import org.nuxeo.ecm.core.api.CoreSession;
+import org.nuxeo.ecm.core.api.DocumentModel;
+
+
+import org.nuxeo.ecm.core.api.DocumentRef;
+import org.nuxeo.ecm.core.api.IdRef;
+import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
+import org.nuxeo.ecm.core.client.NuxeoClient;
+import org.nuxeo.ecm.core.io.DocumentPipe;
+import org.nuxeo.ecm.core.io.DocumentReader;
+import org.nuxeo.ecm.core.io.DocumentWriter;
+import org.nuxeo.ecm.core.io.impl.DocumentPipeImpl;
+import org.nuxeo.ecm.core.io.impl.plugins.SingleDocumentReader;
+import org.nuxeo.ecm.core.io.impl.plugins.XMLDocumentWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Path("/multischema")
+@Consumes("application/xml")
+@Produces("application/xml")
+public class MultischemaResource extends CollectionSpaceResource {
+
+ final Logger logger = LoggerFactory.getLogger(MultischemaResource.class);
+
+ public MultischemaResource() {
+ }
+
+ @POST
+ @Consumes("multipart/form-data")
+ public Response createPerson(MultipartFormDataInput multipart) {
+
+ PersonNuxeo personPart = new PersonNuxeo();
+ DublincoreNuxeo dcPart = new DublincoreNuxeo();
+ CoreSession repoSession = null;
+ RepositoryInstance repo = null;
+ try{
+ if(multipart.getFormData().containsKey("dublincore")){
+ dcPart = multipart.getFormDataPart("dublincore", DublincoreNuxeo.class, null);
+ }
+ if(multipart.getFormData().containsKey("hello")){
+ personPart = multipart.getFormDataPart("hello", PersonNuxeo.class, null);
+ }
+
+ repo = getRepository();
+ repoSession = repo.getSession();
+ DocumentRef nuxeoWspace = new IdRef(CS_PERSON_WORKSPACE_UID);
+ DocumentModel wspacePeople = repoSession.getDocument(nuxeoWspace);
+ String wspacePath = wspacePeople.getPathAsString();
+ String docType = "Hello";
+ String id = IdUtils.generateId("New " + docType);
+ //create document model
+ DocumentModel helloDoc = repoSession.createDocumentModel(wspacePath, id, docType);
+ fillDocument(personPart, helloDoc);
+ //create document with documentmodel
+ helloDoc = repoSession.createDocument(helloDoc);
+ repoSession.save();
+
+ personPart.setId(helloDoc.getId());
+
+ }catch(Exception e){
+ e.printStackTrace();
+ Response response = Response.status(Response.Status.NOT_FOUND).entity(
+ "Create failed").type("text/plain").build();
+ throw new WebApplicationException(response);
+ }finally{
+ try{
+// repo.close(repoSession);
+ }catch(Exception e){
+ logger.error("Could not close the repository session", e);
+ throw new WebApplicationException();
+ }
+ }
+ if(logger.isDebugEnabled()){
+ verbosePerson("createPerson: person", personPart);
+ verboseDublin("createPerson: dublincore", dcPart);
+ }
+ UriBuilder path = UriBuilder.fromResource(MultischemaResource.class);
+ path.path("" + personPart.getId());
+ Response response = Response.created(path.build()).build();
+ return response;
+ }
+
+ @GET
+ @Path("{id}")
+ @Produces("multipart/form-data")
+ public MultipartFormDataOutput getPerson(@PathParam("id") String id) {
+
+ PersonNuxeo personPart = new PersonNuxeo();
+ DublincoreNuxeo dublinPart = new DublincoreNuxeo();
+ MultipartFormDataOutput output = new MultipartFormDataOutput();
+ RepositoryInstance repo = null;
+ CoreSession repoSession = null;
+
+ try{
+ repo = getRepository();
+ repoSession = repo.getSession();
+ DocumentRef helloDocRef = new IdRef(id);
+ DocumentModel helloDoc = repoSession.getDocument(helloDocRef);
+ Document doc = getDocument(repoSession, helloDoc);
+ Element root = doc.getRootElement();
+ //TODO: recognize schema thru namespace uri
+ //Namespace ns = new Namespace("hello", "http://collectionspace.org/hello");
+ Iterator<Element> siter = root.elementIterator("schema");
+ while(siter.hasNext()){
+
+ Element s = siter.next();
+
+ //TODO: recognize schema thru namespace uri
+ if("hello".equals(s.attribute("name").getValue())){
+ personPart.setId(id);
+ Element ele = s.element("cversion");
+ if(ele != null){
+ personPart.setVersion((String) ele.getData());
+ }
+ ele = s.element("firstName");
+ if(ele != null){
+ personPart.setFirstName((String) ele.getData());
+ }
+ ele = s.element("lastName");
+ if(ele != null){
+ personPart.setLastName((String) ele.getData());
+ }
+ ele = s.element("city");
+ if(ele != null){
+ personPart.setCity((String) ele.getData());
+ }
+ ele = s.element("state");
+ if(ele != null){
+ personPart.setState((String) ele.getData());
+ }
+ ele = s.element("zip");
+ if(ele != null){
+ personPart.setZip((String) ele.getData());
+ }
+ ele = s.element("country");
+ if(ele != null){
+ personPart.setCountry((String) ele.getData());
+ }
+ }else if("dublincore".equals(s.attribute("name").getValue())){
+ Element ele = s.element("title");
+ if(ele != null){
+ dublinPart.setTitle((String) ele.getData());
+ }
+ }
+ }//while
+ if(logger.isDebugEnabled()){
+ verbosePerson("getPerson:hello:", personPart);
+ verboseDublin("getPerson:dublincore:", dublinPart);
+ }
+ output.addFormData("hello", personPart, MediaType.APPLICATION_XML_TYPE);
+ output.addFormData("dublincore", dublinPart, MediaType.APPLICATION_XML_TYPE);
+
+ }catch(Exception e){
+ e.printStackTrace();
+ Response response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
+ "Get failed").type("text/plain").build();
+ throw new WebApplicationException(response);
+ }finally{
+ try{
+// repo.close(repoSession);
+ }catch(Exception e){
+ logger.error("Could not close the repository session", e);
+ throw new WebApplicationException();
+ }
+ }
+ if(personPart == null){
+ Response response = Response.status(Response.Status.NOT_FOUND).entity(
+ "Get failed, the requested person ID:" + id + ": was not found.").type("text/plain").build();
+ throw new WebApplicationException(response);
+ }
+
+ return output;
+ }
+
+ @PUT
+ @Path("{id}")
+ public PersonNuxeo updatePerson(
+ @PathParam("id") String id,
+ PersonNuxeo personPart) {
+ if(logger.isDebugEnabled()){
+ verbosePerson("updating person input", personPart);
+ }
+ CoreSession repoSession = null;
+ RepositoryInstance repo = null;
+ try{
+ repo = getRepository();
+ repoSession = repo.getSession();
+ DocumentRef helloDocRef = new IdRef(id);
+ DocumentModel helloDoc = repoSession.getDocument(helloDocRef);
+ fillDocument(personPart, helloDoc);
+ repoSession.saveDocument(helloDoc);
+ repoSession.save();
+ }catch(Exception e){
+ //FIXME: NOT_FOUND?
+ Response response = Response.status(Response.Status.NOT_FOUND).entity(
+ "Update failed ").type("text/plain").build();
+ throw new WebApplicationException(response);
+ }finally{
+ try{
+// repo.close(repoSession);
+ }catch(Exception e){
+ logger.error("Could not close the repository session", e);
+ throw new WebApplicationException();
+ }
+ }
+ return personPart;
+ }
+
+ @DELETE
+ @Path("{id}")
+ public void deletePerson(@PathParam("id") String id) {
+ if(logger.isDebugEnabled()){
+ logger.debug("deleting person with id=" + id);
+ }
+ CoreSession repoSession = null;
+ RepositoryInstance repo = null;
+ try{
+ repo = getRepository();
+ repoSession = repo.getSession();
+ DocumentRef helloDocRef = new IdRef(id);
+ repoSession.removeDocument(helloDocRef);
+ repoSession.save();
+ }catch(Exception e){
+ //FIXME: NOT_FOUND?
+ Response response = Response.status(Response.Status.NOT_FOUND).entity(
+ "Delete failed ").type("text/plain").build();
+ throw new WebApplicationException(response);
+ }finally{
+ try{
+// repo.close(repoSession);
+ }catch(Exception e){
+ logger.error("Could not close the repository session", e);
+ throw new WebApplicationException();
+ }
+ }
+
+ }
+
+ synchronized private RepositoryInstance getRepository() throws Exception {
+ NuxeoConnector rmiClient = NuxeoConnector.getInstance();
+ rmiClient.initialize();
+ NuxeoClient client = rmiClient.getClient();
+ RepositoryInstance repo = client.openRepository();
+ if(logger.isDebugEnabled()){
+ logger.debug("deployNuxeo: repository root: " + repo.getRootDocument());
+ }
+ return repo;
+ }
+
+ private Document getDocument(CoreSession repoSession, DocumentModel helloDoc)
+ throws Exception {
+ Document doc = null;
+ DocumentWriter writer = null;
+ DocumentReader reader = null;
+ ByteArrayOutputStream baos = null;
+ ByteArrayInputStream bais = null;
+ try{
+ baos = new ByteArrayOutputStream();
+ reader = new SingleDocumentReader(repoSession,
+ helloDoc);
+ writer = new XMLDocumentWriter(baos);
+ DocumentPipe pipe = new DocumentPipeImpl();
+
+ pipe.setReader(reader);
+ pipe.setWriter(writer);
+ pipe.run();
+ bais = new ByteArrayInputStream(baos.toByteArray());
+ SAXReader saxReader = new SAXReader();
+ doc = saxReader.read(bais);
+ }finally{
+ if(reader != null){
+ reader.close();
+ }
+ if(writer != null){
+ writer.close();
+ }
+ try{
+ if(bais != null){
+ bais.close();
+ }
+ if(baos != null){
+ baos.close();
+ }
+ }catch(IOException ioe){
+ logger.error("Failed to close io streams with {}", ioe);
+ throw new WebApplicationException();
+ }
+ }
+ return doc;
+ }
+
+ private void fillDocument(PersonNuxeo p, DocumentModel helloDoc) throws Exception {
+ if(p.getFirstName() != null){
+ helloDoc.setPropertyValue("dublincore:title", p.getFirstName() + " " + p.getLastName());
+ helloDoc.setPropertyValue("hello:firstName", p.getFirstName());
+ }
+ if(p.getLastName() != null){
+ helloDoc.setPropertyValue("hello:lastName", p.getLastName());
+ }
+ if(p.getStreet() != null){
+ helloDoc.setPropertyValue("hello:street", p.getStreet());
+ }
+ if(p.getCity() != null){
+ helloDoc.setPropertyValue("hello:city", p.getCity());
+ }
+ if(p.getState() != null){
+ helloDoc.setPropertyValue("hello:state", p.getState());
+ }
+ if(p.getZip() != null){
+ helloDoc.setPropertyValue("hello:zip", p.getZip());
+ }
+ if(p.getCountry() != null){
+ helloDoc.setPropertyValue("hello:country", p.getCountry());
+ }
+ }
+
+ private void verbosePerson(String msg, PersonNuxeo person) {
+ try{
+ if(logger.isDebugEnabled()){
+ logger.debug(msg);
+ }
+ JAXBContext jc = JAXBContext.newInstance(
+ PersonNuxeo.class);
+
+ Marshaller m = jc.createMarshaller();
+ m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
+ Boolean.TRUE);
+ m.marshal(person, System.out);
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+
+ }
+
+ private void verboseDublin(String msg, DublincoreNuxeo dubin) {
+ try{
+ if(logger.isDebugEnabled()){
+ logger.debug(msg);
+ }
+ JAXBContext jc = JAXBContext.newInstance(
+ DublincoreNuxeo.class);
+
+ Marshaller m = jc.createMarshaller();
+ m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
+ Boolean.TRUE);
+ m.marshal(dubin, System.out);
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+
+ }
+}
--- /dev/null
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.collectionspace.services.nuxeo;
+
+import java.io.File;
+import java.util.Collection;
+import org.nuxeo.ecm.core.client.NuxeoApp;
+import org.nuxeo.ecm.core.client.NuxeoClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * NuxeoConnector is a facade to Nuxeo remoting client
+ * @author
+ */
+public class NuxeoConnector {
+ //FIXME: get port and host from configuration
+ public static int NUXEO_PORT = 62474;
+ public static String NUXEO_HOST = "localhost";
+ private Logger logger = LoggerFactory.getLogger(NuxeoConnector.class);
+ private static final NuxeoConnector self = new NuxeoConnector();
+ private NuxeoApp app;
+ private NuxeoClient client;
+ volatile boolean initialized = false; //use volatile for lazy initialization in singleton
+
+ private NuxeoConnector() {
+ }
+
+ public final static NuxeoConnector getInstance() {
+ return self;
+ }
+
+ public void initialize() throws Exception {
+
+ try{
+ if(initialized == false){
+ setProperties();
+ app = new NuxeoApp();
+ app.start();
+ if(logger.isDebugEnabled()) {
+ logger.debug("initialize() NuxeoApp started");
+ }
+ loadBundles();
+ client = NuxeoClient.getInstance();
+ initialized = true;
+ }
+ }catch(Exception e){
+ if(logger.isDebugEnabled()){
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void loadBundles() throws Exception {
+ String bundles = "nuxeo-client/lib/nuxeo-runtime-*:nuxeo-client/lib/nuxeo-*";
+ Collection<File> files = null;
+ if(bundles != null){
+ files = NuxeoApp.getBundleFiles(new File("."), bundles, ":");
+ }
+ if(logger.isDebugEnabled()){
+ logger.debug("loadBundles(): deploying bundles: " + files);
+ }
+ if(files != null){
+ app.deployBundles(files);
+ }
+ }
+
+ private void setProperties() {
+ System.setProperty("org.nuxeo.runtime.server.enabled", Boolean.FALSE.toString());
+ System.setProperty("org.nuxeo.runtime.server.port", "" + NUXEO_PORT);
+ System.setProperty("org.nuxeo.runtime.server.host", "127.0.0.1");
+ //System.setProperty("org.nuxeo.runtime.1.3.3.streaming.port", "3233");
+ System.setProperty("org.nuxeo.runtime.streaming.serverLocator", "socket://127.0.0.1:3233");
+ System.setProperty("org.nuxeo.runtime.streaming.isServer", Boolean.FALSE.toString());
+ System.setProperty("org.nuxeo.client.remote", Boolean.TRUE.toString());
+ }
+
+ public NuxeoClient getClient() throws Exception {
+ if(initialized == true){
+// if(client.isConnected()){
+// return client;
+// }else{
+ //authentication failure error comes when reusing the client
+ //fore connect for now
+ client.forceConnect(NUXEO_HOST, NUXEO_PORT);
+ if(logger.isDebugEnabled()){
+ logger.debug("getClient(): connection successful port=" + NUXEO_PORT);
+ }
+ return client;
+// }
+ }
+ String msg = "NuxeoConnector is not initialized!";
+ logger.error(msg);
+ throw new IllegalStateException(msg);
+ }
+}
--- /dev/null
+# Set root logger level to DEBUG and its only appender to CONSOLE.
+#log4j.rootLogger=INFO, CONSOLE, DEBUG
+log4j.rootLogger=INFO, FILE, CONSOLE
+
+# CONSOLE
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%t] %-5p %C{1} : %m%n
+
+# FILE
+log4j.appender.FILE=org.apache.log4j.FileAppender
+log4j.appender.FILE.File=log/server.log
+log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
+log4j.appender.FILE.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%t] %-5p %C{1} : %m%n
--- /dev/null
+<?xml version="1.0"?>
+
+<component name="org.nuxeo.ecm.platform.login.LoginConfig" version="1.0">
+ <documentation>
+ Login modules used on JBoss
+ @author Bogdan Stefanescu (bs@nuxeo.com)
+ </documentation>
+
+ <extension target="org.nuxeo.runtime.LoginComponent" point="domains">
+
+ <domain name="nuxeo-system-login">
+ <login-module code="org.nuxeo.runtime.api.login.SystemLoginModule" flag="required"/>
+ <login-module code="org.nuxeo.ecm.core.api.local.ClientLoginModule" flag="required">
+ <option name="password-stacking">true</option>
+ <option name="multi-threaded">true</option>
+ </login-module>
+ </domain>
+
+ <domain name="nuxeo-webengine">
+ <login-module code = "org.nuxeo.ecm.platform.login.NuxeoLoginModule"
+ flag = "required">
+ <option name="principalClassName">org.nuxeo.ecm.platform.login.NuxeoPrincipal</option>
+ <option name="useUserIdentificationInfoCB">true</option>
+ </login-module>
+ <!--login-module code="org.nuxeo.ecm.core.api.local.ClientLoginModule" flag="required">
+ <option name="password-stacking">true</option>
+ <option name="multi-threaded">true</option>
+ </login-module-->
+ </domain>
+
+ </extension>
+
+</component>
\ No newline at end of file
--- /dev/null
+
+<jboss-web>
+ <!-- Uncomment the security-domain to enable security. You will
+ need to edit the htmladaptor login configuration to setup the
+ login modules used to authentication users.
+ <security-domain>java:/jaas/jmx-console</security-domain>
+ -->
+ <!--class-loading >
+ <loader-repository>
+ org.nuxeo:loader=nuxeo.ear
+ <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
+ </loader-repository>
+ </class-loading-->
+</jboss-web>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">\r
+<web-app>\r
+ <display-name>HelloworldNuxeo</display-name>\r
+\r
+\r
+ <context-param>\r
+ <param-name>javax.ws.rs.Application</param-name>\r
+ <param-value>org.collectionspace.hello.services.CollectionSpaceApplication</param-value>\r
+ </context-param>\r
+\r
+ <context-param>\r
+ <param-name>resteasy.servlet.mapping.prefix</param-name>\r
+ <param-value>/cspace-nuxeo</param-value>\r
+ </context-param>\r
+\r
+ <listener>\r
+ <listener-class>\r
+ org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap\r
+ </listener-class>\r
+ </listener>\r
+\r
+ <servlet>\r
+ <servlet-name>Resteasy</servlet-name>\r
+ <servlet-class>\r
+ org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher\r
+ </servlet-class>\r
+ </servlet>\r
+\r
+ <servlet-mapping>\r
+ <servlet-name>Resteasy</servlet-name>\r
+ <url-pattern>/cspace-nuxeo/*</url-pattern>\r
+ </servlet-mapping>\r
+\r
+</web-app>\r
static String CS_COLLECTIONOBJECT_WORKSPACE_UID = "5a37d40f-59c4-4d15-93ad-e0e6a0c33587";\r
//sanjay 6c7881fe-54c5-486e-b144-a025dee3a484\r
//demo eae0d7b6-580a-45a3-a0f3-e25e980e03bb\r
- static String CS_PERSON_WORKSPACE_UID = "eae0d7b6-580a-45a3-a0f3-e25e980e03bb";\r
+ static String CS_PERSON_WORKSPACE_UID = "6c7881fe-54c5-486e-b144-a025dee3a484";\r
\r
//replace host if not running on localhost\r
//static String CS_NUXEO_HOST = "173.45.234.217";\r