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 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
24 package org.collectionspace.services.nuxeo.client.java;
26 import java.util.Collection;
27 import java.util.List;
29 import org.collectionspace.services.client.PoxPayloadIn;
30 import org.collectionspace.services.client.PoxPayloadOut;
31 import org.collectionspace.services.common.authorityref.AuthorityRefList;
32 import org.collectionspace.services.common.context.ServiceContext;
33 import org.collectionspace.services.common.datetime.GregorianCalendarDateTimeUtils;
34 import org.collectionspace.services.common.document.AbstractMultipartDocumentHandlerImpl;
35 import org.collectionspace.services.common.document.DocumentFilter;
36 import org.collectionspace.services.common.document.DocumentWrapper;
37 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
38 import org.collectionspace.services.common.profile.Profiler;
39 import org.collectionspace.services.common.repository.RepositoryClient;
40 import org.collectionspace.services.common.repository.RepositoryClientFactory;
41 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.AuthRefConfigInfo;
42 import org.collectionspace.services.lifecycle.Lifecycle;
43 import org.collectionspace.services.lifecycle.State;
44 import org.collectionspace.services.lifecycle.StateList;
45 import org.collectionspace.services.lifecycle.TransitionDef;
46 import org.collectionspace.services.lifecycle.TransitionDefList;
47 import org.collectionspace.services.lifecycle.TransitionList;
49 import org.nuxeo.ecm.core.NXCore;
50 import org.nuxeo.ecm.core.api.ClientException;
51 import org.nuxeo.ecm.core.api.DocumentModel;
52 import org.nuxeo.ecm.core.api.DocumentModelList;
53 import org.nuxeo.ecm.core.api.model.PropertyException;
54 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
55 import org.nuxeo.ecm.core.lifecycle.LifeCycleService;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
61 * DocumentModelHandler is a base abstract Nuxeo document handler
62 * using Nuxeo Java Remote APIs for CollectionSpace services
64 * $LastChangedRevision: $
67 public abstract class DocumentModelHandler<T, TL>
68 extends AbstractMultipartDocumentHandlerImpl<T, TL, DocumentModel, DocumentModelList> {
70 private final Logger logger = LoggerFactory.getLogger(DocumentModelHandler.class);
71 private RepositoryInstance repositorySession;
72 //key=schema, value=documentpart
74 public final static String COLLECTIONSPACE_CORE_SCHEMA = "collectionspace_core";
75 public final static String COLLECTIONSPACE_CORE_TENANTID = "tenantId";
76 public final static String COLLECTIONSPACE_CORE_URI = "uri";
77 public final static String COLLECTIONSPACE_CORE_CREATED_AT = "createdAt";
78 public final static String COLLECTIONSPACE_CORE_UPDATED_AT = "updatedAt";
79 public final static String COLLECTIONSPACE_CORE_CREATED_BY = "createdBy";
80 public final static String COLLECTIONSPACE_CORE_UPDATED_BY = "updatedBy";
81 public final static String COLLECTIONSPACE_CORE_WORKFLOWSTATE = "workflowState";
84 * Map Nuxeo's life cycle object to our JAX-B based life cycle object
86 private Lifecycle createCollectionSpaceLifecycle(org.nuxeo.ecm.core.lifecycle.LifeCycle nuxeoLifecyle) {
87 Lifecycle result = null;
89 if (nuxeoLifecyle != null) {
91 // Copy the life cycle's name
92 result = new Lifecycle();
93 result.setName(nuxeoLifecyle.getName());
95 // We currently support only one initial state, so take the first one from Nuxeo
96 Collection<String> initialStateNames = nuxeoLifecyle.getInitialStateNames();
97 result.setDefaultInitial(initialStateNames.iterator().next());
99 // Next, we copy the state and corresponding transition lists
100 StateList stateList = new StateList();
101 List<State> states = stateList.getState();
102 Collection<org.nuxeo.ecm.core.lifecycle.LifeCycleState> nuxeoStates = nuxeoLifecyle.getStates();
103 for (org.nuxeo.ecm.core.lifecycle.LifeCycleState nuxeoState : nuxeoStates) {
104 State tempState = new State();
105 tempState.setDescription(nuxeoState.getDescription());
106 tempState.setInitial(nuxeoState.isInitial());
107 tempState.setName(nuxeoState.getName());
108 // Now get the list of transitions
109 TransitionList transitionList = new TransitionList();
110 List<String> transitions = transitionList.getTransition();
111 Collection<String> nuxeoTransitions = nuxeoState.getAllowedStateTransitions();
112 for (String nuxeoTransition : nuxeoTransitions) {
113 transitions.add(nuxeoTransition);
115 tempState.setTransitionList(transitionList);
116 states.add(tempState);
118 result.setStateList(stateList);
120 // Finally, we create the transition definitions
121 TransitionDefList transitionDefList = new TransitionDefList();
122 List<TransitionDef> transitionDefs = transitionDefList.getTransitionDef();
123 Collection<org.nuxeo.ecm.core.lifecycle.LifeCycleTransition> nuxeoTransitionDefs = nuxeoLifecyle.getTransitions();
124 for (org.nuxeo.ecm.core.lifecycle.LifeCycleTransition nuxeoTransitionDef : nuxeoTransitionDefs) {
125 TransitionDef tempTransitionDef = new TransitionDef();
126 tempTransitionDef.setDescription(nuxeoTransitionDef.getDescription());
127 tempTransitionDef.setDestinationState(nuxeoTransitionDef.getDestinationStateName());
128 tempTransitionDef.setName(nuxeoTransitionDef.getName());
129 transitionDefs.add(tempTransitionDef);
131 result.setTransitionDefList(transitionDefList);
138 * Returns the the life cycle definition of the related Nuxeo document type for this handler.
140 * @see org.collectionspace.services.common.document.DocumentHandler#getLifecycle()
143 public Lifecycle getLifecycle() {
144 Lifecycle result = null;
146 String docTypeName = null;
148 docTypeName = this.getServiceContext().getDocumentType();
149 result = getLifecycle(docTypeName);
150 } catch (Exception e) {
151 if (logger.isTraceEnabled() == true) {
152 logger.trace("Could not retrieve lifecycle definition for Nuxeo doctype: " + docTypeName);
160 * Returns the the life cycle definition of the related Nuxeo document type for this handler.
162 * @see org.collectionspace.services.common.document.DocumentHandler#getLifecycle(java.lang.String)
165 public Lifecycle getLifecycle(String docTypeName) {
166 org.nuxeo.ecm.core.lifecycle.LifeCycle nuxeoLifecyle;
167 Lifecycle result = null;
170 LifeCycleService lifeCycleService = null;
172 lifeCycleService = NXCore.getLifeCycleService();
173 } catch (Exception e) {
177 String lifeCycleName;
178 lifeCycleName = lifeCycleService.getLifeCycleNameFor(docTypeName);
179 nuxeoLifecyle = lifeCycleService.getLifeCycleByName(lifeCycleName);
181 result = createCollectionSpaceLifecycle(nuxeoLifecyle);
182 // result = (Lifecycle)FileTools.getJaxbObjectFromFile(Lifecycle.class, "default-lifecycle.xml");
183 } catch (Exception e) {
184 // TODO Auto-generated catch block
185 logger.error("Could not retreive life cycle information for Nuxeo doctype: " + docTypeName, e);
192 * We're using the "name" field of Nuxeo's DocumentModel to store
195 public String getCsid(DocumentModel docModel) {
196 return NuxeoUtils.getCsid(docModel);
199 public String getUri(DocumentModel docModel) {
200 return getServiceContextPath()+getCsid(docModel);
203 public RepositoryClient<PoxPayloadIn, PoxPayloadOut> getRepositoryClient(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx) {
204 RepositoryClient<PoxPayloadIn, PoxPayloadOut> repositoryClient = RepositoryClientFactory.getInstance().getClient(ctx.getRepositoryClientName());
205 return repositoryClient;
209 * getRepositorySession returns Nuxeo Repository Session
212 public RepositoryInstance getRepositorySession() {
214 return repositorySession;
218 * setRepositorySession sets repository session
221 public void setRepositorySession(RepositoryInstance repoSession) {
222 this.repositorySession = repoSession;
226 public void handleCreate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
227 // TODO for sub-docs - check to see if the current service context is a multipart input,
228 // OR a docfragment, and call a variant to fill the DocModel.
229 fillAllParts(wrapDoc, Action.CREATE);
230 handleCoreValues(wrapDoc, Action.CREATE);
233 // TODO for sub-docs - Add completeCreate in which we look for set-aside doc fragments
234 // and create the subitems. We will create service contexts with the doc fragments
239 public void handleUpdate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
240 // TODO for sub-docs - check to see if the current service context is a multipart input,
241 // OR a docfragment, and call a variant to fill the DocModel.
242 fillAllParts(wrapDoc, Action.UPDATE);
243 handleCoreValues(wrapDoc, Action.UPDATE);
247 public void handleGet(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
248 extractAllParts(wrapDoc);
252 public void handleGetAll(DocumentWrapper<DocumentModelList> wrapDoc) throws Exception {
253 Profiler profiler = new Profiler(this, 2);
255 setCommonPartList(extractCommonPartList(wrapDoc));
260 public abstract void completeUpdate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception;
263 public abstract void extractAllParts(DocumentWrapper<DocumentModel> wrapDoc) throws Exception;
266 public abstract T extractCommonPart(DocumentWrapper<DocumentModel> wrapDoc) throws Exception;
269 public abstract void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc, Action action) throws Exception;
272 public abstract void fillCommonPart(T obj, DocumentWrapper<DocumentModel> wrapDoc) throws Exception;
275 public abstract TL extractCommonPartList(DocumentWrapper<DocumentModelList> wrapDoc) throws Exception;
278 public abstract T getCommonPart();
281 public abstract void setCommonPart(T obj);
284 public abstract TL getCommonPartList();
287 public abstract void setCommonPartList(TL obj);
290 public DocumentFilter createDocumentFilter() {
291 DocumentFilter filter = new NuxeoDocumentFilter(this.getServiceContext());
296 * Gets the authority refs.
298 * @param docWrapper the doc wrapper
299 * @param authRefFields the auth ref fields
300 * @return the authority refs
301 * @throws PropertyException the property exception
303 abstract public AuthorityRefList getAuthorityRefs(String csid,
304 List<AuthRefConfigInfo> authRefsInfo) throws PropertyException;
306 private void handleCoreValues(DocumentWrapper<DocumentModel> docWrapper,
307 Action action) throws ClientException {
308 DocumentModel documentModel = docWrapper.getWrappedObject();
309 String now = GregorianCalendarDateTimeUtils.timestampUTC();
310 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = getServiceContext();
311 String userId = ctx.getUserId();
312 if(action==Action.CREATE) {
314 // Add the tenant ID value to the new entity
316 String tenantId = ctx.getTenantId();
317 documentModel.setProperty(COLLECTIONSPACE_CORE_SCHEMA,
318 COLLECTIONSPACE_CORE_TENANTID, tenantId);
320 // Add the uri value to the new entity
322 documentModel.setProperty(COLLECTIONSPACE_CORE_SCHEMA,
323 COLLECTIONSPACE_CORE_URI, getUri(documentModel));
325 // Add the CSID to the DublinCore title so we can see the CSID in the default
329 documentModel.setProperty("dublincore", "title",
330 documentModel.getName());
331 } catch (Exception x) {
332 if (logger.isWarnEnabled() == true) {
333 logger.warn("Could not set the Dublin Core 'title' field on document CSID:" +
334 documentModel.getName());
337 documentModel.setProperty(COLLECTIONSPACE_CORE_SCHEMA,
338 COLLECTIONSPACE_CORE_CREATED_AT, now);
339 documentModel.setProperty(COLLECTIONSPACE_CORE_SCHEMA,
340 COLLECTIONSPACE_CORE_CREATED_BY, userId);
342 if(action==Action.CREATE || action==Action.UPDATE) {
343 documentModel.setProperty(COLLECTIONSPACE_CORE_SCHEMA,
344 COLLECTIONSPACE_CORE_UPDATED_AT, now);
345 documentModel.setProperty(COLLECTIONSPACE_CORE_SCHEMA,
346 COLLECTIONSPACE_CORE_UPDATED_BY, userId);