View Javadoc

1   /*
2    * Copyright (c) 2005, The K-Wf Grid Consortium
3    * Fraunhofer Institute for Computer Architecture and Software Technology
4    * See http://www.kwfgrid.eu and http://www.first.fraunhofer.de for more details.
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())),             //path in the XML
94  					   ServletUtilities.decode(((String[])entry.getValue())[i]));     //value of the XML tag or its param
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     /// Replace Methods
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 	    // FIXME: XPath needs namespaces if necessary!
152 	    // These must be defined in the Form itself. (e.g. in HTML notes <!-- $XPATH_NAMESPACE_gwdl = http://www.gridworkflow.org/gworkflowdl --> )
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 	// replace all occurences of XPath placeholders
164 	// FIXME: XPath needs namespaces if necessary!
165 	// These must be defined in the Form itself. (e.g. in HTML notes <!-- $XPATH_NAMESPACE_gwdl = "http://www.gridworkflow.org/gworkflowdl" --> )
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); // FIXME
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 }