]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
097fb241e06765d60758a72fdc14e06c525f7a6f
[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 java.util.Hashtable;
21 import org.collectionspace.services.common.repository.RepositoryClient;
22 import org.collectionspace.services.common.context.ServiceContext;
23 import org.collectionspace.services.common.repository.BadRequestException;
24 import org.collectionspace.services.common.repository.DocumentNotFoundException;
25 import org.collectionspace.services.common.repository.DocumentHandler;
26 import org.collectionspace.services.common.repository.DocumentException;
27 import org.collectionspace.services.common.repository.DocumentHandler.Action;
28 import org.nuxeo.common.utils.IdUtils;
29 import org.nuxeo.ecm.core.api.ClientException;
30 import org.nuxeo.ecm.core.api.DocumentModel;
31 import org.nuxeo.ecm.core.api.DocumentModelList;
32 import org.nuxeo.ecm.core.api.DocumentRef;
33 import org.nuxeo.ecm.core.api.IdRef;
34 import org.nuxeo.ecm.core.api.PathRef;
35 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
36 import org.nuxeo.ecm.core.client.NuxeoClient;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 /**
41  * RepositoryJavaClient is used to perform CRUD operations on documents in Nuxeo
42  * repository using Remote Java APIs. It uses @see DocumentHandler as IOHandler
43  * with the client.
44  * 
45  * $LastChangedRevision: $ $LastChangedDate: $
46  */
47 public class RepositoryJavaClient implements RepositoryClient {
48
49     private final Logger logger = LoggerFactory.getLogger(RepositoryJavaClient.class);
50
51     public RepositoryJavaClient() {
52     }
53
54     /**
55      * create document in the Nuxeo repository
56      *
57      * @param ctx service context under which this method is invoked
58      * @param docType
59      *            of the document created
60      * @param handler
61      *            should be used by the caller to provide and transform the
62      *            document
63      * @return id in repository of the newly created document
64      * @throws DocumentException
65      */
66     @Override
67     public String create(ServiceContext ctx,
68             DocumentHandler handler) throws BadRequestException,
69             DocumentException {
70
71         if(handler.getDocumentType() == null){
72             throw new IllegalArgumentException(
73                     "RemoteRepositoryClient.create: docType is missing");
74         }
75         if(handler == null){
76             throw new IllegalArgumentException(
77                     "RemoteRepositoryClient.create: handler is missing");
78         }
79         String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
80         if(nuxeoWspaceId == null){
81             throw new DocumentNotFoundException(
82                     "Unable to find workspace for service " + ctx.getServiceName() +
83                     " check if the 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() +
195                     " check if the 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     @Override
328     public String createWorkspace(String tenantDomain, String workspaceName) throws Exception {
329         RepositoryInstance repoSession = null;
330         String workspaceId = null;
331         try{
332             repoSession= getRepositorySession();
333             DocumentRef docRef = new PathRef(
334                     "/" + tenantDomain +
335                     "/" + "workspaces");
336             DocumentModel parent = repoSession.getDocument(docRef);
337             DocumentModel doc = repoSession.createDocumentModel(parent.getPathAsString(),
338                     workspaceName, "Workspace");
339             doc.setPropertyValue("dc:title", workspaceName);
340             doc.setPropertyValue("dc:description", "A CollectionSpace workspace for " +
341                     workspaceName);
342             doc = repoSession.createDocument(doc);
343             workspaceId = doc.getId();
344             repoSession.save();
345             if(logger.isDebugEnabled()){
346                 logger.debug("created workspace name=" + workspaceName +
347                         " id=" + workspaceId);
348             }
349         }catch(Exception e){
350             if(logger.isDebugEnabled()){
351                 logger.debug("createWorkspace caught exception ", e);
352             }
353             throw e;
354         }finally{
355             if(repoSession != null){
356                 releaseRepositorySession(repoSession);
357             }
358         }
359         return workspaceId;
360     }
361
362     @Override
363     public String getWorkspaceId(String tenantDomain, String workspaceName) throws Exception {
364         String workspaceId = null;
365         RepositoryInstance repoSession = null;
366         try{
367             repoSession = getRepositorySession();
368             DocumentRef docRef = new PathRef(
369                     "/" + tenantDomain +
370                     "/" + "workspaces" +
371                     "/" + workspaceName);
372             DocumentModel workspace = repoSession.getDocument(docRef);
373             workspaceId = workspace.getId();
374         }catch(DocumentException de){
375             throw de;
376         }catch(Exception e){
377             if(logger.isDebugEnabled()){
378                 logger.debug("Caught exception ", e);
379             }
380             throw new DocumentException(e);
381         }finally{
382             if(repoSession != null){
383                 releaseRepositorySession(repoSession);
384             }
385         }
386         return workspaceId;
387     }
388
389     private RepositoryInstance getRepositorySession() throws Exception {
390         // FIXME: is it possible to reuse repository session?
391         // Authentication failures happen while trying to reuse the session
392         NuxeoClient client = NuxeoConnector.getInstance().getClient();
393         RepositoryInstance repoSession = client.openRepository();
394         if(logger.isDebugEnabled()){
395             logger.debug("getRepository() repository root: " + repoSession.getRootDocument());
396         }
397         return repoSession;
398     }
399
400     private void releaseRepositorySession(RepositoryInstance repoSession) {
401         try{
402             NuxeoClient client = NuxeoConnector.getInstance().getClient();
403             // release session
404             client.releaseRepository(repoSession);
405         }catch(Exception e){
406             logger.error("Could not close the repository session", e);
407             // no need to throw this service specific exception
408         }
409     }
410 }