View Javadoc

1   /*******************************************************************************
2    *  Imixs Workflow 
3    *  Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,  
4    *  http://www.imixs.com
5    *  
6    *  This program is free software; you can redistribute it and/or 
7    *  modify it under the terms of the GNU General Public License 
8    *  as published by the Free Software Foundation; either version 2 
9    *  of the License, or (at your option) any later version.
10   *  
11   *  This program is distributed in the hope that it will be useful, 
12   *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
14   *  General Public License for more details.
15   *  
16   *  You can receive a copy of the GNU General Public
17   *  License at http://www.gnu.org/licenses/gpl.html
18   *  
19   *  Project: 
20   *  	http://www.imixs.org
21   *  	http://java.net/projects/imixs-workflow
22   *  
23   *  Contributors:  
24   *  	Imixs Software Solutions GmbH - initial API and implementation
25   *  	Ralph Soika - Software Developer
26   *******************************************************************************/
27  
28  package org.imixs.workflow.jaxrs;
29  
30  import java.io.BufferedReader;
31  import java.io.IOException;
32  import java.io.InputStream;
33  import java.io.InputStreamReader;
34  import java.io.OutputStream;
35  import java.net.URISyntaxException;
36  import java.net.URLDecoder;
37  import java.util.Collection;
38  import java.util.HashMap;
39  import java.util.List;
40  import java.util.StringTokenizer;
41  import java.util.Vector;
42  
43  import javax.ejb.EJB;
44  import javax.ejb.Stateless;
45  import javax.servlet.http.HttpServletRequest;
46  import javax.ws.rs.Consumes;
47  import javax.ws.rs.DefaultValue;
48  import javax.ws.rs.GET;
49  import javax.ws.rs.POST;
50  import javax.ws.rs.PUT;
51  import javax.ws.rs.Path;
52  import javax.ws.rs.PathParam;
53  import javax.ws.rs.Produces;
54  import javax.ws.rs.QueryParam;
55  import javax.ws.rs.WebApplicationException;
56  import javax.ws.rs.core.Response;
57  import javax.ws.rs.core.StreamingOutput;
58  
59  import org.imixs.workflow.ItemCollection;
60  import org.imixs.workflow.exceptions.AccessDeniedException;
61  import org.imixs.workflow.exceptions.InvalidWorkitemException;
62  import org.imixs.workflow.exceptions.ProcessingErrorException;
63  import org.imixs.workflow.xml.EntityCollection;
64  import org.imixs.workflow.xml.XMLItemCollection;
65  import org.imixs.workflow.xml.XMLItemCollectionAdapter;
66  
67  /**
68   * The WorkflowService Handler supports methods to process different kind of
69   * request URIs
70   * 
71   * @author rsoika
72   * 
73   */
74  @Path("/workflow")
75  @Produces({ "text/html", "application/xml", "application/json" })
76  @Stateless
77  public class WorkflowRestService {
78  
79  	@EJB
80  	org.imixs.workflow.jee.ejb.WorkflowService workflowService;
81  
82  	@javax.ws.rs.core.Context
83  	private static HttpServletRequest servletRequest;
84  
85  	@GET
86  	@Produces("text/html")
87  	@Path("/")
88  	public StreamingOutput getHelpHTML() {
89  
90  		return new StreamingOutput() {
91  			public void write(OutputStream out) throws IOException,
92  					WebApplicationException {
93  
94  				out.write("<html><head>".getBytes());
95  				out.write("<style>".getBytes());
96  				out.write("table {padding:0px;width: 100%;margin-left: -2px;margin-right: -2px;}"
97  						.getBytes());
98  				out.write("body,td,select,input,li {font-family: Verdana, Helvetica, Arial, sans-serif;font-size: 13px;}"
99  						.getBytes());
100 				out.write("table th {color: white;background-color: #bbb;text-align: left;font-weight: bold;}"
101 						.getBytes());
102 
103 				out.write("table th,table td {font-size: 12px;}".getBytes());
104 
105 				out.write("table tr.a {background-color: #ddd;}".getBytes());
106 
107 				out.write("table tr.b {background-color: #eee;}".getBytes());
108 
109 				out.write("</style>".getBytes());
110 				out.write("</head><body>".getBytes());
111 
112 				// body
113 				out.write("<h1>Imixs Workflow REST Service</h1>".getBytes());
114 				out.write("<p>Read the Imixs REST Service <a href=\"http://doc.imixs.org/xml/restservice.html\">Online Help</a> for a detailed description of this Service.</p>"
115 						.getBytes());
116 				out.write("<p>See the <a href=\"http://www.imixs.org\">Imixs Workflow Project Site</a> for general informations.</p>"
117 						.getBytes());
118 
119 				// end
120 				out.write("</body></html>".getBytes());
121 			}
122 		};
123 
124 	}
125 
126 	/**
127 	 * Returns a collection of workitems representing the worklist by the
128 	 * current user
129 	 * 
130 	 * @param start
131 	 * @param count
132 	 * @param type
133 	 * @param sortorder
134 	 */
135 	@GET
136 	@Path("/worklist/{user}")
137 	public EntityCollection getWorkList(@PathParam("user") String user,
138 			@DefaultValue("0") @QueryParam("start") int start,
139 			@DefaultValue("10") @QueryParam("count") int count,
140 			@QueryParam("type") String type,
141 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
142 			@QueryParam("items") String items) {
143 		Collection<ItemCollection> col = null;
144 		try {
145 			if ("null".equalsIgnoreCase(user))
146 				user = null;
147 
148 			col = workflowService.getWorkList(user, start, count, type,
149 					sortorder);
150 			return XMLItemCollectionAdapter.putCollection(col,
151 					getItemList(items));
152 
153 		} catch (Exception e) {
154 			e.printStackTrace();
155 		}
156 		return new EntityCollection();
157 	}
158 
159 	/**
160 	 * 
161 	 * @param start
162 	 * @param count
163 	 * @param type
164 	 * @param sortorder
165 	 * @return
166 	 */
167 	@GET
168 	@Path("/worklist/{user}.xml")
169 	@Produces("application/xml")
170 	public EntityCollection getWorkListXML(@PathParam("user") String user,
171 			@DefaultValue("0") @QueryParam("start") int start,
172 			@DefaultValue("10") @QueryParam("count") int count,
173 			@QueryParam("type") String type,
174 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
175 			@QueryParam("items") String items) {
176 		return getWorkList(user, start, count, type, sortorder, items);
177 	}
178 
179 	@GET
180 	@Path("/worklist/{user}.json")
181 	@Produces("application/json")
182 	public EntityCollection getWorkListJSON(@PathParam("user") String user,
183 			@DefaultValue("0") @QueryParam("start") int start,
184 			@DefaultValue("10") @QueryParam("count") int count,
185 			@QueryParam("type") String type,
186 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
187 			@QueryParam("items") String items) {
188 		return getWorkList(user, start, count, type, sortorder, items);
189 	}
190 
191 	@GET
192 	@Path("/worklistbycreator/{creator}")
193 	public EntityCollection getWorkListByCreator(
194 			@PathParam("creator") String creator,
195 			@DefaultValue("0") @QueryParam("start") int start,
196 			@DefaultValue("10") @QueryParam("count") int count,
197 			@QueryParam("type") String type,
198 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
199 			@QueryParam("items") String items) {
200 		Collection<ItemCollection> col = null;
201 		try {
202 			if ("null".equalsIgnoreCase(creator))
203 				creator = null;
204 
205 			col = workflowService.getWorkListByCreator(creator, start, count,
206 					type, sortorder);
207 			return XMLItemCollectionAdapter.putCollection(col,
208 					getItemList(items));
209 
210 		} catch (Exception e) {
211 			e.printStackTrace();
212 		}
213 		return new EntityCollection();
214 	}
215 
216 	@GET
217 	@Path("/worklistbycreator/{creator}.xml")
218 	@Produces("application/xml")
219 	public EntityCollection getWorkListByCreatorXML(
220 			@PathParam("creator") String creator,
221 			@DefaultValue("0") @QueryParam("start") int start,
222 			@DefaultValue("10") @QueryParam("count") int count,
223 			@QueryParam("type") String type,
224 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
225 			@QueryParam("items") String items) {
226 		return getWorkListByCreator(creator, start, count, type, sortorder,
227 				items);
228 	}
229 
230 	@GET
231 	@Path("/worklistbycreator/{creator}.json")
232 	@Produces("application/json")
233 	public EntityCollection getWorkListByCreatorJSON(
234 			@PathParam("creator") String creator,
235 			@DefaultValue("0") @QueryParam("start") int start,
236 			@DefaultValue("10") @QueryParam("count") int count,
237 			@QueryParam("type") String type,
238 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
239 			@QueryParam("items") String items) {
240 		return getWorkListByCreator(creator, start, count, type, sortorder,
241 				items);
242 	}
243 
244 	@GET
245 	@Path("/worklistbyprocessid/{processid}")
246 	public EntityCollection getWorkListByProcessID(
247 			@PathParam("processid") int processid,
248 			@DefaultValue("0") @QueryParam("start") int start,
249 			@DefaultValue("10") @QueryParam("count") int count,
250 			@QueryParam("type") String type,
251 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
252 			@QueryParam("items") String items) {
253 		Collection<ItemCollection> col = null;
254 		try {
255 			col = workflowService.getWorkListByProcessID(processid, start,
256 					count, type, sortorder);
257 			return XMLItemCollectionAdapter.putCollection(col,
258 					getItemList(items));
259 		} catch (Exception e) {
260 			e.printStackTrace();
261 		}
262 		return new EntityCollection();
263 	}
264 
265 	@GET
266 	@Path("/worklistbyprocessid/{processid}.xml")
267 	@Produces("application/xml")
268 	public EntityCollection getWorkListByProcessIDXML(
269 			@PathParam("processid") int processid,
270 			@DefaultValue("0") @QueryParam("start") int start,
271 			@DefaultValue("10") @QueryParam("count") int count,
272 			@QueryParam("type") String type,
273 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
274 			@QueryParam("items") String items) {
275 		return getWorkListByProcessID(processid, start, count, type, sortorder,
276 				items);
277 	}
278 
279 	@GET
280 	@Path("/worklistbyprocessid/{processid}.json")
281 	@Produces("application/json")
282 	public EntityCollection getWorkListByProcessIDJSON(
283 			@PathParam("processid") int processid,
284 			@DefaultValue("0") @QueryParam("start") int start,
285 			@DefaultValue("10") @QueryParam("count") int count,
286 			@QueryParam("type") String type,
287 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
288 			@QueryParam("items") String items) {
289 		return getWorkListByProcessID(processid, start, count, type, sortorder,
290 				items);
291 	}
292 
293 	@GET
294 	@Path("/worklistbygroup/{processgroup}")
295 	public EntityCollection getWorkListByGroup(
296 			@PathParam("processgroup") String processgroup,
297 			@DefaultValue("0") @QueryParam("start") int start,
298 			@DefaultValue("10") @QueryParam("count") int count,
299 			@QueryParam("type") String type,
300 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
301 			@QueryParam("items") String items) {
302 		Collection<ItemCollection> col = null;
303 		try {
304 			col = workflowService.getWorkListByGroup(processgroup, start,
305 					count, type, sortorder);
306 			return XMLItemCollectionAdapter.putCollection(col,
307 					getItemList(items));
308 		} catch (Exception e) {
309 			e.printStackTrace();
310 		}
311 		return new EntityCollection();
312 	}
313 
314 	@GET
315 	@Path("/worklistbygroup/{processgroup}.xml")
316 	@Produces("application/xml")
317 	public EntityCollection getWorkListByGroupXML(
318 			@PathParam("processgroup") String processgroup,
319 			@DefaultValue("0") @QueryParam("start") int start,
320 			@DefaultValue("10") @QueryParam("count") int count,
321 			@QueryParam("type") String type,
322 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
323 			@QueryParam("items") String items) {
324 		return getWorkListByGroup(processgroup, start, count, type, sortorder,
325 				items);
326 	}
327 
328 	@GET
329 	@Path("/worklistbygroup/{processgroup}.json")
330 	@Produces("application/json")
331 	public EntityCollection getWorkListByGroupJSON(
332 			@PathParam("processgroup") String processgroup,
333 			@DefaultValue("0") @QueryParam("start") int start,
334 			@DefaultValue("10") @QueryParam("count") int count,
335 			@QueryParam("type") String type,
336 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
337 			@QueryParam("items") String items) {
338 		return getWorkListByGroup(processgroup, start, count, type, sortorder,
339 				items);
340 	}
341 
342 	@GET
343 	@Path("/worklistbyowner/{owner}")
344 	public EntityCollection getWorkListByOwner(
345 			@PathParam("owner") String owner,
346 			@DefaultValue("0") @QueryParam("start") int start,
347 			@DefaultValue("10") @QueryParam("count") int count,
348 			@QueryParam("type") String type,
349 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
350 			@QueryParam("items") String items) {
351 		Collection<ItemCollection> col = null;
352 		try {
353 			if ("null".equalsIgnoreCase(owner))
354 				owner = null;
355 
356 			col = workflowService.getWorkListByOwner(owner, start, count, type,
357 					sortorder);
358 			return XMLItemCollectionAdapter.putCollection(col,
359 					getItemList(items));
360 		} catch (Exception e) {
361 			e.printStackTrace();
362 		}
363 		return new EntityCollection();
364 	}
365 
366 	@GET
367 	@Path("/worklistbyowner/{owner}.xml")
368 	@Produces("application/xml")
369 	public EntityCollection getWorkListByOwnerXML(
370 			@PathParam("owner") String owner,
371 			@DefaultValue("0") @QueryParam("start") int start,
372 			@DefaultValue("10") @QueryParam("count") int count,
373 			@QueryParam("type") String type,
374 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
375 			@QueryParam("items") String items) {
376 		return getWorkListByOwner(owner, start, count, type, sortorder, items);
377 	}
378 
379 	@GET
380 	@Path("/worklistbyowner/{owner}.json")
381 	@Produces("application/json")
382 	public EntityCollection getWorkListByOwnerJSON(
383 			@PathParam("owner") String owner,
384 			@DefaultValue("0") @QueryParam("start") int start,
385 			@DefaultValue("10") @QueryParam("count") int count,
386 			@QueryParam("type") String type,
387 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
388 			@QueryParam("items") String items) {
389 		return getWorkListByOwner(owner, start, count, type, sortorder, items);
390 	}
391 
392 	@GET
393 	@Path("/worklistbywriteaccess")
394 	public EntityCollection getWorkListByWriteAccess(
395 			@DefaultValue("0") @QueryParam("start") int start,
396 			@DefaultValue("10") @QueryParam("count") int count,
397 			@QueryParam("type") String type,
398 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
399 			@QueryParam("items") String items) {
400 		Collection<ItemCollection> col = null;
401 		try {
402 			col = workflowService.getWorkListByWriteAccess(start, count, type,
403 					sortorder);
404 			return XMLItemCollectionAdapter.putCollection(col,
405 					getItemList(items));
406 		} catch (Exception e) {
407 			e.printStackTrace();
408 		}
409 		return new EntityCollection();
410 	}
411 
412 	@GET
413 	@Path("/worklistbywriteaccess.xml")
414 	@Produces("application/xml")
415 	public EntityCollection getWorkListByWriteAccessXML(
416 			@DefaultValue("0") @QueryParam("start") int start,
417 			@DefaultValue("10") @QueryParam("count") int count,
418 			@QueryParam("type") String type,
419 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
420 			@QueryParam("items") String items) {
421 
422 		return getWorkListByWriteAccess(start, count, type, sortorder, items);
423 	}
424 
425 	@GET
426 	@Path("/worklistbywriteaccess.json")
427 	@Produces("application/json")
428 	public EntityCollection getWorkListByWriteAccessJSON(
429 			@DefaultValue("0") @QueryParam("start") int start,
430 			@DefaultValue("10") @QueryParam("count") int count,
431 			@QueryParam("type") String type,
432 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
433 			@QueryParam("items") String items) {
434 
435 		return getWorkListByWriteAccess(start, count, type, sortorder, items);
436 	}
437 
438 	@GET
439 	@Path("/worklistbyref/{uniqueid}")
440 	public EntityCollection getWorkListByRef(
441 			@PathParam("uniqueid") String uniqueid,
442 			@DefaultValue("0") @QueryParam("start") int start,
443 			@DefaultValue("10") @QueryParam("count") int count,
444 			@QueryParam("type") String type,
445 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
446 			@QueryParam("items") String items) {
447 		Collection<ItemCollection> col = null;
448 		try {
449 			col = workflowService.getWorkListByRef(uniqueid, start, count,
450 					type, sortorder);
451 			return XMLItemCollectionAdapter.putCollection(col,
452 					getItemList(items));
453 		} catch (Exception e) {
454 			e.printStackTrace();
455 		}
456 		return new EntityCollection();
457 	}
458 
459 	@GET
460 	@Path("/worklistbyref/{uniqueid}.xml")
461 	@Produces("application/xml")
462 	public EntityCollection getWorkListByRefXML(
463 			@PathParam("uniqueid") String uniqueid,
464 			@DefaultValue("0") @QueryParam("start") int start,
465 			@DefaultValue("10") @QueryParam("count") int count,
466 			@QueryParam("type") String type,
467 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
468 			@QueryParam("items") String items) {
469 		return getWorkListByRef(uniqueid, start, count, type, sortorder, items);
470 	}
471 
472 	@GET
473 	@Path("/worklistbyref/{uniqueid}.json")
474 	@Produces("application/json")
475 	public EntityCollection getWorkListByRefJSON(
476 			@PathParam("uniqueid") String uniqueid,
477 			@DefaultValue("0") @QueryParam("start") int start,
478 			@DefaultValue("10") @QueryParam("count") int count,
479 			@QueryParam("type") String type,
480 			@DefaultValue("0") @QueryParam("sortorder") int sortorder,
481 			@QueryParam("items") String items) {
482 		return getWorkListByRef(uniqueid, start, count, type, sortorder, items);
483 	}
484 
485 	/**
486 	 * returns a singel workitem defined by $uniqueid
487 	 * 
488 	 * @param uniqueid
489 	 * @return
490 	 */
491 	@GET
492 	@Path("/workitem/{uniqueid}")
493 	public XMLItemCollection getWorkItem(
494 			@PathParam("uniqueid") String uniqueid,
495 			@QueryParam("items") String items) {
496 		ItemCollection workitem;
497 		try {
498 			workitem = workflowService.getWorkItem(uniqueid);
499 			return XMLItemCollectionAdapter.putItemCollection(workitem,
500 					getItemList(items));
501 		} catch (Exception e) {
502 			e.printStackTrace();
503 			return null;
504 		}
505 	}
506 
507 	@GET
508 	@Path("/workitem/{uniqueid}.xml")
509 	@Produces("application/xml")
510 	public XMLItemCollection getWorkItemXML(
511 			@PathParam("uniqueid") String uniqueid,
512 			@QueryParam("items") String items) {
513 		return getWorkItem(uniqueid, items);
514 	}
515 
516 	@GET
517 	@Path("/workitem/{uniqueid}.json")
518 	@Produces("application/json")
519 	public XMLItemCollection getWorkItemJSON(
520 			@PathParam("uniqueid") String uniqueid,
521 			@QueryParam("items") String items) {
522 		return getWorkItem(uniqueid, items);
523 	}
524 
525 	/**
526 	 * Returns a file attachment located in the property $file of the spcified
527 	 * workitem
528 	 * 
529 	 * @param uniqueid
530 	 * @return
531 	 */
532 	@GET
533 	@Path("/workitem/{uniqueid}/file/{file}")
534 	public Response getWorkItemFile(@PathParam("uniqueid") String uniqueid,
535 			@PathParam("file") String file) {
536 
537 		ItemCollection workItem;
538 		try {
539 			workItem = workflowService.getWorkItem(uniqueid);
540 
541 			if (workItem != null) {
542 				// fetch $file from hashmap....
543 
544 				HashMap mapFiles = null;
545 				Vector vFiles = workItem.getItemValue("$file");
546 				if (vFiles != null && vFiles.size() > 0) {
547 					mapFiles = (HashMap) vFiles.elementAt(0);
548 
549 					Vector<Object> vectorFileInfo = new Vector<Object>();
550 					vectorFileInfo = (Vector) mapFiles.get(file);
551 					if (vectorFileInfo != null) {
552 						String sContentType = vectorFileInfo.elementAt(0)
553 								.toString();
554 						byte[] fileContent = (byte[]) vectorFileInfo
555 								.elementAt(1);
556 
557 						// Set content type in order of the contentType stored
558 						// in the $file attribute
559 						Response.ResponseBuilder builder = Response.ok(
560 								fileContent, sContentType);
561 
562 						return builder.build();
563 
564 					} else
565 						// workitem not found
566 						return Response.status(Response.Status.NOT_FOUND)
567 								.build();
568 
569 				} else
570 					// workitem not found
571 					return Response.status(Response.Status.NOT_FOUND).build();
572 
573 			} else {
574 				// workitem not found
575 				return Response.status(Response.Status.NOT_FOUND).build();
576 			}
577 
578 		} catch (Exception e) {
579 
580 			e.printStackTrace();
581 		}
582 
583 		return Response.status(Response.Status.NOT_FOUND).build();
584 
585 	}
586 
587 	/**
588 	 * This method expects a form post. The method parses the input stream to
589 	 * extract the provides field/value pairs. NOTE: The method did not(!)
590 	 * assume that the put/post request contains a complete workItem. For this
591 	 * reason the method loads the existing instance of the corresponding
592 	 * workItem (identified by the $unqiueid) and adds the values provided by
593 	 * the put/post request into the existing instance.
594 	 * 
595 	 * 
596 	 * After the workItem was processed the method redirect the request to the
597 	 * provided action URI. The action URI can also be computed by the Imixs
598 	 * Workflow ResutlPlugin
599 	 * 
600 	 * @param requestBodyStream
601 	 *            - form content
602 	 * @param action
603 	 *            - return URI
604 	 * @return
605 	 */
606 	@PUT
607 	@Path("/workitem")
608 	@Consumes({ "application/x-www-form-urlencoded" })
609 	public Response putWorkitem(InputStream requestBodyStream,
610 			@QueryParam("action") String action) {
611 
612 		BufferedReader in = new BufferedReader(new InputStreamReader(
613 				requestBodyStream));
614 		String inputLine;
615 		ItemCollection workitem = new ItemCollection();
616 		try {
617 			while ((inputLine = in.readLine()) != null) {
618 				// System.out.println(inputLine);
619 
620 				// split params separated by &
621 				StringTokenizer st = new StringTokenizer(inputLine, "&", false);
622 				while (st.hasMoreTokens()) {
623 					String fieldValue = st.nextToken();
624 					try {
625 						fieldValue = URLDecoder.decode(fieldValue, "UTF-8");
626 						// get fieldname
627 						String fieldName = fieldValue.substring(0,
628 								fieldValue.indexOf('='));
629 						fieldValue = fieldValue.substring(fieldValue
630 								.indexOf('=') + 1);
631 						workitem.replaceItemValue(fieldName, fieldValue);
632 					} catch (NumberFormatException e) {
633 						e.printStackTrace();
634 					} catch (Exception e) {
635 						e.printStackTrace();
636 					}
637 				}
638 
639 			}
640 
641 			// now test if an workitem with this $unqiueid still exits...
642 			String unid = workitem.getItemValueString("$uniqueID");
643 			if (!"".equals(unid)) {
644 				try {
645 					ItemCollection oldWorkitem = workflowService
646 							.getWorkItem(unid);
647 					if (oldWorkitem != null) {
648 						// an instance of this WorkItem still exists! so we need
649 						// to update the new values....
650 						oldWorkitem.getAllItems()
651 								.putAll(workitem.getAllItems());
652 						/*
653 						 * Map map=workitem.getAllItems();
654 						 * 
655 						 * map.p Set<String> set=map.keySet(); for (String
656 						 * key:set) {
657 						 * 
658 						 * oldWorkitem.replaceItemValue(key,
659 						 * workitem.getItem()); }
660 						 */
661 						workitem = oldWorkitem;
662 
663 					}
664 				} catch (Exception e) {
665 					e.printStackTrace();
666 					return Response.status(Response.Status.NOT_ACCEPTABLE)
667 							.build();
668 				}
669 			}
670 
671 			// now lets try to process the workitem...
672 			workitem = workflowService.processWorkItem(workitem);
673 
674 		} catch (IOException e) {
675 			e.printStackTrace();
676 			return Response.status(Response.Status.NOT_ACCEPTABLE).build();
677 		} catch (AccessDeniedException e) {
678 			e.printStackTrace();
679 			return Response.status(Response.Status.NOT_ACCEPTABLE).build();
680 		} catch (InvalidWorkitemException e) {
681 
682 			e.printStackTrace();
683 			return Response.status(Response.Status.NOT_ACCEPTABLE).build();
684 		} catch (ProcessingErrorException e) {
685 
686 			e.printStackTrace();
687 			return Response.status(Response.Status.NOT_ACCEPTABLE).build();
688 		} finally {
689 			try {
690 				in.close();
691 			} catch (IOException e) {
692 				e.printStackTrace();
693 			}
694 
695 		}
696 
697 		// try to get action from workItem if not provided by queryString...
698 		if (action == null || "".equals(action))
699 			action = workitem.getItemValueString("action");
700 
701 		// now redirect if action is available...
702 		if (action != null && !"".equals(action)) {
703 			try {
704 				return Response.seeOther(new java.net.URI(action)).build();
705 			} catch (URISyntaxException e) {
706 				e.printStackTrace();
707 				return Response.status(Response.Status.NOT_ACCEPTABLE).build();
708 			}
709 		}
710 
711 		return Response.status(Response.Status.OK).build();
712 
713 	}
714 
715 	/**
716 	 * This method expects a form post.
717 	 * 
718 	 * @see putWorkitemDefault
719 	 * @param requestBodyStream
720 	 * @return
721 	 */
722 	@POST
723 	@Path("/workitem")
724 	@Consumes({ "application/x-www-form-urlencoded" })
725 	public Response postWorkitem(InputStream requestBodyStream,
726 			@QueryParam("action") String action) {
727 		return putWorkitem(requestBodyStream, action);
728 	}
729 
730 	/**
731 	 * This method post a ItemCollection object to be processed by the
732 	 * WorkflowManager. The method test for the propertys $processid and
733 	 * $activityid
734 	 * 
735 	 * NOTE!! - this method did not update an existing instance of a workItem.
736 	 * The behavior is different to the method putWorkitem(). It need to be
737 	 * discussed if the behavior is wrong or not.
738 	 * 
739 	 * @param workitem
740 	 *            - new workItem data
741 	 */
742 	@PUT
743 	@Path("/workitem")
744 	@Consumes({ "application/xml", "text/xml" })
745 	public Response putWorkitemXML(XMLItemCollection workitem,
746 			@QueryParam("action") String action) {
747 
748 		ItemCollection itemCollection;
749 		try {
750 			itemCollection = XMLItemCollectionAdapter
751 					.getItemCollection(workitem);
752 			itemCollection = workflowService.processWorkItem(itemCollection);
753 
754 			// try to get action from workItem if not provided by queryString...
755 			if (action == null || "".equals(action))
756 				action = itemCollection.getItemValueString("action");
757 			// now redirect if action is available...
758 			if (action != null && !"".equals(action)) {
759 				try {
760 					return Response.seeOther(new java.net.URI(action)).build();
761 				} catch (URISyntaxException e) {
762 					e.printStackTrace();
763 					return Response.status(Response.Status.NOT_ACCEPTABLE)
764 							.build();
765 				}
766 			}
767 			return Response.status(Response.Status.OK).build();
768 		} catch (Exception e) {
769 			e.printStackTrace();
770 		}
771 		return Response.status(Response.Status.NOT_ACCEPTABLE).build();
772 	}
773 
774 	@POST
775 	@Path("/workitem")
776 	@Consumes({ "application/xml", "text/xml" })
777 	public Response postWorkitemXML(XMLItemCollection workitem,
778 			@QueryParam("action") String action) {
779 		return putWorkitemXML(workitem, action);
780 	}
781 
782 	/**
783 	 * This method post a collection of ItemCollection objects to be processed
784 	 * by the WorkflowManager.
785 	 * 
786 	 * @param worklist
787 	 *            - workitem list data
788 	 */
789 	@PUT
790 	@Path("/workitems")
791 	@Consumes({ "application/xml", "text/xml" })
792 	public Response putWorkitemsXML(EntityCollection worklist) {
793 
794 		XMLItemCollection entity;
795 		ItemCollection itemCollection;
796 		try {
797 			// save new entities into database and update modelversion.....
798 			for (int i = 0; i < worklist.getEntity().length; i++) {
799 				entity = worklist.getEntity()[i];
800 				itemCollection = XMLItemCollectionAdapter
801 						.getItemCollection(entity);
802 				// process entity
803 				workflowService.processWorkItem(itemCollection);
804 			}
805 			return Response.status(Response.Status.OK).build();
806 		} catch (Exception e) {
807 			e.printStackTrace();
808 		}
809 		return Response.status(Response.Status.NOT_ACCEPTABLE).build();
810 	}
811 
812 	@POST
813 	@Path("/workitems")
814 	@Consumes({ "application/xml", "text/xml" })
815 	public Response postWorkitemsXML(EntityCollection worklist) {
816 		return putWorkitemsXML(worklist);
817 	}
818 
819 	/**
820 	 * This method returns a List object from a given comma separated string.
821 	 * The method returns null if no elements are found. The provided parameter
822 	 * looks typical like this: <code>
823 	 *   txtWorkflowStatus,numProcessID,txtName
824 	 * </code>
825 	 * 
826 	 * @param items
827 	 * @return
828 	 */
829 	private List<String> getItemList(String items) {
830 		if (items == null || "".equals(items))
831 			return null;
832 		Vector<String> v = new Vector<String>();
833 		StringTokenizer st = new StringTokenizer(items, ",");
834 		while (st.hasMoreTokens())
835 			v.add(st.nextToken());
836 		return v;
837 	}
838 }