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.plugins;
29  
30  import org.imixs.workflow.ItemCollection;
31  import org.imixs.workflow.Plugin;
32  import org.imixs.workflow.exceptions.PluginException;
33  
34  /**
35   * This Pluginmodul generates a result message. The Plugin checks if the activiy
36   * document has an "txtActivityResult" attribute. The value will be parsed for
37   * "<field>attribute</field>" tags and these tags will be replaced with the
38   * values of the corresponding attributes of the workitem.
39   * 
40   * The final result will be stored into the attribute
41   * "txtworkflowresultmessage".
42   * 
43   * This field could be used by an application to display individual messages
44   * (e.g HTML Code) or return result Strings (e.g. JSF Action Results)
45   * 
46   * @author Ralph Soika
47   * @version 1.0
48   * @see org.imixs.workflow.WorkflowManager
49   * 
50   */
51  public class ResultPlugin extends AbstractPlugin {
52  	ItemCollection documentContext;
53  	String sActivityResult;
54  
55  	public int run(ItemCollection adocumentContext,
56  			ItemCollection adocumentActivity) throws PluginException {
57  		documentContext = adocumentContext;
58  
59  		// get ResultMessage
60  		sActivityResult = adocumentActivity
61  				.getItemValueString("txtActivityResult");
62  		sActivityResult = replaceDynamicValues(sActivityResult,
63  				adocumentContext);
64  
65  		// evaluate new items....
66  		evaluate(sActivityResult, adocumentContext);
67  
68  		return Plugin.PLUGIN_OK;
69  	}
70  
71  	public void close(int status) throws PluginException {
72  		try {
73  			// restore changes?
74  			if (status < Plugin.PLUGIN_ERROR) {
75  				documentContext.replaceItemValue("txtworkflowresultmessage",
76  						sActivityResult);
77  			}
78  		} catch (Exception e) {
79  			System.out.println("[ResultPlugin] Error close(): " + e.toString());
80  
81  		}
82  	}
83  
84  	/**
85  	 * This method parses a string for xml tag <item>. Those tags will result in
86  	 * new workitem properties.
87  	 * 
88  	 * <code>
89  	 *   
90  	 *   <item name="txtTitle">new Title</item>
91  	 *   
92  	 *   
93  	 * </code>
94  	 * 
95  	 * Additional the attribute 'type' can be provided to specify a field type
96  	 * 'boolean', 'string', 'integer'
97  	 * 
98  	 * The item will be added into the workitem documentContext
99  	 * 
100 	 * 
101 	 */
102 	public static void evaluate(String aString, ItemCollection documentContext) {
103 		int iTagStartPos;
104 		int iTagEndPos;
105 
106 		int iContentStartPos;
107 		int iContentEndPos;
108 
109 		int iNameStartPos;
110 		int iNameEndPos;
111 
112 		int iTypeStartPos;
113 		int iTypeEndPos;
114 
115 		String sName = "";
116 		String sType = " ";
117 		String sItemValue;
118 
119 		if (aString == null)
120 			return;
121 
122 		// test if a <value> tag exists...
123 		while ((iTagStartPos = aString.toLowerCase().indexOf("<item")) != -1) {
124 
125 			iTagEndPos = aString.toLowerCase().indexOf("</item>", iTagStartPos);
126 
127 			// if no end tag found return string unchanged...
128 			if (iTagEndPos == -1)
129 				return;
130 
131 			// reset pos vars
132 			iContentStartPos = 0;
133 			iContentEndPos = 0;
134 			iNameStartPos = 0;
135 			iNameEndPos = 0;
136 			iTypeStartPos = 0;
137 			iTypeEndPos = 0;
138 			sName = "";
139 			sType = " ";
140 			sItemValue = "";
141 
142 			// so we now search the beginning of the tag content
143 			iContentEndPos = iTagEndPos;
144 			// start pos is the last > before the iContentEndPos
145 			String sTestString = aString.substring(0, iContentEndPos);
146 			iContentStartPos = sTestString.lastIndexOf('>') + 1;
147 
148 			// if no end tag found return string unchanged...
149 			if (iContentStartPos >= iContentEndPos)
150 				return;
151 
152 			iTagEndPos = iTagEndPos + "</item>".length();
153 
154 			// now we have the start and end position of a tag and also the
155 			// start and end pos of the value
156 
157 			// next we check if the start tag contains a 'name' attribute
158 			iNameStartPos = aString.toLowerCase()
159 					.indexOf("name=", iTagStartPos);
160 			// extract format string if available
161 			if (iNameStartPos > -1 && iNameStartPos < iContentStartPos) {
162 				iNameStartPos = aString.indexOf("\"", iNameStartPos) + 1;
163 				iNameEndPos = aString.indexOf("\"", iNameStartPos + 1);
164 				sName = aString.substring(iNameStartPos, iNameEndPos);
165 			}
166 
167 			// next we check if the start tag contains a 'type'
168 			// attribute
169 			iTypeStartPos = aString.toLowerCase()
170 					.indexOf("type=", iTagStartPos);
171 			// extract format string if available
172 			if (iTypeStartPos > -1 && iTypeStartPos < iContentStartPos) {
173 				iTypeStartPos = aString.indexOf("\"", iTypeStartPos) + 1;
174 				iTypeEndPos = aString.indexOf("\"", iTypeStartPos + 1);
175 				sType = aString.substring(iTypeStartPos, iTypeEndPos);
176 			}
177 
178 			// extract Item Value
179 			sItemValue = aString.substring(iContentStartPos, iContentEndPos);
180 
181 			// replace the item value
182 			if (sName != null && !"".equals(sName)) {
183 				// convert to type...
184 				Object oValue = sItemValue;
185 
186 				if ("boolean".equalsIgnoreCase(sType))
187 					// oValue=new Boolean(sItemValue);
188 					oValue = Boolean.valueOf(sItemValue);
189 
190 				if ("integer".equalsIgnoreCase(sType))
191 					oValue = new Integer(sItemValue);
192 
193 				documentContext.replaceItemValue(sName, oValue);
194 			}
195 
196 			// now cut the tag form the string
197 			aString = aString.substring(0, iTagStartPos) + ""
198 					+ aString.substring(iTagEndPos);
199 		}
200 
201 	}
202 
203 }