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;
20 import java.util.Hashtable;
21 import java.util.List;
23 import java.util.UUID;
24 import java.util.regex.Matcher;
25 import java.util.regex.Pattern;
26 import java.util.regex.PatternSyntaxException;
28 import javax.ws.rs.WebApplicationException;
29 import javax.ws.rs.core.MultivaluedMap;
31 import org.collectionspace.services.client.IQueryManager;
32 import org.collectionspace.services.client.PoxPayloadIn;
33 import org.collectionspace.services.client.PoxPayloadOut;
34 import org.collectionspace.services.client.workflow.WorkflowClient;
35 import org.collectionspace.services.common.context.ServiceContext;
36 import org.collectionspace.services.common.datetime.GregorianCalendarDateTimeUtils;
37 import org.collectionspace.services.common.query.QueryContext;
38 import org.collectionspace.services.common.repository.RepositoryClient;
39 import org.collectionspace.services.common.workflow.service.nuxeo.WorkflowDocumentModelHandler;
40 import org.collectionspace.services.common.profile.Profiler;
41 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
43 import org.collectionspace.services.common.document.BadRequestException;
44 import org.collectionspace.services.common.document.DocumentException;
45 import org.collectionspace.services.common.document.DocumentFilter;
46 import org.collectionspace.services.common.document.DocumentHandler;
47 import org.collectionspace.services.common.document.DocumentNotFoundException;
48 import org.collectionspace.services.common.document.DocumentHandler.Action;
49 import org.collectionspace.services.common.document.DocumentWrapper;
50 import org.collectionspace.services.common.document.DocumentWrapperImpl;
52 import org.nuxeo.common.utils.IdUtils;
53 import org.nuxeo.ecm.core.api.ClientException;
54 import org.nuxeo.ecm.core.api.DocumentModel;
55 import org.nuxeo.ecm.core.api.DocumentModelList;
56 import org.nuxeo.ecm.core.api.impl.DocumentModelListImpl;
57 import org.nuxeo.ecm.core.api.DocumentRef;
58 import org.nuxeo.ecm.core.api.IdRef;
59 import org.nuxeo.ecm.core.api.PathRef;
60 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
61 //import org.nuxeo.ecm.core.client.NuxeoClient;
62 import org.nuxeo.ecm.core.schema.SchemaManager;
63 import org.nuxeo.runtime.api.Framework;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
69 * RepositoryJavaClient is used to perform CRUD operations on documents in Nuxeo
70 * repository using Remote Java APIs. It uses @see DocumentHandler as IOHandler
73 * $LastChangedRevision: $ $LastChangedDate: $
75 public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn, PoxPayloadOut> {
78 private final Logger logger = LoggerFactory.getLogger(RepositoryJavaClientImpl.class);
79 // private final Logger profilerLogger = LoggerFactory.getLogger("remperf");
80 // private String foo = Profiler.createLogger();
82 public static final String NUXEO_CORE_TYPE_DOMAIN = "Domain";
83 public static final String NUXEO_CORE_TYPE_WORKSPACEROOT = "WorkspaceRoot";
86 * Instantiates a new repository java client impl.
88 public RepositoryJavaClientImpl() {
93 public void assertWorkflowState(ServiceContext ctx,
94 DocumentModel docModel) throws DocumentNotFoundException, ClientException {
95 MultivaluedMap<String, String> queryParams = ctx.getQueryParams();
96 if (queryParams != null) {
98 // Look for the workflow "delete" query param and see if we need to assert that the
99 // docModel is in a non-deleted workflow state.
101 String currentState = docModel.getCurrentLifeCycleState();
102 String includeDeletedStr = queryParams.getFirst(WorkflowClient.WORKFLOW_QUERY_NONDELETED);
103 boolean includeDeleted = includeDeletedStr == null ? true : Boolean.parseBoolean(includeDeletedStr);
104 if (includeDeleted == false) {
106 // We don't wanted soft-deleted object, so throw an exception if this one is soft-deleted.
108 if (currentState.equalsIgnoreCase(WorkflowClient.WORKFLOWSTATE_DELETED)) {
109 String msg = "GET assertion that docModel not be in 'deleted' workflow state failed.";
111 throw new DocumentNotFoundException(msg);
118 * create document in the Nuxeo repository
120 * @param ctx service context under which this method is invoked
122 * should be used by the caller to provide and transform the
124 * @return id in repository of the newly created document
125 * @throws DocumentException
128 public String create(ServiceContext ctx,
129 DocumentHandler handler) throws BadRequestException,
132 String docType = NuxeoUtils.getTenantQualifiedDocType(ctx); //ctx.getDocumentType();
133 if (docType == null) {
134 throw new IllegalArgumentException(
135 "RepositoryJavaClient.create: docType is missing");
138 if (handler == null) {
139 throw new IllegalArgumentException(
140 "RepositoryJavaClient.create: handler is missing");
142 String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
143 if (nuxeoWspaceId == null) {
144 throw new DocumentNotFoundException(
145 "Unable to find workspace for service " + ctx.getServiceName()
146 + " check if the workspace exists in the Nuxeo repository");
149 RepositoryInstance repoSession = null;
151 handler.prepare(Action.CREATE);
152 repoSession = getRepositorySession();
153 DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId);
154 DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace);
155 String wspacePath = wspaceDoc.getPathAsString();
156 //give our own ID so PathRef could be constructed later on
157 String id = IdUtils.generateId(UUID.randomUUID().toString());
158 // create document model
159 DocumentModel doc = repoSession.createDocumentModel(wspacePath, id, docType);
160 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
161 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
162 handler.handle(Action.CREATE, wrapDoc);
163 // create document with documentmodel
164 doc = repoSession.createDocument(doc);
166 // TODO for sub-docs need to call into the handler to let it deal with subitems. Pass in the id,
167 // and assume the handler has the state it needs (doc fragments).
168 handler.complete(Action.CREATE, wrapDoc);
170 } catch (BadRequestException bre) {
172 } catch (Exception e) {
173 if (logger.isDebugEnabled()) {
174 logger.debug("Caught exception ", e);
176 throw new DocumentException(e);
178 if (repoSession != null) {
179 releaseRepositorySession(repoSession);
186 * get document from the Nuxeo repository
187 * @param ctx service context under which this method is invoked
189 * of the document to retrieve
191 * should be used by the caller to provide and transform the
193 * @throws DocumentException
196 public void get(ServiceContext ctx, String id, DocumentHandler handler)
197 throws DocumentNotFoundException, DocumentException {
199 if (handler == null) {
200 throw new IllegalArgumentException(
201 "RepositoryJavaClient.get: handler is missing");
204 RepositoryInstance repoSession = null;
206 handler.prepare(Action.GET);
207 repoSession = getRepositorySession();
208 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
209 DocumentModel docModel = null;
211 docModel = repoSession.getDocument(docRef);
212 assertWorkflowState(ctx, docModel);
213 } catch (ClientException ce) {
214 String msg = "Could not find document with id=" + id;
215 logger.error(msg, ce);
216 throw new DocumentNotFoundException(msg, ce);
218 //set reposession to handle the document
219 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
220 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(docModel);
221 handler.handle(Action.GET, wrapDoc);
222 handler.complete(Action.GET, wrapDoc);
223 } catch (IllegalArgumentException iae) {
225 } catch (DocumentException de) {
227 } catch (Exception e) {
228 if (logger.isDebugEnabled()) {
229 logger.debug("Caught exception ", e);
231 throw new DocumentException(e);
233 if (repoSession != null) {
234 releaseRepositorySession(repoSession);
240 * get document from the Nuxeo repository, using the docFilter params.
241 * @param ctx service context under which this method is invoked
243 * should be used by the caller to provide and transform the
244 * document. Handler must have a docFilter set to return a single item.
245 * @throws DocumentException
248 public void get(ServiceContext ctx, DocumentHandler handler)
249 throws DocumentNotFoundException, DocumentException {
250 QueryContext queryContext = new QueryContext(ctx, handler);
251 RepositoryInstance repoSession = null;
254 handler.prepare(Action.GET);
255 repoSession = getRepositorySession();
257 DocumentModelList docList = null;
258 // force limit to 1, and ignore totalSize
259 String query = NuxeoUtils.buildNXQLQuery(ctx, queryContext);
260 docList = repoSession.query(query, null, 1, 0, false);
261 if (docList.size() != 1) {
262 throw new DocumentNotFoundException("No document found matching filter params.");
264 DocumentModel doc = docList.get(0);
266 if (logger.isDebugEnabled()) {
267 logger.debug("Executed NXQL query: " + query);
270 //set reposession to handle the document
271 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
272 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
273 handler.handle(Action.GET, wrapDoc);
274 handler.complete(Action.GET, wrapDoc);
275 } catch (IllegalArgumentException iae) {
277 } catch (DocumentException de) {
279 } catch (Exception e) {
280 if (logger.isDebugEnabled()) {
281 logger.debug("Caught exception ", e);
283 throw new DocumentException(e);
285 if (repoSession != null) {
286 releaseRepositorySession(repoSession);
291 public DocumentWrapper<DocumentModel> getDoc(
292 RepositoryInstance repoSession,
293 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
294 String csid) throws DocumentNotFoundException, DocumentException {
295 DocumentWrapper<DocumentModel> wrapDoc = null;
298 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, csid);
299 DocumentModel doc = null;
301 doc = repoSession.getDocument(docRef);
302 } catch (ClientException ce) {
303 String msg = "Could not find document with CSID=" + csid;
304 logger.error(msg, ce);
305 throw new DocumentNotFoundException(msg, ce);
307 wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
308 } catch (IllegalArgumentException iae) {
310 } catch (DocumentException de) {
318 * Get wrapped documentModel from the Nuxeo repository. The search is restricted to the workspace
319 * of the current context.
321 * @param ctx service context under which this method is invoked
323 * of the document to retrieve
324 * @throws DocumentException
327 public DocumentWrapper<DocumentModel> getDoc(
328 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
329 String csid) throws DocumentNotFoundException, DocumentException {
330 RepositoryInstance repoSession = null;
331 DocumentWrapper<DocumentModel> wrapDoc = null;
334 // Open a new repository session
335 repoSession = getRepositorySession();
336 wrapDoc = getDoc(repoSession, ctx, csid);
337 } catch (IllegalArgumentException iae) {
339 } catch (DocumentException de) {
341 } catch (Exception e) {
342 if (logger.isDebugEnabled()) {
343 logger.debug("Caught exception ", e);
345 throw new DocumentException(e);
347 if (repoSession != null) {
348 releaseRepositorySession(repoSession);
352 if (logger.isWarnEnabled() == true) {
353 logger.warn("Returned DocumentModel instance was created with a repository session that is now closed.");
358 public DocumentWrapper<DocumentModel> findDoc(
359 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
360 RepositoryInstance repoSession,
362 throws DocumentNotFoundException, DocumentException {
363 DocumentWrapper<DocumentModel> wrapDoc = null;
366 QueryContext queryContext = new QueryContext(ctx, whereClause);
367 DocumentModelList docList = null;
368 // force limit to 1, and ignore totalSize
369 String query = NuxeoUtils.buildNXQLQuery(ctx, queryContext);
370 docList = repoSession.query(query,
375 if (docList.size() != 1) {
376 if (logger.isDebugEnabled()) {
377 logger.debug("findDoc: Query found: " + docList.size() + " items.");
378 logger.debug(" Query: " + query);
380 throw new DocumentNotFoundException("No document found matching filter params.");
382 DocumentModel doc = docList.get(0);
383 wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
384 } catch (IllegalArgumentException iae) {
386 } catch (DocumentException de) {
388 } catch (Exception e) {
389 if (logger.isDebugEnabled()) {
390 logger.debug("Caught exception ", e);
392 throw new DocumentException(e);
399 * find wrapped documentModel from the Nuxeo repository
400 * @param ctx service context under which this method is invoked
401 * @param whereClause where NXQL where clause to get the document
402 * @throws DocumentException
405 public DocumentWrapper<DocumentModel> findDoc(
406 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
408 throws DocumentNotFoundException, DocumentException {
409 RepositoryInstance repoSession = null;
410 DocumentWrapper<DocumentModel> wrapDoc = null;
413 repoSession = getRepositorySession();
414 wrapDoc = findDoc(ctx, repoSession, whereClause);
415 } catch (Exception e) {
416 throw new DocumentException("Unable to create a Nuxeo repository session.", e);
418 if (repoSession != null) {
419 releaseRepositorySession(repoSession);
423 if (logger.isWarnEnabled() == true) {
424 logger.warn("Returned DocumentModel instance was created with a repository session that is now closed.");
431 * find doc and return CSID from the Nuxeo repository
432 * @param ctx service context under which this method is invoked
433 * @param whereClause where NXQL where clause to get the document
434 * @throws DocumentException
437 public String findDocCSID(
438 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String whereClause)
439 throws DocumentNotFoundException, DocumentException {
441 RepositoryInstance repoSession = null;
443 repoSession = this.getRepositorySession();
444 DocumentWrapper<DocumentModel> wrapDoc = findDoc(ctx, repoSession, whereClause);
445 DocumentModel docModel = wrapDoc.getWrappedObject();
446 csid = NuxeoUtils.getCsid(docModel);//NuxeoUtils.extractId(docModel.getPathAsString());
447 } catch (DocumentNotFoundException dnfe) {
449 } catch (IllegalArgumentException iae) {
451 } catch (DocumentException de) {
453 } catch (Exception e) {
454 if (logger.isDebugEnabled()) {
455 logger.debug("Caught exception ", e);
457 throw new DocumentException(e);
459 if (repoSession != null) {
460 this.releaseRepositorySession(repoSession);
466 public DocumentWrapper<DocumentModelList> findDocs(
467 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
468 RepositoryInstance repoSession,
469 List<String> docTypes,
471 int pageSize, int pageNum, boolean computeTotal)
472 throws DocumentNotFoundException, DocumentException {
473 DocumentWrapper<DocumentModelList> wrapDoc = null;
476 if (docTypes == null || docTypes.size() < 1) {
477 throw new DocumentNotFoundException(
478 "findDocs must specify at least one DocumentType.");
480 DocumentModelList docList = null;
481 // force limit to 1, and ignore totalSize
482 QueryContext queryContext = new QueryContext(ctx, whereClause);
483 String query = NuxeoUtils.buildNXQLQuery(docTypes, queryContext);
484 docList = repoSession.query(query, null, pageSize, pageNum, computeTotal);
485 wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
486 } catch (IllegalArgumentException iae) {
488 } catch (Exception e) {
489 if (logger.isDebugEnabled()) {
490 logger.debug("Caught exception ", e);
492 throw new DocumentException(e);
499 * Find a list of documentModels from the Nuxeo repository
500 * @param docTypes a list of DocType names to match
501 * @param whereClause where the clause to qualify on
505 public DocumentWrapper<DocumentModelList> findDocs(
506 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
507 List<String> docTypes,
509 int pageSize, int pageNum, boolean computeTotal)
510 throws DocumentNotFoundException, DocumentException {
511 RepositoryInstance repoSession = null;
512 DocumentWrapper<DocumentModelList> wrapDoc = null;
515 repoSession = getRepositorySession();
516 wrapDoc = findDocs(ctx, repoSession, docTypes, whereClause,
517 pageSize, pageNum, computeTotal);
518 } catch (IllegalArgumentException iae) {
520 } catch (Exception e) {
521 if (logger.isDebugEnabled()) {
522 logger.debug("Caught exception ", e);
524 throw new DocumentException(e);
526 if (repoSession != null) {
527 releaseRepositorySession(repoSession);
531 if (logger.isWarnEnabled() == true) {
532 logger.warn("Returned DocumentModelList instance was created with a repository session that is now closed.");
539 * @see org.collectionspace.services.common.storage.StorageClient#get(org.collectionspace.services.common.context.ServiceContext, java.util.List, org.collectionspace.services.common.document.DocumentHandler)
542 public void get(ServiceContext ctx, List<String> csidList, DocumentHandler handler)
543 throws DocumentNotFoundException, DocumentException {
544 if (handler == null) {
545 throw new IllegalArgumentException(
546 "RepositoryJavaClient.getAll: handler is missing");
549 RepositoryInstance repoSession = null;
551 handler.prepare(Action.GET_ALL);
552 repoSession = getRepositorySession();
553 DocumentModelList docModelList = new DocumentModelListImpl();
554 //FIXME: Should be using NuxeoUtils.createPathRef for security reasons
555 for (String csid : csidList) {
556 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, csid);
557 DocumentModel docModel = repoSession.getDocument(docRef);
558 docModelList.add(docModel);
561 //set reposession to handle the document
562 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
563 DocumentWrapper<DocumentModelList> wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docModelList);
564 handler.handle(Action.GET_ALL, wrapDoc);
565 handler.complete(Action.GET_ALL, wrapDoc);
566 } catch (DocumentException de) {
568 } catch (Exception e) {
569 if (logger.isDebugEnabled()) {
570 logger.debug("Caught exception ", e);
572 throw new DocumentException(e);
574 if (repoSession != null) {
575 releaseRepositorySession(repoSession);
581 * getAll get all documents for an entity entity service from the Nuxeo
584 * @param ctx service context under which this method is invoked
586 * should be used by the caller to provide and transform the
588 * @throws DocumentException
591 public void getAll(ServiceContext ctx, DocumentHandler handler)
592 throws DocumentNotFoundException, DocumentException {
593 if (handler == null) {
594 throw new IllegalArgumentException(
595 "RepositoryJavaClient.getAll: handler is missing");
597 String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
598 if (nuxeoWspaceId == null) {
599 throw new DocumentNotFoundException(
600 "Unable to find workspace for service "
601 + ctx.getServiceName()
602 + " check if the workspace exists in the Nuxeo repository");
605 RepositoryInstance repoSession = null;
607 handler.prepare(Action.GET_ALL);
608 repoSession = getRepositorySession();
609 DocumentRef wsDocRef = new IdRef(nuxeoWspaceId);
610 DocumentModelList docList = repoSession.getChildren(wsDocRef);
611 //set reposession to handle the document
612 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
613 DocumentWrapper<DocumentModelList> wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
614 handler.handle(Action.GET_ALL, wrapDoc);
615 handler.complete(Action.GET_ALL, wrapDoc);
616 } catch (DocumentException de) {
618 } catch (Exception e) {
619 if (logger.isDebugEnabled()) {
620 logger.debug("Caught exception ", e);
622 throw new DocumentException(e);
624 if (repoSession != null) {
625 releaseRepositorySession(repoSession);
630 private boolean isClauseEmpty(String theString) {
631 boolean result = true;
632 if (theString != null && !theString.isEmpty()) {
638 public DocumentWrapper<DocumentModel> getDocFromCsid(
639 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
640 RepositoryInstance repoSession,
643 DocumentWrapper<DocumentModel> result = null;
645 result = new DocumentWrapperImpl(NuxeoUtils.getDocFromCsid(ctx, repoSession, csid));
651 * A method to find a CollectionSpace document (of any type) given just a service context and
652 * its CSID. A search across *all* service workspaces (within a given tenant context) is performed to find
655 * This query searches Nuxeo's Hierarchy table where our CSIDs are stored in the "name" column.
658 public DocumentWrapper<DocumentModel> getDocFromCsid(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
661 DocumentWrapper<DocumentModel> result = null;
662 RepositoryInstance repoSession = null;
664 repoSession = getRepositorySession();
665 result = getDocFromCsid(ctx, repoSession, csid);
667 if (repoSession != null) {
668 releaseRepositorySession(repoSession);
672 if (logger.isWarnEnabled() == true) {
673 logger.warn("Returned DocumentModel instance was created with a repository session that is now closed.");
680 * find doc and return CSID from the Nuxeo repository
681 * @param ctx service context under which this method is invoked
682 * @param whereClause where NXQL where clause to get the document
683 * @throws DocumentException
686 public String getDocURI(DocumentWrapper<DocumentModel> wrappedDoc) throws ClientException {
687 DocumentModel docModel = wrappedDoc.getWrappedObject();
688 String uri = (String)docModel.getProperty(DocumentModelHandler.COLLECTIONSPACE_CORE_SCHEMA,
689 DocumentModelHandler.COLLECTIONSPACE_CORE_URI);
695 * getFiltered get all documents for an entity service from the Document repository,
696 * given filter parameters specified by the handler.
697 * @param ctx service context under which this method is invoked
698 * @param handler should be used by the caller to provide and transform the document
699 * @throws DocumentNotFoundException if workspace not found
700 * @throws DocumentException
703 public void getFiltered(ServiceContext ctx, DocumentHandler handler)
704 throws DocumentNotFoundException, DocumentException {
706 DocumentFilter filter = handler.getDocumentFilter();
707 String oldOrderBy = filter.getOrderByClause();
708 if (isClauseEmpty(oldOrderBy) == true){
709 filter.setOrderByClause(DocumentFilter.ORDER_BY_LAST_UPDATED); //per http://issues.collectionspace.org/browse/CSPACE-705 (Doesn't this conflict with what happens with the QueryContext instance that we create below?)
711 QueryContext queryContext = new QueryContext(ctx, handler);
713 RepositoryInstance repoSession = null;
715 handler.prepare(Action.GET_ALL);
716 repoSession = getRepositorySession();
717 DocumentModelList docList = null;
718 String query = NuxeoUtils.buildNXQLQuery(ctx, queryContext);
720 if (logger.isDebugEnabled()) {
721 logger.debug("Executing NXQL query: " + query.toString());
724 // If we have limit and/or offset, then pass true to get totalSize
725 // in returned DocumentModelList.
726 Profiler profiler = new Profiler(this, 2);
727 profiler.log("Executing NXQL query: " + query.toString());
729 if ((queryContext.getDocFilter().getOffset() > 0) || (queryContext.getDocFilter().getPageSize() > 0)) {
730 docList = repoSession.query(query, null,
731 queryContext.getDocFilter().getPageSize(), queryContext.getDocFilter().getOffset(), true);
733 docList = repoSession.query(query);
737 //set repoSession to handle the document
738 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
739 DocumentWrapper<DocumentModelList> wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
740 handler.handle(Action.GET_ALL, wrapDoc);
741 handler.complete(Action.GET_ALL, wrapDoc);
742 } catch (DocumentException de) {
744 } catch (Exception e) {
745 if (logger.isDebugEnabled()) {
746 logger.debug("Caught exception ", e);
748 throw new DocumentException(e);
750 if (repoSession != null) {
751 releaseRepositorySession(repoSession);
757 * update given document in the Nuxeo repository
759 * @param ctx service context under which this method is invoked
763 * should be used by the caller to provide and transform the
765 * @throws DocumentException
768 public void update(ServiceContext ctx, String id, DocumentHandler handler)
769 throws BadRequestException, DocumentNotFoundException,
771 if (handler == null) {
772 throw new IllegalArgumentException(
773 "RepositoryJavaClient.update: handler is missing");
776 RepositoryInstance repoSession = null;
778 handler.prepare(Action.UPDATE);
779 repoSession = getRepositorySession();
780 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
781 DocumentModel doc = null;
783 doc = repoSession.getDocument(docRef);
784 } catch (ClientException ce) {
785 String msg = "Could not find document to update with id=" + id;
786 logger.error(msg, ce);
787 throw new DocumentNotFoundException(msg, ce);
789 //set reposession to handle the document
790 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
791 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
792 handler.handle(Action.UPDATE, wrapDoc);
793 repoSession.saveDocument(doc);
795 handler.complete(Action.UPDATE, wrapDoc);
796 } catch (BadRequestException bre) {
798 } catch (DocumentException de) {
800 } catch (WebApplicationException wae){
802 } catch (Exception e) {
803 if (logger.isDebugEnabled()) {
804 logger.debug("Caught exception ", e);
806 throw new DocumentException(e);
808 if (repoSession != null) {
809 releaseRepositorySession(repoSession);
815 * Save a documentModel to the Nuxeo repository.
816 * @param ctx service context under which this method is invoked
817 * @param docModel the document to save
818 * @param fSaveSession if TRUE, will call CoreSession.save() to save accumulated changes.
819 * @throws DocumentException
821 public void saveDocWithoutHandlerProcessing(
822 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
823 RepositoryInstance repoSession,
824 DocumentModel docModel,
825 boolean fSaveSession)
826 throws ClientException, DocumentException {
829 repoSession.saveDocument(docModel);
833 } catch (ClientException ce) {
835 } catch (Exception e) {
836 if (logger.isDebugEnabled()) {
837 logger.debug("Caught exception ", e);
839 throw new DocumentException(e);
845 * Save a list of documentModels to the Nuxeo repository.
847 * @param ctx service context under which this method is invoked
848 * @param docModel the document to save
849 * @param fSaveSession if TRUE, will call CoreSession.save() to save accumulated changes.
850 * @throws DocumentException
852 public void saveDocListWithoutHandlerProcessing(
853 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
854 RepositoryInstance repoSession,
855 DocumentModelList docList,
856 boolean fSaveSession)
857 throws ClientException, DocumentException {
859 repoSession = getRepositorySession();
860 DocumentModel[] docModelArray = new DocumentModel[docList.size()];
861 repoSession.saveDocuments(docList.toArray(docModelArray));
865 } catch (ClientException ce) {
867 } catch (Exception e) {
868 logger.error("Caught exception ", e);
869 throw new DocumentException(e);
874 * delete a document from the Nuxeo repository
875 * @param ctx service context under which this method is invoked
878 * @throws DocumentException
881 public void delete(ServiceContext ctx, String id) throws DocumentNotFoundException,
884 if (logger.isDebugEnabled()) {
885 logger.debug("deleting document with id=" + id);
887 RepositoryInstance repoSession = null;
889 repoSession = getRepositorySession();
890 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
892 repoSession.removeDocument(docRef);
893 } catch (ClientException ce) {
894 String msg = "could not find document to delete with id=" + id;
895 logger.error(msg, ce);
896 throw new DocumentNotFoundException(msg, ce);
899 } catch (DocumentException de) {
901 } catch (Exception e) {
902 if (logger.isDebugEnabled()) {
903 logger.debug("Caught exception ", e);
905 throw new DocumentException(e);
907 if (repoSession != null) {
908 releaseRepositorySession(repoSession);
914 * @see org.collectionspace.services.common.storage.StorageClient#delete(org.collectionspace.services.common.context.ServiceContext, java.lang.String, org.collectionspace.services.common.document.DocumentHandler)
917 public void delete(ServiceContext ctx, String id, DocumentHandler handler)
918 throws DocumentNotFoundException, DocumentException {
919 throw new UnsupportedOperationException();
923 public Hashtable<String, String> retrieveWorkspaceIds(String domainName) throws Exception {
924 return NuxeoConnectorEmbedded.getInstance().retrieveWorkspaceIds(domainName);
928 public String createDomain(String domainName) throws Exception {
929 RepositoryInstance repoSession = null;
930 String domainId = null;
933 // First create the top-level domain directory
935 repoSession = getRepositorySession();
936 DocumentRef parentDocRef = new PathRef("/");
937 DocumentModel parentDoc = repoSession.getDocument(parentDocRef);
938 DocumentModel domainDoc = repoSession.createDocumentModel(parentDoc.getPathAsString(),
939 domainName, NUXEO_CORE_TYPE_DOMAIN);
940 domainDoc.setPropertyValue("dc:title", domainName);
941 domainDoc.setPropertyValue("dc:description", "A CollectionSpace domain "
943 domainDoc = repoSession.createDocument(domainDoc);
944 domainId = domainDoc.getId();
947 // Next, create a "Workspaces" root directory to contain the workspace folders for the individual service documents
949 DocumentModel workspacesRoot = repoSession.createDocumentModel(domainDoc.getPathAsString(),
950 NuxeoUtils.Workspaces, NUXEO_CORE_TYPE_WORKSPACEROOT);
951 workspacesRoot.setPropertyValue("dc:title", NuxeoUtils.Workspaces);
952 workspacesRoot.setPropertyValue("dc:description", "A CollectionSpace workspaces directory for "
953 + domainDoc.getPathAsString());
954 workspacesRoot = repoSession.createDocument(workspacesRoot);
955 String workspacesRootId = workspacesRoot.getId();
957 if (logger.isDebugEnabled()) {
958 logger.debug("Created tenant domain name=" + domainName
959 + " id=" + domainId + " " +
960 NuxeoUtils.Workspaces + " id=" + workspacesRootId);
962 } catch (Exception e) {
963 if (logger.isDebugEnabled()) {
964 logger.debug("Could not create tenant domain name=" + domainName + " caught exception ", e);
968 if (repoSession != null) {
969 releaseRepositorySession(repoSession);
977 public String getDomainId(String domainName) throws Exception {
978 String domainId = null;
979 RepositoryInstance repoSession = null;
981 if (domainName != null && !domainName.isEmpty()) {
983 repoSession = getRepositorySession();
984 DocumentRef docRef = new PathRef(
986 DocumentModel domain = repoSession.getDocument(docRef);
987 domainId = domain.getId();
988 } catch (Exception e) {
989 if (logger.isTraceEnabled()) {
990 logger.trace("Caught exception ", e);
992 //there is no way to identify if document does not exist due to
993 //lack of typed exception for getDocument method
996 if (repoSession != null) {
997 releaseRepositorySession(repoSession);
1006 * @see org.collectionspace.services.common.repository.RepositoryClient#createWorkspace(java.lang.String, java.lang.String)
1009 public String createWorkspace(String domainName, String workspaceName) throws Exception {
1010 RepositoryInstance repoSession = null;
1011 String workspaceId = null;
1013 repoSession = getRepositorySession();
1014 DocumentRef parentDocRef = new PathRef(
1016 + "/" + NuxeoUtils.Workspaces);
1017 DocumentModel parentDoc = repoSession.getDocument(parentDocRef);
1018 DocumentModel doc = repoSession.createDocumentModel(parentDoc.getPathAsString(),
1019 workspaceName, "Workspace");
1020 doc.setPropertyValue("dc:title", workspaceName);
1021 doc.setPropertyValue("dc:description", "A CollectionSpace workspace for "
1023 doc = repoSession.createDocument(doc);
1024 workspaceId = doc.getId();
1026 if (logger.isDebugEnabled()) {
1027 logger.debug("created workspace name=" + workspaceName
1028 + " id=" + workspaceId);
1030 } catch (Exception e) {
1031 if (logger.isDebugEnabled()) {
1032 logger.debug("createWorkspace caught exception ", e);
1036 if (repoSession != null) {
1037 releaseRepositorySession(repoSession);
1044 * @see org.collectionspace.services.common.repository.RepositoryClient#getWorkspaceId(java.lang.String, java.lang.String)
1047 public String getWorkspaceId(String tenantDomain, String workspaceName) throws Exception {
1048 String workspaceId = null;
1050 RepositoryInstance repoSession = null;
1052 repoSession = getRepositorySession();
1053 DocumentRef docRef = new PathRef(
1055 + "/" + NuxeoUtils.Workspaces
1056 + "/" + workspaceName);
1057 DocumentModel workspace = repoSession.getDocument(docRef);
1058 workspaceId = workspace.getId();
1059 } catch (DocumentException de) {
1061 } catch (Exception e) {
1062 if (logger.isDebugEnabled()) {
1063 logger.debug("Caught exception ", e);
1065 throw new DocumentException(e);
1067 if (repoSession != null) {
1068 releaseRepositorySession(repoSession);
1077 * Gets the repository session. - Package access only.
1079 * @return the repository session
1080 * @throws Exception the exception
1082 public RepositoryInstance getRepositorySession() throws Exception {
1083 // FIXME: is it possible to reuse repository session?
1084 // Authentication failures happen while trying to reuse the session
1085 Profiler profiler = new Profiler("getRepositorySession():", 2);
1088 NuxeoClientEmbedded client = NuxeoConnectorEmbedded.getInstance().getClient();
1089 RepositoryInstance repoSession = client.openRepository();
1090 if (logger.isTraceEnabled()) {
1091 logger.trace("Testing call to getRepository() repository root: " + repoSession.getRootDocument());
1099 * Release repository session. - Package access only.
1101 * @param repoSession the repo session
1103 public void releaseRepositorySession(RepositoryInstance repoSession) {
1105 NuxeoClientEmbedded client = NuxeoConnectorEmbedded.getInstance().getClient();
1107 client.releaseRepository(repoSession);
1108 } catch (Exception e) {
1109 logger.error("Could not close the repository session", e);
1110 // no need to throw this service specific exception