1
2
3
4
5
6 package net.kwfgrid.gwui.servlets;
7
8 import java.io.UnsupportedEncodingException;
9 import javax.servlet.http.HttpServletRequest;
10
11 import net.kwfgrid.gworkflowdl.structure.*;
12
13 import java.util.Map;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.regex.*;
17
18 import org.apache.log4j.Logger;
19
20 import org.jaxen.*;
21 import org.jaxen.jdom.*;
22
23 import org.jdom.*;
24
25 /***
26 Must be deployed as "/DefaultDataServlet".
27 */
28 public final class DefaultDataServlet extends DataServletBase {
29 private static Logger logger = Logger.getLogger(DefaultDataServlet.class);
30
31 /*** The prefix of the namespace declarations. */
32 public static final String PREFIX_NAMESPACE_DECLARATION = "NAMESPACE_";
33
34 /*** The prefix of the XPath placeholders. */
35 public static final String PREFIX_PLACEHOLDER_XPATH = "$XPATH_";
36
37 /*** The prefix of the XPath placeholders to be used in regular expressions. */
38 public static final String RX_PREFIX_PLACEHOLDER_XPATH = "//$XPATH_";
39 /*** The prefix of the value placeholders to be used in regular expressions. */
40 public static final String RX_PREFIX_PLACEHOLDER_VALUE = "//$VALUE_";
41 /*** The prefix of a boolean value placeholder for "true" to be used in regular expressions. */
42 public static final String RX_PREFIX_PLACEHOLDER_BOOLEAN_TRUE = "//$IFTRUE_";
43 /*** The prefix of a boolean value placeholder for "false" to be used in regular expressions. */
44 public static final String RX_PREFIX_PLACEHOLDER_BOOLEAN_FALSE = "//$IFFALSE_";
45 /*** The delimiter of a placeholder. */
46 public static final String DELIMITER_PLACEHOLDER = ";";
47 /*** The split character used inside placeholders. */
48 public static final String SPLIT_PLACEHOLDER = "_";
49
50 private static final String[] RX_PREFIXES = new String[] { RX_PREFIX_PLACEHOLDER_VALUE,
51 RX_PREFIX_PLACEHOLDER_BOOLEAN_TRUE,
52 RX_PREFIX_PLACEHOLDER_BOOLEAN_FALSE,
53 RX_PREFIX_PLACEHOLDER_XPATH };
54 protected Logger getLogger() {
55 return logger;
56 }
57 /***
58 Extract namespaces from a "create token" request.
59 */
60 private final Map extractNamespaces(HttpServletRequest request) throws UnsupportedEncodingException {
61 Map params = request.getParameterMap();
62 Map retv = new HashMap();
63 Iterator iter = params.entrySet().iterator();
64 Map.Entry entry;
65 while( iter.hasNext() )
66 {
67 entry = (Map.Entry)( iter.next() );
68 if( ( (String)( entry.getKey() ) ).startsWith( PREFIX_NAMESPACE_DECLARATION) )
69 {
70 retv.put( ( (String)( entry.getKey() ) ).substring( PREFIX_NAMESPACE_DECLARATION.length() ), ServletUtilities.decode(((String[])entry.getValue())[0]));
71 }
72 }
73 return retv;
74 }
75
76 protected Token createToken(HttpServletRequest request) throws WorkflowFormatException, UnsupportedEncodingException {
77 Map nameSpaces = extractNamespaces( request );
78 nameSpaces.put("xsi", "http://www.w3.org/2001/XMLSchema-instance");
79
80 XmlTag myTag = new XmlTag( nameSpaces );
81
82 Map params = request.getParameterMap();
83 Iterator iter = params.entrySet().iterator();
84 Map.Entry entry;
85
86 while( iter.hasNext() )
87 {
88 entry = (Map.Entry)( iter.next() );
89 if( ((String)( entry.getKey() ) ).startsWith( "." ) )
90 {
91 for( int i = 0; i < ((String[])( entry.getValue() ) ).length; i ++ )
92 {
93 myTag.createFromString(ServletUtilities.decode(((String)entry.getKey())),
94 ServletUtilities.decode(((String[])entry.getValue())[i]));
95 }
96 }
97
98 }
99
100 String xml = myTag.createStringRepresentation( 0, true );
101 getLogger().info("Creating token: \n"+xml);
102 Data data = Factory.newData();
103 data.fromXML(xml);
104 Token token = Factory.newToken(data);
105 return token;
106 }
107
108
109
110
111
112 /***
113 Get the input place of the transition that has the edge with the specified edge-expression.
114 */
115 private Place getInputPlace(Transition transition, String edgeexpression) {
116 Edge[] edges = transition.getReadEdges();
117 for (int i=0; i<edges.length; i++) {
118 if (edgeexpression.equals(edges[i].getExpression())) return edges[i].getPlace();
119 }
120 edges = transition.getInEdges();
121 for (int i=0; i<edges.length; i++) {
122 if (edgeexpression.equals(edges[i].getExpression())) return edges[i].getPlace();
123 }
124 return null;
125 }
126
127 private String getXPathReplacement(String xpathplaceholder, Transition transition) {
128 xpathplaceholder = xpathplaceholder.substring(PREFIX_PLACEHOLDER_XPATH.length());
129 String edgeexpression = xpathplaceholder.substring(0, xpathplaceholder.indexOf(SPLIT_PLACEHOLDER));
130 String xpathexpression = xpathplaceholder.substring(edgeexpression.length() + SPLIT_PLACEHOLDER.length(), xpathplaceholder.length()-1);
131
132 Place place = getInputPlace(transition, edgeexpression);
133 if (place == null) {
134 logger.warn("Could not find input-place with edgeexpression "+edgeexpression+" at transition "+transition.getID());
135 return "";
136 }
137
138 Token token = place.getTokens()[0];
139
140 if (!(token instanceof StdToken)) {
141 logger.warn("No JDOMToken on place "+place.getID()+"; can not execute XPath replacement in form.");
142 return "";
143 }
144
145 Element element = (Element)token.getData().get();
146
147 String replacement = "";
148
149 try {
150 XPath xpath = new JDOMXPath(xpathexpression);
151
152
153 replacement = xpath.stringValueOf(element);
154 } catch (JaxenException x) {
155 logger.error("Jaxen exception when executing XPath replacement.", x);
156 return "";
157 }
158
159 return replacement;
160 }
161
162 protected String replaceValues(String form, Transition transition) {
163
164
165
166 Pattern p = Pattern.compile(RX_PREFIX_PLACEHOLDER_XPATH+".*"+DELIMITER_PLACEHOLDER);
167 Matcher m = p.matcher(form);
168 StringBuffer sb = new StringBuffer();
169 while (m.find()) {
170 m.appendReplacement(sb, getXPathReplacement(m.group(), transition));
171 }
172 m.appendTail(sb);
173 return clearValues(sb.toString());
174 }
175
176 protected String replaceValues(String form, Token token) {
177 return clearValues(form);
178 }
179
180 protected String clearValues(String form) {
181 for (int i=0; i<RX_PREFIXES.length; i++) {
182 form = form.replaceAll(RX_PREFIXES[i]+".*"+DELIMITER_PLACEHOLDER, "");
183 }
184 return form;
185 }
186 }