1 package org.collectionspace.hello.services;
3 import java.io.ByteArrayInputStream;
4 import java.io.ByteArrayOutputStream;
5 import java.io.IOException;
6 import java.util.Iterator;
7 import javax.ws.rs.Consumes;
8 import javax.ws.rs.GET;
9 import javax.ws.rs.Path;
10 import javax.ws.rs.Produces;
11 import javax.ws.rs.DELETE;
12 import javax.ws.rs.POST;
13 import javax.ws.rs.PUT;
14 import javax.ws.rs.PathParam;
15 import javax.ws.rs.WebApplicationException;
16 import javax.ws.rs.core.MediaType;
17 import javax.ws.rs.core.Response;
18 import javax.ws.rs.core.UriBuilder;
19 import javax.xml.bind.JAXBContext;
20 import javax.xml.bind.Marshaller;
22 import org.collectionspace.hello.PersonNuxeo;
24 import org.collectionspace.services.nuxeo.NuxeoConnector;
25 import org.collectionspace.world.DublincoreNuxeo;
26 import org.dom4j.Document;
27 import org.dom4j.Element;
28 import org.dom4j.io.SAXReader;
29 import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
30 import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput;
33 import org.nuxeo.common.utils.IdUtils;
34 import org.nuxeo.ecm.core.api.CoreSession;
35 import org.nuxeo.ecm.core.api.DocumentModel;
38 import org.nuxeo.ecm.core.api.DocumentRef;
39 import org.nuxeo.ecm.core.api.IdRef;
40 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
41 import org.nuxeo.ecm.core.client.NuxeoClient;
42 import org.nuxeo.ecm.core.io.DocumentPipe;
43 import org.nuxeo.ecm.core.io.DocumentReader;
44 import org.nuxeo.ecm.core.io.DocumentWriter;
45 import org.nuxeo.ecm.core.io.impl.DocumentPipeImpl;
46 import org.nuxeo.ecm.core.io.impl.plugins.SingleDocumentReader;
47 import org.nuxeo.ecm.core.io.impl.plugins.XMLDocumentWriter;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
52 @Consumes("application/xml")
53 @Produces("application/xml")
54 public class MultischemaResource extends CollectionSpaceResource {
56 final Logger logger = LoggerFactory.getLogger(MultischemaResource.class);
58 public MultischemaResource() {
62 @Consumes("multipart/form-data")
63 public Response createPerson(MultipartFormDataInput multipart) {
65 PersonNuxeo personPart = new PersonNuxeo();
66 DublincoreNuxeo dcPart = new DublincoreNuxeo();
68 RepositoryInstance repoSession = null;
70 if(multipart.getFormData().containsKey("dublincore")){
71 dcPart = multipart.getFormDataPart("dublincore", DublincoreNuxeo.class, null);
73 if(multipart.getFormData().containsKey("hello")){
74 personPart = multipart.getFormDataPart("hello", PersonNuxeo.class, null);
77 repoSession = getRepositorySession();
78 DocumentRef nuxeoWspace = new IdRef(CS_PERSON_WORKSPACE_UID);
79 DocumentModel wspacePeople = repoSession.getDocument(nuxeoWspace);
80 String wspacePath = wspacePeople.getPathAsString();
81 String docType = "Hello";
82 String id = IdUtils.generateId("New " + docType);
83 //create document model
84 DocumentModel helloDoc = repoSession.createDocumentModel(wspacePath, id, docType);
85 fillDocument(personPart, helloDoc);
86 //create document with documentmodel
87 helloDoc = repoSession.createDocument(helloDoc);
90 personPart.setId(helloDoc.getId());
94 Response response = Response.status(Response.Status.NOT_FOUND).entity(
95 "Create failed").type("text/plain").build();
96 throw new WebApplicationException(response);
98 if(repoSession != null){
99 releaseRepositorySession(repoSession);
103 if(logger.isDebugEnabled()){
104 verboseObject("createPerson: person", PersonNuxeo.class, personPart);
105 verboseObject("createPerson: dublincore", DublincoreNuxeo.class, dcPart);
107 UriBuilder path = UriBuilder.fromResource(MultischemaResource.class);
109 path.path("" + personPart.getId());
110 Response response = Response.created(path.build()).build();
116 @Produces("multipart/form-data")
117 public MultipartFormDataOutput getPerson(
118 @PathParam("id") String id) {
120 PersonNuxeo personPart = new PersonNuxeo();
121 DublincoreNuxeo dublinPart = new DublincoreNuxeo();
122 MultipartFormDataOutput output = new MultipartFormDataOutput();
123 RepositoryInstance repoSession = null;
126 repoSession = getRepositorySession();
127 DocumentRef helloDocRef = new IdRef(id);
128 DocumentModel helloDoc = repoSession.getDocument(helloDocRef);
129 if(helloDoc == null){
130 Response response = Response.status(Response.Status.NOT_FOUND).entity(
131 "Get failed, the requested person ID:" + id + ": was not found.").type("text/plain").build();
132 throw new WebApplicationException(response);
134 Document doc = getDocument(repoSession, helloDoc);
135 Element root = doc.getRootElement();
136 //TODO: recognize schema thru namespace uri
137 //Namespace ns = new Namespace("hello", "http://collectionspace.org/hello");
138 Iterator<Element> siter = root.elementIterator("schema");
139 while(siter.hasNext()){
141 Element s = siter.next();
143 //TODO: recognize schema thru namespace uri
144 if("hello".equals(s.attribute("name").getValue())){
145 personPart.setId(id);
146 Element ele = s.element("cversion");
148 personPart.setVersion((String) ele.getData());
150 ele = s.element("firstName");
152 personPart.setFirstName((String) ele.getData());
154 ele = s.element("lastName");
156 personPart.setLastName((String) ele.getData());
158 ele = s.element("city");
160 personPart.setCity((String) ele.getData());
162 ele = s.element("state");
164 personPart.setState((String) ele.getData());
166 ele = s.element("zip");
168 personPart.setZip((String) ele.getData());
170 ele = s.element("country");
172 personPart.setCountry((String) ele.getData());
174 }else if("dublincore".equals(s.attribute("name").getValue())){
175 Element ele = s.element("title");
177 dublinPart.setTitle((String) ele.getData());
181 if(logger.isDebugEnabled()){
182 verboseObject("getPerson:hello:", PersonNuxeo.class, personPart);
183 verboseObject("getPerson:dublincore:", DublincoreNuxeo.class, dublinPart);
185 output.addFormData("hello", personPart, MediaType.APPLICATION_XML_TYPE);
186 output.addFormData("dublincore", dublinPart, MediaType.APPLICATION_XML_TYPE);
189 if(e instanceof WebApplicationException){
190 throw (WebApplicationException) e;
192 if(logger.isDebugEnabled()){
195 Response response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
196 "Get failed").type("text/plain").build();
197 throw new WebApplicationException(response);
199 if(repoSession != null){
200 releaseRepositorySession(repoSession);
208 public PersonNuxeo updatePerson(
209 @PathParam("id") String id,
210 PersonNuxeo personPart) {
211 if(logger.isDebugEnabled()){
212 verboseObject("updating person input", PersonNuxeo.class, personPart);
214 RepositoryInstance repoSession = null;
216 repoSession = getRepositorySession();
217 DocumentRef helloDocRef = new IdRef(id);
218 DocumentModel helloDoc = repoSession.getDocument(helloDocRef);
219 if(helloDoc == null){
220 Response response = Response.status(Response.Status.NOT_FOUND).entity(
221 "Get failed, the requested person ID:" + id + ": was not found.").type("text/plain").build();
222 throw new WebApplicationException(response);
224 fillDocument(personPart, helloDoc);
225 repoSession.saveDocument(helloDoc);
228 if(e instanceof WebApplicationException){
229 throw (WebApplicationException) e;
232 Response response = Response.status(Response.Status.NOT_FOUND).entity(
233 "Update failed ").type("text/plain").build();
234 throw new WebApplicationException(response);
236 if(repoSession != null){
237 releaseRepositorySession(repoSession);
245 public void deletePerson(@PathParam("id") String id) {
246 if(logger.isDebugEnabled()){
247 logger.debug("deleting person with id=" + id);
249 RepositoryInstance repoSession = null;
251 repoSession = getRepositorySession();
252 DocumentRef helloDocRef = new IdRef(id);
253 repoSession.removeDocument(helloDocRef);
257 Response response = Response.status(Response.Status.NOT_FOUND).entity(
258 "Delete failed ").type("text/plain").build();
259 throw new WebApplicationException(response);
261 if(repoSession != null){
262 releaseRepositorySession(repoSession);
267 private RepositoryInstance getRepositorySession() throws Exception {
268 NuxeoConnector nuxeoConnector = NuxeoConnector.getInstance();
269 nuxeoConnector.initialize();
270 NuxeoClient client = nuxeoConnector.getClient();
271 //FIXME: is it possible to reuse repository session?
272 //Authentication failures happen while trying to reuse the session
273 RepositoryInstance repoSession = client.openRepository();
274 if(logger.isDebugEnabled()){
275 logger.debug("getRepository() repository root: " +
276 repoSession.getRootDocument());
281 private void releaseRepositorySession(RepositoryInstance repoSession) {
284 NuxeoClient.getInstance().releaseRepository(repoSession);
286 logger.error("Could not close the repository session", e);
287 //no need to throw this service specific exception
291 private Document getDocument(RepositoryInstance repoSession, DocumentModel helloDoc)
294 DocumentWriter writer = null;
295 DocumentReader reader = null;
296 ByteArrayOutputStream baos = null;
297 ByteArrayInputStream bais = null;
299 baos = new ByteArrayOutputStream();
300 //nuxeo io.impl begin
301 reader = new SingleDocumentReader(repoSession, helloDoc);
302 writer = new XMLDocumentWriter(baos);
303 DocumentPipe pipe = new DocumentPipeImpl();
305 pipe.setReader(reader);
306 pipe.setWriter(writer);
308 bais = new ByteArrayInputStream(baos.toByteArray());
309 SAXReader saxReader = new SAXReader();
310 doc = saxReader.read(bais);
325 }catch(IOException ioe){
326 logger.error("Failed to close io streams with {}", ioe);
327 throw new WebApplicationException();
333 private void fillDocument(PersonNuxeo p, DocumentModel helloDoc) throws Exception {
334 if(p.getFirstName() != null){
335 helloDoc.setPropertyValue("dublincore:title", p.getFirstName() + " " + p.getLastName());
336 helloDoc.setPropertyValue("hello:firstName", p.getFirstName());
338 if(p.getLastName() != null){
339 helloDoc.setPropertyValue("hello:lastName", p.getLastName());
341 if(p.getStreet() != null){
342 helloDoc.setPropertyValue("hello:street", p.getStreet());
344 if(p.getCity() != null){
345 helloDoc.setPropertyValue("hello:city", p.getCity());
347 if(p.getState() != null){
348 helloDoc.setPropertyValue("hello:state", p.getState());
350 if(p.getZip() != null){
351 helloDoc.setPropertyValue("hello:zip", p.getZip());
353 if(p.getCountry() != null){
354 helloDoc.setPropertyValue("hello:country", p.getCountry());
358 private void verboseObject(String msg, Class klass, Object obj) {
360 if(logger.isDebugEnabled()){
363 JAXBContext jc = JAXBContext.newInstance(klass);
364 Marshaller m = jc.createMarshaller();
365 m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
366 m.marshal(obj, System.out);