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.core.MultivaluedMap;
29 import org.collectionspace.services.client.IQueryManager;
30 import org.collectionspace.services.client.PoxPayloadIn;
31 import org.collectionspace.services.client.PoxPayloadOut;
32 import org.collectionspace.services.client.workflow.WorkflowClient;
33 import org.collectionspace.services.common.context.ServiceContext;
34 import org.collectionspace.services.common.datetime.GregorianCalendarDateTimeUtils;
35 import org.collectionspace.services.common.query.QueryContext;
36 import org.collectionspace.services.common.repository.RepositoryClient;
37 import org.collectionspace.services.common.workflow.service.nuxeo.WorkflowDocumentModelHandler;
38 import org.collectionspace.services.common.profile.Profiler;
39 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
41 import org.collectionspace.services.common.document.BadRequestException;
42 import org.collectionspace.services.common.document.DocumentException;
43 import org.collectionspace.services.common.document.DocumentFilter;
44 import org.collectionspace.services.common.document.DocumentHandler;
45 import org.collectionspace.services.common.document.DocumentNotFoundException;
46 import org.collectionspace.services.common.document.DocumentHandler.Action;
47 import org.collectionspace.services.common.document.DocumentWrapper;
48 import org.collectionspace.services.common.document.DocumentWrapperImpl;
50 import org.nuxeo.common.utils.IdUtils;
51 import org.nuxeo.ecm.core.api.ClientException;
52 import org.nuxeo.ecm.core.api.DocumentModel;
53 import org.nuxeo.ecm.core.api.DocumentModelList;
54 import org.nuxeo.ecm.core.api.impl.DocumentModelListImpl;
55 import org.nuxeo.ecm.core.api.DocumentRef;
56 import org.nuxeo.ecm.core.api.IdRef;
57 import org.nuxeo.ecm.core.api.PathRef;
58 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
59 import org.nuxeo.ecm.core.client.NuxeoClient;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
65 * RepositoryJavaClient is used to perform CRUD operations on documents in Nuxeo
66 * repository using Remote Java APIs. It uses @see DocumentHandler as IOHandler
69 * $LastChangedRevision: $ $LastChangedDate: $
71 public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn, PoxPayloadOut> {
74 private final Logger logger = LoggerFactory.getLogger(RepositoryJavaClientImpl.class);
75 // private final Logger profilerLogger = LoggerFactory.getLogger("remperf");
76 // private String foo = Profiler.createLogger();
79 * Instantiates a new repository java client impl.
81 public RepositoryJavaClientImpl() {
86 public void assertWorkflowState(ServiceContext ctx,
87 DocumentModel docModel) throws DocumentNotFoundException, ClientException {
88 MultivaluedMap<String, String> queryParams = ctx.getQueryParams();
89 if (queryParams != null) {
91 // Look for the workflow "delete" query param and see if we need to assert that the
92 // docModel is in a non-deleted workflow state.
94 String currentState = docModel.getCurrentLifeCycleState();
95 String includeDeletedStr = queryParams.getFirst(WorkflowClient.WORKFLOW_QUERY_NONDELETED);
96 boolean includeDeleted = Boolean.parseBoolean(includeDeletedStr);
97 if (includeDeleted == false) {
99 // We don't wanted soft-deleted object, so throw an exception if this one is soft-deleted.
101 if (currentState.equalsIgnoreCase(WorkflowClient.WORKFLOWSTATE_DELETED)) {
102 String msg = "GET assertion that docModel not be in 'deleted' workflow state failed.";
104 throw new DocumentNotFoundException(msg);
111 * Sets the collection space core values.
114 * @param documentModel the document model
115 * @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
117 private void setCollectionSpaceCoreValues(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
118 DocumentModel documentModel,
119 Action action) throws ClientException {
121 // Add the CSID to the DublinCore title so we can see the CSID in the default
125 documentModel.setProperty("dublincore",
127 documentModel.getName());
128 } catch (Exception x) {
129 if (logger.isWarnEnabled() == true) {
130 logger.warn("Could not set the Dublin Core 'title' field on document CSID:" +
131 documentModel.getName());
135 // Add the tenant ID value to the new entity
137 documentModel.setProperty(DocumentModelHandler.COLLECTIONSPACE_CORE_SCHEMA,
138 DocumentModelHandler.COLLECTIONSPACE_CORE_TENANTID,
141 String now = GregorianCalendarDateTimeUtils.timestampUTC();
145 documentModel.setProperty(DocumentModelHandler.COLLECTIONSPACE_CORE_SCHEMA,
146 DocumentModelHandler.COLLECTIONSPACE_CORE_CREATED_AT,
148 documentModel.setProperty(DocumentModelHandler.COLLECTIONSPACE_CORE_SCHEMA,
149 DocumentModelHandler.COLLECTIONSPACE_CORE_UPDATED_AT,
153 documentModel.setProperty(DocumentModelHandler.COLLECTIONSPACE_CORE_SCHEMA,
154 DocumentModelHandler.COLLECTIONSPACE_CORE_UPDATED_AT,
163 * create document in the Nuxeo repository
165 * @param ctx service context under which this method is invoked
167 * should be used by the caller to provide and transform the
169 * @return id in repository of the newly created document
170 * @throws DocumentException
173 public String create(ServiceContext ctx,
174 DocumentHandler handler) throws BadRequestException,
177 if (ctx.getDocumentType() == null) {
178 throw new IllegalArgumentException(
179 "RepositoryJavaClient.create: docType is missing");
181 if (handler == null) {
182 throw new IllegalArgumentException(
183 "RepositoryJavaClient.create: handler is missing");
185 String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
186 if (nuxeoWspaceId == null) {
187 throw new DocumentNotFoundException(
188 "Unable to find workspace for service " + ctx.getServiceName()
189 + " check if the workspace exists in the Nuxeo repository");
191 RepositoryInstance repoSession = null;
193 handler.prepare(Action.CREATE);
194 repoSession = getRepositorySession();
195 DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId);
196 DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace);
197 String wspacePath = wspaceDoc.getPathAsString();
198 //give our own ID so PathRef could be constructed later on
199 String id = IdUtils.generateId(UUID.randomUUID().toString());
200 // create document model
201 DocumentModel doc = repoSession.createDocumentModel(wspacePath, id,
202 ctx.getDocumentType());
203 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
204 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
205 handler.handle(Action.CREATE, wrapDoc);
206 // create document with documentmodel
207 setCollectionSpaceCoreValues(ctx, doc, Action.CREATE);
208 doc = repoSession.createDocument(doc);
210 // TODO for sub-docs need to call into the handler to let it deal with subitems. Pass in the id,
211 // and assume the handler has the state it needs (doc fragments).
212 handler.complete(Action.CREATE, wrapDoc);
214 } catch (BadRequestException bre) {
216 } catch (Exception e) {
217 if (logger.isDebugEnabled()) {
218 logger.debug("Caught exception ", e);
220 throw new DocumentException(e);
222 if (repoSession != null) {
223 releaseRepositorySession(repoSession);
230 * get document from the Nuxeo repository
231 * @param ctx service context under which this method is invoked
233 * of the document to retrieve
235 * should be used by the caller to provide and transform the
237 * @throws DocumentException
240 public void get(ServiceContext ctx, String id, DocumentHandler handler)
241 throws DocumentNotFoundException, DocumentException {
243 if (handler == null) {
244 throw new IllegalArgumentException(
245 "RepositoryJavaClient.get: handler is missing");
247 RepositoryInstance repoSession = null;
250 handler.prepare(Action.GET);
251 repoSession = getRepositorySession();
252 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
253 DocumentModel docModel = null;
255 docModel = repoSession.getDocument(docRef);
256 assertWorkflowState(ctx, docModel);
257 } catch (ClientException ce) {
258 String msg = "Could not find document with id=" + id;
259 logger.error(msg, ce);
260 throw new DocumentNotFoundException(msg, ce);
262 //set reposession to handle the document
263 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
264 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(docModel);
265 handler.handle(Action.GET, wrapDoc);
266 handler.complete(Action.GET, wrapDoc);
267 } catch (IllegalArgumentException iae) {
269 } catch (DocumentException de) {
271 } catch (Exception e) {
272 if (logger.isDebugEnabled()) {
273 logger.debug("Caught exception ", e);
275 throw new DocumentException(e);
277 if (repoSession != null) {
278 releaseRepositorySession(repoSession);
284 * get document from the Nuxeo repository, using the docFilter params.
285 * @param ctx service context under which this method is invoked
287 * should be used by the caller to provide and transform the
288 * document. Handler must have a docFilter set to return a single item.
289 * @throws DocumentException
292 public void get(ServiceContext ctx, DocumentHandler handler)
293 throws DocumentNotFoundException, DocumentException {
294 QueryContext queryContext = new QueryContext(ctx, handler);
295 RepositoryInstance repoSession = null;
298 handler.prepare(Action.GET);
299 repoSession = getRepositorySession();
301 DocumentModelList docList = null;
302 // force limit to 1, and ignore totalSize
303 String query = NuxeoUtils.buildNXQLQuery(queryContext);
304 docList = repoSession.query(query, null, 1, 0, false);
305 if (docList.size() != 1) {
306 throw new DocumentNotFoundException("No document found matching filter params.");
308 DocumentModel doc = docList.get(0);
310 if (logger.isDebugEnabled()) {
311 logger.debug("Executed NXQL query: " + query);
314 //set reposession to handle the document
315 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
316 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
317 handler.handle(Action.GET, wrapDoc);
318 handler.complete(Action.GET, wrapDoc);
319 } catch (IllegalArgumentException iae) {
321 } catch (DocumentException de) {
323 } catch (Exception e) {
324 if (logger.isDebugEnabled()) {
325 logger.debug("Caught exception ", e);
327 throw new DocumentException(e);
329 if (repoSession != null) {
330 releaseRepositorySession(repoSession);
336 * Get wrapped documentModel from the Nuxeo repository. The search is restricted to the workspace
337 * of the current context.
339 * @param ctx service context under which this method is invoked
341 * of the document to retrieve
342 * @throws DocumentException
345 public DocumentWrapper<DocumentModel> getDoc(
346 ServiceContext ctx, String csid)
347 throws DocumentNotFoundException, DocumentException {
348 RepositoryInstance repoSession = null;
349 DocumentWrapper<DocumentModel> wrapDoc = null;
352 repoSession = getRepositorySession();
353 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, csid);
354 DocumentModel doc = null;
356 doc = repoSession.getDocument(docRef);
357 } catch (ClientException ce) {
358 String msg = "could not find document with id=" + csid;
359 logger.error(msg, ce);
360 throw new DocumentNotFoundException(msg, ce);
362 wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
363 } catch (IllegalArgumentException iae) {
365 } catch (DocumentException de) {
367 } catch (Exception e) {
368 if (logger.isDebugEnabled()) {
369 logger.debug("Caught exception ", e);
371 throw new DocumentException(e);
373 if (repoSession != null) {
374 releaseRepositorySession(repoSession);
381 * find wrapped documentModel from the Nuxeo repository
382 * @param ctx service context under which this method is invoked
383 * @param whereClause where NXQL where clause to get the document
384 * @throws DocumentException
387 public DocumentWrapper<DocumentModel> findDoc(
388 ServiceContext ctx, String whereClause)
389 throws DocumentNotFoundException, DocumentException {
390 RepositoryInstance repoSession = null;
391 DocumentWrapper<DocumentModel> wrapDoc = null;
394 QueryContext queryContext = new QueryContext(ctx, whereClause);
395 repoSession = getRepositorySession();
396 DocumentModelList docList = null;
397 // force limit to 1, and ignore totalSize
398 String query = NuxeoUtils.buildNXQLQuery(queryContext);
399 docList = repoSession.query(query,
404 if (docList.size() != 1) {
405 if (logger.isDebugEnabled()) {
406 logger.debug("findDoc: Query found: " + docList.size() + " items.");
407 logger.debug(" Query: " + query);
409 throw new DocumentNotFoundException("No document found matching filter params.");
411 DocumentModel doc = docList.get(0);
412 wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
413 } catch (IllegalArgumentException iae) {
415 } catch (DocumentException de) {
417 } catch (Exception e) {
418 if (logger.isDebugEnabled()) {
419 logger.debug("Caught exception ", e);
421 throw new DocumentException(e);
423 if (repoSession != null) {
424 releaseRepositorySession(repoSession);
431 * find doc and return CSID from the Nuxeo repository
432 * @param ctx service context under which this method is invoked
433 * @param whereClause where NXQL where clause to get the document
434 * @throws DocumentException
437 public String findDocCSID(
438 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String whereClause)
439 throws DocumentNotFoundException, DocumentException {
442 DocumentWrapper<DocumentModel> wrapDoc = findDoc(ctx, whereClause);
443 DocumentModel docModel = wrapDoc.getWrappedObject();
444 csid = NuxeoUtils.getCsid(docModel);//NuxeoUtils.extractId(docModel.getPathAsString());
445 } catch (DocumentNotFoundException dnfe) {
447 } catch (IllegalArgumentException iae) {
449 } catch (DocumentException de) {
451 } catch (Exception e) {
452 if (logger.isDebugEnabled()) {
453 logger.debug("Caught exception ", e);
455 throw new DocumentException(e);
461 * Find a list of documentModels from the Nuxeo repository
462 * @param docTypes a list of DocType names to match
463 * @param whereClause where the clause to qualify on
467 public DocumentWrapper<DocumentModelList> findDocs(
468 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
469 List<String> docTypes,
471 int pageSize, int pageNum, boolean computeTotal)
472 throws DocumentNotFoundException, DocumentException {
473 RepositoryInstance repoSession = null;
474 DocumentWrapper<DocumentModelList> wrapDoc = null;
477 if (docTypes == null || docTypes.size() < 1) {
478 throw new DocumentNotFoundException(
479 "findDocs must specify at least one DocumentType.");
481 repoSession = getRepositorySession();
482 DocumentModelList docList = null;
483 // force limit to 1, and ignore totalSize
484 QueryContext queryContext = new QueryContext(ctx, whereClause);
485 String query = NuxeoUtils.buildNXQLQuery(docTypes, queryContext);
486 docList = repoSession.query(query, null, pageSize, pageNum, computeTotal);
487 wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
488 } catch (IllegalArgumentException iae) {
490 } catch (Exception e) {
491 if (logger.isDebugEnabled()) {
492 logger.debug("Caught exception ", e);
494 throw new DocumentException(e);
496 if (repoSession != null) {
497 releaseRepositorySession(repoSession);
504 * @see org.collectionspace.services.common.storage.StorageClient#get(org.collectionspace.services.common.context.ServiceContext, java.util.List, org.collectionspace.services.common.document.DocumentHandler)
507 public void get(ServiceContext ctx, List<String> csidList, DocumentHandler handler)
508 throws DocumentNotFoundException, DocumentException {
509 if (handler == null) {
510 throw new IllegalArgumentException(
511 "RepositoryJavaClient.getAll: handler is missing");
514 RepositoryInstance repoSession = null;
517 handler.prepare(Action.GET_ALL);
518 repoSession = getRepositorySession();
519 DocumentModelList docModelList = new DocumentModelListImpl();
520 //FIXME: Should be using NuxeoUtils.createPathRef for security reasons
521 for (String csid : csidList) {
522 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, csid);
523 DocumentModel docModel = repoSession.getDocument(docRef);
524 docModelList.add(docModel);
527 //set reposession to handle the document
528 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
529 DocumentWrapper<DocumentModelList> wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docModelList);
530 handler.handle(Action.GET_ALL, wrapDoc);
531 handler.complete(Action.GET_ALL, wrapDoc);
532 } catch (DocumentException de) {
534 } catch (Exception e) {
535 if (logger.isDebugEnabled()) {
536 logger.debug("Caught exception ", e);
538 throw new DocumentException(e);
540 if (repoSession != null) {
541 releaseRepositorySession(repoSession);
547 * getAll get all documents for an entity entity service from the Nuxeo
550 * @param ctx service context under which this method is invoked
552 * should be used by the caller to provide and transform the
554 * @throws DocumentException
557 public void getAll(ServiceContext ctx, DocumentHandler handler)
558 throws DocumentNotFoundException, DocumentException {
559 if (handler == null) {
560 throw new IllegalArgumentException(
561 "RepositoryJavaClient.getAll: handler is missing");
563 String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();
564 if (nuxeoWspaceId == null) {
565 throw new DocumentNotFoundException(
566 "Unable to find workspace for service "
567 + ctx.getServiceName()
568 + " check if the workspace exists in the Nuxeo repository");
570 RepositoryInstance repoSession = null;
573 handler.prepare(Action.GET_ALL);
574 repoSession = getRepositorySession();
575 DocumentRef wsDocRef = new IdRef(nuxeoWspaceId);
576 DocumentModelList docList = repoSession.getChildren(wsDocRef);
577 //set reposession to handle the document
578 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
579 DocumentWrapper<DocumentModelList> wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
580 handler.handle(Action.GET_ALL, wrapDoc);
581 handler.complete(Action.GET_ALL, wrapDoc);
582 } catch (DocumentException de) {
584 } catch (Exception e) {
585 if (logger.isDebugEnabled()) {
586 logger.debug("Caught exception ", e);
588 throw new DocumentException(e);
590 if (repoSession != null) {
591 releaseRepositorySession(repoSession);
596 private boolean isClauseEmpty(String theString) {
597 boolean result = true;
598 if (theString != null && !theString.isEmpty()) {
605 * A method to find a CollectionSpace document (of any type) given just a service context and
606 * its CSID. A search across *all* service workspaces (within a given tenant context) is performed to find
609 * This query searches Nuxeo's Hierarchy table where our CSIDs are stored in the "name" column.
612 public DocumentWrapper<DocumentModel> getDocFromCsid(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
615 DocumentWrapper<DocumentModel> result = null;
616 RepositoryInstance repoSession = getRepositorySession();
618 result = new DocumentWrapperImpl(NuxeoUtils.getDocFromCsid(repoSession, ctx, csid));
620 if (repoSession != null) {
621 releaseRepositorySession(repoSession);
629 * getFiltered get all documents for an entity service from the Document repository,
630 * given filter parameters specified by the handler.
631 * @param ctx service context under which this method is invoked
632 * @param handler should be used by the caller to provide and transform the document
633 * @throws DocumentNotFoundException if workspace not found
634 * @throws DocumentException
637 public void getFiltered(ServiceContext ctx, DocumentHandler handler)
638 throws DocumentNotFoundException, DocumentException {
640 DocumentFilter filter = handler.getDocumentFilter();
641 String oldOrderBy = filter.getOrderByClause();
642 if (isClauseEmpty(oldOrderBy) == true){
643 filter.setOrderByClause(DocumentFilter.ORDER_BY_LAST_UPDATED); //per http://issues.collectionspace.org/browse/CSPACE-705
645 QueryContext queryContext = new QueryContext(ctx, handler);
646 RepositoryInstance repoSession = null;
648 handler.prepare(Action.GET_ALL);
649 repoSession = getRepositorySession();
650 DocumentModelList docList = null;
651 String query = NuxeoUtils.buildNXQLQuery(queryContext);
653 if (logger.isDebugEnabled()) {
654 logger.debug("Executing NXQL query: " + query.toString());
657 // If we have limit and/or offset, then pass true to get totalSize
658 // in returned DocumentModelList.
659 Profiler profiler = new Profiler(this, 2);
660 profiler.log("Executing NXQL query: " + query.toString());
662 if ((queryContext.getDocFilter().getOffset() > 0) || (queryContext.getDocFilter().getPageSize() > 0)) {
663 docList = repoSession.query(query, null,
664 queryContext.getDocFilter().getPageSize(), queryContext.getDocFilter().getOffset(), true);
666 docList = repoSession.query(query);
670 //set repoSession to handle the document
671 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
672 DocumentWrapper<DocumentModelList> wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
673 handler.handle(Action.GET_ALL, wrapDoc);
674 handler.complete(Action.GET_ALL, wrapDoc);
675 } catch (DocumentException de) {
677 } catch (Exception e) {
678 if (logger.isDebugEnabled()) {
679 logger.debug("Caught exception ", e);
681 throw new DocumentException(e);
683 if (repoSession != null) {
684 releaseRepositorySession(repoSession);
690 * update given document in the Nuxeo repository
692 * @param ctx service context under which this method is invoked
696 * should be used by the caller to provide and transform the
698 * @throws DocumentException
701 public void update(ServiceContext ctx, String id, DocumentHandler handler)
702 throws BadRequestException, DocumentNotFoundException,
704 if (handler == null) {
705 throw new IllegalArgumentException(
706 "RepositoryJavaClient.update: handler is missing");
708 RepositoryInstance repoSession = null;
710 handler.prepare(Action.UPDATE);
711 repoSession = getRepositorySession();
712 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
713 DocumentModel doc = null;
715 doc = repoSession.getDocument(docRef);
716 } catch (ClientException ce) {
717 String msg = "Could not find document to update with id=" + id;
718 logger.error(msg, ce);
719 throw new DocumentNotFoundException(msg, ce);
721 //set reposession to handle the document
722 ((DocumentModelHandler) handler).setRepositorySession(repoSession);
723 DocumentWrapper<DocumentModel> wrapDoc = new DocumentWrapperImpl<DocumentModel>(doc);
724 handler.handle(Action.UPDATE, wrapDoc);
725 setCollectionSpaceCoreValues(ctx, doc, Action.UPDATE);
726 repoSession.saveDocument(doc);
728 handler.complete(Action.UPDATE, wrapDoc);
729 } catch (BadRequestException bre) {
731 } catch (DocumentException de) {
733 } catch (Exception e) {
734 if (logger.isDebugEnabled()) {
735 logger.debug("Caught exception ", e);
737 throw new DocumentException(e);
739 if (repoSession != null) {
740 releaseRepositorySession(repoSession);
746 * delete a document from the Nuxeo repository
747 * @param ctx service context under which this method is invoked
750 * @throws DocumentException
753 public void delete(ServiceContext ctx, String id) throws DocumentNotFoundException,
756 if (logger.isDebugEnabled()) {
757 logger.debug("deleting document with id=" + id);
759 RepositoryInstance repoSession = null;
761 repoSession = getRepositorySession();
762 DocumentRef docRef = NuxeoUtils.createPathRef(ctx, id);
764 repoSession.removeDocument(docRef);
765 } catch (ClientException ce) {
766 String msg = "could not find document to delete with id=" + id;
767 logger.error(msg, ce);
768 throw new DocumentNotFoundException(msg, ce);
771 } catch (DocumentException de) {
773 } catch (Exception e) {
774 if (logger.isDebugEnabled()) {
775 logger.debug("Caught exception ", e);
777 throw new DocumentException(e);
779 if (repoSession != null) {
780 releaseRepositorySession(repoSession);
786 * @see org.collectionspace.services.common.storage.StorageClient#delete(org.collectionspace.services.common.context.ServiceContext, java.lang.String, org.collectionspace.services.common.document.DocumentHandler)
789 public void delete(ServiceContext ctx, String id, DocumentHandler handler)
790 throws DocumentNotFoundException, DocumentException {
791 throw new UnsupportedOperationException();
795 public Hashtable<String, String> retrieveWorkspaceIds(String domainName) throws Exception {
796 return NuxeoConnector.getInstance().retrieveWorkspaceIds(domainName);
800 public String createDomain(String domainName) throws Exception {
801 RepositoryInstance repoSession = null;
802 String domainId = null;
804 repoSession = getRepositorySession();
805 DocumentRef parentDocRef = new PathRef("/");
806 DocumentModel parentDoc = repoSession.getDocument(parentDocRef);
807 DocumentModel doc = repoSession.createDocumentModel(parentDoc.getPathAsString(),
808 domainName, "Domain");
809 doc.setPropertyValue("dc:title", domainName);
810 doc.setPropertyValue("dc:description", "A CollectionSpace domain "
812 doc = repoSession.createDocument(doc);
813 domainId = doc.getId();
815 if (logger.isDebugEnabled()) {
816 logger.debug("created tenant domain name=" + domainName
817 + " id=" + domainId);
819 } catch (Exception e) {
820 if (logger.isDebugEnabled()) {
821 logger.debug("createTenantSpace caught exception ", e);
825 if (repoSession != null) {
826 releaseRepositorySession(repoSession);
833 public String getDomainId(String domainName) throws Exception {
834 String domainId = null;
835 RepositoryInstance repoSession = null;
837 repoSession = getRepositorySession();
838 DocumentRef docRef = new PathRef(
840 DocumentModel domain = repoSession.getDocument(docRef);
841 domainId = domain.getId();
842 } catch (Exception e) {
843 if (logger.isDebugEnabled()) {
844 logger.debug("Caught exception ", e);
846 //there is no way to identify if document does not exist due to
847 //lack of typed exception for getDocument method
850 if (repoSession != null) {
851 releaseRepositorySession(repoSession);
858 * @see org.collectionspace.services.common.repository.RepositoryClient#createWorkspace(java.lang.String, java.lang.String)
861 public String createWorkspace(String domainName, String workspaceName) throws Exception {
862 RepositoryInstance repoSession = null;
863 String workspaceId = null;
865 repoSession = getRepositorySession();
866 DocumentRef parentDocRef = new PathRef(
868 + "/" + "workspaces");
869 DocumentModel parentDoc = repoSession.getDocument(parentDocRef);
870 DocumentModel doc = repoSession.createDocumentModel(parentDoc.getPathAsString(),
871 workspaceName, "Workspace");
872 doc.setPropertyValue("dc:title", workspaceName);
873 doc.setPropertyValue("dc:description", "A CollectionSpace workspace for "
875 doc = repoSession.createDocument(doc);
876 workspaceId = doc.getId();
878 if (logger.isDebugEnabled()) {
879 logger.debug("created workspace name=" + workspaceName
880 + " id=" + workspaceId);
882 } catch (Exception e) {
883 if (logger.isDebugEnabled()) {
884 logger.debug("createWorkspace caught exception ", e);
888 if (repoSession != null) {
889 releaseRepositorySession(repoSession);
896 * @see org.collectionspace.services.common.repository.RepositoryClient#getWorkspaceId(java.lang.String, java.lang.String)
899 public String getWorkspaceId(String tenantDomain, String workspaceName) throws Exception {
900 String workspaceId = null;
901 RepositoryInstance repoSession = null;
903 repoSession = getRepositorySession();
904 DocumentRef docRef = new PathRef(
907 + "/" + workspaceName);
908 DocumentModel workspace = repoSession.getDocument(docRef);
909 workspaceId = workspace.getId();
910 } catch (DocumentException de) {
912 } catch (Exception e) {
913 if (logger.isDebugEnabled()) {
914 logger.debug("Caught exception ", e);
916 throw new DocumentException(e);
918 if (repoSession != null) {
919 releaseRepositorySession(repoSession);
927 * Gets the repository session.
929 * @return the repository session
930 * @throws Exception the exception
932 private RepositoryInstance getRepositorySession() throws Exception {
933 // FIXME: is it possible to reuse repository session?
934 // Authentication failures happen while trying to reuse the session
935 Profiler profiler = new Profiler("getRepositorySession():", 2);
937 NuxeoClient client = NuxeoConnector.getInstance().getClient();
938 RepositoryInstance repoSession = client.openRepository();
939 if (logger.isTraceEnabled()) {
940 logger.debug("getRepository() repository root: " + repoSession.getRootDocument());
947 * Release repository session.
949 * @param repoSession the repo session
951 private void releaseRepositorySession(RepositoryInstance repoSession) {
953 NuxeoClient client = NuxeoConnector.getInstance().getClient();
955 client.releaseRepository(repoSession);
956 } catch (Exception e) {
957 logger.error("Could not close the repository session", e);
958 // no need to throw this service specific exception