]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
afa8160489bc77abeb2db82bf544492196eb6a70
[tmp/jakarta-migration.git] /
1 /**
2  *  This document is a part of the source code and related artifacts
3  *  for CollectionSpace, an open source collections management system
4  *  for museums and related institutions:
5
6  *  http://www.collectionspace.org
7  *  http://wiki.collectionspace.org
8
9  *  Copyright 2009 University of California at Berkeley
10
11  *  Licensed under the Educational Community License (ECL), Version 2.0.
12  *  You may not use this file except in compliance with this License.
13
14  *  You may obtain a copy of the ECL 2.0 License at
15
16  *  https://source.collectionspace.org/collection-space/LICENSE.txt
17  */
18 package org.collectionspace.services.nuxeo.client.java;
19
20 import org.collectionspace.services.common.repository.RepositoryClient;
21 import org.collectionspace.services.common.context.ServiceContext;
22 import org.collectionspace.services.common.repository.BadRequestException;
23 import org.collectionspace.services.common.repository.DocumentNotFoundException;
24 import org.collectionspace.services.common.repository.DocumentHandler;
25 import org.collectionspace.services.common.repository.DocumentException;
26 import org.collectionspace.services.common.repository.DocumentHandler.Action;
27 import org.nuxeo.common.utils.IdUtils;
28 import org.nuxeo.ecm.core.api.ClientException;
29 import org.nuxeo.ecm.core.api.DocumentModel;
30 import org.nuxeo.ecm.core.api.DocumentModelList;
31 import org.nuxeo.ecm.core.api.DocumentRef;
32 import org.nuxeo.ecm.core.api.IdRef;
33 import org.nuxeo.ecm.core.api.PathRef;
34 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
35 import org.nuxeo.ecm.core.client.NuxeoClient;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * RepositoryJavaClient is used to perform CRUD operations on documents in Nuxeo
41  * repository using Remote Java APIs. It uses @see DocumentHandler as IOHandler
42  * with the client.
43  * 
44  * $LastChangedRevision: $ $LastChangedDate: $
45  */
46 public class RepositoryJavaClient implements RepositoryClient {
47
48     private final Logger logger = LoggerFactory.getLogger(RepositoryJavaClient.class);
49
50     public RepositoryJavaClient() {
51     }
52
53     /**
54      * create document in the Nuxeo repository
55      *
56      * @param ctx service context under which this method is invoked
57      * @param docType
58      *            of the document created
59      * @param handler
60      *            should be used by the caller to provide and transform the
61      *            document
62      * @return id in repository of the newly created document
63      * @throws DocumentException
64      */
65     @Override
66     public String create(ServiceContext ctx,
67             DocumentHandler handler) throws BadRequestException,
68             DocumentException {
69
70         if(handler.getDocumentType() == null){
71             throw new IllegalArgumentException(
72                     "RemoteRepositoryClient.create: docType is missing");
73         }
74         if(handler == null){
75             throw new IllegalArgumentException(
76                     "RemoteRepositoryClient.create: handler is missing");
77         }
78         String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
79         if(nuxeoWspaceId == null){
80             throw new DocumentNotFoundException(
81                     "Unable to find workspace for service " + ctx.getServiceName() +
82                     " check if the mapping exists in service-config.xml or" +
83                     " the the mapped workspace exists in the Nuxeo repository");
84         }
85         RepositoryInstance repoSession = null;
86         try{
87             handler.prepare(Action.CREATE);
88             repoSession = getRepositorySession();
89             DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId);
90             DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace);
91             String wspacePath = wspaceDoc.getPathAsString();
92             String id = IdUtils.generateId("New " + handler.getDocumentType());
93             // create document model
94             DocumentModel doc = repoSession.createDocumentModel(wspacePath, id,
95                     handler.getDocumentType());
96             ((DocumentModelHandler) handler).setRepositorySession(repoSession);
97             DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
98             handler.handle(Action.CREATE, wrapDoc);
99             // create document with documentmodel
100             doc = repoSession.createDocument(doc);
101             repoSession.save();
102             handler.complete(Action.CREATE, wrapDoc);
103             return doc.getId();
104         }catch(Exception e){
105             if(logger.isDebugEnabled()){
106                 logger.debug("Caught exception ", e);
107             }
108             throw new DocumentException(e);
109         }finally{
110             if(repoSession != null){
111                 releaseRepositorySession(repoSession);
112             }
113         }
114
115     }
116
117     /**
118      * get document from the Nuxeo repository
119      * @param ctx service context under which this method is invoked
120      * @param id
121      *            of the document to retrieve
122      * @param handler
123      *            should be used by the caller to provide and transform the
124      *            document
125      * @throws DocumentException
126      */
127     @Override
128     public void get(ServiceContext ctx, String id, DocumentHandler handler)
129             throws DocumentNotFoundException, DocumentException {
130
131         if(handler == null){
132             throw new IllegalArgumentException(
133                     "RemoteRepositoryClient.get: handler is missing");
134         }
135         RepositoryInstance repoSession = null;
136
137         try{
138             handler.prepare(Action.GET);
139             repoSession = getRepositorySession();
140             //FIXME, there is a potential privacy violation here, one tenant could
141             //retrieve doc id of another tenant and could retrieve the document
142             //PathRef does not seem to come to rescue as expected. Needs more thoughts.
143             DocumentRef docRef = new IdRef(id);
144             DocumentModel doc = null;
145             try{
146                 doc = repoSession.getDocument(docRef);
147             }catch(ClientException ce){
148                 String msg = "could not find document with id=" + id;
149                 logger.error(msg, ce);
150                 throw new DocumentNotFoundException(msg, ce);
151             }
152             //set reposession to handle the document
153             ((DocumentModelHandler) handler).setRepositorySession(repoSession);
154             DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
155             handler.handle(Action.GET, wrapDoc);
156             handler.complete(Action.GET, wrapDoc);
157         }catch(IllegalArgumentException iae){
158             throw iae;
159         }catch(DocumentException de){
160             throw de;
161         }catch(Exception e){
162             if(logger.isDebugEnabled()){
163                 logger.debug("Caught exception ", e);
164             }
165             throw new DocumentException(e);
166         }finally{
167             if(repoSession != null){
168                 releaseRepositorySession(repoSession);
169             }
170         }
171     }
172
173     /**
174      * getAll get all documents for an entity entity service from the Nuxeo
175      * repository
176      *
177      * @param ctx service context under which this method is invoked
178      * @param handler
179      *            should be used by the caller to provide and transform the
180      *            document
181      * @throws DocumentException
182      */
183     @Override
184     public void getAll(ServiceContext ctx, DocumentHandler handler)
185             throws DocumentNotFoundException, DocumentException {
186         if(handler == null){
187             throw new IllegalArgumentException(
188                     "RemoteRepositoryClient.getAll: handler is missing");
189         }
190         String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
191         if(nuxeoWspaceId == null){
192             throw new DocumentNotFoundException(
193                     "Unable to find workspace for service " + 
194                     ctx.getServiceName() + " check if the mapping exists in service-config.xml or " +
195                     " the the mapped workspace exists in the Nuxeo repository");
196         }
197         RepositoryInstance repoSession = null;
198
199         try{
200             handler.prepare(Action.GET_ALL);
201             repoSession = getRepositorySession();
202             DocumentRef wsDocRef = new IdRef(nuxeoWspaceId);
203             DocumentModelList docList = repoSession.getChildren(wsDocRef);
204             //set reposession to handle the document
205             ((DocumentModelHandler) handler).setRepositorySession(repoSession);
206             DocumentModelListWrapper wrapDoc = new DocumentModelListWrapper(
207                     docList);
208             handler.handle(Action.GET_ALL, wrapDoc);
209             handler.complete(Action.GET_ALL, wrapDoc);
210         }catch(DocumentException de){
211             throw de;
212         }catch(Exception e){
213             if(logger.isDebugEnabled()){
214                 logger.debug("Caught exception ", e);
215             }
216             throw new DocumentException(e);
217         }finally{
218             if(repoSession != null){
219                 releaseRepositorySession(repoSession);
220             }
221         }
222     }
223
224     /**
225      * update given document in the Nuxeo repository
226      *
227      * @param ctx service context under which this method is invoked
228      * @param id
229      *            of the document
230      * @param handler
231      *            should be used by the caller to provide and transform the
232      *            document
233      * @throws DocumentException
234      */
235     @Override
236     public void update(ServiceContext ctx, String id, DocumentHandler handler)
237             throws BadRequestException, DocumentNotFoundException,
238             DocumentException {
239         if(id == null){
240             throw new BadRequestException(
241                     "RemoteRepositoryClient.update: id is missing");
242         }
243         if(handler == null){
244             throw new IllegalArgumentException(
245                     "RemoteRepositoryClient.update: handler is missing");
246         }
247         RepositoryInstance repoSession = null;
248         try{
249             handler.prepare(Action.UPDATE);
250             repoSession = getRepositorySession();
251             //FIXME, there is a potential privacy violation here, one tenant could
252             //retrieve doc id of another tenant and could retrieve the document
253             //PathRef does not seem to come to rescue as expected. Needs more thoughts.
254             DocumentRef docRef = new IdRef(id);
255             DocumentModel doc = null;
256             try{
257                 doc = repoSession.getDocument(docRef);
258             }catch(ClientException ce){
259                 String msg = "Could not find document to update with id=" + id;
260                 logger.error(msg, ce);
261                 throw new DocumentNotFoundException(msg, ce);
262             }
263             //set reposession to handle the document
264             ((DocumentModelHandler) handler).setRepositorySession(repoSession);
265             DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
266             handler.handle(Action.UPDATE, wrapDoc);
267             repoSession.saveDocument(doc);
268             repoSession.save();
269             handler.complete(Action.UPDATE, wrapDoc);
270         }catch(DocumentException de){
271             throw de;
272         }catch(Exception e){
273             if(logger.isDebugEnabled()){
274                 logger.debug("Caught exception ", e);
275             }
276             throw new DocumentException(e);
277         }finally{
278             if(repoSession != null){
279                 releaseRepositorySession(repoSession);
280             }
281         }
282     }
283
284     /**
285      * delete a document from the Nuxeo repository
286      * @param ctx service context under which this method is invoked
287      * @param id
288      *            of the document
289      * @throws DocumentException
290      */
291     @Override
292     public void delete(ServiceContext ctx, String id) throws DocumentNotFoundException,
293             DocumentException {
294
295         if(logger.isDebugEnabled()){
296             logger.debug("deleting document with id=" + id);
297         }
298         RepositoryInstance repoSession = null;
299         try{
300             repoSession = getRepositorySession();
301             //FIXME, there is a potential privacy violation here, one tenant could
302             //retrieve doc id of another tenant and could retrieve the document
303             //PathRef does not seem to come to rescue as expected. needs more thoughts.
304             DocumentRef docRef = new IdRef(id);
305             try{
306                 repoSession.removeDocument(docRef);
307             }catch(ClientException ce){
308                 String msg = "could not find document to delete with id=" + id;
309                 logger.error(msg, ce);
310                 throw new DocumentNotFoundException(msg, ce);
311             }
312             repoSession.save();
313         }catch(DocumentException de){
314             throw de;
315         }catch(Exception e){
316             if(logger.isDebugEnabled()){
317                 logger.debug("Caught exception ", e);
318             }
319             throw new DocumentException(e);
320         }finally{
321             if(repoSession != null){
322                 releaseRepositorySession(repoSession);
323             }
324         }
325     }
326
327     private RepositoryInstance getRepositorySession() throws Exception {
328         // FIXME: is it possible to reuse repository session?
329         // Authentication failures happen while trying to reuse the session
330         NuxeoClient client = NuxeoConnector.getInstance().getClient();
331         RepositoryInstance repoSession = client.openRepository();
332         if(logger.isDebugEnabled()){
333             logger.debug("getRepository() repository root: " + repoSession.getRootDocument());
334         }
335         return repoSession;
336     }
337
338     private void releaseRepositorySession(RepositoryInstance repoSession) {
339         try{
340             NuxeoClient client = NuxeoConnector.getInstance().getClient();
341             // release session
342             client.releaseRepository(repoSession);
343         }catch(Exception e){
344             logger.error("Could not close the repository session", e);
345             // no need to throw this service specific exception
346         }
347     }
348 }