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