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:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright 2009 University of California at Berkeley
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
18 package org.collectionspace.services.nuxeo.client.java;
21 import java.util.UUID;
22 import org.collectionspace.services.common.repository.RepositoryClient;
23 import org.collectionspace.services.common.context.ServiceContext;
24 import org.collectionspace.services.common.repository.BadRequestException;
25 import org.collectionspace.services.common.repository.DocumentNotFoundException;
26 import org.collectionspace.services.common.repository.DocumentHandler;
27 import org.collectionspace.services.common.repository.DocumentException;
28 import org.collectionspace.services.common.repository.DocumentHandler.Action;
29 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
30 import org.nuxeo.common.utils.IdUtils;
31 import org.nuxeo.ecm.core.api.ClientException;
32 import org.nuxeo.ecm.core.api.DocumentModel;
33 import org.nuxeo.ecm.core.api.DocumentModelList;
34 import org.nuxeo.ecm.core.api.DocumentRef;
35 import org.nuxeo.ecm.core.api.IdRef;
36 import org.nuxeo.ecm.core.api.PathRef;
37 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
38 import org.nuxeo.ecm.core.client.NuxeoClient;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
43 * RepositoryJavaClient is used to perform CRUD operations on documents in Nuxeo
44 * repository using Remote Java APIs. It uses @see DocumentHandler as IOHandler
47 * $LastChangedRevision: $ $LastChangedDate: $
49 public class RepositoryJavaClient implements RepositoryClient {
51 private final Logger logger = LoggerFactory.getLogger(RepositoryJavaClient.class);
53 public RepositoryJavaClient() {
57 * create document in the Nuxeo repository
59 * @param ctx service context under which this method is invoked
61 * of the document created
63 * should be used by the caller to provide and transform the
65 * @return id in repository of the newly created document
66 * @throws DocumentException
69 public String create(ServiceContext ctx,
70 DocumentHandler handler) throws BadRequestException,
73 if (handler.getDocumentType() == null) {
74 throw new IllegalArgumentException(
75 "RemoteRepositoryClient.create: docType is missing");
77 if (handler == null) {
78 throw new IllegalArgumentException(
79 "RemoteRepositoryClient.create: handler is missing");
81 String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
82 if (nuxeoWspaceId == null) {
83 throw new DocumentNotFoundException(
84 "Unable to find workspace for service " + ctx.getServiceName() +
85 " check if the workspace exists in the Nuxeo repository");
87 RepositoryInstance repoSession = null;
89 handler.prepare(Action.CREATE);
90 repoSession = getRepositorySession();
91 DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId);
92 DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace);
93 String wspacePath = wspaceDoc.getPathAsString();
94 //give our own ID so PathRef could be constructed later on
95 String id = IdUtils.generateId(UUID.randomUUID().toString());
96 // create document model
97 DocumentModel doc = repoSession.createDocumentModel(wspacePath, id,
98 handler.getDocumentType());
99 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
100 DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
101 handler.handle(Action.CREATE, wrapDoc);
102 // create document with documentmodel
103 doc = repoSession.createDocument(doc);
105 handler.complete(Action.CREATE, wrapDoc);
107 } catch (Exception e) {
108 if (logger.isDebugEnabled()) {
109 logger.debug("Caught exception ", e);
111 throw new DocumentException(e);
113 if (repoSession != null) {
114 releaseRepositorySession(repoSession);
121 * get document from the Nuxeo repository
122 * @param ctx service context under which this method is invoked
124 * of the document to retrieve
126 * should be used by the caller to provide and transform the
128 * @throws DocumentException
131 public void get(ServiceContext ctx, String id, DocumentHandler handler)
132 throws DocumentNotFoundException, DocumentException {
134 if (handler == null) {
135 throw new IllegalArgumentException(
136 "RemoteRepositoryClient.get: handler is missing");
138 RepositoryInstance repoSession = null;
141 handler.prepare(Action.GET);
142 repoSession = getRepositorySession();
143 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
144 DocumentModel doc = null;
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);
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) {
159 } catch (DocumentException de) {
161 } catch (Exception e) {
162 if (logger.isDebugEnabled()) {
163 logger.debug("Caught exception ", e);
165 throw new DocumentException(e);
167 if (repoSession != null) {
168 releaseRepositorySession(repoSession);
174 * getAll get all documents for an entity entity service from the Nuxeo
177 * @param ctx service context under which this method is invoked
179 * should be used by the caller to provide and transform the
181 * @throws DocumentException
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");
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");
197 RepositoryInstance repoSession = null;
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(
208 handler.handle(Action.GET_ALL, wrapDoc);
209 handler.complete(Action.GET_ALL, wrapDoc);
210 } catch (DocumentException de) {
212 } catch (Exception e) {
213 if (logger.isDebugEnabled()) {
214 logger.debug("Caught exception ", e);
216 throw new DocumentException(e);
218 if (repoSession != null) {
219 releaseRepositorySession(repoSession);
225 * update given document in the Nuxeo repository
227 * @param ctx service context under which this method is invoked
231 * should be used by the caller to provide and transform the
233 * @throws DocumentException
236 public void update(ServiceContext ctx, String id, DocumentHandler handler)
237 throws BadRequestException, DocumentNotFoundException,
240 throw new BadRequestException(
241 "RemoteRepositoryClient.update: id is missing");
243 if (handler == null) {
244 throw new IllegalArgumentException(
245 "RemoteRepositoryClient.update: handler is missing");
247 RepositoryInstance repoSession = null;
249 handler.prepare(Action.UPDATE);
250 repoSession = getRepositorySession();
251 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
252 DocumentModel doc = null;
254 doc = repoSession.getDocument(docRef);
255 } catch (ClientException ce) {
256 String msg = "Could not find document to update with id=" + id;
257 logger.error(msg, ce);
258 throw new DocumentNotFoundException(msg, ce);
260 //set reposession to handle the document
261 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
262 DocumentModelWrapper wrapDoc = new DocumentModelWrapper(doc);
263 handler.handle(Action.UPDATE, wrapDoc);
264 repoSession.saveDocument(doc);
266 handler.complete(Action.UPDATE, wrapDoc);
267 } catch (DocumentException de) {
269 } catch (Exception e) {
270 if (logger.isDebugEnabled()) {
271 logger.debug("Caught exception ", e);
273 throw new DocumentException(e);
275 if (repoSession != null) {
276 releaseRepositorySession(repoSession);
282 * delete a document from the Nuxeo repository
283 * @param ctx service context under which this method is invoked
286 * @throws DocumentException
289 public void delete(ServiceContext ctx, String id) throws DocumentNotFoundException,
292 if (logger.isDebugEnabled()) {
293 logger.debug("deleting document with id=" + id);
295 RepositoryInstance repoSession = null;
297 repoSession = getRepositorySession();
298 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
300 repoSession.removeDocument(docRef);
301 } catch (ClientException ce) {
302 String msg = "could not find document to delete with id=" + id;
303 logger.error(msg, ce);
304 throw new DocumentNotFoundException(msg, ce);
307 } catch (DocumentException de) {
309 } catch (Exception e) {
310 if (logger.isDebugEnabled()) {
311 logger.debug("Caught exception ", e);
313 throw new DocumentException(e);
315 if (repoSession != null) {
316 releaseRepositorySession(repoSession);
322 public String createWorkspace(String tenantDomain, String workspaceName) throws Exception {
323 RepositoryInstance repoSession = null;
324 String workspaceId = null;
326 repoSession= getRepositorySession();
327 DocumentRef docRef = new PathRef(
330 DocumentModel parent = repoSession.getDocument(docRef);
331 DocumentModel doc = repoSession.createDocumentModel(parent.getPathAsString(),
332 workspaceName, "Workspace");
333 doc.setPropertyValue("dc:title", workspaceName);
334 doc.setPropertyValue("dc:description", "A CollectionSpace workspace for " +
336 doc = repoSession.createDocument(doc);
337 workspaceId = doc.getId();
339 if(logger.isDebugEnabled()){
340 logger.debug("created workspace name=" + workspaceName +
341 " id=" + workspaceId);
344 if(logger.isDebugEnabled()){
345 logger.debug("createWorkspace caught exception ", e);
349 if(repoSession != null){
350 releaseRepositorySession(repoSession);
357 public String getWorkspaceId(String tenantDomain, String workspaceName) throws Exception {
358 String workspaceId = null;
359 RepositoryInstance repoSession = null;
361 repoSession = getRepositorySession();
362 DocumentRef docRef = new PathRef(
365 "/" + workspaceName);
366 DocumentModel workspace = repoSession.getDocument(docRef);
367 workspaceId = workspace.getId();
368 }catch(DocumentException de){
371 if(logger.isDebugEnabled()){
372 logger.debug("Caught exception ", e);
374 throw new DocumentException(e);
376 if(repoSession != null){
377 releaseRepositorySession(repoSession);
383 private RepositoryInstance getRepositorySession() throws Exception {
384 // FIXME: is it possible to reuse repository session?
385 // Authentication failures happen while trying to reuse the session
386 NuxeoClient client = NuxeoConnector.getInstance().getClient();
387 RepositoryInstance repoSession = client.openRepository();
388 if (logger.isDebugEnabled()) {
389 logger.debug("getRepository() repository root: " + repoSession.getRootDocument());
394 private void releaseRepositorySession(RepositoryInstance repoSession) {
396 NuxeoClient client = NuxeoConnector.getInstance().getClient();
398 client.releaseRepository(repoSession);
399 } catch (Exception e) {
400 logger.error("Could not close the repository session", e);
401 // no need to throw this service specific exception