]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
74e3bc8fbe7ecfcc13f94e90c6ff5b2fa5aa9a7b
[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         PoxPayloadOut result = null;
180
181         try {
182             ServiceContext<PoxPayloadIn, PoxPayloadOut> parentCtx = createServiceContext(uriInfo);
183             String parentWorkspaceName = parentCtx.getRepositoryWorkspaceName();
184
185             MultipartServiceContext ctx = (MultipartServiceContext) createServiceContext(WorkflowClient.SERVICE_NAME, uriInfo);
186             WorkflowDocumentModelHandler handler = createWorkflowDocumentHandler(ctx);
187             ctx.setRespositoryWorkspaceName(parentWorkspaceName); //find the document in the parent's workspace
188             getRepositoryClient(ctx).get(ctx, csid, handler);
189             result = ctx.getOutput();
190         } catch (Exception e) {
191             throw bigReThrow(e, ServiceMessages.READ_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, csid);
192         }
193
194         return result.getBytes();
195     }
196     
197     protected TransitionDef getTransitionDef(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String transition) {
198         TransitionDef result = null;
199         
200                 Lifecycle lifecycle;
201                 try {
202                         lifecycle = ctx.getDocumentHandler().getLifecycle();
203                         result = NuxeoUtils.getTransitionDef(lifecycle, transition);
204                 } catch (Exception e) {
205                         logger.error("Failed to get transition definition.", e);
206                 }
207         
208         return result;
209     }
210         
211     private PoxPayloadIn synthEmptyWorkflowInput() {
212         PoxPayloadIn result = null;
213         
214         PoxPayloadOut output = new PoxPayloadOut(WorkflowClient.SERVICE_PAYLOAD_NAME);
215         WorkflowCommon workflowCommons = new WorkflowCommon();
216         PayloadOutputPart commonPart = output.addPart(WorkflowClient.SERVICE_COMMONPART_NAME, workflowCommons);
217         String payloadXML = output.toXML();
218         try {
219                         result = new PoxPayloadIn(payloadXML);
220                 } catch (DocumentException e) {
221                         // TODO Auto-generated catch block
222                         e.printStackTrace();
223                 }
224         
225         return result;
226     }
227     
228     public PoxPayloadOut updateWorkflowWithTransition(ServiceContext existingContext,
229                 UriInfo uriInfo,
230                 String csid,
231                 String transition) {
232
233         PoxPayloadOut result = null;
234                 
235         try {
236                 MultipartServiceContextImpl workflowCtx = (MultipartServiceContextImpl)createServiceContext(WorkflowClient.SERVICE_NAME, uriInfo);
237                 //
238                 // Get properties out of the existing context if one was passed in
239                 //
240                 if (existingContext != null) {
241                         if (existingContext.getCurrentRepositorySession() != null) {
242                                 workflowCtx.setCurrentRepositorySession(existingContext.getCurrentRepositorySession());
243                         }
244                         if (existingContext.getProperties() != null) {
245                                 workflowCtx.setProperties(existingContext.getProperties());
246                         }
247                 }
248
249                 //
250                 // Create an empty workflow_commons input part and set it into a new "workflow" sub-resource context
251                 //
252                 PoxPayloadIn input = new PoxPayloadIn(WorkflowClient.SERVICE_PAYLOAD_NAME, new WorkflowCommon(), 
253                                 WorkflowClient.SERVICE_COMMONPART_NAME);
254             workflowCtx.setInput(input);
255                 
256             // Create a service context and document handler for the target resource.
257             ServiceContext<PoxPayloadIn, PoxPayloadOut> targetCtx = createServiceContext(workflowCtx.getUriInfo());
258             DocumentHandler targetDocHandler = createDocumentHandler(targetCtx);  
259             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
260
261             // When looking for the document, we need to use the parent's workspace name -not the "workflow" workspace name
262             String targetWorkspaceName = targetCtx.getRepositoryWorkspaceName();
263             workflowCtx.setRespositoryWorkspaceName(targetWorkspaceName); //find the document in the parent's workspace
264             
265                 // Get the type of transition we're being asked to make and store it as a context parameter -used by the workflow document handler
266             TransitionDef transitionDef = getTransitionDef(targetCtx, transition);
267             if (transitionDef == null) {
268                 throw new DocumentException(String.format("The document with ID='%s' does not support the workflow transition '%s'.",
269                                 csid, transition));
270             }
271             workflowCtx.setProperty(WorkflowClient.TRANSITION_ID, transitionDef);
272
273             WorkflowDocumentModelHandler workflowHandler = createWorkflowDocumentHandler(workflowCtx);
274             getRepositoryClient(workflowCtx).update(workflowCtx, csid, workflowHandler);
275             result = workflowCtx.getOutput();
276         } catch (Exception e) {
277             throw bigReThrow(e, ServiceMessages.UPDATE_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, csid);
278         }
279         
280         return result;
281     
282     }
283     
284     /*
285      * We should consider changing this code.  The RepositoryClient (from call to getRepositoryClient) could support a call doWorkflowTransition() instead?
286      */
287     @PUT
288     @Path("{csid}" + WorkflowClient.SERVICE_PATH + "/" + "{transition}")
289     public byte[] updateWorkflowWithTransition(
290                 @Context UriInfo uriInfo,
291                 @PathParam("csid") String csid,
292                 @PathParam("transition") String transition) {
293         PoxPayloadOut result = null;
294                 
295         try {
296                 result = updateWorkflowWithTransition(NULL_CONTEXT, uriInfo, csid, transition);
297         } catch (Exception e) {
298             throw bigReThrow(e, ServiceMessages.UPDATE_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, csid);
299         }
300         
301         return result.getBytes();
302     }
303     
304 }