Beispiel #1
0
  /**
   * Run the query in pull mode.
   *
   * <p>
   *
   * <p>For maximum effect this method should be used when lazyConstructionMode has been set in the
   * Configuration.
   *
   * <p>
   *
   * <p><b>Note: this method usually has very similar performance to the {@link
   * #run(DynamicQueryContext,javax.xml.transform.Result,java.util.Properties)} method (which does
   * the same thing), but sometimes it is significantly slower. Therefore, the run() method is
   * preferred.</b>
   *
   * @param dynamicEnv the dynamic context for query evaluation
   * @param destination the destination of the query results
   * @param outputProperties the serialization parameters
   * @see Configuration#setLazyConstructionMode(boolean)
   */
  public void pull(DynamicQueryContext dynamicEnv, Result destination, Properties outputProperties)
      throws XPathException {
    if (isUpdating) {
      throw new XPathException("Cannot call pull() on an updating query");
    }
    Configuration config = dynamicEnv.getConfiguration();
    try {
      Controller controller = newController();
      // initializeController(dynamicEnv, controller);
      EventIterator iter = iterateEvents(controller, dynamicEnv);
      // iter = new Decomposer(iter, config);

      Properties actualProperties = validateOutputProperties(controller, outputProperties);
      SerializerFactory sf = config.getSerializerFactory();
      PipelineConfiguration pipe = config.makePipelineConfiguration();
      pipe.setSerializing(true);
      Receiver receiver = sf.getReceiver(destination, pipe, actualProperties);

      receiver = new NamespaceReducer(receiver);
      if ("yes".equals(actualProperties.getProperty(SaxonOutputKeys.WRAP))) {
        receiver = new SequenceWrapper(receiver);
        // receiver = new TracingFilter(receiver);
      } else {
        receiver = new TreeReceiver(receiver);
      }
      EventIteratorToReceiver.copy(iter, (SequenceReceiver) receiver);
    } catch (XPathException err) {
      config.reportFatalError(err);
      throw err;
    }
  }
 /**
  * Notify a namespace. Namespaces are notified <b>after</b> the startElement event, and before any
  * children for the element.
  */
 public void namespace(int namespaceCode, int properties) throws XPathException {
   if (namespaceCode == NamespaceConstant.XML_NAMESPACE_CODE) {
     return;
   }
   NamePool pool = pipe.getConfiguration().getNamePool();
   String prefix = pool.getPrefixFromNamespaceCode(namespaceCode);
   String uri = pool.getURIFromNamespaceCode(namespaceCode);
   if ((!undeclareNamespaces) && "".equals(uri) && !("".equals(prefix))) {
     // This is a namespace undeclaration, but the ContentHandler doesn't want to know about
     // undeclarations
     return;
   }
   try {
     handler.startPrefixMapping(prefix, uri);
     namespaceStack.push(prefix);
   } catch (SAXException err) {
     handleSAXException(err);
   }
 }
  /**
   * Notify the start of the content, that is, the completion of all attributes and namespaces. Note
   * that the initial receiver of output from XSLT instructions will not receive this event, it has
   * to detect it itself. Note that this event is reported for every element even if it has no
   * attributes, no namespaces, and no content.
   */
  public void startContent() throws XPathException {
    try {
      NamePool namePool = pipe.getConfiguration().getNamePool();
      if (depth > 0 || !requireWellFormed) {
        String uri = namePool.getURI(pendingElement);
        String localName = namePool.getLocalName(pendingElement);
        String qname = namePool.getDisplayName(pendingElement);

        handler.startElement(uri, localName, qname, pendingAttributes);

        elementStack.push(uri);
        elementStack.push(localName);
        elementStack.push(qname);

        pendingAttributes.clear();
        pendingElement = -1;
      }
    } catch (SAXException err) {
      handleSAXException(err);
    }
  }
 protected Receiver createXMLSerializer(
     Emitter emitter,
     Properties props,
     PipelineConfiguration pipe,
     ProxyReceiver normalizer,
     CharacterMapExpander characterMapExpander)
     throws XPathException {
   Receiver target;
   target = emitter;
   if ("1.0".equals(props.getProperty(OutputKeys.VERSION))
       && pipe.getConfiguration().getXMLVersion() == Configuration.XML11) {
     // Check result meets XML 1.0 constraints if configuration allows XML 1.1 input but
     // this result document must conform to 1.0
     ProxyReceiver in = newXML10ContentChecker(pipe, props);
     in.setUnderlyingReceiver(target);
     target = in;
   }
   if ("yes".equals(props.getProperty(OutputKeys.INDENT))) {
     ProxyReceiver in = newXMLIndenter(pipe, props);
     in.setUnderlyingReceiver(target);
     target = in;
   }
   if (normalizer != null) {
     normalizer.setUnderlyingReceiver(target);
     target = normalizer;
   }
   if (characterMapExpander != null) {
     characterMapExpander.setUnderlyingReceiver(target);
     target = characterMapExpander;
   }
   String cdataElements = props.getProperty(OutputKeys.CDATA_SECTION_ELEMENTS);
   if (cdataElements != null && cdataElements.length() > 0) {
     ProxyReceiver filter = newCDATAFilter(pipe, props);
     filter.setUnderlyingReceiver(target);
     target = filter;
   }
   return target;
 }
  /**
   * 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());
  }
 /** Get the pipeline configuration */
 public Configuration getConfiguration() {
   return pipe.getConfiguration();
 }
 /** Set the pipeline configuration */
 public void setPipelineConfiguration(PipelineConfiguration pipe) {
   this.pipe = pipe;
   this.locationProvider = pipe.getLocationProvider();
 }