All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.saxon.s9api.Destination Maven / Gradle / Ivy

There is a newer version: 12.5
Show newest version
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2018-2022 Saxonica Limited
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

package net.sf.saxon.s9api;

import net.sf.saxon.event.Outputter;
import net.sf.saxon.event.PipelineConfiguration;
import net.sf.saxon.event.Receiver;
import net.sf.saxon.serialize.SerializationProperties;

import java.net.URI;
import java.util.function.Consumer;

/**
 * A Destination represents a place where XDM values can be sent. It is used, for example,
 * to define the output of a transformation or query.
 * 

* A {@code Destination} is either a tree destination or a raw destination. A tree destination * performs sequence normalization on the stream of events passed to it, to construct * a tree rooted at a single XDM document node, as defined in the W3C serialization specification * (even if the destination is not actually a serializer). A raw destination omits this step. * Examples of tree destinations are those designed to accept XML: {@link DOMDestination}, * {@link SAXDestination}, {@link XdmDestination}, {@link SchemaValidator}. *

* The {@link Serializer} acts as a tree destination when the output methods XML, HTML, XHTML, or TEXT * are used, but as a raw destination when the output method is JSON or ADAPTIVE. *

* The interface {@code Destination} has some similarities with the JAXP * {@link javax.xml.transform.Result} class. It differs, however, in that implementations * of this interface can be written by users or third parties to define new kinds of * destination, and any such implementation can be supplied to the Saxon methods that * take a {@code Destination} as an argument. *

* Implementing a new {@code Destination} will generally require access * to implementation-level classes and methods within the Saxon product. The only method that * needs to be supplied is {@link #getReceiver}, which returns an instance of * {@link Outputter}, and unless you use an existing implementation of * {@code Receiver}, you will need to handle internal Saxon concepts such as name codes * and name pools. *

* In general a Destination is not thread-safe (cannot be used from more than one thread), * and is not serially reusable. So a Destination should only be used once. A Destination * supplied to Saxon may be modified by Saxon. *

* The {@link #close} method is called by the system when * it finishes writing the document, and this should cause all resources held by the Destination * to be released. */ public interface Destination { /** * Set the base URI of the resource being written to this destination * @param baseURI the base URI to be used */ void setDestinationBaseURI(URI baseURI); /** * Get the base URI of the resource being written to this destination * @return the baseURI, or null if none is known */ URI getDestinationBaseURI(); /** * Return a {@link Receiver}. Saxon calls this method to obtain a Receiver, to which it then sends * a sequence of events representing an XDM value. The method is intended * primarily for internal use, and may give poor diagnostics if used incorrectly. *

* This method is normally only called once. However, in the case where a stylesheet includes * a call of xsl:result-document with no href attribute (or with an * href attribute that resolves to the base output URI of the transformation), the * method may be called a second time (with a potentially different set of serialization parameters, * and perhaps a different validation request) to return a second {@link Outputter}, which will typically * write to the same destination. The XSLT rules ensure that it is not possible to write principal and * secondary output to the same destination, so only one of these Receivers will actually be used. * * @param pipe The pipeline configuration. This is supplied so that the destination can * use information from the configuration (for example, a reference to the name pool) * to construct or configure the returned Receiver. * @param params Serialization parameters known to the caller of the method; typically, * output properties defined in a stylesheet or query. These will mainly * be of interest if the destination is performing serialization, but some * properties (such as {@code item-separator}) are also used in other * situations. These properties are typically subordinate to any properties * defined on the (serializer) destination itself: for example if {@code indent=yes} * was explicitly specified on a {@code Serializer}, this takes precedence * over {@code indent=no} defined in a query or stylesheet. *

* The {@link SerializationProperties} object may also contain a factory object for * generating a validator to add to the output pipeline. The {@link Destination} object * is responsible for instantiating this validator and inserting it into the pipeline. * In most cases this is done by invoking the helper method * {@link SerializationProperties#makeSequenceNormalizer(Receiver)}. Validation can be skipped * in the case of non-XML destinations. * @return the Receiver to which events are to be sent. *

It is the caller's responsibility to * initialize this Receiver with a {@link net.sf.saxon.event.PipelineConfiguration} before calling * its {@code open()} method.

*

The {@code Receiver} is expected to handle a regular event sequence as defined in * {@link net.sf.saxon.event.RegularSequenceChecker}. It is the caller's responsibility to * ensure that the sequence of calls to the {@code Receiver} satisfies these rules, and it * is the responsibility of the implementation to accept any sequence conforming these rules; * the implementation is not expected to check that the sequence is valid, but it can do so * if it wishes by inserting a {@link net.sf.saxon.event.RegularSequenceChecker} into the pipeline.

*

The sequence of events passed to the {@code Receiver} represents the raw results of * the query or transformation. If the {@code Destination} is to perform sequence normalization, * this is typically done by returning a {@link net.sf.saxon.event.SequenceNormalizer} as the * result of this method.

*

The returned {@code Receiver} is responsible for ensuring that when its {@link Outputter#close()} * method is called, this results in all registered {@code onClose} actions being invoked. * An implementation returning a {@code SequenceNormalizer} can achieve this by registering * the actions with the {@link net.sf.saxon.event.SequenceNormalizer#onClose} method.

*

Only a single call on this method will be made during the lifetime of the {@code Destination} * object, with the exception of the case noted above where a secondary result document is written * to the same destination as the principal transformation result.

* @throws SaxonApiException if the Receiver cannot be created */ Receiver getReceiver(PipelineConfiguration pipe, SerializationProperties params) throws SaxonApiException; /** * Register a listener to be notified when a {@link Outputter} linked to this destination is closed. *

Example: destination.onClose(() -> System.out.println("Finished writing to " + uri)

*

The method must be called before the call on {@link #getReceiver(PipelineConfiguration, SerializationProperties)}; the * effect of calling it after getting a {@code Receiver}, but before closing the * {@link Outputter}, is undefined.

* * @param listener an object to be notified when writing to the destination * is successfully completed */ void onClose(Action listener); /** * Close the destination and notify all registered listeners that it has been closed. * This method is intended for internal use by Saxon. The method first calls {@link #close} * to close the destination, then it calls {@link Consumer#accept} on each of the * listeners in turn to notify the fact that it has been closed. * @throws SaxonApiException if the close() method throws {@code SaxonApiException}. */ void closeAndNotify() throws SaxonApiException; /** * Close the destination, allowing resources to be released. Saxon calls this method when * it has finished writing to the destination. *

* The {@code close()} method should not cause any adverse effects if it is called more than * once. If any other method is called after the {@code close()} call, the results are undefined. * This means that a Destination is not, in general, serially reusable. *

* If an {@link #onClose} action has been associated with the destination, * this will be called after the destination is closed.

* * @throws SaxonApiException if any failure occurs */ void close() throws SaxonApiException; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy