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;
22 import java.util.UUID;
23 import java.util.regex.Matcher;
24 import java.util.regex.Pattern;
25 import java.util.regex.PatternSyntaxException;
27 import javax.ws.rs.WebApplicationException;
28 import javax.ws.rs.core.MultivaluedMap;
30 import org.collectionspace.services.client.IQueryManager;
31 import org.collectionspace.services.client.PoxPayloadIn;
32 import org.collectionspace.services.client.PoxPayloadOut;
33 import org.collectionspace.services.client.workflow.WorkflowClient;
34 import org.collectionspace.services.common.context.ServiceContext;
35 import org.collectionspace.services.common.datetime.GregorianCalendarDateTimeUtils;
36 import org.collectionspace.services.common.query.QueryContext;
37 import org.collectionspace.services.common.repository.RepositoryClient;
38 import org.collectionspace.services.common.workflow.service.nuxeo.WorkflowDocumentModelHandler;
39 import org.collectionspace.services.common.profile.Profiler;
40 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
42 import org.collectionspace.services.common.document.BadRequestException;
43 import org.collectionspace.services.common.document.DocumentException;
44 import org.collectionspace.services.common.document.DocumentFilter;
45 import org.collectionspace.services.common.document.DocumentHandler;
46 import org.collectionspace.services.common.document.DocumentNotFoundException;
47 import org.collectionspace.services.common.document.DocumentHandler.Action;
48 import org.collectionspace.services.common.document.DocumentWrapper;
49 import org.collectionspace.services.common.document.DocumentWrapperImpl;
51 import org.nuxeo.common.utils.IdUtils;
52 import org.nuxeo.ecm.core.api.ClientException;
53 import org.nuxeo.ecm.core.api.DocumentModel;
54 import org.nuxeo.ecm.core.api.DocumentModelList;
55 import org.nuxeo.ecm.core.api.impl.DocumentModelListImpl;
56 import org.nuxeo.ecm.core.api.DocumentRef;
57 import org.nuxeo.ecm.core.api.IdRef;
58 import org.nuxeo.ecm.core.api.PathRef;
59 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
60 import org.nuxeo.ecm.core.client.NuxeoClient;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
66 * RepositoryJavaClient is used to perform CRUD operations on documents in Nuxeo
67 * repository using Remote Java APIs. It uses @see DocumentHandler as IOHandler
70 * $LastChangedRevision: $ $LastChangedDate: $
72 public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn, PoxPayloadOut> {
75 private final Logger logger = LoggerFactory.getLogger(RepositoryJavaClientImpl.class);
76 // private final Logger profilerLogger = LoggerFactory.getLogger("remperf");
77 // private String foo = Profiler.createLogger();
80 * Instantiates a new repository java client impl.
82 public RepositoryJavaClientImpl() {
87 public void assertWorkflowState(ServiceContext ctx,
88 DocumentModel docModel) throws DocumentNotFoundException, ClientException {
89 MultivaluedMap<String, String> queryParams = ctx.getQueryParams();
90 if (queryParams != null) {
92 // Look for the workflow "delete" query param and see if we need to assert that the
93 // docModel is in a non-deleted workflow state.
95 String currentState = docModel.getCurrentLifeCycleState();
96 String includeDeletedStr = queryParams.getFirst(WorkflowClient.WORKFLOW_QUERY_NONDELETED);
97 boolean includeDeleted = includeDeletedStr == null ? true : Boolean.parseBoolean(includeDeletedStr);
98 if (includeDeleted == false) {
100 // We don't wanted soft-deleted object, so throw an exception if this one is soft-deleted.
102 if (currentState.equalsIgnoreCase(WorkflowClient.WORKFLOWSTATE_DELETED)) {
103 String msg = "GET assertion that docModel not be in 'deleted' workflow state failed.";
105 throw new DocumentNotFoundException(msg);
112 * Sets the collection space core values.
115 * @param documentModel the document model
116 * @throws ClientException the client exception //FIXME: REM - This behavior needs to be part of the base DocumentHandler classes, so our JPA services get this behavior as well
118 private void setCollectionSpaceCoreValues(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
119 DocumentModel documentModel,
120 Action action) throws ClientException {
122 // Add the CSID to the DublinCore title so we can see the CSID in the default
126 documentModel.setProperty("dublincore",
128 documentModel.getName());
129 } catch (Exception x) {
130 if (logger.isWarnEnabled() == true) {
131 logger.warn("Could not set the Dublin Core 'title' field on document CSID:" +
132 documentModel.getName());
136 // Add the tenant ID value to the new entity
138 documentModel.setProperty(DocumentModelHandler.COLLECTIONSPACE_CORE_SCHEMA,
139 DocumentModelHandler.COLLECTIONSPACE_CORE_TENANTID,
142 String now = GregorianCalendarDateTimeUtils.timestampUTC();
146 documentModel.setProperty(DocumentModelHandler.COLLECTIONSPACE_CORE_SCHEMA,
147 DocumentModelHandler.COLLECTIONSPACE_CORE_CREATED_AT,
149 documentModel.setProperty(DocumentModelHandler.COLLECTIONSPACE_CORE_SCHEMA,
150 DocumentModelHandler.COLLECTIONSPACE_CORE_UPDATED_AT,
154 documentModel.setProperty(DocumentModelHandler.COLLECTIONSPACE_CORE_SCHEMA,
155 DocumentModelHandler.COLLECTIONSPACE_CORE_UPDATED_AT,
164 * create document in the Nuxeo repository
166 * @param ctx service context under which this method is invoked
168 * should be used by the caller to provide and transform the
170 * @return id in repository of the newly created document
171 * @throws DocumentException
174 public String create(ServiceContext ctx,
175 DocumentHandler handler) throws BadRequestException,
178 if (ctx.getDocumentType() == null) {
179 throw new IllegalArgumentException(
180 "RepositoryJavaClient.create: docType is missing");
182 if (handler == null) {
183 throw new IllegalArgumentException(
184 "RepositoryJavaClient.create: handler is missing");
186 String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
187 if (nuxeoWspaceId == null) {
188 throw new DocumentNotFoundException(
189 "Unable to find workspace for service " + ctx.getServiceName()
190 + " check if the workspace exists in the Nuxeo repository");
192 RepositoryInstance repoSession = null;
194 handler.prepare(Action.CREATE);
195 repoSession = getRepositorySession();
196 DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId);
197 DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace);
198 String wspacePath = wspaceDoc.getPathAsString();
199 //give our own ID so PathRef could be constructed later on
200 String id = IdUtils.generateId(UUID.randomUUID().toString());
201 // create document model
202 DocumentModel doc = repoSession.createDocumentModel(wspacePath, id,
203 ctx.getDocumentType());
204 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
205 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
206 handler.handle(Action.CREATE, wrapDoc);
207 // create document with documentmodel
208 setCollectionSpaceCoreValues(ctx, doc, Action.CREATE);
209 doc = repoSession.createDocument(doc);
211 // TODO for sub-docs need to call into the handler to let it deal with subitems. Pass in the id,
212 // and assume the handler has the state it needs (doc fragments).
213 handler.complete(Action.CREATE, wrapDoc);
215 } catch (BadRequestException bre) {
217 } catch (Exception e) {
218 if (logger.isDebugEnabled()) {
219 logger.debug("Caught exception ", e);
221 throw new DocumentException(e);
223 if (repoSession != null) {
224 releaseRepositorySession(repoSession);
231 * get document from the Nuxeo repository
232 * @param ctx service context under which this method is invoked
234 * of the document to retrieve
236 * should be used by the caller to provide and transform the
238 * @throws DocumentException
241 public void get(ServiceContext ctx, String id, DocumentHandler handler)
242 throws DocumentNotFoundException, DocumentException {
244 if (handler == null) {
245 throw new IllegalArgumentException(
246 "RepositoryJavaClient.get: handler is missing");
248 RepositoryInstance repoSession = null;
251 handler.prepare(Action.GET);
252 repoSession = getRepositorySession();
253 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
254 DocumentModel docModel = null;
256 docModel = repoSession.getDocument(docRef);
257 assertWorkflowState(ctx, docModel);
258 } catch (ClientException ce) {
259 String msg = "Could not find document with id=" + id;
260 logger.error(msg, ce);
261 throw new DocumentNotFoundException(msg, ce);
263 //set reposession to handle the document
264 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
265 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(docModel);
266 handler.handle(Action.GET, wrapDoc);
267 handler.complete(Action.GET, wrapDoc);
268 } catch (IllegalArgumentException iae) {
270 } catch (DocumentException de) {
272 } catch (Exception e) {
273 if (logger.isDebugEnabled()) {
274 logger.debug("Caught exception ", e);
276 throw new DocumentException(e);
278 if (repoSession != null) {
279 releaseRepositorySession(repoSession);
285 * get document from the Nuxeo repository, using the docFilter params.
286 * @param ctx service context under which this method is invoked
288 * should be used by the caller to provide and transform the
289 * document. Handler must have a docFilter set to return a single item.
290 * @throws DocumentException
293 public void get(ServiceContext ctx, DocumentHandler handler)
294 throws DocumentNotFoundException, DocumentException {
295 QueryContext queryContext = new QueryContext(ctx, handler);
296 RepositoryInstance repoSession = null;
299 handler.prepare(Action.GET);
300 repoSession = getRepositorySession();
302 DocumentModelList docList = null;
303 // force limit to 1, and ignore totalSize
304 String query = NuxeoUtils.buildNXQLQuery(queryContext);
305 docList = repoSession.query(query, null, 1, 0, false);
306 if (docList.size() != 1) {
307 throw new DocumentNotFoundException("No document found matching filter params.");
309 DocumentModel doc = docList.get(0);
311 if (logger.isDebugEnabled()) {
312 logger.debug("Executed NXQL query: " + query);
315 //set reposession to handle the document
316 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
317 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
318 handler.handle(Action.GET, wrapDoc);
319 handler.complete(Action.GET, wrapDoc);
320 } catch (IllegalArgumentException iae) {
322 } catch (DocumentException de) {
324 } catch (Exception e) {
325 if (logger.isDebugEnabled()) {
326 logger.debug("Caught exception ", e);
328 throw new DocumentException(e);
330 if (repoSession != null) {
331 releaseRepositorySession(repoSession);
337 * Get wrapped documentModel from the Nuxeo repository. The search is restricted to the workspace
338 * of the current context.
340 * @param ctx service context under which this method is invoked
342 * of the document to retrieve
343 * @throws DocumentException
346 public DocumentWrapper<DocumentModel> getDoc(
347 ServiceContext ctx, String csid)
348 throws DocumentNotFoundException, DocumentException {
349 RepositoryInstance repoSession = null;
350 DocumentWrapper<DocumentModel> wrapDoc = null;
353 repoSession = getRepositorySession();
354 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, csid);
355 DocumentModel doc = null;
357 doc = repoSession.getDocument(docRef);
358 } catch (ClientException ce) {
359 String msg = "could not find document with id=" + csid;
360 logger.error(msg, ce);
361 throw new DocumentNotFoundException(msg, ce);
363 wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
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(repoSession);
382 * find wrapped documentModel from the Nuxeo repository
383 * @param ctx service context under which this method is invoked
384 * @param whereClause where NXQL where clause to get the document
385 * @throws DocumentException
388 public DocumentWrapper<DocumentModel> findDoc(
389 ServiceContext ctx, String whereClause)
390 throws DocumentNotFoundException, DocumentException {
391 RepositoryInstance repoSession = null;
392 DocumentWrapper<DocumentModel> wrapDoc = null;
395 QueryContext queryContext = new QueryContext(ctx, whereClause);
396 repoSession = getRepositorySession();
397 DocumentModelList docList = null;
398 // force limit to 1, and ignore totalSize
399 String query = NuxeoUtils.buildNXQLQuery(queryContext);
400 docList = repoSession.query(query,
405 if (docList.size() != 1) {
406 if (logger.isDebugEnabled()) {
407 logger.debug("findDoc: Query found: " + docList.size() + " items.");
408 logger.debug(" Query: " + query);
410 throw new DocumentNotFoundException("No document found matching filter params.");
412 DocumentModel doc = docList.get(0);
413 wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
414 } catch (IllegalArgumentException iae) {
416 } catch (DocumentException de) {
418 } catch (Exception e) {
419 if (logger.isDebugEnabled()) {
420 logger.debug("Caught exception ", e);
422 throw new DocumentException(e);
424 if (repoSession != null) {
425 releaseRepositorySession(repoSession);
432 * find doc and return CSID from the Nuxeo repository
433 * @param ctx service context under which this method is invoked
434 * @param whereClause where NXQL where clause to get the document
435 * @throws DocumentException
438 public String findDocCSID(
439 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String whereClause)
440 throws DocumentNotFoundException, DocumentException {
443 DocumentWrapper<DocumentModel> wrapDoc = findDoc(ctx, whereClause);
444 DocumentModel docModel = wrapDoc.getWrappedObject();
445 csid = NuxeoUtils.getCsid(docModel);//NuxeoUtils.extractId(docModel.getPathAsString());
446 } catch (DocumentNotFoundException dnfe) {
448 } catch (IllegalArgumentException iae) {
450 } catch (DocumentException de) {
452 } catch (Exception e) {
453 if (logger.isDebugEnabled()) {
454 logger.debug("Caught exception ", e);
456 throw new DocumentException(e);
462 * Find a list of documentModels from the Nuxeo repository
463 * @param docTypes a list of DocType names to match
464 * @param whereClause where the clause to qualify on
468 public DocumentWrapper<DocumentModelList> findDocs(
469 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
470 List<String> docTypes,
472 int pageSize, int pageNum, boolean computeTotal)
473 throws DocumentNotFoundException, DocumentException {
474 RepositoryInstance repoSession = null;
475 DocumentWrapper<DocumentModelList> wrapDoc = null;
478 if (docTypes == null || docTypes.size() < 1) {
479 throw new DocumentNotFoundException(
480 "findDocs must specify at least one DocumentType.");
482 repoSession = getRepositorySession();
483 DocumentModelList docList = null;
484 // force limit to 1, and ignore totalSize
485 QueryContext queryContext = new QueryContext(ctx, whereClause);
486 String query = NuxeoUtils.buildNXQLQuery(docTypes, queryContext);
487 docList = repoSession.query(query, null, pageSize, pageNum, computeTotal);
488 wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
489 } catch (IllegalArgumentException iae) {
491 } catch (Exception e) {
492 if (logger.isDebugEnabled()) {
493 logger.debug("Caught exception ", e);
495 throw new DocumentException(e);
497 if (repoSession != null) {
498 releaseRepositorySession(repoSession);
505 * @see org.collectionspace.services.common.storage.StorageClient#get(org.collectionspace.services.common.context.ServiceContext, java.util.List, org.collectionspace.services.common.document.DocumentHandler)
508 public void get(ServiceContext ctx, List<String> csidList, DocumentHandler handler)
509 throws DocumentNotFoundException, DocumentException {
510 if (handler == null) {
511 throw new IllegalArgumentException(
512 "RepositoryJavaClient.getAll: handler is missing");
515 RepositoryInstance repoSession = null;
518 handler.prepare(Action.GET_ALL);
519 repoSession = getRepositorySession();
520 DocumentModelList docModelList = new DocumentModelListImpl();
521 //FIXME: Should be using NuxeoUtils.createPathRef for security reasons
522 for (String csid : csidList) {
523 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, csid);
524 DocumentModel docModel = repoSession.getDocument(docRef);
525 docModelList.add(docModel);
528 //set reposession to handle the document
529 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
530 DocumentWrapper<DocumentModelList> wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docModelList);
531 handler.handle(Action.GET_ALL, wrapDoc);
532 handler.complete(Action.GET_ALL, wrapDoc);
533 } catch (DocumentException de) {
535 } catch (Exception e) {
536 if (logger.isDebugEnabled()) {
537 logger.debug("Caught exception ", e);
539 throw new DocumentException(e);
541 if (repoSession != null) {
542 releaseRepositorySession(repoSession);
548 * getAll get all documents for an entity entity service from the Nuxeo
551 * @param ctx service context under which this method is invoked
553 * should be used by the caller to provide and transform the
555 * @throws DocumentException
558 public void getAll(ServiceContext ctx, DocumentHandler handler)
559 throws DocumentNotFoundException, DocumentException {
560 if (handler == null) {
561 throw new IllegalArgumentException(
562 "RepositoryJavaClient.getAll: handler is missing");
564 String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
565 if (nuxeoWspaceId == null) {
566 throw new DocumentNotFoundException(
567 "Unable to find workspace for service "
568 + ctx.getServiceName()
569 + " check if the workspace exists in the Nuxeo repository");
571 RepositoryInstance repoSession = null;
574 handler.prepare(Action.GET_ALL);
575 repoSession = getRepositorySession();
576 DocumentRef wsDocRef = new IdRef(nuxeoWspaceId);
577 DocumentModelList docList = repoSession.getChildren(wsDocRef);
578 //set reposession to handle the document
579 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
580 DocumentWrapper<DocumentModelList> wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
581 handler.handle(Action.GET_ALL, wrapDoc);
582 handler.complete(Action.GET_ALL, wrapDoc);
583 } catch (DocumentException de) {
585 } catch (Exception e) {
586 if (logger.isDebugEnabled()) {
587 logger.debug("Caught exception ", e);
589 throw new DocumentException(e);
591 if (repoSession != null) {
592 releaseRepositorySession(repoSession);
597 private boolean isClauseEmpty(String theString) {
598 boolean result = true;
599 if (theString != null && !theString.isEmpty()) {
606 * A method to find a CollectionSpace document (of any type) given just a service context and
607 * its CSID. A search across *all* service workspaces (within a given tenant context) is performed to find
610 * This query searches Nuxeo's Hierarchy table where our CSIDs are stored in the "name" column.
613 public DocumentWrapper<DocumentModel> getDocFromCsid(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
616 DocumentWrapper<DocumentModel> result = null;
617 RepositoryInstance repoSession = getRepositorySession();
619 result = new DocumentWrapperImpl(NuxeoUtils.getDocFromCsid(repoSession, ctx, csid));
621 if (repoSession != null) {
622 releaseRepositorySession(repoSession);
630 * getFiltered get all documents for an entity service from the Document repository,
631 * given filter parameters specified by the handler.
632 * @param ctx service context under which this method is invoked
633 * @param handler should be used by the caller to provide and transform the document
634 * @throws DocumentNotFoundException if workspace not found
635 * @throws DocumentException
638 public void getFiltered(ServiceContext ctx, DocumentHandler handler)
639 throws DocumentNotFoundException, DocumentException {
641 DocumentFilter filter = handler.getDocumentFilter();
642 String oldOrderBy = filter.getOrderByClause();
643 if (isClauseEmpty(oldOrderBy) == true){
644 filter.setOrderByClause(DocumentFilter.ORDER_BY_LAST_UPDATED); //per http://issues.collectionspace.org/browse/CSPACE-705
646 QueryContext queryContext = new QueryContext(ctx, handler);
647 RepositoryInstance repoSession = null;
649 handler.prepare(Action.GET_ALL);
650 repoSession = getRepositorySession();
651 DocumentModelList docList = null;
652 String query = NuxeoUtils.buildNXQLQuery(queryContext);
654 if (logger.isDebugEnabled()) {
655 logger.debug("Executing NXQL query: " + query.toString());
658 // If we have limit and/or offset, then pass true to get totalSize
659 // in returned DocumentModelList.
660 Profiler profiler = new Profiler(this, 2);
661 profiler.log("Executing NXQL query: " + query.toString());
663 if ((queryContext.getDocFilter().getOffset() > 0) || (queryContext.getDocFilter().getPageSize() > 0)) {
664 docList = repoSession.query(query, null,
665 queryContext.getDocFilter().getPageSize(), queryContext.getDocFilter().getOffset(), true);
667 docList = repoSession.query(query);
671 //set repoSession to handle the document
672 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
673 DocumentWrapper<DocumentModelList> wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
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(repoSession);
691 * update given document in the Nuxeo repository
693 * @param ctx service context under which this method is invoked
697 * should be used by the caller to provide and transform the
699 * @throws DocumentException
702 public void update(ServiceContext ctx, String id, DocumentHandler handler)
703 throws BadRequestException, DocumentNotFoundException,
705 if (handler == null) {
706 throw new IllegalArgumentException(
707 "RepositoryJavaClient.update: handler is missing");
709 RepositoryInstance repoSession = null;
711 handler.prepare(Action.UPDATE);
712 repoSession = getRepositorySession();
713 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
714 DocumentModel doc = null;
716 doc = repoSession.getDocument(docRef);
717 } catch (ClientException ce) {
718 String msg = "Could not find document to update with id=" + id;
719 logger.error(msg, ce);
720 throw new DocumentNotFoundException(msg, ce);
722 //set reposession to handle the document
723 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
724 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
725 handler.handle(Action.UPDATE, wrapDoc);
726 setCollectionSpaceCoreValues(ctx, doc, Action.UPDATE);
727 repoSession.saveDocument(doc);
729 handler.complete(Action.UPDATE, wrapDoc);
730 } catch (BadRequestException bre) {
732 } catch (DocumentException de) {
734 } catch (WebApplicationException wae){
736 } catch (Exception e) {
737 if (logger.isDebugEnabled()) {
738 logger.debug("Caught exception ", e);
740 throw new DocumentException(e);
742 if (repoSession != null) {
743 releaseRepositorySession(repoSession);
749 * delete a document from the Nuxeo repository
750 * @param ctx service context under which this method is invoked
753 * @throws DocumentException
756 public void delete(ServiceContext ctx, String id) throws DocumentNotFoundException,
759 if (logger.isDebugEnabled()) {
760 logger.debug("deleting document with id=" + id);
762 RepositoryInstance repoSession = null;
764 repoSession = getRepositorySession();
765 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
767 repoSession.removeDocument(docRef);
768 } catch (ClientException ce) {
769 String msg = "could not find document to delete with id=" + id;
770 logger.error(msg, ce);
771 throw new DocumentNotFoundException(msg, ce);
774 } catch (DocumentException de) {
776 } catch (Exception e) {
777 if (logger.isDebugEnabled()) {
778 logger.debug("Caught exception ", e);
780 throw new DocumentException(e);
782 if (repoSession != null) {
783 releaseRepositorySession(repoSession);
789 * @see org.collectionspace.services.common.storage.StorageClient#delete(org.collectionspace.services.common.context.ServiceContext, java.lang.String, org.collectionspace.services.common.document.DocumentHandler)
792 public void delete(ServiceContext ctx, String id, DocumentHandler handler)
793 throws DocumentNotFoundException, DocumentException {
794 throw new UnsupportedOperationException();
798 public Hashtable<String, String> retrieveWorkspaceIds(String domainName) throws Exception {
799 return NuxeoConnector.getInstance().retrieveWorkspaceIds(domainName);
803 public String createDomain(String domainName) throws Exception {
804 RepositoryInstance repoSession = null;
805 String domainId = null;
807 repoSession = getRepositorySession();
808 DocumentRef parentDocRef = new PathRef("/");
809 DocumentModel parentDoc = repoSession.getDocument(parentDocRef);
810 DocumentModel doc = repoSession.createDocumentModel(parentDoc.getPathAsString(),
811 domainName, "Domain");
812 doc.setPropertyValue("dc:title", domainName);
813 doc.setPropertyValue("dc:description", "A CollectionSpace domain "
815 doc = repoSession.createDocument(doc);
816 domainId = doc.getId();
818 if (logger.isDebugEnabled()) {
819 logger.debug("created tenant domain name=" + domainName
820 + " id=" + domainId);
822 } catch (Exception e) {
823 if (logger.isDebugEnabled()) {
824 logger.debug("createTenantSpace caught exception ", e);
828 if (repoSession != null) {
829 releaseRepositorySession(repoSession);
836 public String getDomainId(String domainName) throws Exception {
837 String domainId = null;
838 RepositoryInstance repoSession = null;
840 if (domainName != null && !domainName.isEmpty()) {
842 repoSession = getRepositorySession();
843 DocumentRef docRef = new PathRef(
845 DocumentModel domain = repoSession.getDocument(docRef);
846 domainId = domain.getId();
847 } catch (Exception e) {
848 if (logger.isDebugEnabled()) {
849 logger.debug("Caught exception ", e);
851 //there is no way to identify if document does not exist due to
852 //lack of typed exception for getDocument method
855 if (repoSession != null) {
856 releaseRepositorySession(repoSession);
865 * @see org.collectionspace.services.common.repository.RepositoryClient#createWorkspace(java.lang.String, java.lang.String)
868 public String createWorkspace(String domainName, String workspaceName) throws Exception {
869 RepositoryInstance repoSession = null;
870 String workspaceId = null;
872 repoSession = getRepositorySession();
873 DocumentRef parentDocRef = new PathRef(
875 + "/" + "workspaces");
876 DocumentModel parentDoc = repoSession.getDocument(parentDocRef);
877 DocumentModel doc = repoSession.createDocumentModel(parentDoc.getPathAsString(),
878 workspaceName, "Workspace");
879 doc.setPropertyValue("dc:title", workspaceName);
880 doc.setPropertyValue("dc:description", "A CollectionSpace workspace for "
882 doc = repoSession.createDocument(doc);
883 workspaceId = doc.getId();
885 if (logger.isDebugEnabled()) {
886 logger.debug("created workspace name=" + workspaceName
887 + " id=" + workspaceId);
889 } catch (Exception e) {
890 if (logger.isDebugEnabled()) {
891 logger.debug("createWorkspace caught exception ", e);
895 if (repoSession != null) {
896 releaseRepositorySession(repoSession);
903 * @see org.collectionspace.services.common.repository.RepositoryClient#getWorkspaceId(java.lang.String, java.lang.String)
906 public String getWorkspaceId(String tenantDomain, String workspaceName) throws Exception {
907 String workspaceId = null;
908 RepositoryInstance repoSession = null;
910 repoSession = getRepositorySession();
911 DocumentRef docRef = new PathRef(
914 + "/" + workspaceName);
915 DocumentModel workspace = repoSession.getDocument(docRef);
916 workspaceId = workspace.getId();
917 } catch (DocumentException de) {
919 } catch (Exception e) {
920 if (logger.isDebugEnabled()) {
921 logger.debug("Caught exception ", e);
923 throw new DocumentException(e);
925 if (repoSession != null) {
926 releaseRepositorySession(repoSession);
934 * Gets the repository session.
936 * @return the repository session
937 * @throws Exception the exception
939 private RepositoryInstance getRepositorySession() throws Exception {
940 // FIXME: is it possible to reuse repository session?
941 // Authentication failures happen while trying to reuse the session
942 Profiler profiler = new Profiler("getRepositorySession():", 2);
944 NuxeoClient client = NuxeoConnector.getInstance().getClient();
945 RepositoryInstance repoSession = client.openRepository();
946 if (logger.isTraceEnabled()) {
947 logger.debug("getRepository() repository root: " + repoSession.getRootDocument());
954 * Release repository session.
956 * @param repoSession the repo session
958 private void releaseRepositorySession(RepositoryInstance repoSession) {
960 NuxeoClient client = NuxeoConnector.getInstance().getClient();
962 client.releaseRepository(repoSession);
963 } catch (Exception e) {
964 logger.error("Could not close the repository session", e);
965 // no need to throw this service specific exception