Package client.net.sf.saxon.ce.value

Source Code of client.net.sf.saxon.ce.value.SequenceType

package client.net.sf.saxon.ce.value;

import client.net.sf.saxon.ce.Configuration;
import client.net.sf.saxon.ce.expr.StaticProperty;
import client.net.sf.saxon.ce.om.Item;
import client.net.sf.saxon.ce.om.SequenceIterator;
import client.net.sf.saxon.ce.pattern.AnyNodeTest;
import client.net.sf.saxon.ce.pattern.EmptySequenceTest;
import client.net.sf.saxon.ce.pattern.NodeKindTest;
import client.net.sf.saxon.ce.trans.XPathException;
import client.net.sf.saxon.ce.type.AnyItemType;
import client.net.sf.saxon.ce.type.BuiltInAtomicType;
import client.net.sf.saxon.ce.type.ItemType;

import java.util.HashMap;
import java.util.Map;

/**
* SequenceType: a sequence type consists of a primary type, which indicates the type of item,
* and a cardinality, which indicates the number of occurrences permitted. Where the primary type
* is element or attribute, there may also be a content type, indicating the required type
* annotation on the element or attribute content.
*/

public final class SequenceType {

    private ItemType primaryType;    // the primary type of the item, e.g. "element", "comment", or "integer"
    private int cardinality;    // the required cardinality

    private static Map pool = new HashMap(50);

    /**
     * A type that allows any sequence of items
     */

    public static final SequenceType ANY_SEQUENCE =
            makeSequenceType(AnyItemType.getInstance(), StaticProperty.ALLOWS_ZERO_OR_MORE);

    /**
     * A type that allows exactly one item, of any kind
     */

    public static final SequenceType SINGLE_ITEM =
            makeSequenceType(AnyItemType.getInstance(), StaticProperty.EXACTLY_ONE);

    /**
     * A type that allows zero or one items, of any kind
     */

    public static final SequenceType OPTIONAL_ITEM =
            makeSequenceType(AnyItemType.getInstance(), StaticProperty.ALLOWS_ZERO_OR_ONE);

    /**
     * A type that allows exactly one atomic value
     */

    public static final SequenceType SINGLE_ATOMIC =
            makeSequenceType(BuiltInAtomicType.ANY_ATOMIC,
                    StaticProperty.EXACTLY_ONE);

    /**
     * A type that allows zero or one atomic values
     */

    public static final SequenceType OPTIONAL_ATOMIC =
            makeSequenceType(BuiltInAtomicType.ANY_ATOMIC,
                    StaticProperty.ALLOWS_ZERO_OR_ONE);
    /**
     * A type that allows zero or more atomic values
     */

    public static final SequenceType ATOMIC_SEQUENCE =
            makeSequenceType(BuiltInAtomicType.ANY_ATOMIC,
                    StaticProperty.ALLOWS_ZERO_OR_MORE);

    /**
     * A type that allows a single string
     */

    public static final SequenceType SINGLE_STRING =
            makeSequenceType(BuiltInAtomicType.STRING, StaticProperty.EXACTLY_ONE);

    public static final SequenceType OPTIONAL_STRING =
            makeSequenceType(BuiltInAtomicType.STRING, StaticProperty.ALLOWS_ZERO_OR_ONE);

    public static final SequenceType STRING_SEQUENCE =
            makeSequenceType(BuiltInAtomicType.STRING, StaticProperty.ALLOWS_ZERO_OR_MORE);


    /**
     * A type that allows a single untyped atomic
     */

    public static final SequenceType SINGLE_UNTYPED_ATOMIC =
            makeSequenceType(BuiltInAtomicType.UNTYPED_ATOMIC, StaticProperty.EXACTLY_ONE);


    /**
     * A type that allows a single optional integer
     */

    public static final SequenceType OPTIONAL_INTEGER =
            makeSequenceType(BuiltInAtomicType.INTEGER, StaticProperty.ALLOWS_ZERO_OR_ONE);

    public static final SequenceType SINGLE_INTEGER =
            makeSequenceType(BuiltInAtomicType.INTEGER, StaticProperty.EXACTLY_ONE);

    public static final SequenceType INTEGER_SEQUENCE =
            makeSequenceType(BuiltInAtomicType.INTEGER, StaticProperty.ALLOWS_ZERO_OR_MORE);


    /**
     * A type that allows an optional numeric value
     */

    public static final SequenceType OPTIONAL_NUMERIC =
            makeSequenceType(BuiltInAtomicType.NUMERIC,
                    StaticProperty.ALLOWS_ZERO_OR_ONE);

    /**
     * A type that allows zero or one nodes
     */

    public static final SequenceType OPTIONAL_NODE =
            makeSequenceType(AnyNodeTest.getInstance(), StaticProperty.ALLOWS_ZERO_OR_ONE);

    public static final SequenceType SINGLE_NODE =
            makeSequenceType(AnyNodeTest.getInstance(), StaticProperty.EXACTLY_ONE);

    public static final SequenceType NODE_SEQUENCE =
            makeSequenceType(AnyNodeTest.getInstance(), StaticProperty.ALLOWS_ZERO_OR_MORE);


    public static final SequenceType OPTIONAL_DOCUMENT =
            makeSequenceType(NodeKindTest.DOCUMENT, StaticProperty.ALLOWS_ZERO_OR_ONE);

    public static final SequenceType SINGLE_ELEMENT =
            makeSequenceType(NodeKindTest.ELEMENT, StaticProperty.EXACTLY_ONE);

    public static final SequenceType ELEMENT_SEQUENCE =
            makeSequenceType(NodeKindTest.ELEMENT, StaticProperty.ALLOWS_ZERO_OR_MORE);

    /**
     * A type that allows a sequence of zero or more numeric values
     */

    public static final SequenceType NUMERIC_SEQUENCE =
            makeSequenceType(BuiltInAtomicType.NUMERIC, StaticProperty.ALLOWS_ZERO_OR_MORE);

    public static final SequenceType OPTIONAL_BOOLEAN =
            makeSequenceType(BuiltInAtomicType.BOOLEAN, StaticProperty.ALLOWS_ZERO_OR_ONE);

    public static final SequenceType SINGLE_BOOLEAN =
            makeSequenceType(BuiltInAtomicType.BOOLEAN, StaticProperty.EXACTLY_ONE);

    public static final SequenceType OPTIONAL_DATE =
            makeSequenceType(BuiltInAtomicType.DATE, StaticProperty.ALLOWS_ZERO_OR_ONE);

    public static final SequenceType SINGLE_DATE =
            makeSequenceType(BuiltInAtomicType.DATE, StaticProperty.EXACTLY_ONE);

    public static final SequenceType OPTIONAL_DATE_TIME =
            makeSequenceType(BuiltInAtomicType.DATE_TIME, StaticProperty.ALLOWS_ZERO_OR_ONE);

    public static final SequenceType SINGLE_DATE_TIME =
            makeSequenceType(BuiltInAtomicType.DATE_TIME, StaticProperty.EXACTLY_ONE);

    public static final SequenceType OPTIONAL_TIME =
            makeSequenceType(BuiltInAtomicType.TIME, StaticProperty.ALLOWS_ZERO_OR_ONE);

    public static final SequenceType SINGLE_TIME =
            makeSequenceType(BuiltInAtomicType.TIME, StaticProperty.EXACTLY_ONE);

    public static final SequenceType OPTIONAL_DURATION =
            makeSequenceType(BuiltInAtomicType.DURATION, StaticProperty.ALLOWS_ZERO_OR_ONE);

    public static final SequenceType OPTIONAL_DAY_TIME_DURATION =
            makeSequenceType(BuiltInAtomicType.DAY_TIME_DURATION, StaticProperty.ALLOWS_ZERO_OR_ONE);

    public static final SequenceType SINGLE_DAY_TIME_DURATION =
            makeSequenceType(BuiltInAtomicType.DAY_TIME_DURATION, StaticProperty.EXACTLY_ONE);

    public static final SequenceType OPTIONAL_ANY_URI =
            makeSequenceType(BuiltInAtomicType.ANY_URI, StaticProperty.ALLOWS_ZERO_OR_ONE);

    public static final SequenceType SINGLE_ANY_URI =
            makeSequenceType(BuiltInAtomicType.ANY_URI, StaticProperty.EXACTLY_ONE);

    public static final SequenceType OPTIONAL_QNAME =
            makeSequenceType(BuiltInAtomicType.QNAME, StaticProperty.ALLOWS_ZERO_OR_ONE);

    public static final SequenceType OPTIONAL_DECIMAL =
            makeSequenceType(BuiltInAtomicType.DECIMAL, StaticProperty.ALLOWS_ZERO_OR_ONE);

    public static final SequenceType SINGLE_QNAME =
            makeSequenceType(BuiltInAtomicType.QNAME, StaticProperty.EXACTLY_ONE);

    public static final SequenceType SINGLE_DOUBLE =
            makeSequenceType(BuiltInAtomicType.DOUBLE, StaticProperty.EXACTLY_ONE);


    /**
     * A type that only permits the empty sequence
     */

    public static final SequenceType EMPTY_SEQUENCE =
            makeSequenceType(EmptySequenceTest.getInstance(), StaticProperty.EMPTY);

    /**
     * Construct an instance of SequenceType. This is a private constructor: all external
     * clients use the factory method makeSequenceType(), to allow object pooling.
     *
     * @param primaryType The item type
     * @param cardinality The required cardinality
     */
    private SequenceType(ItemType primaryType, int cardinality) {
        this.primaryType = primaryType;
        if (primaryType instanceof EmptySequenceTest) {
            this.cardinality = StaticProperty.EMPTY;
        } else {
            this.cardinality = cardinality;
        }
    }

    /**
     * Construct an instance of SequenceType. This is a factory method: it maintains a
     * pool of SequenceType objects to reduce the amount of object creation.
     *
     * @param primaryType The item type
     * @param cardinality The required cardinality
     */

    public static SequenceType makeSequenceType(ItemType primaryType, int cardinality) {

        if (!(primaryType instanceof BuiltInAtomicType)) {
            return new SequenceType(primaryType, cardinality);
        }

        // For each ItemType, there is an array of 8 SequenceTypes, one for each possible
        // cardinality (including impossible cardinalities, such as "0 or many"). The pool
        // is a static HashMap that obtains this array, given an ItemType. The array contains null
        // entries for cardinalities that have not been requested.

        SequenceType[] array = (SequenceType[]) pool.get(primaryType);
        if (array == null) {
            array = new SequenceType[8];
            pool.put(primaryType, array);
        }
        int code = StaticProperty.getCardinalityCode(cardinality);
        if (array[code] == null) {
            SequenceType s = new SequenceType(primaryType, cardinality);
            array[code] = s;
            return s;
        } else {
            return array[code];
        }
    }

    /**
     * Get the "primary" part of this required type. E.g. for type element(*, xs:date) the "primary type" is element()
     *
     * @return The item type code of the primary type
     */
    public ItemType getPrimaryType() {
        return primaryType;
    }

    /**
     * Get the cardinality component of this SequenceType. This is one of the constants Cardinality.EXACTLY_ONE,
     * Cardinality.ONE_OR_MORE, etc
     *
     * @return the required cardinality
     * @see client.net.sf.saxon.ce.value.Cardinality
     */
    public int getCardinality() {
        return cardinality;
    }

    /**
     * Determine whether a given value is a valid instance of this SequenceType
     *
     * @param value the value to be tested
     * @return true if the value is a valid instance of this type
     */

    public boolean matches(Value value, Configuration config) throws XPathException {
        int length = value.getLength();
        if (length > 1 && !Cardinality.allowsMany(cardinality)) {
            return false;
        }
        if (length == 0 && !Cardinality.allowsZero(cardinality)) {
            return false;
        }
        SequenceIterator iter = value.iterate();
        while (true) {
            Item item = iter.next();
            if (item == null) {
                return true;
            }
            if (!primaryType.matchesItem(item, false, config)) {
                return false;
            }
        }
    }

    /**
     * Return a string representation of this SequenceType
     *
     * @return the string representation as an instance of the XPath
     *         SequenceType construct
     */
    public String toString() {
        String s = primaryType.toString();
        if (cardinality == StaticProperty.ALLOWS_ONE_OR_MORE) {
            s = s + '+';
        } else if (cardinality == StaticProperty.ALLOWS_ZERO_OR_MORE) {
            s = s + '*';
        } else if (cardinality == StaticProperty.ALLOWS_ZERO_OR_ONE) {
            s = s + '?';
        }
        return s;
    }

    /**
     * Returns a hash code value for the object.
     */
    public int hashCode() {
        return primaryType.hashCode() ^ cardinality;
    }

    /**
     * Indicates whether some other object is "equal to" this one.
     */
    public boolean equals(Object obj) {
        return obj instanceof SequenceType &&
                this.primaryType.equals(((SequenceType) obj).primaryType) &&
                this.cardinality == ((SequenceType) obj).cardinality;
    }


}

// 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.value.SequenceType

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.