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.UUID;
22 import java.util.List;
24 import org.collectionspace.services.common.context.ServiceContext;
26 import org.collectionspace.services.common.document.BadRequestException;
27 import org.collectionspace.services.common.document.DocumentException;
28 import org.collectionspace.services.common.document.DocumentFilter;
29 import org.collectionspace.services.common.document.DocumentHandler;
30 import org.collectionspace.services.common.document.DocumentNotFoundException;
31 import org.collectionspace.services.common.document.DocumentHandler.Action;
32 import org.collectionspace.services.common.document.DocumentWrapper;
33 import org.collectionspace.services.common.document.DocumentWrapperImpl;
35 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
36 import org.collectionspace.services.common.query.IQueryManager;
37 import org.collectionspace.services.common.repository.RepositoryClient;
39 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
40 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
41 import org.nuxeo.common.utils.IdUtils;
42 import org.nuxeo.ecm.core.api.ClientException;
43 import org.nuxeo.ecm.core.api.DocumentModel;
44 import org.nuxeo.ecm.core.api.DocumentModelList;
45 import org.nuxeo.ecm.core.api.impl.DocumentModelListImpl;
46 import org.nuxeo.ecm.core.api.DocumentRef;
47 import org.nuxeo.ecm.core.api.IdRef;
48 import org.nuxeo.ecm.core.api.PathRef;
49 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
50 import org.nuxeo.ecm.core.client.NuxeoClient;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
56 * RepositoryJavaClient is used to perform CRUD operations on documents in Nuxeo
57 * repository using Remote Java APIs. It uses @see DocumentHandler as IOHandler
60 * $LastChangedRevision: $ $LastChangedDate: $
62 public class RepositoryJavaClientImpl implements RepositoryClient {
65 * The Class QueryContext.
67 private class QueryContext {
71 /** The doc filter. */
72 DocumentFilter docFilter;
73 /** The where clause. */
81 * Instantiates a new query context.
84 * @throws DocumentNotFoundException the document not found exception
85 * @throws DocumentException the document exception
87 QueryContext(ServiceContext<MultipartInput, MultipartOutput> ctx) throws DocumentNotFoundException, DocumentException {
88 docType = ctx.getDocumentType();
89 if (docType == null) {
90 throw new DocumentNotFoundException(
91 "Unable to find DocumentType for service " + ctx.getServiceName());
93 domain = ctx.getRepositoryDomainName();
95 throw new DocumentNotFoundException(
96 "Unable to find Domain for service " + ctx.getServiceName());
98 tenantId = ctx.getTenantId();
99 if (tenantId == null) {
100 throw new IllegalArgumentException(
101 "Service context has no Tenant ID specified.");
106 * Instantiates a new query context.
109 * @param theWhereClause the the where clause
110 * @throws DocumentNotFoundException the document not found exception
111 * @throws DocumentException the document exception
113 QueryContext(ServiceContext<MultipartInput, MultipartOutput> ctx,
114 String theWhereClause) throws DocumentNotFoundException, DocumentException {
116 whereClause = theWhereClause;
120 * Instantiates a new query context.
123 * @param handler the handler
124 * @throws DocumentNotFoundException the document not found exception
125 * @throws DocumentException the document exception
127 QueryContext(ServiceContext<MultipartInput, MultipartOutput> ctx,
128 DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
130 if (handler == null) {
131 throw new IllegalArgumentException(
132 "Document handler is missing.");
134 docFilter = handler.getDocumentFilter();
135 if (docFilter == null) {
136 throw new IllegalArgumentException(
137 "Document handler has no Filter specified.");
139 whereClause = docFilter.getWhereClause();
143 private final Logger logger = LoggerFactory.getLogger(RepositoryJavaClientImpl.class);
146 * Instantiates a new repository java client impl.
148 public RepositoryJavaClientImpl() {
153 * Sets the collection space core values.
156 * @param documentModel the document model
157 * @throws ClientException the client exception
159 private void setCollectionSpaceCoreValues(ServiceContext<MultipartInput, MultipartOutput> ctx,
160 DocumentModel documentModel,
161 Action action) throws ClientException {
163 // Add the tenant ID value to the new entity
165 documentModel.setProperty(DocumentModelHandler.COLLECTIONSPACE_CORE_SCHEMA,
166 DocumentModelHandler.COLLECTIONSPACE_CORE_TENANTID,
170 //add creation date value
180 * create document in the Nuxeo repository
182 * @param ctx service context under which this method is invoked
184 * of the document created
186 * should be used by the caller to provide and transform the
188 * @return id in repository of the newly created document
189 * @throws DocumentException
192 public String create(ServiceContext ctx,
193 DocumentHandler handler) throws BadRequestException,
196 if (ctx.getDocumentType() == null) {
197 throw new IllegalArgumentException(
198 "RepositoryJavaClient.create: docType is missing");
200 if (handler == null) {
201 throw new IllegalArgumentException(
202 "RepositoryJavaClient.create: handler is missing");
204 String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
205 if (nuxeoWspaceId == null) {
206 throw new DocumentNotFoundException(
207 "Unable to find workspace for service " + ctx.getServiceName()
208 + " check if the workspace exists in the Nuxeo repository");
210 RepositoryInstance repoSession = null;
212 handler.prepare(Action.CREATE);
213 repoSession = getRepositorySession();
214 DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId);
215 DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace);
216 String wspacePath = wspaceDoc.getPathAsString();
217 //give our own ID so PathRef could be constructed later on
218 String id = IdUtils.generateId(UUID.randomUUID().toString());
219 // create document model
220 DocumentModel doc = repoSession.createDocumentModel(wspacePath, id,
221 ctx.getDocumentType());
222 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
223 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
224 handler.handle(Action.CREATE, wrapDoc);
225 // create document with documentmodel
226 setCollectionSpaceCoreValues(ctx, doc, Action.CREATE);
227 doc = repoSession.createDocument(doc);
229 // TODO for sub-docs need to call into the handler to let it deal with subitems. Pass in the id,
230 // and assume the handler has the state it needs (doc fragments).
231 handler.complete(Action.CREATE, wrapDoc);
233 } catch (BadRequestException bre) {
235 } catch (Exception e) {
236 if (logger.isDebugEnabled()) {
237 logger.debug("Caught exception ", e);
239 throw new DocumentException(e);
241 if (repoSession != null) {
242 releaseRepositorySession(repoSession);
249 * get document from the Nuxeo repository
250 * @param ctx service context under which this method is invoked
252 * of the document to retrieve
254 * should be used by the caller to provide and transform the
256 * @throws DocumentException
259 public void get(ServiceContext ctx, String id, DocumentHandler handler)
260 throws DocumentNotFoundException, DocumentException {
262 if (handler == null) {
263 throw new IllegalArgumentException(
264 "RepositoryJavaClient.get: handler is missing");
266 RepositoryInstance repoSession = null;
269 handler.prepare(Action.GET);
270 repoSession = getRepositorySession();
271 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
272 DocumentModel doc = null;
274 doc = repoSession.getDocument(docRef);
275 } catch (ClientException ce) {
276 String msg = "could not find document with id=" + id;
277 logger.error(msg, ce);
278 throw new DocumentNotFoundException(msg, ce);
280 //set reposession to handle the document
281 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
282 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
283 handler.handle(Action.GET, wrapDoc);
284 handler.complete(Action.GET, wrapDoc);
285 } catch (IllegalArgumentException iae) {
287 } catch (DocumentException de) {
289 } catch (Exception e) {
290 if (logger.isDebugEnabled()) {
291 logger.debug("Caught exception ", e);
293 throw new DocumentException(e);
295 if (repoSession != null) {
296 releaseRepositorySession(repoSession);
302 * get document from the Nuxeo repository, using the docFilter params.
303 * @param ctx service context under which this method is invoked
305 * should be used by the caller to provide and transform the
306 * document. Handler must have a docFilter set to return a single item.
307 * @throws DocumentException
310 public void get(ServiceContext ctx, DocumentHandler handler)
311 throws DocumentNotFoundException, DocumentException {
312 QueryContext queryContext = new QueryContext(ctx, handler);
313 RepositoryInstance repoSession = null;
316 handler.prepare(Action.GET);
317 repoSession = getRepositorySession();
319 DocumentModelList docList = null;
320 // force limit to 1, and ignore totalSize
321 String query = buildNXQLQuery(queryContext);
322 docList = repoSession.query(query, null, 1, 0, false);
323 if (docList.size() != 1) {
324 throw new DocumentNotFoundException("No document found matching filter params.");
326 DocumentModel doc = docList.get(0);
328 if (logger.isDebugEnabled()) {
329 logger.debug("Executed NXQL query: " + query);
332 //set reposession to handle the document
333 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
334 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
335 handler.handle(Action.GET, wrapDoc);
336 handler.complete(Action.GET, wrapDoc);
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);
354 * get wrapped documentModel from the Nuxeo repository
355 * @param ctx service context under which this method is invoked
357 * of the document to retrieve
358 * @throws DocumentException
361 public DocumentWrapper<DocumentModel> getDoc(
362 ServiceContext ctx, String id)
363 throws DocumentNotFoundException, DocumentException {
364 RepositoryInstance repoSession = null;
365 DocumentWrapper<DocumentModel> wrapDoc = null;
368 repoSession = getRepositorySession();
369 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
370 DocumentModel doc = null;
372 doc = repoSession.getDocument(docRef);
373 } catch (ClientException ce) {
374 String msg = "could not find document with id=" + id;
375 logger.error(msg, ce);
376 throw new DocumentNotFoundException(msg, ce);
378 wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
379 } catch (IllegalArgumentException iae) {
381 } catch (DocumentException de) {
383 } catch (Exception e) {
384 if (logger.isDebugEnabled()) {
385 logger.debug("Caught exception ", e);
387 throw new DocumentException(e);
389 if (repoSession != null) {
390 releaseRepositorySession(repoSession);
397 * find wrapped documentModel from the Nuxeo repository
398 * @param ctx service context under which this method is invoked
399 * @param where NXQL where clause to get the document
400 * @throws DocumentException
403 public DocumentWrapper<DocumentModel> findDoc(
404 ServiceContext ctx, String whereClause)
405 throws DocumentNotFoundException, DocumentException {
406 RepositoryInstance repoSession = null;
407 DocumentWrapper<DocumentModel> wrapDoc = null;
410 QueryContext queryContext = new QueryContext(ctx, whereClause);
411 repoSession = getRepositorySession();
412 DocumentModelList docList = null;
413 // force limit to 1, and ignore totalSize
414 String query = buildNXQLQuery(queryContext);
415 docList = repoSession.query(query,
420 if (docList.size() != 1) {
421 if (logger.isDebugEnabled()) {
422 logger.debug("findDoc: Query found: " + docList.size() + " items.");
423 logger.debug(" Query: " + query);
425 throw new DocumentNotFoundException("No document found matching filter params.");
427 DocumentModel doc = docList.get(0);
428 wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
429 } catch (IllegalArgumentException iae) {
431 } catch (DocumentException de) {
433 } catch (Exception e) {
434 if (logger.isDebugEnabled()) {
435 logger.debug("Caught exception ", e);
437 throw new DocumentException(e);
439 if (repoSession != null) {
440 releaseRepositorySession(repoSession);
447 * find doc and return CSID from the Nuxeo repository
448 * @param ctx service context under which this method is invoked
449 * @param where NXQL where clause to get the document
450 * @throws DocumentException
453 public String findDocCSID(
454 ServiceContext ctx, String whereClause)
455 throws DocumentNotFoundException, DocumentException {
458 DocumentWrapper<DocumentModel> wrapDoc = findDoc(ctx, whereClause);
459 DocumentModel docModel = wrapDoc.getWrappedObject();
460 csid = NuxeoUtils.extractId(docModel.getPathAsString());
461 } catch (DocumentNotFoundException dnfe) {
463 } catch (IllegalArgumentException iae) {
465 } catch (DocumentException de) {
467 } catch (Exception e) {
468 if (logger.isDebugEnabled()) {
469 logger.debug("Caught exception ", e);
471 throw new DocumentException(e);
477 * Find a list of documentModels from the Nuxeo repository
478 * @param docTypes a list of DocType names to match
479 * @param where the clause to qualify on
480 * @param domain the domain for the associated services
484 public DocumentWrapper<DocumentModelList> findDocs(
486 List<String> docTypes,
488 int pageSize, int pageNum, boolean computeTotal)
489 throws DocumentNotFoundException, DocumentException {
490 RepositoryInstance repoSession = null;
491 DocumentWrapper<DocumentModelList> wrapDoc = null;
494 if (docTypes == null || docTypes.size() < 1) {
495 throw new DocumentNotFoundException(
496 "findDocs must specify at least one DocumentType.");
498 repoSession = getRepositorySession();
499 DocumentModelList docList = null;
500 // force limit to 1, and ignore totalSize
501 QueryContext queryContext = new QueryContext(ctx, whereClause);
502 String query = buildNXQLQuery(docTypes, queryContext);
503 docList = repoSession.query(query, null, pageSize, pageNum, computeTotal);
504 wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
505 } catch (IllegalArgumentException iae) {
507 } catch (Exception e) {
508 if (logger.isDebugEnabled()) {
509 logger.debug("Caught exception ", e);
511 throw new DocumentException(e);
513 if (repoSession != null) {
514 releaseRepositorySession(repoSession);
521 * @see org.collectionspace.services.common.storage.StorageClient#get(org.collectionspace.services.common.context.ServiceContext, java.util.List, org.collectionspace.services.common.document.DocumentHandler)
524 public void get(ServiceContext ctx, List<String> csidList, DocumentHandler handler)
525 throws DocumentNotFoundException, DocumentException {
526 if (handler == null) {
527 throw new IllegalArgumentException(
528 "RepositoryJavaClient.getAll: handler is missing");
531 RepositoryInstance repoSession = null;
534 handler.prepare(Action.GET_ALL);
535 repoSession = getRepositorySession();
536 DocumentModelList docModelList = new DocumentModelListImpl();
537 //FIXME: Should be using NuxeoUtils.createPathRef for security reasons
538 for (String csid : csidList) {
539 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, csid);
540 DocumentModel docModel = repoSession.getDocument(docRef);
541 docModelList.add(docModel);
544 //set reposession to handle the document
545 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
546 DocumentWrapper<DocumentModelList> wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docModelList);
547 handler.handle(Action.GET_ALL, wrapDoc);
548 handler.complete(Action.GET_ALL, wrapDoc);
549 } catch (DocumentException de) {
551 } catch (Exception e) {
552 if (logger.isDebugEnabled()) {
553 logger.debug("Caught exception ", e);
555 throw new DocumentException(e);
557 if (repoSession != null) {
558 releaseRepositorySession(repoSession);
564 * getAll get all documents for an entity entity service from the Nuxeo
567 * @param ctx service context under which this method is invoked
569 * should be used by the caller to provide and transform the
571 * @throws DocumentException
574 public void getAll(ServiceContext ctx, DocumentHandler handler)
575 throws DocumentNotFoundException, DocumentException {
576 if (handler == null) {
577 throw new IllegalArgumentException(
578 "RepositoryJavaClient.getAll: handler is missing");
580 String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
581 if (nuxeoWspaceId == null) {
582 throw new DocumentNotFoundException(
583 "Unable to find workspace for service "
584 + ctx.getServiceName()
585 + " check if the workspace exists in the Nuxeo repository");
587 RepositoryInstance repoSession = null;
590 handler.prepare(Action.GET_ALL);
591 repoSession = getRepositorySession();
592 DocumentRef wsDocRef = new IdRef(nuxeoWspaceId);
593 DocumentModelList docList = repoSession.getChildren(wsDocRef);
594 //set reposession to handle the document
595 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
596 DocumentWrapper<DocumentModelList> wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
597 handler.handle(Action.GET_ALL, wrapDoc);
598 handler.complete(Action.GET_ALL, wrapDoc);
599 } catch (DocumentException de) {
601 } catch (Exception e) {
602 if (logger.isDebugEnabled()) {
603 logger.debug("Caught exception ", e);
605 throw new DocumentException(e);
607 if (repoSession != null) {
608 releaseRepositorySession(repoSession);
614 * getFiltered get all documents for an entity service from the Document repository,
615 * given filter parameters specified by the handler.
616 * @param ctx service context under which this method is invoked
617 * @param handler should be used by the caller to provide and transform the document
618 * @throws DocumentNotFoundException if workspace not found
619 * @throws DocumentException
622 public void getFiltered(ServiceContext ctx, DocumentHandler handler)
623 throws DocumentNotFoundException, DocumentException {
624 QueryContext queryContext = new QueryContext(ctx, handler);
626 RepositoryInstance repoSession = null;
628 handler.prepare(Action.GET_ALL);
629 repoSession = getRepositorySession();
630 DocumentModelList docList = null;
631 String query = buildNXQLQuery(queryContext);
633 if (logger.isDebugEnabled()) {
634 logger.debug("Executing NXQL query: " + query.toString());
637 // If we have limit and/or offset, then pass true to get totalSize
638 // in returned DocumentModelList.
639 if ((queryContext.docFilter.getOffset() > 0) || (queryContext.docFilter.getPageSize() > 0)) {
640 docList = repoSession.query(query, null,
641 queryContext.docFilter.getPageSize(), queryContext.docFilter.getOffset(), true);
643 docList = repoSession.query(query);
646 //set repoSession to handle the document
647 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
648 DocumentWrapper<DocumentModelList> wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
649 handler.handle(Action.GET_ALL, wrapDoc);
650 handler.complete(Action.GET_ALL, wrapDoc);
651 } catch (DocumentException de) {
653 } catch (Exception e) {
654 if (logger.isDebugEnabled()) {
655 logger.debug("Caught exception ", e);
657 throw new DocumentException(e);
659 if (repoSession != null) {
660 releaseRepositorySession(repoSession);
666 * update given document in the Nuxeo repository
668 * @param ctx service context under which this method is invoked
672 * should be used by the caller to provide and transform the
674 * @throws DocumentException
677 public void update(ServiceContext ctx, String id, DocumentHandler handler)
678 throws BadRequestException, DocumentNotFoundException,
680 if (handler == null) {
681 throw new IllegalArgumentException(
682 "RepositoryJavaClient.update: handler is missing");
684 RepositoryInstance repoSession = null;
686 handler.prepare(Action.UPDATE);
687 repoSession = getRepositorySession();
688 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
689 DocumentModel doc = null;
691 doc = repoSession.getDocument(docRef);
692 } catch (ClientException ce) {
693 String msg = "Could not find document to update with id=" + id;
694 logger.error(msg, ce);
695 throw new DocumentNotFoundException(msg, ce);
697 //set reposession to handle the document
698 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
699 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
700 handler.handle(Action.UPDATE, wrapDoc);
701 setCollectionSpaceCoreValues(ctx, doc, Action.CREATE);
702 repoSession.saveDocument(doc);
704 handler.complete(Action.UPDATE, wrapDoc);
705 } catch (BadRequestException bre) {
707 } catch (DocumentException de) {
709 } catch (Exception e) {
710 if (logger.isDebugEnabled()) {
711 logger.debug("Caught exception ", e);
713 throw new DocumentException(e);
715 if (repoSession != null) {
716 releaseRepositorySession(repoSession);
722 * delete a document from the Nuxeo repository
723 * @param ctx service context under which this method is invoked
726 * @throws DocumentException
729 public void delete(ServiceContext ctx, String id) throws DocumentNotFoundException,
732 if (logger.isDebugEnabled()) {
733 logger.debug("deleting document with id=" + id);
735 RepositoryInstance repoSession = null;
737 repoSession = getRepositorySession();
738 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
740 repoSession.removeDocument(docRef);
741 } catch (ClientException ce) {
742 String msg = "could not find document to delete with id=" + id;
743 logger.error(msg, ce);
744 throw new DocumentNotFoundException(msg, ce);
747 } catch (DocumentException de) {
749 } catch (Exception e) {
750 if (logger.isDebugEnabled()) {
751 logger.debug("Caught exception ", e);
753 throw new DocumentException(e);
755 if (repoSession != null) {
756 releaseRepositorySession(repoSession);
762 * @see org.collectionspace.services.common.storage.StorageClient#delete(org.collectionspace.services.common.context.ServiceContext, java.lang.String, org.collectionspace.services.common.document.DocumentHandler)
765 public void delete(ServiceContext ctx, String id, DocumentHandler handler)
766 throws DocumentNotFoundException, DocumentException {
767 throw new UnsupportedOperationException();
771 public Hashtable<String, String> retrieveWorkspaceIds(String domainName) throws Exception {
772 return NuxeoConnector.getInstance().retrieveWorkspaceIds(domainName);
776 public String createDomain(String domainName) throws Exception {
777 RepositoryInstance repoSession = null;
778 String domainId = null;
780 repoSession = getRepositorySession();
781 DocumentRef parentDocRef = new PathRef("/");
782 DocumentModel parentDoc = repoSession.getDocument(parentDocRef);
783 DocumentModel doc = repoSession.createDocumentModel(parentDoc.getPathAsString(),
784 domainName, "Domain");
785 doc.setPropertyValue("dc:title", domainName);
786 doc.setPropertyValue("dc:description", "A CollectionSpace domain "
788 doc = repoSession.createDocument(doc);
789 domainId = doc.getId();
791 if (logger.isDebugEnabled()) {
792 logger.debug("created tenant domain name=" + domainName
793 + " id=" + domainId);
795 } catch (Exception e) {
796 if (logger.isDebugEnabled()) {
797 logger.debug("createTenantSpace caught exception ", e);
801 if (repoSession != null) {
802 releaseRepositorySession(repoSession);
809 public String getDomainId(String domainName) throws Exception {
810 String domainId = null;
811 RepositoryInstance repoSession = null;
813 repoSession = getRepositorySession();
814 DocumentRef docRef = new PathRef(
816 DocumentModel domain = repoSession.getDocument(docRef);
817 domainId = domain.getId();
818 } catch (Exception e) {
819 if (logger.isDebugEnabled()) {
820 logger.debug("Caught exception ", e);
822 //there is no way to identify if document does not exist due to
823 //lack of typed exception for getDocument method
826 if (repoSession != null) {
827 releaseRepositorySession(repoSession);
834 * @see org.collectionspace.services.common.repository.RepositoryClient#createWorkspace(java.lang.String, java.lang.String)
837 public String createWorkspace(String domainName, String workspaceName) throws Exception {
838 RepositoryInstance repoSession = null;
839 String workspaceId = null;
841 repoSession = getRepositorySession();
842 DocumentRef parentDocRef = new PathRef(
844 + "/" + "workspaces");
845 DocumentModel parentDoc = repoSession.getDocument(parentDocRef);
846 DocumentModel doc = repoSession.createDocumentModel(parentDoc.getPathAsString(),
847 workspaceName, "Workspace");
848 doc.setPropertyValue("dc:title", workspaceName);
849 doc.setPropertyValue("dc:description", "A CollectionSpace workspace for "
851 doc = repoSession.createDocument(doc);
852 workspaceId = doc.getId();
854 if (logger.isDebugEnabled()) {
855 logger.debug("created workspace name=" + workspaceName
856 + " id=" + workspaceId);
858 } catch (Exception e) {
859 if (logger.isDebugEnabled()) {
860 logger.debug("createWorkspace caught exception ", e);
864 if (repoSession != null) {
865 releaseRepositorySession(repoSession);
872 * @see org.collectionspace.services.common.repository.RepositoryClient#getWorkspaceId(java.lang.String, java.lang.String)
875 public String getWorkspaceId(String tenantDomain, String workspaceName) throws Exception {
876 String workspaceId = null;
877 RepositoryInstance repoSession = null;
879 repoSession = getRepositorySession();
880 DocumentRef docRef = new PathRef(
883 + "/" + workspaceName);
884 DocumentModel workspace = repoSession.getDocument(docRef);
885 workspaceId = workspace.getId();
886 } catch (DocumentException de) {
888 } catch (Exception e) {
889 if (logger.isDebugEnabled()) {
890 logger.debug("Caught exception ", e);
892 throw new DocumentException(e);
894 if (repoSession != null) {
895 releaseRepositorySession(repoSession);
904 * @param query the query
905 * @param where the where
906 * @param domain the domain
908 private final void appendNXQLWhere(StringBuilder query, QueryContext queryContext) {
910 // Restrict search to a specific Nuxeo domain
911 // TODO This is a slow method for tenant-filter
912 // We should make this a property that is indexed.
914 query.append(" WHERE ecm:path STARTSWITH '/" + queryContext.domain + "'");
917 // Restrict search to the current tenant ID. Is the domain path filter (above) still needed?
919 query.append(IQueryManager.SEARCH_QUALIFIER_AND + DocumentModelHandler.COLLECTIONSPACE_CORE_SCHEMA + ":"
920 + DocumentModelHandler.COLLECTIONSPACE_CORE_TENANTID
921 + " = " + queryContext.tenantId);
923 // Finally, append the incoming where clause
925 String whereClause = queryContext.whereClause;
926 if (whereClause != null && whereClause.length() > 0) {
927 // Due to an apparent bug/issue in how Nuxeo translates the NXQL query string
928 // into SQL, we need to parenthesize our 'where' clause
929 query.append(IQueryManager.SEARCH_QUALIFIER_AND + "(" + whereClause + ")");
932 // Please lookup this use in Nuxeo support and document here
934 query.append(IQueryManager.SEARCH_QUALIFIER_AND + "ecm:isProxy = 0");
938 * Builds the nxql query.
940 * @param docType the doc type
941 * @param where the where
942 * @param domain the domain
943 * @param tenantId the tenant id
946 private final String buildNXQLQuery(QueryContext queryContext) {
947 StringBuilder query = new StringBuilder("SELECT * FROM ");
948 query.append(queryContext.docType);
949 appendNXQLWhere(query, queryContext);
950 return query.toString();
954 * Builds the nxql query.
956 * @param docTypes the doc types
957 * @param where the where
958 * @param domain the domain
961 private final String buildNXQLQuery(List<String> docTypes, QueryContext queryContext) {
962 StringBuilder query = new StringBuilder("SELECT * FROM ");
963 boolean fFirst = true;
964 for (String docType : docTypes) {
970 query.append(docType);
972 appendNXQLWhere(query, queryContext);
973 return query.toString();
977 * Gets the repository session.
979 * @return the repository session
980 * @throws Exception the exception
982 private RepositoryInstance getRepositorySession() throws Exception {
983 // FIXME: is it possible to reuse repository session?
984 // Authentication failures happen while trying to reuse the session
985 NuxeoClient client = NuxeoConnector.getInstance().getClient();
986 RepositoryInstance repoSession = client.openRepository();
987 if (logger.isDebugEnabled()) {
988 logger.debug("getRepository() repository root: " + repoSession.getRootDocument());
994 * Release repository session.
996 * @param repoSession the repo session
998 private void releaseRepositorySession(RepositoryInstance repoSession) {
1000 NuxeoClient client = NuxeoConnector.getInstance().getClient();
1002 client.releaseRepository(repoSession);
1003 } catch (Exception e) {
1004 logger.error("Could not close the repository session", e);
1005 // no need to throw this service specific exception