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.DocumentModel;
37 import org.nuxeo.ecm.core.api.DocumentRef;
38 import org.nuxeo.ecm.core.api.IdRef;
39 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
40 import org.nuxeo.ecm.core.client.NuxeoClient;
41 import org.nuxeo.ecm.core.io.DocumentPipe;
42 import org.nuxeo.ecm.core.io.DocumentReader;
43 import org.nuxeo.ecm.core.io.DocumentWriter;
44 import org.nuxeo.ecm.core.io.impl.DocumentPipeImpl;
45 import org.nuxeo.ecm.core.io.impl.plugins.SingleDocumentReader;
46 import org.nuxeo.ecm.core.io.impl.plugins.XMLDocumentWriter;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
51 @Consumes("application/xml")
52 @Produces("application/xml")
53 public class MultischemaResource extends CollectionSpaceResource {
55 final Logger logger = LoggerFactory.getLogger(MultischemaResource.class);
57 public MultischemaResource() {
61 @Consumes("multipart/form-data")
62 public Response createPerson(MultipartFormDataInput multipart) {
64 PersonNuxeo personPart = new PersonNuxeo();
65 DublincoreNuxeo dcPart = new DublincoreNuxeo();
67 RepositoryInstance repoSession = null;
69 if(multipart.getFormData().containsKey("dublincore")){
70 dcPart = multipart.getFormDataPart("dublincore", DublincoreNuxeo.class, null);
72 if(multipart.getFormData().containsKey("hello")){
73 personPart = multipart.getFormDataPart("hello", PersonNuxeo.class, null);
76 repoSession = getRepositorySession();
77 DocumentRef nuxeoWspace = new IdRef(CS_PERSON_WORKSPACE_UID);
78 DocumentModel wspacePeople = repoSession.getDocument(nuxeoWspace);
79 String wspacePath = wspacePeople.getPathAsString();
80 String docType = "Hello";
81 String id = IdUtils.generateId("New " + docType);
82 //create document model
83 DocumentModel helloDoc = repoSession.createDocumentModel(wspacePath, id, docType);
84 fillDocument(personPart, helloDoc);
85 //create document with documentmodel
86 helloDoc = repoSession.createDocument(helloDoc);
89 personPart.setId(helloDoc.getId());
93 Response response = Response.status(Response.Status.NOT_FOUND).entity(
94 "Create failed").type("text/plain").build();
95 throw new WebApplicationException(response);
97 if(repoSession != null){
98 releaseRepositorySession(repoSession);
102 if(logger.isDebugEnabled()){
103 verboseObject("createPerson: person", PersonNuxeo.class, personPart);
104 verboseObject("createPerson: dublincore", DublincoreNuxeo.class, dcPart);
106 UriBuilder path = UriBuilder.fromResource(MultischemaResource.class);
108 path.path("" + personPart.getId());
109 Response response = Response.created(path.build()).build();
115 @Produces("multipart/form-data")
116 public MultipartFormDataOutput getPerson(
117 @PathParam("id") String id) {
119 PersonNuxeo personPart = new PersonNuxeo();
120 DublincoreNuxeo dublinPart = new DublincoreNuxeo();
121 MultipartFormDataOutput output = new MultipartFormDataOutput();
122 RepositoryInstance repoSession = null;
125 repoSession = getRepositorySession();
126 DocumentRef helloDocRef = new IdRef(id);
127 DocumentModel helloDoc = repoSession.getDocument(helloDocRef);
128 if(helloDoc == null){
129 Response response = Response.status(Response.Status.NOT_FOUND).entity(
130 "Get failed, the requested person ID:" + id + ": was not found.").type("text/plain").build();
131 throw new WebApplicationException(response);
133 Document doc = getDocument(repoSession, helloDoc);
134 Element root = doc.getRootElement();
135 //TODO: recognize schema thru namespace uri
136 //Namespace ns = new Namespace("hello", "http://collectionspace.org/hello");
137 Iterator<Element> siter = root.elementIterator("schema");
138 while(siter.hasNext()){
140 Element s = siter.next();
142 //TODO: recognize schema thru namespace uri
143 if("hello".equals(s.attribute("name").getValue())){
144 personPart.setId(id);
145 Element ele = s.element("cversion");
147 personPart.setVersion((String) ele.getData());
149 ele = s.element("firstName");
151 personPart.setFirstName((String) ele.getData());
153 ele = s.element("lastName");
155 personPart.setLastName((String) ele.getData());
157 ele = s.element("city");
159 personPart.setCity((String) ele.getData());
161 ele = s.element("state");
163 personPart.setState((String) ele.getData());
165 ele = s.element("zip");
167 personPart.setZip((String) ele.getData());
169 ele = s.element("country");
171 personPart.setCountry((String) ele.getData());
173 }else if("dublincore".equals(s.attribute("name").getValue())){
174 Element ele = s.element("title");
176 dublinPart.setTitle((String) ele.getData());
180 if(logger.isDebugEnabled()){
181 verboseObject("getPerson:hello:", PersonNuxeo.class, personPart);
182 verboseObject("getPerson:dublincore:", DublincoreNuxeo.class, dublinPart);
184 output.addFormData("hello", personPart, MediaType.APPLICATION_XML_TYPE);
185 output.addFormData("dublincore", dublinPart, MediaType.APPLICATION_XML_TYPE);
188 if(e instanceof WebApplicationException){
189 throw (WebApplicationException) e;
191 if(logger.isDebugEnabled()){
194 Response response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
195 "Get failed").type("text/plain").build();
196 throw new WebApplicationException(response);
198 if(repoSession != null){
199 releaseRepositorySession(repoSession);
207 public PersonNuxeo updatePerson(
208 @PathParam("id") String id,
209 PersonNuxeo personPart) {
210 if(logger.isDebugEnabled()){
211 verboseObject("updating person input", PersonNuxeo.class, personPart);
213 RepositoryInstance repoSession = null;
215 repoSession = getRepositorySession();
216 DocumentRef helloDocRef = new IdRef(id);
217 DocumentModel helloDoc = repoSession.getDocument(helloDocRef);
218 if(helloDoc == null){
219 Response response = Response.status(Response.Status.NOT_FOUND).entity(
220 "Get failed, the requested person ID:" + id + ": was not found.").type("text/plain").build();
221 throw new WebApplicationException(response);
223 fillDocument(personPart, helloDoc);
224 repoSession.saveDocument(helloDoc);
227 if(e instanceof WebApplicationException){
228 throw (WebApplicationException) e;
231 Response response = Response.status(Response.Status.NOT_FOUND).entity(
232 "Update failed ").type("text/plain").build();
233 throw new WebApplicationException(response);
235 if(repoSession != null){
236 releaseRepositorySession(repoSession);
244 public void deletePerson(@PathParam("id") String id) {
245 if(logger.isDebugEnabled()){
246 logger.debug("deleting person with id=" + id);
248 RepositoryInstance repoSession = null;
250 repoSession = getRepositorySession();
251 DocumentRef helloDocRef = new IdRef(id);
252 repoSession.removeDocument(helloDocRef);
256 Response response = Response.status(Response.Status.NOT_FOUND).entity(
257 "Delete failed ").type("text/plain").build();
258 throw new WebApplicationException(response);
260 if(repoSession != null){
261 releaseRepositorySession(repoSession);
266 private RepositoryInstance getRepositorySession() throws Exception {
267 NuxeoConnector nuxeoConnector = NuxeoConnector.getInstance();
268 nuxeoConnector.initialize();
269 NuxeoClient client = nuxeoConnector.getClient();
270 //FIXME: is it possible to reuse repository session?
271 //Authentication failures happen while trying to reuse the session
272 RepositoryInstance repoSession = client.openRepository();
273 if(logger.isDebugEnabled()){
274 logger.debug("getRepository() repository root: " +
275 repoSession.getRootDocument());
280 private void releaseRepositorySession(RepositoryInstance repoSession) {
283 NuxeoClient.getInstance().releaseRepository(repoSession);
285 logger.error("Could not close the repository session", e);
286 //no need to throw this service specific exception
290 private Document getDocument(RepositoryInstance repoSession, DocumentModel helloDoc)
293 DocumentWriter writer = null;
294 DocumentReader reader = null;
295 ByteArrayOutputStream baos = null;
296 ByteArrayInputStream bais = null;
298 baos = new ByteArrayOutputStream();
299 //nuxeo io.impl begin
300 reader = new SingleDocumentReader(repoSession, helloDoc);
301 writer = new XMLDocumentWriter(baos);
302 DocumentPipe pipe = new DocumentPipeImpl();
304 pipe.setReader(reader);
305 pipe.setWriter(writer);
307 bais = new ByteArrayInputStream(baos.toByteArray());
308 SAXReader saxReader = new SAXReader();
309 doc = saxReader.read(bais);
324 }catch(IOException ioe){
325 logger.error("Failed to close io streams with {}", ioe);
326 throw new WebApplicationException();
332 private void fillDocument(PersonNuxeo p, DocumentModel helloDoc) throws Exception {
333 if(p.getFirstName() != null){
334 helloDoc.setPropertyValue("dublincore:title", p.getFirstName() + " " + p.getLastName());
335 helloDoc.setPropertyValue("hello:firstName", p.getFirstName());
337 if(p.getLastName() != null){
338 helloDoc.setPropertyValue("hello:lastName", p.getLastName());
340 if(p.getStreet() != null){
341 helloDoc.setPropertyValue("hello:street", p.getStreet());
343 if(p.getCity() != null){
344 helloDoc.setPropertyValue("hello:city", p.getCity());
346 if(p.getState() != null){
347 helloDoc.setPropertyValue("hello:state", p.getState());
349 if(p.getZip() != null){
350 helloDoc.setPropertyValue("hello:zip", p.getZip());
352 if(p.getCountry() != null){
353 helloDoc.setPropertyValue("hello:country", p.getCountry());
357 private void verboseObject(String msg, Class klass, Object obj) {
359 if(logger.isDebugEnabled()){
362 JAXBContext jc = JAXBContext.newInstance(klass);
363 Marshaller m = jc.createMarshaller();
364 m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
365 m.marshal(obj, System.out);