/**
   * @see
   *     org.apache.ode.bpel.explang.ExpressionLanguageRuntime#evaluate(org.apache.ode.bpel.obj.OExpression,
   *     org.apache.ode.bpel.explang.EvaluationContext)
   */
  public List evaluate(OExpression cexp, EvaluationContext ctx)
      throws FaultException, EvaluationException {
    List result;
    Object someRes = evaluate(cexp, ctx, XPathConstants.NODESET);

    if (someRes instanceof List) {
      result = (List) someRes;
      if (__log.isDebugEnabled()) {
        __log.debug("Returned list of size " + result.size());
      }

      if ((result.size() == 1) && !(result.get(0) instanceof Node)) {
        // Dealing with a Java class
        Object simpleType = result.get(0);

        // Dates get a separate treatment as we don't want to call toString on them
        String textVal;

        if (simpleType instanceof Date) {
          textVal = ISO8601DateParser.format((Date) simpleType);
        } else if (simpleType instanceof DurationValue) {
          textVal = ((DurationValue) simpleType).getStringValue();
        } else {
          textVal = simpleType.toString();
        }

        // Wrapping in a document
        Document d = DOMUtils.newDocument();

        // Giving our node a parent just in case it's an LValue expression
        Element wrapper = d.createElement("wrapper");
        Text text = d.createTextNode(textVal);
        wrapper.appendChild(text);
        d.appendChild(wrapper);
        result = Collections.singletonList(text);
      }
    } else if (someRes instanceof NodeList) {
      NodeList retVal = (NodeList) someRes;
      if (__log.isDebugEnabled()) {
        __log.debug("Returned node list of size " + retVal.getLength());
      }
      result = new ArrayList(retVal.getLength());

      for (int m = 0; m < retVal.getLength(); ++m) {
        Node val = retVal.item(m);

        if (val.getNodeType() == Node.DOCUMENT_NODE) {
          val = ((Document) val).getDocumentElement();
        }

        result.add(val);
      }
    } else {
      result = null;
    }

    return result;
  }
 public Node fetchVariableData(
     VariableInstance variable, ScopeFrame scopeFrame, boolean forWriting) throws FaultException {
   if (variable.declaration.extVar != null) {
     // Note, that when using external variables, the database will not contain the value of the
     // variable, instead we need to go the external variable subsystems.
     Element reference =
         (Element)
             _brc.fetchVariableData(
                 scopeFrame.resolve(variable.declaration.extVar.related), false);
     try {
       Node ret = _brc.readExtVar(variable, reference);
       if (ret == null) {
         throw new FaultException(
             _runtime._oprocess.constants.qnUninitializedVariable,
             "The external variable \""
                 + variable.declaration.name
                 + "\" has not been initialized.");
       }
       return ret;
     } catch (IncompleteKeyException ike) {
       // This indicates that the external variable needed to be written do, put has not been.
       __log.error(
           "External variable could not be read due to incomplete key; the following key "
               + "components were missing: "
               + ike.getMissing());
       throw new FaultException(
           _runtime._oprocess.constants.qnUninitializedVariable,
           "The extenral variable \""
               + variable.declaration.name
               + "\" has not been properly initialized;"
               + "the following key compoenents were missing:"
               + ike.getMissing());
     } catch (ExternalVariableModuleException e) {
       throw new BpelEngineException(e);
     }
   } else /* not external */ {
     Node data = _brc.fetchVariableData(variable, forWriting);
     if (data == null) {
       // Special case of messageType variables with no part
       if (variable.declaration.type instanceof OMessageVarType) {
         OMessageVarType msgType = (OMessageVarType) variable.declaration.type;
         if (msgType.parts.size() == 0) {
           Document doc = DOMUtils.newDocument();
           Element root = doc.createElement("message");
           doc.appendChild(root);
           return root;
         }
       }
       throw new FaultException(
           _runtime._oprocess.constants.qnUninitializedVariable,
           "The variable " + variable.declaration.name + " isn't properly initialized.");
     }
     return data;
   }
 }
Esempio n. 3
0
  /**
   * Create a property mapping based on the initial values in the deployment descriptor.
   *
   * @param dd
   * @return
   */
  public static Map<QName, Node> calcInitialProperties(
      Properties properties, TDeployment.Process dd) {
    HashMap<QName, Node> ret = new HashMap<QName, Node>();

    for (Object key1 : properties.keySet()) {
      String key = (String) key1;
      Document doc = DOMUtils.newDocument();
      doc.appendChild(doc.createElementNS(null, "temporary-simple-type-wrapper"));
      doc.getDocumentElement().appendChild(doc.createTextNode(properties.getProperty(key)));

      ret.put(new QName(key), doc.getDocumentElement());
    }

    for (TDeployment.Process.Property property : dd.getPropertyArray()) {
      Element elmtContent = DOMUtils.getElementContent(property.getDomNode());
      if (elmtContent != null) {
        // We'll need DOM Level 3
        Document doc = DOMUtils.newDocument();
        doc.appendChild(doc.importNode(elmtContent, true));
        ret.put(property.getName(), doc.getDocumentElement());
      } else ret.put(property.getName(), property.getDomNode().getFirstChild());
    }
    return ret;
  }
  /**
   * Cast XQuery sequence into an opaque list
   *
   * @param type type
   * @param result result
   * @return value
   * @throws XQException XQException
   */
  private Object getResultValue(QName type, XQResultSequence result) throws XQException {
    Document document = DOMUtils.newDocument();
    Object resultValue = null;
    if (XPathConstants.NODESET.equals(type)) {
      List list = new ArrayList();

      while (result.next()) {
        Object itemValue = getItemValue(result.getItem());
        if (itemValue instanceof Document) {
          itemValue = DOMUtils.cloneNode(document, ((Document) itemValue).getDocumentElement());
        } else if (itemValue instanceof Node) {
          itemValue = DOMUtils.cloneNode(document, (Node) itemValue);
        }

        if (itemValue != null) {
          list.add(itemValue);
        }
      }

      resultValue = list;
    } else if (XPathConstants.NODE.equals(type)) {
      XQItem item = null;
      if (result.count() > 0) {
        result.first();
        if (result.isOnItem()) {
          item = result.getItem();
        }
      }
      if (item != null) {
        resultValue = getItemValue(item);
        if (resultValue instanceof Node) {
          resultValue = DOMUtils.cloneNode(document, (Node) resultValue);
        }
      }
    } else if (XPathConstants.STRING.equals(type)) {
      resultValue = result.getSequenceAsString(new Properties());
    } else if (XPathConstants.NUMBER.equals(type)) {
      resultValue = result.getSequenceAsString(new Properties());
      resultValue = Integer.parseInt((String) resultValue);
    } else if (XPathConstants.BOOLEAN.equals(type)) {
      resultValue = result.getSequenceAsString(new Properties());
      resultValue = Boolean.parseBoolean((String) resultValue);
    }
    return resultValue;
  }
  /**
   * Evaluate expression and return opaque type
   *
   * @param cexp cexp
   * @param ctx ctx
   * @param type type
   * @return type
   * @throws FaultException FaultException
   * @throws EvaluationException EvaluationException
   */
  private Object evaluate(OExpression cexp, EvaluationContext ctx, QName type)
      throws FaultException, EvaluationException {
    try {
      OXQuery10ExpressionBPEL20 oxquery10 = ((OXQuery10ExpressionBPEL20) cexp);

      XQDataSource xqds = new SaxonXQDataSource();
      XQConnection xqconn = xqds.getConnection();

      Configuration configuration = ((SaxonXQConnection) xqconn).getConfiguration();
      configuration.setAllNodesUntyped(true);
      configuration.setHostLanguage(Configuration.XQUERY);

      XQStaticContext staticEnv = xqconn.getStaticContext();

      NSContext nsContext = oxquery10.getNamespaceCtx();
      Set<String> prefixes = nsContext.getPrefixes();
      for (String prefix : prefixes) {
        String uri = nsContext.getNamespaceURI(prefix);
        staticEnv.declareNamespace(prefix, uri);
      }

      configuration.setSchemaValidationMode(Validation.SKIP);
      xqconn.setStaticContext(staticEnv);

      // Prepare expression, for starters
      String xquery =
          oxquery10
              .getXquery()
              .replaceFirst(
                  Constants.XQUERY_FUNCTION_HANDLER_COMPILER,
                  Constants.XQUERY_FUNCTION_HANDLER_RUNTIME);
      XQPreparedExpression exp = xqconn.prepareExpression(xquery);

      JaxpFunctionResolver funcResolver = new JaxpFunctionResolver(ctx, oxquery10);
      JaxpVariableResolver variableResolver =
          new JaxpVariableResolver(ctx, oxquery10, configuration);
      // Bind external variables to runtime values
      for (QName variable : exp.getAllUnboundExternalVariables()) {
        // Evaluate referenced variable
        Object value = variableResolver.resolveVariable(variable);

        if (value instanceof Value) {
          SaxonXQConnection saxonConn = (SaxonXQConnection) xqconn;
          try {
            Item item = ((Value) value).asItem();
            if (item == null) {
              exp.bindSequence(variable, xqconn.createSequence(Collections.EMPTY_LIST.iterator()));
            } else {
              XQItem item2 = new SaxonXQItem(item, saxonConn);
              exp.bindItem(variable, item2);
            }
          } catch (XPathException e) {
            __log.warn("", e);
          }
        } else {

          if (value instanceof Date) {
            Date d = (Date) value;
            value = org.apache.ode.utils.ISO8601DateParser.format(d);
          }

          // Figure out type of variable
          XQSequenceType xqType = getItemType(xqconn, value);

          // Saxon doesn't like binding sequences to variables
          if (value instanceof Node) {
            // a node is a node-list, but the inverse isn't true.
            // so, if the value is truly a node, leave it alone.
          } else if (value instanceof NodeList) {
            // So extract the first item from the node list
            NodeList nodeList = (NodeList) value;
            ArrayList nodeArray = new ArrayList();
            for (int i = 0; i < nodeList.getLength(); i++) {
              nodeArray.add(nodeList.item(i));
            }
            value = xqconn.createSequence(nodeArray.iterator());
          }

          // Bind value with external variable
          if (value != null && xqType != null) {
            if (value instanceof XQSequence) {
              exp.bindSequence(variable, (XQSequence) value);
            } else {
              if (xqType instanceof XQItemType) {
                exp.bindObject(variable, value, (XQItemType) xqType);
              }
            }
          }
        }
      }

      // Set context node
      Node contextNode = (ctx.getRootNode() == null) ? DOMUtils.newDocument() : ctx.getRootNode();
      contextNode.setUserData(
          XQuery10BpelFunctions.USER_DATA_KEY_FUNCTION_RESOLVER, funcResolver, null);
      exp.bindItem(
          XQConstants.CONTEXT_ITEM,
          xqconn.createItemFromNode(contextNode, xqconn.createNodeType()));

      // Execute query
      XQResultSequence result = exp.executeQuery();

      // Cast Saxon result to Java result
      Object evalResult = getResultValue(type, result);

      if ((evalResult != null) && __log.isDebugEnabled()) {
        __log.debug(
            "Expression "
                + cexp.toString()
                + " generated result "
                + evalResult
                + " - type="
                + evalResult.getClass().getName());

        if (ctx.getRootNode() != null) {
          __log.debug("Was using context node " + DOMUtils.domToString(ctx.getRootNode()));
        }
      }

      return evalResult;
    } catch (XQException xqe) {
      // Extracting the real cause from all this wrapping isn't a simple task
      Throwable cause = (xqe.getCause() != null) ? xqe.getCause() : xqe;

      if (cause instanceof DynamicError) {
        Throwable th = ((DynamicError) cause).getException();

        if (th != null) {
          cause = th;

          if (cause.getCause() != null) {
            cause = cause.getCause();
          }
        }
      }

      throw new EvaluationException(
          "Error while executing an XQuery expression: " + cause.toString(), cause);
    } catch (WrappedResolverException wre) {
      __log.debug("Could not evaluate expression because of ", wre);
      throw (FaultException) wre.getCause();
    }
  }