⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xpathexpressionevaluator.java

📁 jbpm-bpel-1.1.Beta3 JBoss jBPM Starters Kit  是一个综合包
💻 JAVA
字号:
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the JBPM BPEL PUBLIC LICENSE AGREEMENT as
 * published by JBoss Inc.; either version 1.0 of the License, or
 * (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
package org.jbpm.bpel.sublang.xpath;

import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.jaxen.Context;
import org.jaxen.ContextSupport;
import org.jaxen.FunctionContext;
import org.jaxen.JaxenException;
import org.jaxen.XPathFunctionContext;
import org.jaxen.expr.Expr;
import org.jaxen.expr.FilterExpr;
import org.jaxen.expr.FunctionCallExpr;
import org.jaxen.expr.LiteralExpr;
import org.jaxen.expr.LocationPath;
import org.jaxen.expr.NumberExpr;
import org.jaxen.expr.PathExpr;
import org.jaxen.expr.Predicate;
import org.jaxen.expr.PredicateSet;
import org.jaxen.expr.VariableReferenceExpr;
import org.jaxen.expr.VisitorSupport;
import org.w3c.dom.Node;

import org.jbpm.bpel.BpelException;
import org.jbpm.bpel.sublang.exe.ExpressionEvaluator;
import org.jbpm.bpel.variable.def.VariableDefinition;
import org.jbpm.bpel.variable.exe.MessageValue;
import org.jbpm.bpel.xml.BpelConstants;
import org.jbpm.bpel.xml.util.XmlUtil;
import org.jbpm.graph.exe.Token;

/**
 * Default evaluator for expressions. When XPath 1.0 is used as an expression
 * language, there is no context node available.
 * @see "WS-BPEL 2.0 §8.2.4"
 * @author Alejandro Gu韟ar
 * @version $Revision: 1.4 $ $Date: 2006/10/29 06:13:41 $
 */
public class XPathExpressionEvaluator extends XPathEvaluator implements
    ExpressionEvaluator {

  public static final FunctionContext FUNCTION_LIBRARY;

  private static final long serialVersionUID = 1L;

  protected XPathExpressionEvaluator(String text) throws JaxenException {
    super(text);
  }

  /**
   * Evaluates this expression. The context of XPath evaluation is:
   * <ul>
   * <li>the context node, position and size are unspecified</li>
   * <li>the function library, namespace declaration and variable bindings are
   * obtained by a call to {@link #getContext(Object)} with the given
   * <code>contextInfo</code> as argument</li>
   * <ul>
   */
  public Object evaluate(Token contextInfo) {
    Object result = null;
    try {
      List nodeset = selectNodes(contextInfo);
      if (nodeset != null) {
        switch (nodeset.size()) {
        case 0:
          break;
        case 1:
          result = nodeset.get(0);
          break;
        default:
          result = nodeset;
        }
      }
    }
    catch (JaxenException e) {
      throw new BpelException("could not select nodes", e);
    }
    return result;
  }

  public void assign(Token contextInfo, Object value) {
    Expr rootExpr = getRootExpr();
    Context context = getContext(contextInfo);
    // direct variable assignment?
    if (rootExpr instanceof VariableReferenceExpr) {
      assignVariable((VariableReferenceExpr) rootExpr, context, value);
    }
    else {
      new ExprAssigner().assign(rootExpr, context, value);
    }
  }

  protected void assignVariable(VariableReferenceExpr rootExpr,
      Context context, Object value) {
    String variableName = rootExpr.getVariableName();
    ScopeVariableContext variableContext = (ScopeVariableContext) context.getContextSupport()
        .getVariableContext();
    // look for a dot in the variable name, indicating a message part access
    int dotIndex = variableName.indexOf('.');
    if (dotIndex == -1) {
      /*
       * dotless name, a schema type or element describes the variable - find
       * variable definition
       */
      VariableDefinition variableDefinition = variableContext.getVariableDefinition(variableName);
      if (variableDefinition == null) {
        throw new BpelException("variable not found: " + variableName);
      }
      Object valueForAssign = variableDefinition.getValueForAssign(variableContext.getToken());
      // prevent direct access to a message variable
      if (valueForAssign instanceof MessageValue) {
        throw new BpelException("illegal access to message variable: "
            + variableName);
      }
      // assign variable value
      variableDefinition.getType().setValue(valueForAssign, value);
    }
    else {
      /*
       * dotted name, a message describes the variable - find variable
       * definition
       */
      String messageName = variableName.substring(0, dotIndex);
      VariableDefinition variableDefinition = variableContext.getVariableDefinition(messageName);
      if (variableDefinition == null) {
        throw new BpelException("variable not found: " + messageName);
      }
      Object valueForAssign = variableDefinition.getValueForAssign(variableContext.getToken());
      // prevent access to a non-existent part
      if (!(valueForAssign instanceof MessageValue)) {
        throw new BpelException("non-message variable does not have part: "
            + variableName);
      }
      // extract initialized message value
      MessageValue messageValue = (MessageValue) valueForAssign;
      // assign part value
      String partName = variableName.substring(dotIndex + 1);
      messageValue.setPart(partName, value);
    }
  }

  protected FunctionContext createFunctionContext() {
    return FUNCTION_LIBRARY;
  }

  /**
   * Gets a context for XPath evaluation. The context for an expression
   * expression is:
   * <ul>
   * <li>the variable bindings are the variables in the scope of the given
   * token</li>
   * <li>the function library is {@link #FUNCTION_LIBRARY}</li>
   * <li>the namespace declarations are taken from the snippet</li>
   * </ul>
   * @param node an instance of {@link Token}
   */
  protected Context getContext(Object node) {
    ContextSupport support = new ContextSupport(getNamespaceContext(),
        getFunctionContext(), new ScopeVariableContext((Token) node),
        getNavigator());
    return new Context(support);
  }

  private class ExprAssigner extends VisitorSupport {

    private Context context;
    private Object result;

    public void assign(Expr pathExpr, Context context, Object value) {
      this.context = context;
      pathExpr.accept(this);
      Node node = result instanceof List ? getSingleNode((List) result)
          : (Node) result;
      XmlUtil.setObjectValue(node, value);
    }

    public void visit(PathExpr pathExpr) {
      pathExpr.getFilterExpr().accept(this);
      visit(pathExpr.getLocationPath());
    }

    public void visit(FilterExpr filterExpr) {
      filterExpr.getExpr().accept(this);
      // result is a node set so far?
      if (result instanceof List) {
        result = evaluatePredicates(filterExpr.getPredicateSet(),
            (List) result, context.getContextSupport());
      }
    }

    public void visit(LocationPath locationPath) {
      context.setNodeSet(result instanceof List ? (List) result
          : Collections.singletonList(result));
      try {
        result = selectOrCreateNodes(locationPath, context);
      }
      catch (JaxenException e) {
        throw new BpelException("could not select (or create) nodes", e);
      }
    }

    public void visit(VariableReferenceExpr varExpr) {
      String variableName = varExpr.getVariableName();
      ScopeVariableContext variableContext = (ScopeVariableContext) context.getContextSupport()
          .getVariableContext();
      // look for a dot in the variable name, indicating a message part access
      int dotIndex = variableName.indexOf('.');
      if (dotIndex == -1) {
        /*
         * dotless name, a schema type or element describes the variable - find
         * variable definition
         */
        VariableDefinition variableDefinition = variableContext.getVariableDefinition(variableName);
        if (variableDefinition == null) {
          throw new BpelException("variable not found: " + variableName);
        }
        // variable value for assign
        result = variableDefinition.getValueForAssign(variableContext.getToken());
      }
      else {
        /*
         * dotted name, a message describes the variable - find variable
         * definition
         */
        String messageName = variableName.substring(0, dotIndex);
        VariableDefinition definition = variableContext.getVariableDefinition(messageName);
        if (definition == null) {
          throw new BpelException("variable not found: " + messageName);
        }
        // prevent access to a non-existent part
        if (!definition.getType().isMessage()) {
          throw new BpelException("non-message variable does not have part: "
              + variableName);
        }
        // extract initialized message value
        MessageValue messageValue = (MessageValue) definition.getValueForAssign(variableContext.getToken());
        // part value for assign
        String partName = variableName.substring(dotIndex + 1);
        result = messageValue.getPartForAssign(partName);
      }
    }

    public void visit(LiteralExpr literalExpr) {
      try {
        result = literalExpr.evaluate(context);
      }
      catch (JaxenException e) {
        throw new BpelException("could not evaluate literal expression", e);
      }
    }

    public void visit(NumberExpr numberExpr) {
      try {
        result = numberExpr.evaluate(context);
      }
      catch (JaxenException e) {
        throw new BpelException("could not evaluate number expression", e);
      }
    }

    public void visit(FunctionCallExpr callExpr) {
      try {
        result = callExpr.evaluate(context);
      }
      catch (JaxenException e) {
        throw new BpelException("could not evaluate call expression", e);
      }
    }

    private List evaluatePredicates(PredicateSet predicateSet, List nodes,
        ContextSupport support) {
      List predicates = predicateSet.getPredicates();
      if (!predicates.isEmpty()) {
        try {
          Iterator predicateIt = predicateSet.getPredicates().iterator();
          while (predicateIt.hasNext()) {
            nodes = predicateSet.applyPredicate((Predicate) predicateIt.next(),
                nodes, support);
          }
        }
        catch (JaxenException e) {
          throw new BpelException("could not apply predicate", e);
        }
      }
      return nodes;
    }
  }

  static {
    XPathFunctionContext functionContext = new XPathFunctionContext();
    FUNCTION_LIBRARY = functionContext;
    // BPEL library
    functionContext.registerFunction(BpelConstants.NS_BPEL_1_1,
        "getVariableData", new GetVariableDataFunction());
    functionContext.registerFunction(BpelConstants.NS_BPEL_1_1,
        "getVariableProperty", new GetVariablePropertyFunction());
    functionContext.registerFunction(BpelConstants.NS_BPEL,
        "getVariableProperty", new GetVariablePropertyFunction());
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -