View Javadoc

1   /*
2    * Copyright 2010 Fraunhofer Gesellschaft, Munich, Germany,
3    * for its Fraunhofer Institute for Computer Architecture and Software
4    * Technology (FIRST), Berlin, Germany. All rights reserved.
5    * http://www.first.fraunhofer.de/
6    */
7   
8   package net.kwfgrid.gwes;
9   
10  import org.apache.log4j.Logger;
11  import org.jdom.Element;
12  import org.jdom.Content;
13  import org.jdom.Document;
14  import org.jaxen.SimpleNamespaceContext;
15  import org.jaxen.JaxenException;
16  import org.jaxen.XPath;
17  import org.jaxen.jdom.JDOMXPath;
18  import net.kwfgrid.gworkflowdl.structure.*;
19  import net.kwfgrid.gwes.util.StringUtils;
20  
21  import java.util.List;
22  import java.io.IOException;
23  
24  /**
25   * This class evaluates XPath expressions and generates tokens based on the evaluation result.
26   * @author Andreas Hoheisel
27   *         (<a href="http://www.andreas-hoheisel.de">www.andreas-hoheisel.de</a>)
28   * @version $Id: TokenProcessor.java 1433 2010-11-29 18:06:07Z hoheisel $
29   */
30  public class TokenProcessor {
31  
32      private final static Logger logger = Logger.getLogger(TokenProcessor.class);
33  
34      private final Document context;
35  
36      private final TokenParameterList tokenList;
37  
38      private final SimpleNamespaceContext nsContext;
39  
40      /**
41       * Constructor of the data token processor.
42       * @param context The xml which is used as context for the evaluation.
43       * @param tokenList A list of token parameters. 
44       * @throws WorkflowFormatException
45       */
46      public TokenProcessor(SimpleNamespaceContext nsContext, Document context, TokenParameterList tokenList) {
47          this.context = context;
48          this.tokenList = tokenList;
49          this.nsContext = nsContext;
50          if (logger.isDebugEnabled()) {
51              try {
52                  logger.debug("context:\n"+JdomString.document2string(context));
53              } catch (IOException e) {
54                  logger.error("exception: " + e, e);
55              }
56          }
57      }
58  
59      /**
60       * Generate the data output tokens by evaluating the XPath expressions against the context.
61       * This method only creates new tokens if the current token is null and if the XPath expression evaluation
62       * returns a non-empty value.
63       * @param props The generic properties to be included for all tokens.
64       * @return The Token Map.
65       * @throws WorkflowFormatException
66       */
67      public TokenParameterList generateOutputTokens(GenericProperties props) throws WorkflowFormatException {
68          if (tokenList == null) return null;
69          for (TokenParameter tp : tokenList) {
70              // only generate new token if there is no old token.
71              if (tp.token != null) continue;
72              switch(tp.scope) {
73                  case OUTPUT:
74                      String xpathExpression = StringUtils.expandContextVariables(StringUtils.stripOwl(tp.edge.getExpression()));
75                      if (xpathExpression == null) continue;
76                      try {
77                          Object obj = evaluate(xpathExpression);
78                          Element tokenElement = new Element("data");
79                          if (obj == null) {
80                              // do nothing
81                          } else if (obj instanceof List) {
82                              List tokenElements = ((List) obj);
83                              // create also data token, if list is empty
84                              for (Object elementobj : tokenElements) {
85                                  Content content = (Content) ((Content) elementobj).clone();
86                                  tokenElement.addContent(content);
87                              }
88                          } else if (obj instanceof Double) {
89                              Element element = new Element("double");
90                              element.addContent(obj.toString());
91                              tokenElement.addContent(element);
92                          } else if (obj instanceof Boolean) {
93                              Element element = new Element("boolean");
94                              element.addContent(obj.toString());
95                              tokenElement.addContent(element);
96                          } else if (obj instanceof String) {
97                              Element element = new Element("string");
98                              element.addContent(obj.toString());
99                              tokenElement.addContent(element);
100                         } else {
101                             throw new WorkflowFormatException("Type of evaluation result ["+obj.toString()+"] of edgeExpression '" + xpathExpression + "' is not supported");
102                         }
103                         Data data = Factory.newData(tokenElement);
104                         tp.token = Factory.newToken(data,props);
105                     } catch (JaxenException e) {
106                         logger.error("exception: " + e, e);
107                         throw new WorkflowFormatException("Could not interpret edgeExpression '" + xpathExpression + "' as XPath expression: " +e, e);
108                     }
109 
110                     break;
111             }
112         }
113 
114         return tokenList;
115     }
116 
117     /**
118      * This method evaluates one XPath expression.
119      * @param xpathExpression The XPath expression to evaluate.
120      * @return The evaluation object.
121      * @throws JaxenException
122      */
123     private Object evaluate(String xpathExpression) throws JaxenException {
124         // xpath evaluation
125         XPath xpath = new JDOMXPath(xpathExpression);
126         xpath.setNamespaceContext(nsContext);
127         Object ret = xpath.evaluate(context);
128         if (logger.isDebugEnabled()) {
129             logger.debug("Evaluation of expression '" + xpathExpression + "' returns " + ret.toString());
130         }
131         return ret;
132     }
133 
134 }