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.io.Serializable;
21 import java.sql.Connection;
22 import java.sql.ResultSet;
23 import java.sql.Statement;
24 import java.util.Hashtable;
25 import java.util.Iterator;
26 import java.util.List;
28 import java.util.UUID;
30 import javax.ws.rs.WebApplicationException;
31 import javax.ws.rs.core.MultivaluedMap;
33 import org.collectionspace.services.client.CollectionSpaceClient;
34 import org.collectionspace.services.client.IQueryManager;
35 import org.collectionspace.services.client.PoxPayloadIn;
36 import org.collectionspace.services.client.PoxPayloadOut;
37 import org.collectionspace.services.client.Profiler;
38 import org.collectionspace.services.client.workflow.WorkflowClient;
39 import org.collectionspace.services.common.context.ServiceContext;
40 import org.collectionspace.services.common.query.QueryContext;
41 import org.collectionspace.services.common.repository.RepositoryClient;
42 import org.collectionspace.services.common.storage.JDBCTools;
43 import org.collectionspace.services.lifecycle.TransitionDef;
44 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
46 import org.collectionspace.services.common.document.BadRequestException;
47 import org.collectionspace.services.common.document.DocumentException;
48 import org.collectionspace.services.common.document.DocumentFilter;
49 import org.collectionspace.services.common.document.DocumentHandler;
50 import org.collectionspace.services.common.document.DocumentNotFoundException;
51 import org.collectionspace.services.common.document.DocumentHandler.Action;
52 import org.collectionspace.services.common.document.DocumentWrapper;
53 import org.collectionspace.services.common.document.DocumentWrapperImpl;
54 import org.collectionspace.services.common.document.TransactionException;
55 import org.collectionspace.services.config.tenant.RepositoryDomainType;
57 import org.nuxeo.common.utils.IdUtils;
58 import org.nuxeo.ecm.core.api.ClientException;
59 import org.nuxeo.ecm.core.api.DocumentModel;
60 import org.nuxeo.ecm.core.api.DocumentModelList;
61 import org.nuxeo.ecm.core.api.IterableQueryResult;
62 import org.nuxeo.ecm.core.api.VersioningOption;
63 import org.nuxeo.ecm.core.api.impl.DocumentModelListImpl;
64 import org.nuxeo.ecm.core.api.DocumentRef;
65 import org.nuxeo.ecm.core.api.IdRef;
66 import org.nuxeo.ecm.core.api.PathRef;
67 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
68 import org.nuxeo.runtime.transaction.TransactionRuntimeException;
71 // CSPACE-5036 - How to make CMISQL queries from Nuxeo
73 import org.apache.chemistry.opencmis.commons.server.CallContext;
74 import org.apache.chemistry.opencmis.server.impl.CallContextImpl;
75 import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoCmisService;
76 import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoRepository;
78 import org.slf4j.Logger;
79 import org.slf4j.LoggerFactory;
82 * RepositoryJavaClient is used to perform CRUD operations on documents in Nuxeo
83 * repository using Remote Java APIs. It uses @see DocumentHandler as IOHandler
86 * $LastChangedRevision: $ $LastChangedDate: $
88 public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn, PoxPayloadOut> {
91 private final Logger logger = LoggerFactory.getLogger(RepositoryJavaClientImpl.class);
92 // private final Logger profilerLogger = LoggerFactory.getLogger("remperf");
93 // private String foo = Profiler.createLogger();
95 public static final String NUXEO_CORE_TYPE_DOMAIN = "Domain";
96 public static final String NUXEO_CORE_TYPE_WORKSPACEROOT = "WorkspaceRoot";
99 * Instantiates a new repository java client impl.
101 public RepositoryJavaClientImpl() {
106 public void assertWorkflowState(ServiceContext ctx,
107 DocumentModel docModel) throws DocumentNotFoundException, ClientException {
108 MultivaluedMap<String, String> queryParams = ctx.getQueryParams();
109 if (queryParams != null) {
111 // Look for the workflow "delete" query param and see if we need to assert that the
112 // docModel is in a non-deleted workflow state.
114 String currentState = docModel.getCurrentLifeCycleState();
115 String includeDeletedStr = queryParams.getFirst(WorkflowClient.WORKFLOW_QUERY_NONDELETED);
116 boolean includeDeleted = includeDeletedStr == null ? true : Boolean.parseBoolean(includeDeletedStr);
117 if (includeDeleted == false) {
119 // We don't wanted soft-deleted object, so throw an exception if this one is soft-deleted.
121 if (currentState.equalsIgnoreCase(WorkflowClient.WORKFLOWSTATE_DELETED)) {
122 String msg = "The GET assertion that docModel not be in 'deleted' workflow state failed.";
124 throw new DocumentNotFoundException(msg);
131 * create document in the Nuxeo repository
133 * @param ctx service context under which this method is invoked
135 * should be used by the caller to provide and transform the
137 * @return id in repository of the newly created document
138 * @throws BadRequestException
139 * @throws TransactionException
140 * @throws DocumentException
143 public String create(ServiceContext ctx,
144 DocumentHandler handler) throws BadRequestException,
145 TransactionException, DocumentException {
147 String docType = NuxeoUtils.getTenantQualifiedDocType(ctx); //ctx.getDocumentType();
148 if (docType == null) {
149 throw new IllegalArgumentException(
150 "RepositoryJavaClient.create: docType is missing");
153 if (handler == null) {
154 throw new IllegalArgumentException(
155 "RepositoryJavaClient.create: handler is missing");
157 String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
158 if (nuxeoWspaceId == null) {
159 throw new DocumentNotFoundException(
160 "Unable to find workspace for service " + ctx.getServiceName()
161 + " check if the workspace exists in the Nuxeo repository");
164 RepositoryInstance repoSession = null;
166 handler.prepare(Action.CREATE);
167 repoSession = getRepositorySession(ctx);
168 DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId);
169 DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace);
170 String wspacePath = wspaceDoc.getPathAsString();
171 //give our own ID so PathRef could be constructed later on
172 String id = IdUtils.generateId(UUID.randomUUID().toString());
173 // create document model
174 DocumentModel doc = repoSession.createDocumentModel(wspacePath, id, docType);
175 /* Check for a versioned document, and check In and Out before we proceed.
176 * This does not work as we do not have the uid schema on our docs.
177 if(((DocumentModelHandler) handler).supportsVersioning()) {
178 doc.setProperty("uid","major_version",1);
179 doc.setProperty("uid","minor_version",0);
182 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
183 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
184 handler.handle(Action.CREATE, wrapDoc);
185 // create document with documentmodel
186 doc = repoSession.createDocument(doc);
188 // TODO for sub-docs need to call into the handler to let it deal with subitems. Pass in the id,
189 // and assume the handler has the state it needs (doc fragments).
190 handler.complete(Action.CREATE, wrapDoc);
192 } catch (BadRequestException bre) {
194 } catch (Exception e) {
195 logger.error("Caught exception ", e);
196 throw new DocumentException(e);
198 if (repoSession != null) {
199 releaseRepositorySession(ctx, repoSession);
206 * get document from the Nuxeo repository
207 * @param ctx service context under which this method is invoked
209 * of the document to retrieve
211 * should be used by the caller to provide and transform the
213 * @throws DocumentNotFoundException if the document cannot be found in the repository
214 * @throws TransactionException
215 * @throws DocumentException
218 public void get(ServiceContext ctx, String id, DocumentHandler handler)
219 throws DocumentNotFoundException, TransactionException, DocumentException {
221 if (handler == null) {
222 throw new IllegalArgumentException(
223 "RepositoryJavaClient.get: handler is missing");
226 RepositoryInstance repoSession = null;
228 handler.prepare(Action.GET);
229 repoSession = getRepositorySession(ctx);
230 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
231 DocumentModel docModel = null;
233 docModel = repoSession.getDocument(docRef);
234 assertWorkflowState(ctx, docModel);
235 } catch (ClientException ce) {
236 String msg = logException(ce, "Could not find document with CSID=" + id);
237 throw new DocumentNotFoundException(msg, ce);
240 // Set repository session to handle the document
242 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
243 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(docModel);
244 handler.handle(Action.GET, wrapDoc);
245 handler.complete(Action.GET, wrapDoc);
246 } catch (IllegalArgumentException iae) {
248 } catch (DocumentException de) {
250 } catch (Exception e) {
251 if (logger.isDebugEnabled()) {
252 logger.debug("Caught exception ", e);
254 throw new DocumentException(e);
256 if (repoSession != null) {
257 releaseRepositorySession(ctx, repoSession);
263 * get a document from the Nuxeo repository, using the docFilter params.
264 * @param ctx service context under which this method is invoked
266 * should be used by the caller to provide and transform the
267 * document. Handler must have a docFilter set to return a single item.
268 * @throws DocumentNotFoundException if the document cannot be found in the repository
269 * @throws TransactionException
270 * @throws DocumentException
273 public void get(ServiceContext ctx, DocumentHandler handler)
274 throws DocumentNotFoundException, TransactionException, DocumentException {
275 QueryContext queryContext = new QueryContext(ctx, handler);
276 RepositoryInstance repoSession = null;
279 handler.prepare(Action.GET);
280 repoSession = getRepositorySession(ctx);
282 DocumentModelList docList = null;
283 // force limit to 1, and ignore totalSize
284 String query = NuxeoUtils.buildNXQLQuery(ctx, queryContext);
285 docList = repoSession.query(query, null, 1, 0, false);
286 if (docList.size() != 1) {
287 throw new DocumentNotFoundException("No document found matching filter params: " + query);
289 DocumentModel doc = docList.get(0);
291 if (logger.isDebugEnabled()) {
292 logger.debug("Executed NXQL query: " + query);
295 //set reposession to handle the document
296 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
297 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
298 handler.handle(Action.GET, wrapDoc);
299 handler.complete(Action.GET, wrapDoc);
300 } catch (IllegalArgumentException iae) {
302 } catch (DocumentException de) {
304 } catch (Exception e) {
305 if (logger.isDebugEnabled()) {
306 logger.debug("Caught exception ", e);
308 throw new DocumentException(e);
310 if (repoSession != null) {
311 releaseRepositorySession(ctx, repoSession);
316 public DocumentWrapper<DocumentModel> getDoc(
317 RepositoryInstance repoSession,
318 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
319 String csid) throws DocumentNotFoundException, DocumentException {
320 DocumentWrapper<DocumentModel> wrapDoc = null;
323 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, csid);
324 DocumentModel doc = null;
326 doc = repoSession.getDocument(docRef);
327 } catch (ClientException ce) {
328 String msg = logException(ce, "Could not find document with CSID=" + csid);
329 throw new DocumentNotFoundException(msg, ce);
331 wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
332 } catch (IllegalArgumentException iae) {
334 } catch (DocumentException de) {
342 * Get wrapped documentModel from the Nuxeo repository. The search is restricted to the workspace
343 * of the current context.
345 * @param ctx service context under which this method is invoked
347 * of the document to retrieve
348 * @throws DocumentNotFoundException
349 * @throws TransactionException
350 * @throws DocumentException
351 * @return a wrapped documentModel
354 public DocumentWrapper<DocumentModel> getDoc(
355 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
356 String csid) throws DocumentNotFoundException, TransactionException, DocumentException {
357 RepositoryInstance repoSession = null;
358 DocumentWrapper<DocumentModel> wrapDoc = null;
361 // Open a new repository session
362 repoSession = getRepositorySession(ctx);
363 wrapDoc = getDoc(repoSession, ctx, csid);
364 } catch (IllegalArgumentException iae) {
366 } catch (DocumentException de) {
368 } catch (Exception e) {
369 if (logger.isDebugEnabled()) {
370 logger.debug("Caught exception ", e);
372 throw new DocumentException(e);
374 if (repoSession != null) {
375 releaseRepositorySession(ctx, repoSession);
379 if (logger.isWarnEnabled() == true) {
380 logger.warn("Returned DocumentModel instance was created with a repository session that is now closed.");
385 public DocumentWrapper<DocumentModel> findDoc(
386 RepositoryInstance repoSession,
387 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
389 throws DocumentNotFoundException, DocumentException {
390 DocumentWrapper<DocumentModel> wrapDoc = null;
393 QueryContext queryContext = new QueryContext(ctx, whereClause);
394 DocumentModelList docList = null;
395 // force limit to 1, and ignore totalSize
396 String query = NuxeoUtils.buildNXQLQuery(ctx, queryContext);
397 docList = repoSession.query(query,
402 if (docList.size() != 1) {
403 if (logger.isDebugEnabled()) {
404 logger.debug("findDoc: Query found: " + docList.size() + " items.");
405 logger.debug(" Query: " + query);
407 throw new DocumentNotFoundException("No document found matching filter params: " + query);
409 DocumentModel doc = docList.get(0);
410 wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
411 } catch (IllegalArgumentException iae) {
413 } catch (DocumentException de) {
415 } catch (Exception e) {
416 if (logger.isDebugEnabled()) {
417 logger.debug("Caught exception ", e);
419 throw new DocumentException(e);
426 * find wrapped documentModel from the Nuxeo repository
427 * @param ctx service context under which this method is invoked
428 * @param whereClause where NXQL where clause to get the document
429 * @throws DocumentNotFoundException
430 * @throws TransactionException
431 * @throws DocumentException
432 * @return a wrapped documentModel retrieved by the repository query
435 public DocumentWrapper<DocumentModel> findDoc(
436 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
438 throws DocumentNotFoundException, TransactionException, DocumentException {
439 RepositoryInstance repoSession = null;
440 DocumentWrapper<DocumentModel> wrapDoc = null;
443 repoSession = getRepositorySession(ctx);
444 wrapDoc = findDoc(repoSession, ctx, whereClause);
445 } catch (Exception e) {
446 throw new DocumentException("Unable to create a Nuxeo repository session.", e);
448 if (repoSession != null) {
449 releaseRepositorySession(ctx, repoSession);
453 if (logger.isWarnEnabled() == true) {
454 logger.warn("Returned DocumentModel instance was created with a repository session that is now closed.");
461 * find doc and return CSID from the Nuxeo repository
463 * @param ctx service context under which this method is invoked
464 * @param whereClause where NXQL where clause to get the document
465 * @throws DocumentNotFoundException
466 * @throws TransactionException
467 * @throws DocumentException
468 * @return the CollectionSpace ID (CSID) of the requested document
471 public String findDocCSID(RepositoryInstance repoSession,
472 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String whereClause)
473 throws DocumentNotFoundException, TransactionException, DocumentException {
475 boolean releaseSession = false;
477 if (repoSession == null) {
478 repoSession = this.getRepositorySession(ctx);
479 releaseSession = true;
481 DocumentWrapper<DocumentModel> wrapDoc = findDoc(repoSession, ctx, whereClause);
482 DocumentModel docModel = wrapDoc.getWrappedObject();
483 csid = NuxeoUtils.getCsid(docModel);//NuxeoUtils.extractId(docModel.getPathAsString());
484 } catch (DocumentNotFoundException dnfe) {
486 } catch (IllegalArgumentException iae) {
488 } catch (DocumentException de) {
490 } catch (Exception e) {
491 if (logger.isDebugEnabled()) {
492 logger.debug("Caught exception ", e);
494 throw new DocumentException(e);
496 if(releaseSession && (repoSession != null)) {
497 this.releaseRepositorySession(ctx, repoSession);
503 public DocumentWrapper<DocumentModelList> findDocs(
504 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
505 RepositoryInstance repoSession,
506 List<String> docTypes,
508 String orderByClause,
511 boolean computeTotal)
512 throws DocumentNotFoundException, DocumentException {
513 DocumentWrapper<DocumentModelList> wrapDoc = null;
516 if (docTypes == null || docTypes.size() < 1) {
517 throw new DocumentNotFoundException(
518 "The findDocs() method must specify at least one DocumentType.");
520 DocumentModelList docList = null;
521 QueryContext queryContext = new QueryContext(ctx, whereClause, orderByClause);
522 String query = NuxeoUtils.buildNXQLQuery(docTypes, queryContext);
523 if (logger.isDebugEnabled()) {
524 logger.debug("findDocs() NXQL: "+query);
526 docList = repoSession.query(query, null, pageSize, pageSize*pageNum, computeTotal);
527 wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
528 } catch (IllegalArgumentException iae) {
530 } catch (Exception e) {
531 if (logger.isDebugEnabled()) {
532 logger.debug("Caught exception ", e);
534 throw new DocumentException(e);
540 protected static String buildInListForDocTypes(List<String> docTypes) {
541 StringBuilder sb = new StringBuilder();
543 boolean first = true;
544 for(String docType:docTypes) {
555 return sb.toString();
558 public DocumentWrapper<DocumentModelList> findDocs(
559 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
560 DocumentHandler handler,
561 RepositoryInstance repoSession,
562 List<String> docTypes)
563 throws DocumentNotFoundException, DocumentException {
564 DocumentWrapper<DocumentModelList> wrapDoc = null;
566 DocumentFilter filter = handler.getDocumentFilter();
567 String oldOrderBy = filter.getOrderByClause();
568 if (isClauseEmpty(oldOrderBy) == true){
569 filter.setOrderByClause(DocumentFilter.ORDER_BY_LAST_UPDATED);
571 QueryContext queryContext = new QueryContext(ctx, handler);
574 if (docTypes == null || docTypes.size() < 1) {
575 throw new DocumentNotFoundException(
576 "The findDocs() method must specify at least one DocumentType.");
578 DocumentModelList docList = null;
579 if (handler.isCMISQuery() == true) {
580 String inList = buildInListForDocTypes(docTypes);
581 ctx.getQueryParams().add(IQueryManager.SEARCH_RELATED_MATCH_OBJ_DOCTYPES, inList);
582 docList = getFilteredCMIS(repoSession, ctx, handler, queryContext);
584 String query = NuxeoUtils.buildNXQLQuery(docTypes, queryContext);
585 if (logger.isDebugEnabled()) {
586 logger.debug("findDocs() NXQL: "+query);
588 docList = repoSession.query(query, null, filter.getPageSize(), filter.getOffset(), true);
590 wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
591 } catch (IllegalArgumentException iae) {
593 } catch (Exception e) {
594 if (logger.isDebugEnabled()) {
595 logger.debug("Caught exception ", e);
597 throw new DocumentException(e);
606 * Find a list of documentModels from the Nuxeo repository
607 * @param docTypes a list of DocType names to match
608 * @param whereClause where the clause to qualify on
609 * @throws DocumentNotFoundException
610 * @throws TransactionException
611 * @throws DocumentException
612 * @return a list of documentModels
615 public DocumentWrapper<DocumentModelList> findDocs(
616 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
617 List<String> docTypes,
619 int pageSize, int pageNum, boolean computeTotal)
620 throws DocumentNotFoundException, TransactionException, DocumentException {
621 RepositoryInstance repoSession = null;
622 DocumentWrapper<DocumentModelList> wrapDoc = null;
625 repoSession = getRepositorySession(ctx);
626 wrapDoc = findDocs(ctx, repoSession, docTypes, whereClause, null,
627 pageSize, pageNum, computeTotal);
628 } catch (IllegalArgumentException iae) {
630 } catch (Exception e) {
631 if (logger.isDebugEnabled()) {
632 logger.debug("Caught exception ", e);
634 throw new DocumentException(e);
636 if (repoSession != null) {
637 releaseRepositorySession(ctx, repoSession);
641 if (logger.isWarnEnabled() == true) {
642 logger.warn("Returned DocumentModelList instance was created with a repository session that is now closed.");
649 * @see org.collectionspace.services.common.storage.StorageClient#get(org.collectionspace.services.common.context.ServiceContext, java.util.List, org.collectionspace.services.common.document.DocumentHandler)
652 public void get(ServiceContext ctx, List<String> csidList, DocumentHandler handler)
653 throws DocumentNotFoundException, TransactionException, DocumentException {
654 if (handler == null) {
655 throw new IllegalArgumentException(
656 "RepositoryJavaClient.getAll: handler is missing");
659 RepositoryInstance repoSession = null;
661 handler.prepare(Action.GET_ALL);
662 repoSession = getRepositorySession(ctx);
663 DocumentModelList docModelList = new DocumentModelListImpl();
664 //FIXME: Should be using NuxeoUtils.createPathRef for security reasons
665 for (String csid : csidList) {
666 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, csid);
667 DocumentModel docModel = repoSession.getDocument(docRef);
668 docModelList.add(docModel);
671 //set reposession to handle the document
672 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
673 DocumentWrapper<DocumentModelList> wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docModelList);
674 handler.handle(Action.GET_ALL, wrapDoc);
675 handler.complete(Action.GET_ALL, wrapDoc);
676 } catch (DocumentException de) {
678 } catch (Exception e) {
679 if (logger.isDebugEnabled()) {
680 logger.debug("Caught exception ", e);
682 throw new DocumentException(e);
684 if (repoSession != null) {
685 releaseRepositorySession(ctx, repoSession);
691 * getAll get all documents for an entity entity service from the Nuxeo
694 * @param ctx service context under which this method is invoked
696 * should be used by the caller to provide and transform the
698 * @throws DocumentNotFoundException
699 * @throws TransactionException
700 * @throws DocumentException
703 public void getAll(ServiceContext ctx, DocumentHandler handler)
704 throws DocumentNotFoundException, TransactionException, DocumentException {
705 if (handler == null) {
706 throw new IllegalArgumentException(
707 "RepositoryJavaClient.getAll: handler is missing");
709 String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
710 if (nuxeoWspaceId == null) {
711 throw new DocumentNotFoundException(
712 "Unable to find workspace for service "
713 + ctx.getServiceName()
714 + " check if the workspace exists in the Nuxeo repository.");
717 RepositoryInstance repoSession = null;
719 handler.prepare(Action.GET_ALL);
720 repoSession = getRepositorySession(ctx);
721 DocumentRef wsDocRef = new IdRef(nuxeoWspaceId);
722 DocumentModelList docList = repoSession.getChildren(wsDocRef);
723 //set reposession to handle the document
724 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
725 DocumentWrapper<DocumentModelList> wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
726 handler.handle(Action.GET_ALL, wrapDoc);
727 handler.complete(Action.GET_ALL, wrapDoc);
728 } catch (DocumentException de) {
730 } catch (Exception e) {
731 if (logger.isDebugEnabled()) {
732 logger.debug("Caught exception ", e);
734 throw new DocumentException(e);
736 if (repoSession != null) {
737 releaseRepositorySession(ctx, repoSession);
742 private boolean isClauseEmpty(String theString) {
743 boolean result = true;
744 if (theString != null && !theString.isEmpty()) {
750 public DocumentWrapper<DocumentModel> getDocFromCsid(
751 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
752 RepositoryInstance repoSession,
755 DocumentWrapper<DocumentModel> result = null;
757 result = new DocumentWrapperImpl(NuxeoUtils.getDocFromCsid(ctx, repoSession, csid));
763 * A method to find a CollectionSpace document (of any type) given just a service context and
764 * its CSID. A search across *all* service workspaces (within a given tenant context) is performed to find
767 * This query searches Nuxeo's Hierarchy table where our CSIDs are stored in the "name" column.
770 public DocumentWrapper<DocumentModel> getDocFromCsid(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
773 DocumentWrapper<DocumentModel> result = null;
774 RepositoryInstance repoSession = null;
776 repoSession = getRepositorySession(ctx);
777 result = getDocFromCsid(ctx, repoSession, csid);
779 if (repoSession != null) {
780 releaseRepositorySession(ctx, repoSession);
784 if (logger.isWarnEnabled() == true) {
785 logger.warn("Returned DocumentModel instance was created with a repository session that is now closed.");
792 * Returns a URI value for a document in the Nuxeo repository
793 * @param wrappedDoc a wrapped documentModel
794 * @throws ClientException
795 * @return a document URI
798 public String getDocURI(DocumentWrapper<DocumentModel> wrappedDoc) throws ClientException {
799 DocumentModel docModel = wrappedDoc.getWrappedObject();
800 String uri = (String)docModel.getProperty(CollectionSpaceClient.COLLECTIONSPACE_CORE_SCHEMA,
801 CollectionSpaceClient.COLLECTIONSPACE_CORE_URI);
806 * See CSPACE-5036 - How to make CMISQL queries from Nuxeo
808 private IterableQueryResult makeCMISQLQuery(RepositoryInstance repoSession, String query, QueryContext queryContext) {
809 IterableQueryResult result = null;
811 // the NuxeoRepository should be constructed only once, then cached
812 // (its construction is expensive)
814 NuxeoRepository repo = new NuxeoRepository(
815 repoSession.getRepositoryName(), repoSession
816 .getRootDocument().getId());
817 logger.debug("Repository ID:" + repo.getId() + " Root folder:"
818 + repo.getRootFolderId());
820 CallContextImpl callContext = new CallContextImpl(
821 CallContext.BINDING_LOCAL, repo.getId(), false);
822 callContext.put(CallContext.USERNAME, repoSession.getPrincipal()
824 NuxeoCmisService cmisService = new NuxeoCmisService(repo,
825 callContext, repoSession);
827 result = repoSession.queryAndFetch(query, "CMISQL", cmisService);
828 } catch (ClientException e) {
829 // TODO Auto-generated catch block
830 logger.error("Encounter trouble making the following CMIS query: " + query, e);
837 * getFiltered get all documents for an entity service from the Document repository,
838 * given filter parameters specified by the handler.
839 * @param ctx service context under which this method is invoked
840 * @param handler should be used by the caller to provide and transform the document
841 * @throws DocumentNotFoundException if workspace not found
842 * @throws TransactionException
843 * @throws DocumentException
846 public void getFiltered(ServiceContext ctx, DocumentHandler handler)
847 throws DocumentNotFoundException, TransactionException, DocumentException {
849 DocumentFilter filter = handler.getDocumentFilter();
850 String oldOrderBy = filter.getOrderByClause();
851 if (isClauseEmpty(oldOrderBy) == true){
852 filter.setOrderByClause(DocumentFilter.ORDER_BY_LAST_UPDATED);
854 QueryContext queryContext = new QueryContext(ctx, handler);
856 RepositoryInstance repoSession = null;
858 handler.prepare(Action.GET_ALL);
859 repoSession = getRepositorySession(ctx); //Keeps a refcount here for the repository session so you need to release this when finished
861 DocumentModelList docList = null;
862 String query = NuxeoUtils.buildNXQLQuery(ctx, queryContext);
864 if (logger.isDebugEnabled()) {
865 logger.debug("Executing NXQL query: " + query.toString());
868 // If we have limit and/or offset, then pass true to get totalSize
869 // in returned DocumentModelList.
870 Profiler profiler = new Profiler(this, 2);
871 profiler.log("Executing NXQL query: " + query.toString());
873 if (handler.isJDBCQuery() == true) {
874 docList = getFilteredJDBC(repoSession, ctx, handler, queryContext);
875 } else if (handler.isCMISQuery() == true) {
876 docList = getFilteredCMIS(repoSession, ctx, handler, queryContext); //FIXME: REM - Need to deal with paging info in CMIS query
877 } else if ((queryContext.getDocFilter().getOffset() > 0) || (queryContext.getDocFilter().getPageSize() > 0)) {
878 docList = repoSession.query(query, null,
879 queryContext.getDocFilter().getPageSize(), queryContext.getDocFilter().getOffset(), true);
881 docList = repoSession.query(query);
885 //set repoSession to handle the document
886 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
887 DocumentWrapper<DocumentModelList> wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
888 handler.handle(Action.GET_ALL, wrapDoc);
889 handler.complete(Action.GET_ALL, wrapDoc);
890 } catch (DocumentException de) {
892 } catch (Exception e) {
893 if (logger.isDebugEnabled()) {
894 logger.debug("Caught exception ", e);
896 throw new DocumentException(e);
898 if (repoSession != null) {
899 releaseRepositorySession(ctx, repoSession);
904 private DocumentModelList getFilteredJDBC(RepositoryInstance repoSession, ServiceContext ctx, DocumentHandler handler, QueryContext queryContext)
906 DocumentModelList result = new DocumentModelListImpl();
908 String dataSourceName = JDBCTools.NUXEO_DATASOURCE_NAME;
909 String repositoryName = ctx.getRepositoryName();
910 Connection connection = JDBCTools.getConnection(dataSourceName, repositoryName);
912 String theQuery = "<build up the query and put it in this string.";
914 // make sure autocommit is off see
915 // http://jdbc.postgresql.org/documentation/80/query.html#query-with-cursor
916 // http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html
918 connection.setAutoCommit(false);
919 Statement st = connection.createStatement();
921 MultivaluedMap<String, String> queryParams = ctx.getQueryParams();
922 String partialTerm = queryParams.getFirst(IQueryManager.SEARCH_TYPE_PARTIALTERM);
924 // Turn use of the cursor on.
926 ResultSet rs = st.executeQuery(partialTerm);
928 String id = rs.getString("id");
929 System.out.print("A row was returned with ID:" + id);
933 // Close the statement.
939 private DocumentModelList getFilteredCMIS(RepositoryInstance repoSession, ServiceContext ctx, DocumentHandler handler, QueryContext queryContext)
940 throws DocumentNotFoundException, DocumentException {
942 DocumentModelList result = new DocumentModelListImpl();
944 String query = handler.getCMISQuery(queryContext);
946 DocumentFilter docFilter = handler.getDocumentFilter();
947 int pageSize = docFilter.getPageSize();
948 int offset = docFilter.getOffset();
949 if (logger.isDebugEnabled()) {
950 logger.debug("Executing CMIS query: " + query.toString()
951 + "with pageSize: "+pageSize+" at offset: "+offset);
954 // If we have limit and/or offset, then pass true to get totalSize
955 // in returned DocumentModelList.
956 Profiler profiler = new Profiler(this, 2);
957 profiler.log("Executing CMIS query: " + query.toString());
960 IterableQueryResult queryResult = makeCMISQLQuery(repoSession, query, queryContext);
962 int totalSize = (int)queryResult.size();
963 ((DocumentModelListImpl)result).setTotalSize(totalSize);
964 // Skip the rows before our offset
966 queryResult.skipTo(offset);
969 for (Map<String, Serializable> row : queryResult) {
970 if (logger.isTraceEnabled()) {
971 logger.trace(" Hierarchy Table ID is:" + row.get(IQueryManager.CMIS_TARGET_NUXEO_ID)
972 + " nuxeo:pathSegment is: " + row.get(IQueryManager.CMIS_TARGET_NAME));
974 String nuxeoId = (String) row.get(IQueryManager.CMIS_TARGET_NUXEO_ID);
975 DocumentModel docModel = NuxeoUtils.getDocumentModel(repoSession, nuxeoId);
976 result.add(docModel);
978 if (nRows >= pageSize && pageSize != 0 ) { // A page size of zero means that they want all of them
979 logger.debug("Got page full of items - quitting");
989 } catch (Exception e) {
990 if (logger.isDebugEnabled()) {
991 logger.debug("Caught exception ", e);
993 throw new DocumentException(e);
997 // Since we're not supporting paging yet for CMIS queries, we need to perform
998 // a workaround for the paging information we return in our list of results
1001 if (result != null) {
1002 docFilter.setStartPage(0);
1003 if (totalSize > docFilter.getPageSize()) {
1004 docFilter.setPageSize(totalSize);
1005 ((DocumentModelListImpl)result).setTotalSize(totalSize);
1013 private String logException(Exception e, String msg) {
1014 String result = null;
1016 String exceptionMessage = e.getMessage();
1017 exceptionMessage = exceptionMessage != null ? exceptionMessage : "<No details provided>";
1018 result = msg = msg + ". Caught exception:" + exceptionMessage;
1020 if (logger.isTraceEnabled() == true) {
1021 logger.error(msg, e);
1030 * update given document in the Nuxeo repository
1032 * @param ctx service context under which this method is invoked
1036 * should be used by the caller to provide and transform the
1038 * @throws BadRequestException
1039 * @throws DocumentNotFoundException
1040 * @throws TransactionException if the transaction times out or otherwise cannot be successfully completed
1041 * @throws DocumentException
1044 public void update(ServiceContext ctx, String csid, DocumentHandler handler)
1045 throws BadRequestException, DocumentNotFoundException, TransactionException,
1047 if (handler == null) {
1048 throw new IllegalArgumentException(
1049 "RepositoryJavaClient.update: document handler is missing.");
1052 RepositoryInstance repoSession = null;
1054 handler.prepare(Action.UPDATE);
1055 repoSession = getRepositorySession(ctx);
1056 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, csid);
1057 DocumentModel doc = null;
1059 doc = repoSession.getDocument(docRef);
1060 } catch (ClientException ce) {
1061 String msg = logException(ce, "Could not find document to update with CSID=" + csid);
1062 throw new DocumentNotFoundException(msg, ce);
1064 // Check for a versioned document, and check In and Out before we proceed.
1065 if(((DocumentModelHandler) handler).supportsVersioning()) {
1066 /* Once we advance to 5.5 or later, we can add this.
1067 * See also https://jira.nuxeo.com/browse/NXP-8506
1068 if(!doc.isVersionable()) {
1069 throw new DocumentException("Configuration for: "
1070 +handler.getServiceContextPath()+" supports versioning, but Nuxeo config does not!");
1073 /* Force a version number - Not working. Apparently we need to configure the uid schema??
1074 if(doc.getProperty("uid","major_version") == null) {
1075 doc.setProperty("uid","major_version",1);
1077 if(doc.getProperty("uid","minor_version") == null) {
1078 doc.setProperty("uid","minor_version",0);
1081 doc.checkIn(VersioningOption.MINOR, null);
1086 // Set reposession to handle the document
1088 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
1089 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
1090 handler.handle(Action.UPDATE, wrapDoc);
1091 repoSession.saveDocument(doc);
1093 handler.complete(Action.UPDATE, wrapDoc);
1094 } catch (BadRequestException bre) {
1096 } catch (DocumentException de) {
1098 } catch (WebApplicationException wae){
1100 } catch (Exception e) {
1101 if (logger.isDebugEnabled()) {
1102 logger.debug("Caught exception ", e);
1104 throw new DocumentException(e);
1106 if (repoSession != null) {
1107 releaseRepositorySession(ctx, repoSession);
1113 * Save a documentModel to the Nuxeo repository.
1114 * @param ctx service context under which this method is invoked
1115 * @param repoSession
1116 * @param docModel the document to save
1117 * @param fSaveSession if TRUE, will call CoreSession.save() to save accumulated changes.
1118 * @throws ClientException
1119 * @throws DocumentException
1121 public void saveDocWithoutHandlerProcessing(
1122 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
1123 RepositoryInstance repoSession,
1124 DocumentModel docModel,
1125 boolean fSaveSession)
1126 throws ClientException, DocumentException {
1129 repoSession.saveDocument(docModel);
1133 } catch (ClientException ce) {
1135 } catch (Exception e) {
1136 if (logger.isDebugEnabled()) {
1137 logger.debug("Caught exception ", e);
1139 throw new DocumentException(e);
1145 * Save a list of documentModels to the Nuxeo repository.
1147 * @param ctx service context under which this method is invoked
1148 * @param repoSession a repository session
1149 * @param docModelList a list of document models
1150 * @param fSaveSession if TRUE, will call CoreSession.save() to save accumulated changes.
1151 * @throws ClientException
1152 * @throws DocumentException
1154 public void saveDocListWithoutHandlerProcessing(
1155 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
1156 RepositoryInstance repoSession,
1157 DocumentModelList docList,
1158 boolean fSaveSession)
1159 throws ClientException, DocumentException {
1161 DocumentModel[] docModelArray = new DocumentModel[docList.size()];
1162 repoSession.saveDocuments(docList.toArray(docModelArray));
1166 } catch (ClientException ce) {
1168 } catch (Exception e) {
1169 logger.error("Caught exception ", e);
1170 throw new DocumentException(e);
1175 * delete a document from the Nuxeo repository
1176 * @param ctx service context under which this method is invoked
1179 * @throws DocumentException
1182 public void delete(ServiceContext ctx, String id, DocumentHandler handler) throws DocumentNotFoundException,
1183 DocumentException, TransactionException {
1185 throw new IllegalArgumentException(
1186 "delete(ctx, ix, handler): ctx is missing");
1188 if (handler == null) {
1189 throw new IllegalArgumentException(
1190 "delete(ctx, ix, handler): handler is missing");
1192 if (logger.isDebugEnabled()) {
1193 logger.debug("Deleting document with CSID=" + id);
1195 RepositoryInstance repoSession = null;
1197 handler.prepare(Action.DELETE);
1198 repoSession = getRepositorySession(ctx);
1199 DocumentWrapper<DocumentModel> wrapDoc = null;
1201 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
1202 wrapDoc = new DocumentWrapperImpl<DocumentModel>(repoSession.getDocument(docRef));
1203 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
1204 handler.handle(Action.DELETE, wrapDoc);
1205 repoSession.removeDocument(docRef);
1206 } catch (ClientException ce) {
1207 String msg = logException(ce, "Could not find document to delete with CSID=" + id);
1208 throw new DocumentNotFoundException(msg, ce);
1211 handler.complete(Action.DELETE, wrapDoc);
1212 } catch (DocumentException de) {
1214 } catch (Exception e) {
1215 if (logger.isDebugEnabled()) {
1216 logger.debug("Caught exception ", e);
1218 throw new DocumentException(e);
1220 if (repoSession != null) {
1221 releaseRepositorySession(ctx, repoSession);
1227 * @see org.collectionspace.services.common.storage.StorageClient#delete(org.collectionspace.services.common.context.ServiceContext, java.lang.String, org.collectionspace.services.common.document.DocumentHandler)
1231 public void delete(@SuppressWarnings("rawtypes") ServiceContext ctx, String id)
1232 throws DocumentNotFoundException, DocumentException {
1233 throw new UnsupportedOperationException();
1234 // Use the other delete instead
1238 public Hashtable<String, String> retrieveWorkspaceIds(RepositoryDomainType repoDomain) throws Exception {
1239 return NuxeoConnectorEmbedded.getInstance().retrieveWorkspaceIds(repoDomain);
1243 public String createDomain(RepositoryDomainType repositoryDomain) throws Exception {
1244 RepositoryInstance repoSession = null;
1245 String domainId = null;
1248 // Open a connection to the domain's repo/db
1250 String repoName = repositoryDomain.getRepositoryName();
1251 repoSession = getRepositorySession(repoName); // domainName=storageName=repoName=databaseName
1253 // First create the top-level domain directory
1255 String domainName = repositoryDomain.getStorageName();
1256 DocumentRef parentDocRef = new PathRef("/");
1257 DocumentModel parentDoc = repoSession.getDocument(parentDocRef);
1258 DocumentModel domainDoc = repoSession.createDocumentModel(parentDoc.getPathAsString(),
1259 domainName, NUXEO_CORE_TYPE_DOMAIN);
1260 domainDoc.setPropertyValue("dc:title", domainName);
1261 domainDoc.setPropertyValue("dc:description", "A CollectionSpace domain "
1263 domainDoc = repoSession.createDocument(domainDoc);
1264 domainId = domainDoc.getId();
1267 // Next, create a "Workspaces" root directory to contain the workspace folders for the individual service documents
1269 DocumentModel workspacesRoot = repoSession.createDocumentModel(domainDoc.getPathAsString(),
1270 NuxeoUtils.Workspaces, NUXEO_CORE_TYPE_WORKSPACEROOT);
1271 workspacesRoot.setPropertyValue("dc:title", NuxeoUtils.Workspaces);
1272 workspacesRoot.setPropertyValue("dc:description", "A CollectionSpace workspaces directory for "
1273 + domainDoc.getPathAsString());
1274 workspacesRoot = repoSession.createDocument(workspacesRoot);
1275 String workspacesRootId = workspacesRoot.getId();
1278 if (logger.isDebugEnabled()) {
1279 logger.debug("Created tenant domain name=" + domainName
1280 + " id=" + domainId + " " +
1281 NuxeoUtils.Workspaces + " id=" + workspacesRootId);
1282 logger.debug("Path to Domain: "+domainDoc.getPathAsString());
1283 logger.debug("Path to Workspaces root: "+workspacesRoot.getPathAsString());
1285 } catch (Exception e) {
1286 if (logger.isDebugEnabled()) {
1287 logger.debug("Could not create tenant domain name=" + repositoryDomain.getStorageName() + " caught exception ", e);
1291 if (repoSession != null) {
1292 releaseRepositorySession(null, repoSession);
1300 public String getDomainId(RepositoryDomainType repositoryDomain) throws Exception {
1301 String domainId = null;
1302 RepositoryInstance repoSession = null;
1304 String repoName = repositoryDomain.getRepositoryName();
1305 String domainStorageName = repositoryDomain.getStorageName();
1306 if (domainStorageName != null && !domainStorageName.isEmpty()) {
1308 repoSession = getRepositorySession(repoName);
1309 DocumentRef docRef = new PathRef("/" + domainStorageName);
1310 DocumentModel domain = repoSession.getDocument(docRef);
1311 domainId = domain.getId();
1312 } catch (Exception e) {
1313 if (logger.isTraceEnabled()) {
1314 logger.trace("Caught exception ", e); // The document doesn't exist, this let's us know we need to create it
1316 //there is no way to identify if document does not exist due to
1317 //lack of typed exception for getDocument method
1320 if (repoSession != null) {
1321 releaseRepositorySession(null, repoSession);
1330 * Returns the workspaces root directory for a given domain.
1332 private DocumentModel getWorkspacesRoot(RepositoryInstance repoSession,
1333 String domainName) throws Exception {
1334 DocumentModel result = null;
1336 String domainPath = "/" + domainName;
1337 DocumentRef parentDocRef = new PathRef(domainPath);
1338 DocumentModelList domainChildrenList = repoSession.getChildren(
1340 Iterator<DocumentModel> witer = domainChildrenList.iterator();
1341 while (witer.hasNext()) {
1342 DocumentModel childNode = witer.next();
1343 if (NuxeoUtils.Workspaces.equalsIgnoreCase(childNode.getName())) {
1345 logger.trace("Found workspaces directory at: " + result.getPathAsString());
1350 if (result == null) {
1351 throw new ClientException("Could not find workspace root directory in: "
1359 * @see org.collectionspace.services.common.repository.RepositoryClient#createWorkspace(java.lang.String, java.lang.String)
1362 public String createWorkspace(RepositoryDomainType repositoryDomain, String workspaceName) throws Exception {
1363 RepositoryInstance repoSession = null;
1364 String workspaceId = null;
1366 String repoName = repositoryDomain.getRepositoryName();
1367 repoSession = getRepositorySession(repoName);
1369 String domainStorageName = repositoryDomain.getStorageName();
1370 DocumentModel parentDoc = getWorkspacesRoot(repoSession, domainStorageName);
1371 if (logger.isTraceEnabled()) {
1372 for (String facet : parentDoc.getFacets()) {
1373 logger.trace("Facet: " + facet);
1377 DocumentModel doc = repoSession.createDocumentModel(parentDoc.getPathAsString(),
1378 workspaceName, NuxeoUtils.WORKSPACE_DOCUMENT_TYPE);
1379 doc.setPropertyValue("dc:title", workspaceName);
1380 doc.setPropertyValue("dc:description", "A CollectionSpace workspace for "
1382 doc = repoSession.createDocument(doc);
1383 workspaceId = doc.getId();
1385 if (logger.isDebugEnabled()) {
1386 logger.debug("Created workspace name=" + workspaceName
1387 + " id=" + workspaceId);
1389 } catch (Exception e) {
1390 if (logger.isDebugEnabled()) {
1391 logger.debug("createWorkspace caught exception ", e);
1395 if (repoSession != null) {
1396 releaseRepositorySession(null, repoSession);
1403 * @see org.collectionspace.services.common.repository.RepositoryClient#getWorkspaceId(java.lang.String, java.lang.String)
1407 public String getWorkspaceId(String tenantDomain, String workspaceName) throws Exception {
1408 String workspaceId = null;
1410 RepositoryInstance repoSession = null;
1412 repoSession = getRepositorySession((ServiceContext)null);
1413 DocumentRef docRef = new PathRef(
1415 + "/" + NuxeoUtils.Workspaces
1416 + "/" + workspaceName);
1417 DocumentModel workspace = repoSession.getDocument(docRef);
1418 workspaceId = workspace.getId();
1419 } catch (DocumentException de) {
1421 } catch (Exception e) {
1422 if (logger.isDebugEnabled()) {
1423 logger.debug("Caught exception ", e);
1425 throw new DocumentException(e);
1427 if (repoSession != null) {
1428 releaseRepositorySession(null, repoSession);
1435 public RepositoryInstance getRepositorySession(ServiceContext ctx) throws Exception {
1436 return getRepositorySession(ctx, ctx.getRepositoryName());
1439 public RepositoryInstance getRepositorySession(String repoName) throws Exception {
1440 return getRepositorySession(null, repoName);
1444 * Gets the repository session. - Package access only. If the 'ctx' param is null then the repo name must be non-mull and vice-versa
1446 * @return the repository session
1447 * @throws Exception the exception
1449 public RepositoryInstance getRepositorySession(ServiceContext ctx, String repoName) throws Exception {
1450 RepositoryInstance repoSession = null;
1452 Profiler profiler = new Profiler("getRepositorySession():", 2);
1455 // To get a connection to the Nuxeo repo, we need either a valid ServiceContext instance or a repository name
1458 repoName = ctx.getRepositoryName(); // Notice we are overriding the passed in 'repoName' since we have a valid service context passed in to us
1459 repoSession = (RepositoryInstance)ctx.getCurrentRepositorySession(); // Look to see if one exists in the context before creating one
1460 } else if (repoName == null || repoName.trim().isEmpty()) {
1461 String errMsg = String.format("We can't get a connection to the Nuxeo repo because the service context passed in was null and no repository name was passed in either.");
1462 logger.error(errMsg);
1463 throw new Exception(errMsg);
1466 // If we couldn't find a repoSession from the service context (or the context was null) then we need to create a new one using
1467 // just the repo name
1469 if (repoSession == null) {
1470 NuxeoClientEmbedded client = NuxeoConnectorEmbedded.getInstance().getClient();
1471 repoSession = client.openRepository(repoName);
1473 if (logger.isDebugEnabled() == true) {
1474 logger.warn("Reusing the current context's repository session.");
1478 if (logger.isTraceEnabled()) {
1479 logger.trace("Testing call to getRepository() repository root: " + repoSession.getRootDocument());
1485 ctx.setCurrentRepositorySession(repoSession); // For reusing, save the repository session in the current service context
1492 * Release repository session. - Package access only.
1494 * @param repoSession the repo session
1496 public void releaseRepositorySession(ServiceContext ctx, RepositoryInstance repoSession) throws TransactionException {
1498 NuxeoClientEmbedded client = NuxeoConnectorEmbedded.getInstance().getClient();
1501 ctx.clearCurrentRepositorySession(); //clear the current context of the now closed repo session
1502 if (ctx.getCurrentRepositorySession() == null) {
1503 client.releaseRepository(repoSession); //release the repo session if the service context's ref count is zeo.
1506 client.releaseRepository(repoSession); //repo session was acquired without a service context
1508 } catch (TransactionRuntimeException tre) {
1509 TransactionException te = new TransactionException(tre);
1510 logger.error(te.getMessage(), tre); // Log the standard transaction exception message, plus an exception-specific stack trace
1512 } catch (Exception e) {
1513 logger.error("Could not close the repository session", e);
1514 // no need to throw this service specific exception
1519 public void doWorkflowTransition(ServiceContext ctx, String id,
1520 DocumentHandler handler, TransitionDef transitionDef)
1521 throws BadRequestException, DocumentNotFoundException,
1523 // This is a placeholder for when we change the StorageClient interface to treat workflow transitions as 1st class operations like 'get', 'create', 'update, 'delete', etc