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