Package client.net.sf.saxon.ce.expr.instruct

Source Code of client.net.sf.saxon.ce.expr.instruct.DocumentInstr

package client.net.sf.saxon.ce.expr.instruct;

import client.net.sf.saxon.ce.Controller;
import client.net.sf.saxon.ce.event.Builder;
import client.net.sf.saxon.ce.event.PipelineConfiguration;
import client.net.sf.saxon.ce.event.Receiver;
import client.net.sf.saxon.ce.event.SequenceReceiver;
import client.net.sf.saxon.ce.expr.*;
import client.net.sf.saxon.ce.functions.StringJoin;
import client.net.sf.saxon.ce.functions.SystemFunction;
import client.net.sf.saxon.ce.om.DocumentInfo;
import client.net.sf.saxon.ce.om.Item;
import client.net.sf.saxon.ce.om.SequenceIterator;
import client.net.sf.saxon.ce.om.StandardNames;
import client.net.sf.saxon.ce.pattern.NodeKindTest;
import client.net.sf.saxon.ce.trans.XPathException;
import client.net.sf.saxon.ce.tree.util.FastStringBuffer;
import client.net.sf.saxon.ce.type.BuiltInAtomicType;
import client.net.sf.saxon.ce.type.ItemType;
import client.net.sf.saxon.ce.type.TypeHierarchy;
import client.net.sf.saxon.ce.value.StringValue;
import client.net.sf.saxon.ce.value.TextFragmentValue;
import client.net.sf.saxon.ce.value.UntypedAtomicValue;


/**
* An instruction to create a document node. This corresponds to the xsl:document-node
* instruction in XSLT. It is also used to support the document node constructor
* expression in XQuery, and is generated implicitly within an xsl:variable
* that constructs a temporary tree.
*
* <p>Conceptually it represents an XSLT instruction xsl:document-node,
* with no attributes, whose content is a complex content constructor for the
* children of the document node.</p>
*/

public class DocumentInstr extends ParentNodeConstructor {

    //private static final int[] treeSizeParameters = {50, 10, 5, 200};
    // estimated size of a temporary tree: {nodes, attributes, namespaces, characters}

    private boolean textOnly;
    private String constantText;

    /**
     * Create a document constructor instruction
     * @param textOnly true if the content contains text nodes only
     * @param constantText if the content contains text nodes only and the text is known at compile time,
     *        supplies the textual content
     * @param baseURI the base URI of the instruction
     */

    public DocumentInstr(boolean textOnly,
                         String constantText,
                         String baseURI) {
        this.textOnly = textOnly;
        this.constantText = constantText;
        setBaseURI(baseURI);
    }

    /**
     * An implementation of Expression must provide at least one of the methods evaluateItem(), iterate(), or process().
     * This method indicates which of these methods is prefered. For instructions this is the process() method.
     */

    public int getImplementationMethod() {
        return Expression.EVALUATE_METHOD;
    }

    /**
     * Determine whether this is a "text only" document: essentially, an XSLT xsl:variable that contains
     * a single text node or xsl:value-of instruction.
     * @return true if this is a text-only document
     */

    public boolean isTextOnly() {
        return textOnly;
    }

    /**
     * Simplify an expression. This performs any static optimization (by rewriting the expression
     * as a different expression). The default implementation does nothing.
     *
     * @return the simplified expression
     * @throws client.net.sf.saxon.ce.trans.XPathException
     *          if an error is discovered during expression rewriting
     * @param visitor an expression visitor
     */

    public Expression simplify(ExpressionVisitor visitor) throws XPathException {
        return super.simplify(visitor);
    }


    /**
     * In the case of a text-only instruction (xsl:variable containing a text node or one or more xsl:value-of
     * instructions), return an expression that evaluates to the textual content as an instance of xs:untypedAtomic
     * @param env the static evaluation context
     * @return an expression that evaluates to the textual content
     */

    public Expression getStringValueExpression(StaticContext env) {
        if (textOnly) {
            if (constantText != null) {
                return new StringLiteral(new UntypedAtomicValue(constantText));
            } else if (content instanceof ValueOf) {
                return ((ValueOf)content).convertToCastAsString();
            } else {
                StringJoin fn = (StringJoin)SystemFunction.makeSystemFunction(
                        "string-join", new Expression[]{content, new StringLiteral(StringValue.EMPTY_STRING)});
                CastExpression cast = new CastExpression(fn, BuiltInAtomicType.UNTYPED_ATOMIC, false);
                ExpressionTool.copyLocationInfo(this, cast);
                return cast;
            }
        } else {
            throw new AssertionError("getStringValueExpression() called on non-text-only document instruction");
        }
    }


    /**
     * Get the item type
     * @param th The TypeHierarchy
     * @return the in
     */
    public ItemType getItemType(TypeHierarchy th) {
        return NodeKindTest.DOCUMENT;
    }

    public TailCall processLeavingTail(XPathContext context) throws XPathException {
        SequenceReceiver out = context.getReceiver();
        out.startDocument();
        content.process(context);
        out.endDocument();
        return null;
    }

    /**
     * Evaluate as an expression.
     */

    public Item evaluateItem(XPathContext context) throws XPathException {

        Controller controller = context.getController();
        DocumentInfo root;
        if (textOnly) {
            CharSequence textValue;
            if (constantText != null) {
                textValue = constantText;
            } else {
                FastStringBuffer sb = new FastStringBuffer(FastStringBuffer.SMALL);
                SequenceIterator iter = content.iterate(context);
                while (true) {
                    Item item = iter.next();
                    if (item==null) break;
                    sb.append(item.getStringValueCS());
                }
                textValue = sb.condense();
            }
            root = new TextFragmentValue(textValue, getBaseURI());
            ((TextFragmentValue)root).setConfiguration(controller.getConfiguration());
        } else {
            try {
                XPathContext c2 = context.newMinorContext();

                Builder builder = controller.makeBuilder();

                //receiver.setSystemId(getBaseURI());
                builder.setBaseURI(getBaseURI());

                PipelineConfiguration pipe = controller.makePipelineConfiguration();
                builder.setPipelineConfiguration(pipe);

                c2.changeOutputDestination(builder, false);
                Receiver out = c2.getReceiver();
                out.open();
                out.startDocument();

                content.process(c2);

                out.endDocument();
                out.close();

                root = (DocumentInfo)builder.getCurrentRoot();
            } catch (XPathException e) {
                e.maybeSetLocation(getSourceLocator());
                e.maybeSetContext(context);
                throw e;
            }
        }
        return root;
    }


    /**
     * Get the name of this instruction for diagnostic and tracing purposes
     * (the string "document-constructor")
     */

    public int getInstructionNameCode() {
        return StandardNames.XSL_DOCUMENT;
    }


}

// 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.
TOP

Related Classes of client.net.sf.saxon.ce.expr.instruct.DocumentInstr

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.