/**
   * Process this instruction
   *
   * @param context the dynamic context of the transformation
   * @return a TailCall to be executed by the caller, always null for this instruction
   */
  public TailCall processLeavingTail(XPathContext context) throws XPathException {
    Controller controller = context.getController();
    SequenceReceiver out = context.getReceiver();
    int opt = options;
    int ann = annotation;

    // we may need to change the namespace prefix if the one we chose is
    // already in use with a different namespace URI: this is done behind the scenes
    // by the Outputter

    CharSequence value = expandChildren(context);
    if (schemaType != null) {
      // test whether the value actually conforms to the given type
      XPathException err =
          schemaType.validateContent(
              value,
              DummyNamespaceResolver.getInstance(),
              context.getConfiguration().getNameChecker());
      if (err != null) {
        ValidationException verr =
            new ValidationException(
                "Attribute value "
                    + Err.wrap(value, Err.VALUE)
                    + " does not the match the required type "
                    + schemaType.getDescription()
                    + ". "
                    + err.getMessage());
        verr.setErrorCode("XTTE1540");
        verr.setLocator(this);
        throw verr;
      }
    } else if (validationAction == Validation.STRICT || validationAction == Validation.LAX) {
      try {
        ann = controller.getConfiguration().validateAttribute(nameCode, value, validationAction);
      } catch (ValidationException e) {
        DynamicError err = DynamicError.makeDynamicError(e);
        String errorCode = e.getErrorCodeLocalPart();
        if (errorCode == null) {
          errorCode = (validationAction == Validation.STRICT ? "XTTE1510" : "XTTE1515");
        }
        err.setErrorCode(errorCode);
        err.setXPathContext(context);
        err.setLocator(this);
        err.setIsTypeError(true);
        throw err;
      }
    }
    try {
      out.attribute(nameCode, ann, value, locationId, opt);
    } catch (XPathException err) {
      throw dynamicError(this, err, context);
    }

    return null;
  }
 /**
  * Get the dateTime value representing the nominal date/time of this transformation run. Two calls
  * within the same query or transformation will always return the same answer.
  *
  * @param context the XPath dynamic context. May be null, in which case the current date and time
  *     are taken directly from the system clock
  * @return the current xs:dateTime
  */
 public static DateTimeValue getCurrentDateTime(XPathContext context) {
   Controller c;
   if (context == null || (c = context.getController()) == null) {
     // non-XSLT/XQuery environment
     // We also take this path when evaluating compile-time expressions that require an implicit
     // timezone.
     return new DateTimeValue(new GregorianCalendar(), true);
   } else {
     return c.getCurrentDateTime();
   }
 }
示例#3
0
  private TransformerHandler createTransformerHandler() {
    try {
      TransformerHandlerImpl transformerHandler =
          (TransformerHandlerImpl) GENERIC_FACTORY.newTransformerHandler(templates);

      TransformerImpl impl = (TransformerImpl) transformerHandler.getTransformer();
      XsltTransformer xslt = impl.getUnderlyingXsltTransformer();
      Controller controller = (Controller) xslt.getUnderlyingController();

      if (configuration != null) {
        for (Entry<String, Object> entry : configuration.entrySet()) {
          String name = entry.getKey();

          // is valid XSLT parameter name
          if (XSLT_PARAMETER_NAME_PATTERN.matcher(name).matches()) {
            xslt.setParameter(new QName(name), new XdmExternalObject(entry.getValue()));
          }
        }
      }

      controller.setErrorListener(new TraxErrorListener(LOG, source.toExternalForm()));

      if (context != null) {
        xslt.setParameter(CoreConstants.APPLICATION_CONTEXT_PARAM, new XdmExternalObject(context));
      }

      Map<String, Object> model = HttpContextHelper.getModel(parameters);
      xslt.setParameter(CoreConstants.MODEL_PARAM, new XdmExternalObject(model));

      if (parameters != null)
        try {
          ServletContext servletContext = HttpContextHelper.getServletContext(parameters);
          xslt.setParameter(
              CoreConstants.SERVLET_CONTEXT_PARAM, new XdmExternalObject(servletContext));

          HttpServletRequest servletRequest = HttpContextHelper.getRequest(parameters);
          HttpServletResponse servletResponse = HttpContextHelper.getResponse(parameters);

          if (servletRequest != null) {
            controller.setURIResolver(new SaxonResolver(servletRequest, servletResponse));

            xslt.setParameter(
                Message.LOCALE_PARAM,
                new XdmExternalObject(RequestContextUtils.getLocale(servletRequest)));

            xslt.setParameter(
                CoreConstants.SERVLET_REQUEST_PARAM, new XdmExternalObject(servletRequest));

            HttpSession session = servletRequest.getSession(false);
            if (session != null) {
              xslt.setParameter(
                  CoreConstants.SERVLET_SESSION_PARAM, new XdmExternalObject(session));
            }

            // add support for form binding
            xslt.setParameter(
                CoreConstants.REQUEST_CONTEXT_PARAM,
                new XdmExternalObject(
                    new RequestContext(servletRequest, servletResponse, servletContext, model)));
          }

          if (servletResponse != null) {
            xslt.setParameter(
                CoreConstants.SERVLET_RESPONSE_PARAM, new XdmExternalObject(servletResponse));
          }
        } catch (IllegalStateException e) {
          LOG.debug("Not a Servlet request!", e);

          //				@SuppressWarnings({"rawtypes", "unchecked"})
          //				HashMap<String, Object> model = (HashMap) parameters.get("model");
          //
          //				HttpServletRequest servletRequest = new VirtualRequest();
          //				servletRequest.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE,
          // context);
          //				RequestContext requestContext = new RequestContext(servletRequest, model);
          //
          //				transformer.setParameter(CoreConstants.REQUEST_CONTEXT_PARAM, requestContext);
        }

      return transformerHandler;
    } catch (TransformerConfigurationException ex) {
      throw new SetupException("Could not initialize transformer handler.", ex);
    }
  }
  /**
   * Get a Receiver that wraps a given Result object. Saxon calls this method to construct a
   * serialization pipeline. The method can be overridden in a subclass; alternatively, the subclass
   * can override the various methods used to instantiate components of the serialization pipeline.
   *
   * @param result The final destination of the serialized output. Usually a StreamResult, but other
   *     kinds of Result are possible.
   * @param pipe The PipelineConfiguration.
   * @param props The serialization properties
   */
  public Receiver getReceiver(Result result, PipelineConfiguration pipe, Properties props)
      throws XPathException {
    if (result instanceof Emitter) {
      ((Emitter) result).setOutputProperties(props);
      return (Emitter) result;
    } else if (result instanceof Receiver) {
      Receiver receiver = (Receiver) result;
      receiver.setSystemId(result.getSystemId());
      receiver.setPipelineConfiguration(pipe);
      return receiver;
    } else if (result instanceof SAXResult) {
      ContentHandlerProxy proxy = newContentHandlerProxy();
      proxy.setUnderlyingContentHandler(((SAXResult) result).getHandler());
      proxy.setPipelineConfiguration(pipe);
      proxy.setOutputProperties(props);
      if ("yes".equals(props.getProperty(SaxonOutputKeys.SUPPLY_SOURCE_LOCATOR))) {
        if (pipe.getConfiguration().isCompileWithTracing()) {
          pipe.getController().addTraceListener(proxy.getTraceListener());
        } else {
          DynamicError de =
              new DynamicError(
                  "Cannot use saxon:supply-source-locator unless tracing was enabled at compile time");
          de.setErrorCode(SaxonErrorCode.SXSE0002);
          throw de;
        }
      }
      proxy.open();
      return proxy;
    } else if (result instanceof StreamResult) {

      // The "target" is the start of the output pipeline, the Receiver that
      // instructions will actually write to (except that other things like a
      // NamespaceReducer may get added in front of it). The "emitter" is the
      // last thing in the output pipeline, the Receiver that actually generates
      // characters or bytes that are written to the StreamResult.

      Receiver target;
      String method = props.getProperty(OutputKeys.METHOD);
      if (method == null) {
        target = newUncommittedSerializer(result, props);
        target.setPipelineConfiguration(pipe);
        return target;
      }

      Emitter emitter;

      CharacterMapExpander characterMapExpander = null;
      String useMaps = props.getProperty(SaxonOutputKeys.USE_CHARACTER_MAPS);
      if (useMaps != null) {
        Controller controller = (pipe == null ? null : pipe.getController());
        if (controller == null) {
          DynamicError de =
              new DynamicError("Cannot use character maps in an environment with no Controller");
          de.setErrorCode(SaxonErrorCode.SXSE0001);
          throw de;
        }
        characterMapExpander = controller.makeCharacterMapExpander(useMaps, this);
        characterMapExpander.setPipelineConfiguration(pipe);
      }

      ProxyReceiver normalizer = null;
      String normForm = props.getProperty(SaxonOutputKeys.NORMALIZATION_FORM);
      if (normForm != null && !normForm.equals("none")) {
        normalizer = newUnicodeNormalizer(pipe, props);
      }

      if ("html".equals(method)) {
        emitter = newHTMLEmitter();
        emitter.setPipelineConfiguration(pipe);
        target = createHTMLSerializer(emitter, props, pipe, characterMapExpander, normalizer);

      } else if ("xml".equals(method)) {
        emitter = newXMLEmitter();
        emitter.setPipelineConfiguration(pipe);
        target = createXMLSerializer(emitter, props, pipe, normalizer, characterMapExpander);

      } else if ("xhtml".equals(method)) {
        emitter = newXHTMLEmitter();
        emitter.setPipelineConfiguration(pipe);
        target = createXHTMLSerializer(emitter, props, pipe, normalizer, characterMapExpander);

      } else if ("text".equals(method)) {
        emitter = newTEXTEmitter();
        emitter.setPipelineConfiguration(pipe);
        target = createTextSerializer(emitter, characterMapExpander, normalizer);

      } else {
        Receiver userReceiver;
        if (pipe == null) {
          throw new DynamicError("Unsupported serialization method " + method);
        } else {
          // See if this output method is recognized by the Configuration
          userReceiver = pipe.getConfiguration().makeEmitter(method, pipe.getController());
          userReceiver.setPipelineConfiguration(pipe);
          if (userReceiver instanceof ContentHandlerProxy
              && "yes".equals(props.getProperty(SaxonOutputKeys.SUPPLY_SOURCE_LOCATOR))) {
            if (pipe.getConfiguration().isCompileWithTracing()) {
              pipe.getController()
                  .addTraceListener(((ContentHandlerProxy) userReceiver).getTraceListener());
            } else {
              DynamicError de =
                  new DynamicError(
                      "Cannot use saxon:supply-source-locator unless tracing was enabled at compile time");
              de.setErrorCode(SaxonErrorCode.SXSE0002);
              throw de;
            }
          }
          target = userReceiver;
          if (userReceiver instanceof Emitter) {
            emitter = (Emitter) userReceiver;
          } else {
            return userReceiver;
          }
        }
      }
      emitter.setOutputProperties(props);
      StreamResult sr = (StreamResult) result;
      emitter.setStreamResult(sr);
      return target;

    } else {
      if (pipe != null) {
        // try to find an external object model that knows this kind of Result
        List externalObjectModels = pipe.getConfiguration().getExternalObjectModels();
        for (int m = 0; m < externalObjectModels.size(); m++) {
          ExternalObjectModel model = (ExternalObjectModel) externalObjectModels.get(m);
          Receiver builder = model.getDocumentBuilder(result);
          if (builder != null) {
            builder.setSystemId(result.getSystemId());
            builder.setPipelineConfiguration(pipe);
            return builder;
          }
        }
      }
    }

    throw new IllegalArgumentException("Unknown type of result: " + result.getClass());
  }
    public void process(XPathContext context) throws XPathException {
      // Prepare the SQL statement (only do this once)

      Controller controller = context.getController();
      Item conn = arguments[CONNECTION].evaluateItem(context);
      if (!(conn instanceof ObjectValue
          && ((ObjectValue) conn).getObject() instanceof Connection)) {
        DynamicError de =
            new DynamicError("Value of connection expression is not a JDBC Connection");
        de.setXPathContext(context);
        throw de;
      }
      Connection connection = (Connection) ((ObjectValue) conn).getObject();

      String dbCol = arguments[COLUMN].evaluateAsString(context);
      String dbTab = arguments[TABLE].evaluateAsString(context);
      String dbWhere = arguments[WHERE].evaluateAsString(context);

      NamePool pool = controller.getNamePool();
      int rowCode = pool.allocate("", "", rowTag);
      int colCode = pool.allocate("", "", colTag);

      PreparedStatement ps = null;
      ResultSet rs = null;
      DynamicError de = null;

      try {
        StringBuffer statement = new StringBuffer();
        statement.append("SELECT " + dbCol + " FROM " + dbTab);
        if (dbWhere != "") {
          statement.append(" WHERE " + dbWhere);
        }
        // System.err.println("-> SQL: " + statement.toString());

        // -- Prepare the SQL statement
        ps = connection.prepareStatement(statement.toString());
        controller.setUserData(this, "sql:statement", ps);

        // -- Execute Statement
        rs = ps.executeQuery();

        // -- Print out Result
        Receiver out = context.getReceiver();
        String result = "";
        int icol = rs.getMetaData().getColumnCount();
        while (rs.next()) { // next row
          // System.out.print("<- SQL : "+ rowStart);
          out.startElement(rowCode, StandardNames.XDT_UNTYPED, locationId, 0);
          for (int col = 1; col <= icol; col++) { // next column
            // Read result from RS only once, because
            // of JDBC-Specifications
            result = rs.getString(col);
            out.startElement(colCode, StandardNames.XDT_UNTYPED, locationId, 0);
            if (result != null) {
              out.characters(result, locationId, options);
            }
            out.endElement();
          }
          // System.out.println(rowEnd);
          out.endElement();
        }
        // rs.close();

        if (!connection.getAutoCommit()) {
          connection.commit();
        }

      } catch (SQLException ex) {
        de = new DynamicError("(SQL) " + ex.getMessage());
        de.setXPathContext(context);
        throw de;
      } finally {
        boolean wasDEThrown = (de != null);
        if (rs != null) {
          try {
            rs.close();
          } catch (SQLException ex) {
            de = new DynamicError("(SQL) " + ex.getMessage());
            de.setXPathContext(context);
          }
        }
        if (ps != null) {
          try {
            ps.close();
          } catch (SQLException ex) {
            de = new DynamicError("(SQL) " + ex.getMessage());
            de.setXPathContext(context);
          }
        }
        if (!wasDEThrown && de != null) {
          throw de; // test so we don't lose the real exception
        }
      }
    }
  /** Enumerate the results of the expression */
  public SequenceIterator iterate(XPathContext context) throws XPathException {

    Controller controller = context.getController();

    Item arg2;
    try {
      arg2 = argument[2].evaluateItem(context);
    } catch (XPathException e) {
      if ("XPDY0002".equals(e.getErrorCodeLocalPart())) {
        dynamicError(
            "Cannot call the key() function when there is no context item", "XTDE1270", context);
        return null;
      } else if ("XPDY0050".equals(e.getErrorCodeLocalPart())) {
        dynamicError(
            "In the key() function,"
                + " the node supplied in the third argument (or the context node if absent)"
                + " must be in a tree whose root is a document node",
            "XTDE1270",
            context);
        return null;
      } else if ("XPTY0020".equals(e.getErrorCodeLocalPart())) {
        dynamicError(
            "Cannot call the key() function when the context item is an atomic value",
            "XTDE1270",
            context);
        return null;
      }
      throw e;
    }

    NodeInfo origin = (NodeInfo) arg2;
    NodeInfo root = origin.getRoot();
    if (root.getNodeKind() != Type.DOCUMENT) {
      dynamicError(
          "In the key() function,"
              + " the node supplied in the third argument (or the context node if absent)"
              + " must be in a tree whose root is a document node",
          "XTDE1270",
          context);
      return null;
    }
    DocumentInfo doc = (DocumentInfo) root;

    int fprint = keyFingerprint;
    if (fprint == -1) {
      String givenkeyname = argument[0].evaluateItem(context).getStringValue();
      try {
        fprint =
            controller
                    .getNamePool()
                    .allocateLexicalQName(
                        givenkeyname,
                        false,
                        nsContext,
                        controller.getConfiguration().getNameChecker())
                & NamePool.FP_MASK;
      } catch (XPathException err) {
        dynamicError("Invalid key name: " + err.getMessage(), "XTDE1260", context);
      }
      if (fprint == -1) {
        dynamicError("Key '" + givenkeyname + "' has not been defined", "XTDE1260", context);
        return null;
      }
    }

    //        if (internal) {
    //            System.err.println("Using key " + fprint + " on doc " + doc);
    //        }

    // If the second argument is a singleton, we evaluate the function
    // directly; otherwise we recurse to evaluate it once for each Item
    // in the sequence.

    Expression expression = argument[1];
    SequenceIterator allResults;
    if (Cardinality.allowsMany(expression.getCardinality())) {
      final XPathContext keyContext = context;
      final DocumentInfo document = doc;
      final KeyManager keyManager = controller.getKeyManager();
      MappingFunction map =
          new MappingFunction() {
            // Map a value to the sequence of nodes having that value as a key value
            public Object map(Item item) throws XPathException {
              return keyManager.selectByKey(
                  keyFingerprint, document, (AtomicValue) item, keyContext);
            }
          };

      SequenceIterator keys = argument[1].iterate(context);
      SequenceIterator allValues = new MappingIterator(keys, map);
      allResults = new DocumentOrderIterator(allValues, LocalOrderComparer.getInstance());
    } else {
      try {
        AtomicValue keyValue = (AtomicValue) argument[1].evaluateItem(context);
        if (keyValue == null) {
          return EmptyIterator.getInstance();
        }
        KeyManager keyManager = controller.getKeyManager();
        allResults = keyManager.selectByKey(fprint, doc, keyValue, context);
      } catch (XPathException e) {
        if (e.getLocator() == null) {
          e.setLocator(this);
        }
        throw e;
      }
    }
    if (origin == doc) {
      return allResults;
    }
    SubtreeFilter filter = new SubtreeFilter();
    filter.origin = origin;
    return new ItemMappingIterator(allResults, filter);
  }
  public SequenceIterator iterate(XPathContext context) throws XPathException {
    Controller controller = context.getController();
    ObjectValue ov = (ObjectValue) controller.getParameter("{" + Test.TE_NS + "}core");
    TECore core = (TECore) ov.getObject();

    Expression[] argExpressions = getArguments();
    String xml = "<params>\n";
    List<QName> params = fe.getParams();
    for (int i = 0; i < params.size(); i++) {
      QName param = params.get(i);
      xml += "<param";
      xml += " local-name=\"" + param.getLocalPart() + "\"";
      xml += " namespace-uri=\"" + param.getNamespaceURI() + "\"";
      xml += " prefix=\"" + param.getPrefix() + "\"";
      ValueRepresentation vr = ExpressionTool.eagerEvaluate(argExpressions[i], context);
      // ValueRepresentation vr =
      // ExpressionTool.lazyEvaluate(argExpressions[i], context, 1);
      Value v = Value.asValue(vr);
      try {
        Node n = (Node) v.convertToJava(Node.class, context);
        int type = n.getNodeType();
        if (type == Node.ATTRIBUTE_NODE) {
          xml += ">\n";
          Attr attr = (Attr) n;
          xml +=
              "<value " + attr.getNodeName() + "=\"" + attr.getValue().replace("&", "&amp;") + "\"";
          if (attr.getPrefix() != null) {
            xml += " xmlns:" + attr.getPrefix() + "=\"" + attr.getNamespaceURI() + "\"";
          }
          xml += "/>\n";
          // } else if (type == Node.ELEMENT_NODE || type ==
          // Node.DOCUMENT_NODE) {
          // xml += ">\n";
          // xml += "<value>";
          // xml += DomUtils.serializeNode(n);
          // xml += "</value>\n";
        } else if (type == Node.ELEMENT_NODE) {
          xml += " type=\"node()\">\n";
          xml += "<value>";
          xml += DomUtils.serializeNode(n);
          xml += "</value>\n";
        } else if (type == Node.DOCUMENT_NODE) {
          xml += " type=\"document-node()\">\n";
          xml += "<value>";
          xml += DomUtils.serializeNode(n);
          xml += "</value>\n";
        } else {
          ItemType it = v.getItemType(context.getConfiguration().getTypeHierarchy());
          xml += " type=\"" + getTypeName(it) + "\">\n";
          xml += "<value>" + n.getNodeValue() + "</value>\n";
        }
      } catch (Exception e) {
        ItemType it = v.getItemType(context.getConfiguration().getTypeHierarchy());
        xml += " type=\"" + getTypeName(it) + "\">\n";
        xml += "<value>" + v.getStringValue() + "</value>\n";
      }
      xml += "</param>\n";
    }
    xml += "</params>";
    // System.out.println(xml);
    Source src = new StreamSource(new CharArrayReader(xml.toCharArray()));
    // XdmValue result = null;
    NodeInfo result = null;
    try {
      // result = core.executeTemplate(fe, Globals.builder.build(src),
      // context);
      NodeInfo paramsNode = core.getEngine().getBuilder().build(src).getUnderlyingNode();
      result = core.executeXSLFunction(context, fe, paramsNode);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    if (result == null) {
      return EmptyIterator.getInstance();
    } else {
      // Value v = Value.asValue(result);
      // return v.iterate();
      return result.iterateAxis(Axis.CHILD);
    }
  }