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