1
2
3
4
5
6 package net.kwfgrid.gwui.servlets;
7
8 import javax.servlet.http.HttpServlet;
9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 import javax.servlet.http.HttpSession;
12 import javax.servlet.ServletException;
13 import javax.servlet.ServletContext;
14 import javax.servlet.RequestDispatcher;
15 import java.io.*;
16 import java.net.URL;
17 import java.net.MalformedURLException;
18 import java.net.URLDecoder;
19 import java.util.Map;
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.Properties;
23 import java.util.List;
24 import java.util.LinkedList;
25 import java.util.Enumeration;
26 import java.util.StringTokenizer;
27 import java.rmi.RemoteException;
28
29 import net.kwfgrid.gworkflowdl.protocol.IllegalModificationException;
30 import net.kwfgrid.gworkflowdl.protocol.IncompatibleVersionsException;
31 import net.kwfgrid.gworkflowdl.protocol.client.ClientWorkflow;
32 import net.kwfgrid.gworkflowdl.structure.*;
33 import net.kwfgrid.gwui.workflow.XMLUtilities;
34
35 import org.apache.log4j.Logger;
36
37 /***
38 Servlet to allow the user to select between different forms for data input.
39 This servlet MUST be deployed in the same webapp as the data-servlets and must be addressable
40 at path "/FormSelectionServlet".
41 */
42 public class FormSelectionServlet extends HttpServlet implements ServletConstants {
43 private static final Logger logger = Logger.getLogger(FormSelectionServlet.class);
44
45 /*** The key for the "servlet" parameter. */
46 public static final String KEY_SERVLET = "servlet";
47
48 /*** The key for the "form-selection-template-url" property. */
49 public static final String KEY_FORM_SELECTION_TEMPLATE_URL = "form-selection-template-url";
50 /*** The key for the "generic-form-url" property */
51 public static final String KEY_GENERIC_FORM_URL = "generic-form-url";
52 /*** The key for the "generic-form-width" property */
53 public static final String KEY_GENERIC_FORM_WIDTH = "generic-form-width";
54 /*** The key for the "generic-form-height" property */
55 public static final String KEY_GENERIC_FORM_HEIGHT = "generic-form-height";
56 /*** The key for the "control-token-form-url" property */
57 public static final String KEY_CONTROL_TOKEN_FORM_URL = "control-token-form-url";
58 /*** The key for the "control-token-form-width" property */
59 public static final String KEY_CONTROL_TOKEN_FORM_WIDTH = "control-token-form-width";
60 /*** The key for the "control-token-form-height" property */
61 public static final String KEY_CONTROL_TOKEN_FORM_HEIGHT = "control-token-form-height";
62 /*** The key for the "form-selection-template-width" property */
63 public static final String KEY_FORM_SELECTION_TEMPLATE_WIDTH = "form-selection-template-width";
64 /*** The key for the "form-selection-template-width" property */
65 public static final String KEY_FORM_SELECTION_TEMPLATE_HEIGHT = "form-selection-template-height";
66
67 public static final String PLACEHOLDER_ADDITIONAL_PARAMETERS = "//$ADDITIONAL_PARAMETERS";
68 public static final String PLACEHOLDER_FORM_URLS = "//$FORM_ARRAY";
69 public static final String PLACEHOLDER_SERVLET_NAMES = "//$SERVLET_ARRAY";
70 public static final String PLACEHOLDER_FORM_WIDTHS = "//$WIDTH_ARRAY";
71 public static final String PLACEHOLDER_FORM_HEIGHTS = "//$HEIGHT_ARRAY";
72 public static final String PLACEHOLDER_FORMSELECTIONSERVLET_URLS = "//$SELECTION_SERVLET_ARRAY";
73 public static final String PLACEHOLDER_GENERIC_SERVLET = "//$GENERIC_SERVLET";
74 public static final String PLACEHOLDER_GENERIC_FORM = "//$GENERIC_FORM_URL";
75 public static final String PLACEHOLDER_GENERIC_FORM_WIDTH = "//$GENERIC_FORM_WIDTH";
76 public static final String PLACEHOLDER_GENERIC_FORM_HEIGHT = "//$GENERIC_FORM_HEIGHT";
77 public static final String PLACEHOLDER_GENERIC_FORMSELECTIONSERVLET = "//$GENERIC_SELECTION_SERVLET";
78 public static final String PLACEHOLDER_TEMPLATE_WIDTH = "//$TEMPLATE_WIDTH";
79 public static final String PLACEHOLDER_TEMPLATE_HEIGHT = "//$TEMPLATE_HEIGHT";
80
81 private static Properties PROPERTIES = new Properties();
82
83 static {
84 try {
85 PROPERTIES.load(FormSelectionServlet.class.getResourceAsStream("/dataservletbase.properties"));
86
87 if (PROPERTIES.getProperty(KEY_SERVLET_BASE_URL) == null)
88 throw new IOException("No servlet-base-url property defined.");
89 if (PROPERTIES.getProperty(KEY_GENERIC_FORM_URL) == null)
90 throw new IOException("No generic-form-url property defined.");
91 if (PROPERTIES.getProperty(KEY_GENERIC_FORM_WIDTH) == null)
92 throw new IOException("No generic-form-width property defined.");
93 if (PROPERTIES.getProperty(KEY_GENERIC_FORM_HEIGHT) == null)
94 throw new IOException("No generic-form-height property defined.");
95 if (PROPERTIES.getProperty(KEY_CONTROL_TOKEN_FORM_URL) == null)
96 throw new IOException("No control-token-form-url property defined.");
97 if (PROPERTIES.getProperty(KEY_CONTROL_TOKEN_FORM_WIDTH) == null)
98 throw new IOException("No control-token-form-width property defined.");
99 if (PROPERTIES.getProperty(KEY_CONTROL_TOKEN_FORM_HEIGHT) == null)
100 throw new IOException("No control-token-form-height property defined.");
101 if (PROPERTIES.getProperty(KEY_FORM_SELECTION_TEMPLATE_URL) == null)
102 throw new IOException("No form-selection-template-url property defined.");
103 if (PROPERTIES.getProperty(KEY_FORM_SELECTION_TEMPLATE_HEIGHT) == null)
104 throw new IOException("No form-selection-template-height property defined.");
105 if (PROPERTIES.getProperty(KEY_FORM_SELECTION_TEMPLATE_WIDTH) == null)
106 throw new IOException("No form-selection-template-width property defined.");
107 } catch (Exception x) {
108 logger.fatal("Could not load properties.", x);
109 }
110 }
111
112 protected String getProperty(String key) {
113 return PROPERTIES.getProperty(key);
114 }
115
116 protected void doPost(HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
117 doAll( request, response );
118 }
119
120 protected void doGet(HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
121 doAll( request, response );
122 }
123
124 private void doAll(HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
125 HttpSession session = request.getSession(false);
126 boolean shouldbenew = request.getParameter(KEY_NEWSESSION)!=null;
127
128 if (session != null && shouldbenew) {
129 logger.info("Got outdated session information. Discarding and starting new session...");
130 session.invalidate();
131 session = null;
132 }
133
134 ClientWorkflow workflow = null;
135 String servlet = request.getParameter(KEY_SERVLET);
136 boolean requestfromuser = servlet != null;
137
138 try {
139 if (session == null && !requestfromuser) {
140 String gwesaddress = request.getParameter(KEY_GWESADDRESS);
141 String workflowid = request.getParameter(KEY_WORKFLOWID);
142 String command = request.getParameter(KEY_COMMAND);
143 String placeid = request.getParameter(KEY_PLACEID);
144 String transitionid = request.getParameter(KEY_TRANSITIONID);
145
146 workflow = (ClientWorkflow)Factory.newWorkflow(workflowid);
147 workflow.update();
148
149 if (EDIT_COMMAND.equals(command) ||
150 CREATE_COMMAND.equals(command)) {
151 Place place = workflow.getPlace(placeid);
152 if (place == null)
153 throw new ServletException("Place with ID "+placeid+" not available.");
154 showForPlace(place, createAdditionalParameters(request), null, request, response);
155 } else if (FIRE_COMMAND.equals(command)) {
156 Transition transition = workflow.getTransition(transitionid);
157 if (transition == null)
158 throw new ServletException("Transition with ID "+transitionid+" not available.");
159 Edge[] outedges = transition.getOutEdges();
160 if (outedges.length < 1)
161 throw new ServletException("No output places available at transition with ID "+transitionid+".");
162 Place place = outedges[0].getPlace();
163 showForPlace(place, createAdditionalParameters(request), null, request, response);
164 } else {
165 throw new ServletException("Unknown command: "+command);
166 }
167 } else {
168 if (requestfromuser) {
169 ServletContext ctx = getServletContext();
170 RequestDispatcher rq = ctx.getRequestDispatcher("/"+servlet);
171 logger.info("Forwarding request to "+servlet+".");
172 rq.forward(request, response);
173 } else {
174 workflow = (ClientWorkflow)session.getAttribute(KEY_WORKFLOWINSTANCE);
175 String transitionid = (String)session.getAttribute(KEY_TRANSITIONID);
176 Transition transition = workflow.getTransition(transitionid);
177 int outedgeindex = ((Integer)session.getAttribute(KEY_OUTEDGEINDEX)).intValue();
178 Edge[] outedges = transition.getOutEdges();
179 Place place = outedges[outedgeindex].getPlace();
180 showForPlace(place, "", getProperty(KEY_SERVLET_BASE_URL), request, response);
181 }
182 }
183 } catch (UnsupportedEncodingException x) {
184 throw new ServletException("Unsupported encoding.", x);
185 }
186 }
187
188 private String createAdditionalParameters(HttpServletRequest request) throws UnsupportedEncodingException {
189 StringBuffer p = new StringBuffer();
190 Enumeration e = request.getParameterNames();
191 while (e.hasMoreElements()) {
192 String name = (String)e.nextElement();
193 String value = ServletUtilities.decode(request.getParameter(name));
194 p.append("&").append(name).append("=").append(value);
195 }
196 return p.toString();
197 }
198
199 /***
200 @param place The place.
201 @param js_additionalparameters Additional parameters to be included into the form
202 (only if this is the first call of FormSelectionServlet during a session, empty string otherwise).
203 @param servlethost The servlethost (plus the path to the webapp) where the servlets must reside
204 (only if this is a subsequent call during a session, null if it is the first call.)
205 @param request
206 @param response
207 */
208 private void showForPlace(Place place,
209 String js_additionalparameters,
210 String servlethost,
211 HttpServletRequest request,
212 HttpServletResponse response)
213 throws ServletException, IOException {
214 List forms = new LinkedList();
215 String[] formurls = parseStringArray(place.getProperties().get("token.form.urls"));
216 String[] servleturls = parseStringArray(place.getProperties().get("token.servlet.urls"));
217 String[][] geometries = parseGeometriesArray(parseStringArray(place.getProperties().get("token.form.geometries")));
218 String[] formselectionservleturls = new String[servleturls.length];
219 String[] servlethosts = new String[servleturls.length];
220 String[] servletnames = new String[servleturls.length];
221
222 if (formurls.length != servleturls.length ||
223 formurls.length != geometries[0].length ||
224 servleturls.length != geometries[0].length)
225 throw new ServletException("Invalid form properties at place "+place.getID());
226
227 for (int i=0; i<servleturls.length; i++) {
228 if (servleturls[i].equalsIgnoreCase("na")) {
229 if (servlethost == null)
230 servleturls[i] = getProperty(KEY_SERVLET_BASE_URL)+"DefaultDataServlet";
231 else
232 servleturls[i] = servlethost + "DefaultDataServlet";
233 }
234
235 servlethosts[i] = servleturls[i].substring(0, servleturls[i].lastIndexOf("/")+1).trim();
236 servletnames[i] = servleturls[i].substring(servleturls[i].lastIndexOf("/")+1).trim();
237 formselectionservleturls[i] = response.encodeURL(servlethosts[i] + "FormSelectionServlet");
238
239
240 if (servlethost != null && !servlethosts[i].equals(servlethost)) {
241 servletnames[i] = null;
242 servlethosts[i] = null;
243 formselectionservleturls[i] = null;
244 formurls[i] = null;
245 geometries[0][i] = null;
246 geometries[1][i] = null;
247 }
248
249
250 if (formurls[i] != null && forms.contains(formurls[i] + " " + servleturls[i])) {
251 servletnames[i] = null;
252 servlethosts[i] = null;
253 formselectionservleturls[i] = null;
254 formurls[i] = null;
255 geometries[0][i] = null;
256 geometries[1][i] = null;
257 }
258
259 if (formurls[i] != null) {
260 forms.add(formurls[i] + " " + servleturls[i]);
261 logger.info("Form: "+formurls[i]+", "+geometries[0][i]+"x"+geometries[1][i]);
262 }
263 }
264
265 String js_formurls = buildJSArray(formurls, "\"");
266 String js_servletnames = buildJSArray(servletnames, "\"");
267 String js_formwidths = buildJSArray(geometries[0], "\"");
268 String js_formheights = buildJSArray(geometries[1], "\"");
269 String js_formselectionservleturls = buildJSArray(formselectionservleturls, "\"");
270
271 logger.info("Form URLs: "+js_formurls);
272 logger.info("Servlet Names: "+js_servletnames);
273 logger.info("Form Widths: "+js_formwidths);
274 logger.info("Form Heights: "+js_formheights);
275
276 String js_genericservlet = null;
277 String js_genericform = null;
278 String js_genericform_width = null;
279 String js_genericform_height = null;
280 String js_genericformselectionservlet = null;
281
282 if (!XMLUtilities.isControlPlace(place)) {
283 js_genericservlet = "GenericDataServlet";
284 js_genericform = getProperty(KEY_GENERIC_FORM_URL);
285 js_genericform_width = getProperty(KEY_GENERIC_FORM_WIDTH);
286 js_genericform_height = getProperty(KEY_GENERIC_FORM_HEIGHT);
287 js_genericformselectionservlet = getProperty(KEY_SERVLET_BASE_URL)+"FormSelectionServlet";
288 } else {
289 js_genericservlet = "DefaultDataServlet";
290 js_genericform = getProperty(KEY_CONTROL_TOKEN_FORM_URL);
291 js_genericform_width = getProperty(KEY_CONTROL_TOKEN_FORM_WIDTH);
292 js_genericform_height = getProperty(KEY_CONTROL_TOKEN_FORM_HEIGHT);
293 js_genericformselectionservlet = getProperty(KEY_SERVLET_BASE_URL)+"FormSelectionServlet";
294 }
295
296
297 String form = ServletUtilities.readFile(getProperty(KEY_FORM_SELECTION_TEMPLATE_URL));
298
299 form = ServletUtilities.replace(form, PLACEHOLDER_ADDITIONAL_PARAMETERS, js_additionalparameters);
300 form = ServletUtilities.replace(form, PLACEHOLDER_FORM_URLS, js_formurls);
301 form = ServletUtilities.replace(form, PLACEHOLDER_SERVLET_NAMES, js_servletnames);
302 form = ServletUtilities.replace(form, PLACEHOLDER_FORM_WIDTHS, js_formwidths);
303 form = ServletUtilities.replace(form, PLACEHOLDER_FORM_HEIGHTS, js_formheights);
304 form = ServletUtilities.replace(form, PLACEHOLDER_FORMSELECTIONSERVLET_URLS, js_formselectionservleturls);
305
306 form = ServletUtilities.replace(form, PLACEHOLDER_GENERIC_SERVLET, js_genericservlet);
307 form = ServletUtilities.replace(form, PLACEHOLDER_GENERIC_FORM, js_genericform);
308 form = ServletUtilities.replace(form, PLACEHOLDER_GENERIC_FORM_WIDTH, js_genericform_width);
309 form = ServletUtilities.replace(form, PLACEHOLDER_GENERIC_FORM_HEIGHT, js_genericform_height);
310 form = ServletUtilities.replace(form, PLACEHOLDER_GENERIC_FORMSELECTIONSERVLET, js_genericformselectionservlet);
311
312 form = ServletUtilities.replace(form, PLACEHOLDER_TEMPLATE_WIDTH, getProperty(KEY_FORM_SELECTION_TEMPLATE_WIDTH));
313 form = ServletUtilities.replace(form, PLACEHOLDER_TEMPLATE_HEIGHT, getProperty(KEY_FORM_SELECTION_TEMPLATE_HEIGHT));
314
315 PrintWriter out = response.getWriter();
316 out.println(form);
317
318 logger.info("Form: \n"+form);
319 }
320
321
322
323
324
325 protected String buildJSArray(String[] parts, String quote) {
326 StringBuffer s = new StringBuffer();
327 for (int i=0; i<parts.length; i++) {
328 if (parts[i] != null) {
329 s.append(quote).append(parts[i]).append(quote);
330 s.append(",");
331 }
332 }
333 if (s.length()>0) s.deleteCharAt(s.length()-1);
334 return s.toString();
335 }
336
337 protected String[] parseStringArray(String string) {
338 if (string == null)
339 return new String[0];
340
341 StringTokenizer z = new StringTokenizer(string, " ", false);
342 String[] arr = new String[z.countTokens()];
343 for (int i=0; z.hasMoreTokens(); i++) {
344 arr[i] = z.nextToken();
345 }
346
347 return arr;
348 }
349
350 protected String[][] parseGeometriesArray(String[] string) {
351 if (string == null)
352 return new String[2][0];
353
354 String[][] geo = new String[2][string.length];
355 for (int i=0; i<string.length; i++) {
356 geo[0][i] = string[i].substring(0, string[i].indexOf("x"));
357 geo[1][i] = string[i].substring(string[i].indexOf("x")+1);
358 }
359
360 return geo;
361 }
362 }