]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
57948fcade94b7e4653d0fc67c447fe866762138
[tmp/jakarta-migration.git] /
1 /**     
2  * AbstractMultiPartCollectionSpaceResourceImpl.java
3  *
4  * {Purpose of This Class}
5  *
6  * {Other Notes Relating to This Class (Optional)}
7  *
8  * $LastChangedBy: $
9  * $LastChangedRevision: $
10  * $LastChangedDate: $
11  *
12  * This document is a part of the source code and related artifacts
13  * for CollectionSpace, an open source collections management system
14  * for museums and related institutions:
15  *
16  * http://www.collectionspace.org
17  * http://wiki.collectionspace.org
18  *
19  * Copyright © 2009 {Contributing Institution}
20  *
21  * Licensed under the Educational Community License (ECL), Version 2.0.
22  * You may not use this file except in compliance with this License.
23  *
24  * You may obtain a copy of the ECL 2.0 License at
25  * https://source.collectionspace.org/collection-space/LICENSE.txt
26  */
27 package org.collectionspace.services.common;
28
29 import java.util.Iterator;
30 import java.util.List;
31
32 import javax.ws.rs.GET;
33 import javax.ws.rs.PUT;
34 import javax.ws.rs.Path;
35 import javax.ws.rs.PathParam;
36 import javax.ws.rs.core.Context;
37 import javax.ws.rs.core.Request;
38 import javax.ws.rs.core.UriInfo;
39
40 import org.collectionspace.services.client.PayloadOutputPart;
41 import org.collectionspace.services.client.PoxPayloadIn;
42 import org.collectionspace.services.client.PoxPayloadOut;
43 import org.collectionspace.services.client.workflow.WorkflowClient;
44 import org.collectionspace.services.common.context.MultipartServiceContext;
45 import org.collectionspace.services.common.context.MultipartServiceContextFactory;
46 import org.collectionspace.services.common.context.MultipartServiceContextImpl;
47 import org.collectionspace.services.common.context.ServiceContext;
48 import org.collectionspace.services.common.context.ServiceContextFactory;
49 import org.collectionspace.services.common.document.DocumentHandler;
50 import org.collectionspace.services.common.workflow.service.nuxeo.WorkflowDocumentModelHandler;
51 import org.collectionspace.services.lifecycle.Lifecycle;
52 import org.collectionspace.services.lifecycle.TransitionDef;
53 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
54 import org.collectionspace.services.workflow.WorkflowCommon;
55 import org.dom4j.DocumentException;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59 /**
60  * The Class AbstractMultiPartCollectionSpaceResourceImpl.
61  */
62 public abstract class AbstractMultiPartCollectionSpaceResourceImpl extends AbstractCollectionSpaceResourceImpl<PoxPayloadIn, PoxPayloadOut> {
63
64     protected final Logger logger = LoggerFactory.getLogger(this.getClass());
65
66     @Override
67     public ServiceContextFactory<PoxPayloadIn, PoxPayloadOut> getServiceContextFactory() {
68         return MultipartServiceContextFactory.get();
69     }
70     
71     abstract protected String getOrderByField(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx);    
72
73         abstract protected String getPartialTermMatchField(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx);
74     
75     @Override
76     public DocumentHandler createDocumentHandler(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx) throws Exception {
77         return createDocumentHandler(ctx, ctx.getCommonPartLabel(), getCommonPartClass());
78     }
79
80     /**
81      * Creates the document handler.
82      * 
83      * @param serviceContext the service context
84      * @param schemaName the schema name
85      * @param commonClass the common class
86      * 
87      * @return the document handler
88      * 
89      * @throws Exception the exception
90      */
91     public DocumentHandler createDocumentHandler(ServiceContext<PoxPayloadIn, PoxPayloadOut> serviceContext,
92             String schemaName,
93             Class<?> commonClass) throws Exception {
94         DocumentHandler result = null;
95
96         MultipartServiceContext ctx = (MultipartServiceContext) serviceContext;
97         Object commonPart = null;
98         if (ctx.getInput() != null) {
99             commonPart = ctx.getInputPart(schemaName);
100         }
101         result = super.createDocumentHandler(ctx, commonPart);
102
103         return result;
104     }
105
106     /**
107      * Creates the document handler.
108      * 
109      * @param ctx the ctx
110      * @param commonClass the common class
111      * 
112      * @return the document handler
113      * 
114      * @throws Exception the exception
115      */
116     public DocumentHandler createDocumentHandler(
117             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
118             Class<Object> commonClass) throws Exception {
119         return createDocumentHandler(ctx, ctx.getCommonPartLabel(), commonClass);
120     }
121
122     /**
123      * Creates the contact document handler.
124      * 
125      * @param ctx the ctx
126      * @param inAuthority the in authority
127      * @param inItem the in item
128      * 
129      * @return the document handler
130      * 
131      * @throws Exception the exception
132      */
133     protected WorkflowDocumentModelHandler createWorkflowDocumentHandler(
134             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx) throws Exception {
135
136         WorkflowDocumentModelHandler docHandler = (WorkflowDocumentModelHandler) createDocumentHandler(ctx,
137                 WorkflowClient.SERVICE_COMMONPART_NAME,
138                 WorkflowCommon.class);
139
140         return docHandler;
141     }
142     
143     /**
144      * Get the workflow lifecycle description of a resource
145      * @param uriInfo
146      * @return
147      */
148     @GET
149     @Path(WorkflowClient.SERVICE_PATH)
150     public Lifecycle getWorkflow(@Context Request jaxRsRequest, @Context UriInfo uriInfo) {
151         Lifecycle result;
152
153         String documentType = "undefined";
154         MultipartServiceContext ctx = null;
155         try {
156             ctx = (MultipartServiceContext) createServiceContext(uriInfo);
157             DocumentHandler handler = ctx.getDocumentHandler();
158             result = handler.getLifecycle();
159         } catch (Exception e) {
160             throw bigReThrow(e, ServiceMessages.READ_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, ctx.getDocumentType());
161         }
162
163         if (result == null) {
164                 result = new Lifecycle();
165                 result.setName("No life cycle defined for:" + documentType);
166         }
167         
168         return result;
169     }
170         
171     /*
172      * We should change this method.  The RepositoryClient (from call to getRepositoryClient) should support a call getWorkflowTransition() instead.
173      */    
174     @GET
175     @Path("{csid}" + WorkflowClient.SERVICE_PATH)
176     public byte[] getWorkflow(
177                 @Context UriInfo uriInfo,
178             @PathParam("csid") String csid) {
179         return getWorkflowWithExistingContext(null, uriInfo, csid);
180     }
181
182     public byte[] getWorkflowWithExistingContext(
183             ServiceContext<PoxPayloadIn, PoxPayloadOut> existingContext,
184             UriInfo uriInfo,
185             String csid) {
186         PoxPayloadOut result = null;
187
188         try {
189             ServiceContext<PoxPayloadIn, PoxPayloadOut> parentCtx = createServiceContext(uriInfo);
190             String parentWorkspaceName = parentCtx.getRepositoryWorkspaceName();
191
192             MultipartServiceContext ctx = (MultipartServiceContext) createServiceContext(WorkflowClient.SERVICE_NAME, uriInfo);
193             if (existingContext != null && existingContext.getCurrentRepositorySession() != null) {
194                 ctx.setCurrentRepositorySession(existingContext.getCurrentRepositorySession()); // Reuse the current repo session if one exists
195             }
196             WorkflowDocumentModelHandler handler = createWorkflowDocumentHandler(ctx);
197             ctx.setRespositoryWorkspaceName(parentWorkspaceName); //find the document in the parent's workspace
198             getRepositoryClient(ctx).get(ctx, csid, handler);
199             result = ctx.getOutput();
200         } catch (Exception e) {
201             throw bigReThrow(e, ServiceMessages.READ_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, csid);
202         }
203
204         return result.getBytes();
205     }
206     
207     protected TransitionDef getTransitionDef(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String transition) {
208         TransitionDef result = null;
209         
210                 Lifecycle lifecycle;
211                 try {
212                         lifecycle = ctx.getDocumentHandler().getLifecycle();
213                         result = NuxeoUtils.getTransitionDef(lifecycle, transition);
214                 } catch (Exception e) {
215                         logger.error("Failed to get transition definition.", e);
216                 }
217         
218         return result;
219     }
220         
221     private PoxPayloadIn synthEmptyWorkflowInput() {
222         PoxPayloadIn result = null;
223         
224         PoxPayloadOut output = new PoxPayloadOut(WorkflowClient.SERVICE_PAYLOAD_NAME);
225         WorkflowCommon workflowCommons = new WorkflowCommon();
226         PayloadOutputPart commonPart = output.addPart(WorkflowClient.SERVICE_COMMONPART_NAME, workflowCommons);
227         String payloadXML = output.toXML();
228         try {
229                         result = new PoxPayloadIn(payloadXML);
230                 } catch (DocumentException e) {
231                         // TODO Auto-generated catch block
232                         e.printStackTrace();
233                 }
234         
235         return result;
236     }
237     
238     public PoxPayloadOut updateWorkflowWithTransition(ServiceContext existingContext,
239                 UriInfo uriInfo,
240                 String csid,
241                 String transition) {
242
243         PoxPayloadOut result = null;
244                 
245         try {
246                 MultipartServiceContextImpl workflowCtx = (MultipartServiceContextImpl)createServiceContext(WorkflowClient.SERVICE_NAME, uriInfo);
247                 //
248                 // Get properties out of the existing context if one was passed in
249                 //
250                 if (existingContext != null) {
251                         if (existingContext.getCurrentRepositorySession() != null) {
252                                 workflowCtx.setCurrentRepositorySession(existingContext.getCurrentRepositorySession());
253                         }
254                         if (existingContext.getProperties() != null) {
255                                 workflowCtx.setProperties(existingContext.getProperties());
256                         }
257                 }
258
259                 //
260                 // Create an empty workflow_commons input part and set it into a new "workflow" sub-resource context
261                 //
262                 PoxPayloadIn input = new PoxPayloadIn(WorkflowClient.SERVICE_PAYLOAD_NAME, new WorkflowCommon(), 
263                                 WorkflowClient.SERVICE_COMMONPART_NAME);
264             workflowCtx.setInput(input);
265                 
266             // Create a service context and document handler for the target resource.
267             ServiceContext<PoxPayloadIn, PoxPayloadOut> targetCtx = createServiceContext(workflowCtx.getUriInfo());
268             DocumentHandler targetDocHandler = createDocumentHandler(targetCtx);  
269             workflowCtx.setProperty(WorkflowClient.TARGET_DOCHANDLER, targetDocHandler); //added as a context param for the workflow document handler -it will call the parent's dochandler "prepareForWorkflowTranstion" method
270
271             // When looking for the document, we need to use the parent's workspace name -not the "workflow" workspace name
272             String targetWorkspaceName = targetCtx.getRepositoryWorkspaceName();
273             workflowCtx.setRespositoryWorkspaceName(targetWorkspaceName); //find the document in the parent's workspace
274             
275                 // Get the type of transition we're being asked to make and store it as a context parameter -used by the workflow document handler
276             TransitionDef transitionDef = getTransitionDef(targetCtx, transition);
277             if (transitionDef == null) {
278                 throw new DocumentException(String.format("The document with ID='%s' does not support the workflow transition '%s'.",
279                                 csid, transition));
280             }
281             workflowCtx.setProperty(WorkflowClient.TRANSITION_ID, transitionDef);
282
283             WorkflowDocumentModelHandler workflowHandler = createWorkflowDocumentHandler(workflowCtx);
284             getRepositoryClient(workflowCtx).update(workflowCtx, csid, workflowHandler);
285             result = workflowCtx.getOutput();
286         } catch (Exception e) {
287             throw bigReThrow(e, ServiceMessages.UPDATE_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, csid);
288         }
289         
290         return result;
291     
292     }
293     
294     /*
295      * We should consider changing this code.  The RepositoryClient (from call to getRepositoryClient) could support a call doWorkflowTransition() instead?
296      */
297     @PUT
298     @Path("{csid}" + WorkflowClient.SERVICE_PATH + "/" + "{transition}")
299     public byte[] updateWorkflowWithTransition(
300                 @Context UriInfo uriInfo,
301                 @PathParam("csid") String csid,
302                 @PathParam("transition") String transition) {
303         PoxPayloadOut result = null;
304                 
305         try {
306                 result = updateWorkflowWithTransition(NULL_CONTEXT, uriInfo, csid, transition);
307         } catch (Exception e) {
308             throw bigReThrow(e, ServiceMessages.UPDATE_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, csid);
309         }
310         
311         return result.getBytes();
312     }
313     
314 }