FileDocCategorySizeDatePackage
XSWildcardDecl.javaAPI DocApache Xerces 3.0.124775Fri Sep 14 20:33:52 BST 2007org.apache.xerces.impl.xs

XSWildcardDecl

public class XSWildcardDecl extends Object implements org.apache.xerces.xs.XSWildcard
The XML representation for a wildcard declaration schema component is an <any> or <anyAttribute> element information item
xerces.internal
author
Sandy Gao, IBM
author
Rahul Srivastava, Sun Microsystems Inc.
version
$Id: XSWildcardDecl.java 449424 2006-09-24 16:22:30Z mrglavas $

Fields Summary
public static final String
ABSENT
public short
fType
public short
fProcessContents
public String[]
fNamespaceList
public org.apache.xerces.xs.XSObjectList
fAnnotations
private String
fDescription
get the string description of this wildcard
Constructors Summary
Methods Summary
public booleanallowNamespace(java.lang.String namespace)
Validation Rule: Wildcard allows Namespace Name

  

    // I'm trying to implement the following constraint exactly as what the
    // spec describes. Sometimes it seems redundant, and sometimes there seems
    // to be much easier solutions. But it makes it easy to understand,
    // easy to maintain, and easy to find a bug (either in the code, or in the
    // spec). -SG
    //
    // NOTE: Schema spec only requires that ##other not(tNS,absent).
    //       The way we store ##other is not(NS1,NS2,...,NSN), which covers
    //       what's required by Schema, and allows future enhanced features.
    //
    // In the following in-line comments:
    // - Bullet removed from w3c specification.
    // + Bullet added as proposed by Sandy Gao, IBM.
    // / Since we store ##other as not(NS1,NS2,...,NSN), we need to put some
    //   comments on where we didn't follow the spec exactly.
    // * When we really support not(NS1,NS2,...,NSN), we need to revisit these items.

               
        
        // For a value which is either a namespace name or absent to be valid with respect to a wildcard constraint (the value of a {namespace constraint}) one of the following must be true:

        // 1 The constraint must be any.
        if (fType == NSCONSTRAINT_ANY)
            return true;

        // 2 All of the following must be true:
        // 2.1 The constraint is a pair of not and a namespace name or absent ([Definition:]  call this the namespace test).
        // 2.2 The value must not be identical to the namespace test.
        // 2.3 The value must not be absent.
        // / we store ##other as not(list), so our actual rule is
        // / 2 The constraint is a pair of not and a set, and the value is not in such set.
        if (fType == NSCONSTRAINT_NOT) {
            boolean found = false;
            int listNum = fNamespaceList.length;
            for (int i = 0; i < listNum && !found; i++) {
                if (namespace == fNamespaceList[i])
                    found = true;
            }

            if (!found)
                return true;
        }

        // 3 The constraint is a set, and the value is identical to one of the members of the set.
        if (fType == NSCONSTRAINT_LIST) {
            int listNum = fNamespaceList.length;
            for (int i = 0; i < listNum; i++) {
                if (namespace == fNamespaceList[i])
                    return true;
            }
        }

        // none of the above conditions applied, so return false.
        return false;
    
private booleanareSame(org.apache.xerces.impl.xs.XSWildcardDecl wildcard)

        if (fType == wildcard.fType) {
            // ##any, true
            if (fType == NSCONSTRAINT_ANY)
                return true;

            // ##other, only check the negated value
            // * when we support not(list), we need to check in the same way
            //   as for NSCONSTRAINT_LIST.
            if (fType == NSCONSTRAINT_NOT)
                return fNamespaceList[0] == wildcard.fNamespaceList[0];

            // ## list, must have the same length,
            // and each item in one list must appear in the other one
            // (we are assuming that there are no duplicate items in a list)
            if (fNamespaceList.length == wildcard.fNamespaceList.length) {
                for (int i=0; i<fNamespaceList.length; i++) {
                    if (!elementInSet(fNamespaceList[i], wildcard.fNamespaceList))
                        return false;
                }
                return true;
            }
        }

        return false;
    
booleanelementInSet(java.lang.String ele, java.lang.String[] set)

        boolean found = false;
        for (int i=0; i<set.length && !found; i++) {
            if (ele==set[i])
                found = true;
        }

        return found;
    
public org.apache.xerces.xs.XSAnnotationgetAnnotation()
Optional. Annotation.

        return (fAnnotations != null) ? (XSAnnotation) fAnnotations.item(0) : null;
    
public org.apache.xerces.xs.XSObjectListgetAnnotations()
Optional. Annotations.

        return (fAnnotations != null) ? fAnnotations : XSObjectListImpl.EMPTY_LIST;
    
public shortgetConstraintType()
Namespace constraint: A constraint type: any, not, list.

        return fType;
    
public java.lang.StringgetName()
The name of this XSObject depending on the XSObject type.

        return null;
    
public java.lang.StringgetNamespace()
The namespace URI of this node, or null if it is unspecified. defines how a namespace URI is attached to schema components.

        return null;
    
public org.apache.xerces.xs.XSNamespaceItemgetNamespaceItem()

see
org.apache.xerces.xs.XSObject#getNamespaceItem()

        // REVISIT: implement
		return null;
	
public org.apache.xerces.xs.StringListgetNsConstraintList()
Namespace constraint. For constraintType LIST_NSCONSTRAINT, the list contains allowed namespaces. For constraintType NOT_NSCONSTRAINT, the list contains disallowed namespaces.

        return new StringListImpl(fNamespaceList, fNamespaceList == null ? 0 : fNamespaceList.length);
    
public shortgetProcessContents()
{process contents} One of skip, lax or strict. Valid constants values are: PC_SKIP, PC_LAX, PC_STRICT.

        return fProcessContents;
    
public java.lang.StringgetProcessContentsAsString()
String valid of {process contents}. One of "skip", "lax" or "strict".

        switch (fProcessContents) {
            case XSWildcardDecl.PC_SKIP: return "skip";
            case XSWildcardDecl.PC_LAX: return "lax";
            case XSWildcardDecl.PC_STRICT: return "strict";
            default: return "invalid value";
        }
    
public shortgetType()
Get the type of the object, i.e ELEMENT_DECLARATION.

        return XSConstants.WILDCARD;
    
java.lang.String[]intersect2sets(java.lang.String[] one, java.lang.String[] theOther)

        String[] result = new String[Math.min(one.length,theOther.length)];

        // simple implemention,
        int count = 0;
        for (int i=0; i<one.length; i++) {
            if (elementInSet(one[i], theOther))
                result[count++] = one[i];
        }

        String[] result2 = new String[count];
        System.arraycopy(result, 0, result2, 0, count);

        return result2;
    
public booleanisSubsetOf(org.apache.xerces.impl.xs.XSWildcardDecl superWildcard)
Schema Component Constraint: Wildcard Subset

        // if the super is null (not expressible), return false
        if (superWildcard == null)
            return false;

        // For a namespace constraint (call it sub) to be an intensional subset of another
        // namespace constraint (call it super) one of the following must be true:

        // 1 super must be any.
        if (superWildcard.fType == NSCONSTRAINT_ANY) {
            return true;
        }

        // 2 All of the following must be true:
        //   2.1 sub must be a pair of not and a namespace name or absent.
        //   2.2 super must be a pair of not and the same value.
        //   * we can't just compare whether the namespace are the same value
        //     since we store other as not(list)
        if (fType == NSCONSTRAINT_NOT) {
            if (superWildcard.fType == NSCONSTRAINT_NOT &&
                fNamespaceList[0] == superWildcard.fNamespaceList[0]) {
                return true;
            }
        }

        // 3 All of the following must be true:
        //   3.1 sub must be a set whose members are either namespace names or absent.
        //   3.2 One of the following must be true:
        //       3.2.1 super must be the same set or a superset thereof.
        //       -3.2.2 super must be a pair of not and a namespace name or absent and
        //              that value must not be in sub's set.
        //       +3.2.2 super must be a pair of not and a namespace name or absent and
        //              either that value or absent must not be in sub's set.
        //       * since we store ##other as not(list), we acturally need to make sure
        //         that none of the namespaces in super.list is in sub.list.
        if (fType == NSCONSTRAINT_LIST) {
            if (superWildcard.fType == NSCONSTRAINT_LIST &&
                subset2sets(fNamespaceList, superWildcard.fNamespaceList)) {
                return true;
            }

            if (superWildcard.fType == NSCONSTRAINT_NOT &&
                !elementInSet(superWildcard.fNamespaceList[0], fNamespaceList) &&
                !elementInSet(ABSENT, fNamespaceList)) {
                return true;
            }
        }

        // none of the above conditions applied, so return false.
        return false;

    
public org.apache.xerces.impl.xs.XSWildcardDeclperformIntersectionWith(org.apache.xerces.impl.xs.XSWildcardDecl wildcard, short processContents)
Schema Component Constraint: Attribute Wildcard Intersection

        // if the other wildcard is not expressible, the result is still not expressible
        if (wildcard == null)
            return null;

        // For a wildcard's {namespace constraint} value to be the intensional intersection of
        // two other such values (call them O1 and O2): the appropriate case among the following
        // must be true:

        XSWildcardDecl intersectWildcard = new XSWildcardDecl();
        intersectWildcard.fProcessContents = processContents;

        // 1 If O1 and O2 are the same value, then that value must be the value.
        if (areSame(wildcard)) {
            intersectWildcard.fType = fType;
            intersectWildcard.fNamespaceList = fNamespaceList;
        }

        // 2 If either O1 or O2 is any, then the other must be the value.
        else if ( (fType == NSCONSTRAINT_ANY) || (wildcard.fType == NSCONSTRAINT_ANY) ) {
            // both cannot be ANY, if we have reached here.
            XSWildcardDecl other = this;

            if (fType == NSCONSTRAINT_ANY)
                other = wildcard;

            intersectWildcard.fType = other.fType;
            intersectWildcard.fNamespaceList = other.fNamespaceList;
        }

        // -3 If either O1 or O2 is a pair of not and a namespace name and the other is a set of
        //    (namespace names or absent), then that set, minus the negated namespace name if
        //    it was in the set, must be the value.
        // +3 If either O1 or O2 is a pair of not and a namespace name and the other
        //    is a set of (namespace names or absent), then that set, minus the negated
        //    namespace name if it was in the set, then minus absent if it was in the
        //    set, must be the value.
        // * when we have not(list), the operation is just list-otherlist
        else if ( ((fType == NSCONSTRAINT_NOT) && (wildcard.fType == NSCONSTRAINT_LIST)) ||
                  ((fType == NSCONSTRAINT_LIST) && (wildcard.fType == NSCONSTRAINT_NOT)) ) {
            String[] list = null;
            String[] other = null;

            if (fType == NSCONSTRAINT_NOT) {
                other = fNamespaceList;
                list = wildcard.fNamespaceList;
            }
            else {
                other = wildcard.fNamespaceList;
                list = fNamespaceList;
            }

            int listSize = list.length;
            String[] intersect = new String[listSize];
            int newSize = 0;
            for (int i = 0; i < listSize; i++) {
                if (list[i] != other[0] && list[i] != ABSENT)
                    intersect[newSize++] = list[i];
            }

            intersectWildcard.fType = NSCONSTRAINT_LIST;
            intersectWildcard.fNamespaceList = new String[newSize];
            System.arraycopy(intersect, 0, intersectWildcard.fNamespaceList, 0, newSize);
        }

        // 4 If both O1 and O2 are sets of (namespace names or absent), then the intersection of those
        //   sets must be the value.
        else if ( (fType == NSCONSTRAINT_LIST) && (wildcard.fType == NSCONSTRAINT_LIST) ) {
            intersectWildcard.fType = NSCONSTRAINT_LIST;
            intersectWildcard.fNamespaceList = intersect2sets(fNamespaceList, wildcard.fNamespaceList);
        }

        // -5 If the two are negations of different namespace names, then the intersection is not expressible.
        // +5 If the two are negations of namespace names or absent, then The
        //    appropriate case among the following must be true:
        //    +5.1 If the two are negations of different namespace names, then the
        //         intersection is not expressible.
        //    +5.2 If one of the two is a pair of not and absent, the other must be
        //         the value.
        // * when we have not(list), the operation is just not(onelist+otherlist)
        else if (fType == NSCONSTRAINT_NOT && wildcard.fType == NSCONSTRAINT_NOT) {
            if (fNamespaceList[0] != ABSENT && wildcard.fNamespaceList[0] != ABSENT)
                return null;

            XSWildcardDecl other = this;
            if (fNamespaceList[0] == ABSENT)
                other = wildcard;

            intersectWildcard.fType = other.fType;
            intersectWildcard.fNamespaceList = other.fNamespaceList;
        }

        return intersectWildcard;

    
public org.apache.xerces.impl.xs.XSWildcardDeclperformUnionWith(org.apache.xerces.impl.xs.XSWildcardDecl wildcard, short processContents)
Schema Component Constraint: Attribute Wildcard Union

        // if the other wildcard is not expressible, the result is still not expressible
        if (wildcard == null)
            return null;

        // For a wildcard's {namespace constraint} value to be the intensional union of two
        // other such values (call them O1 and O2): the appropriate case among the following
        // must be true:

        XSWildcardDecl unionWildcard = new XSWildcardDecl();
        unionWildcard.fProcessContents = processContents;

        // 1 If O1 and O2 are the same value, then that value must be the value.
        if (areSame(wildcard)) {
            unionWildcard.fType = fType;
            unionWildcard.fNamespaceList = fNamespaceList;
        }

        // 2 If either O1 or O2 is any, then any must be the value.
        else if ( (fType == NSCONSTRAINT_ANY) || (wildcard.fType == NSCONSTRAINT_ANY) ) {
            unionWildcard.fType = NSCONSTRAINT_ANY;
        }

        // 3 If both O1 and O2 are sets of (namespace names or absent), then the union of
        //   those sets must be the value.
        else if ( (fType == NSCONSTRAINT_LIST) && (wildcard.fType == NSCONSTRAINT_LIST) ) {
            unionWildcard.fType = NSCONSTRAINT_LIST;
            unionWildcard.fNamespaceList = union2sets(fNamespaceList, wildcard.fNamespaceList);
        }

        // -4 If the two are negations of different namespace names, then the intersection
        //    is not expressible.
        // +4 If the two are negations of different namespace names or absent, then
        //    a pair of not and absent must be the value.
        // * now we store ##other as not(list), the result should be
        //   not(intersection of two lists).
        else if (fType == NSCONSTRAINT_NOT && wildcard.fType == NSCONSTRAINT_NOT) {
            unionWildcard.fType = NSCONSTRAINT_NOT;
            unionWildcard.fNamespaceList = new String[2];
            unionWildcard.fNamespaceList[0] = ABSENT;
            unionWildcard.fNamespaceList[1] = ABSENT;
        }

        // 5 If either O1 or O2 is a pair of not and a namespace name and the other is a set of
        //   (namespace names or absent), then The appropriate case among the following must be true:
        //      -5.1 If the set includes the negated namespace name, then any must be the value.
        //      -5.2 If the set does not include the negated namespace name, then whichever of O1 or O2
        //           is a pair of not and a namespace name must be the value.
        //    +5.1 If the negated value is a namespace name, then The appropriate case
        //         among the following must be true:
        //        +5.1.1 If the set includes both the namespace name and absent, then any
        //               must be the value.
        //        +5.1.2 If the set includes the namespace name but does not include
        //               absent, then a pair of not and absent must be the value.
        //        +5.1.3 If the set does not include the namespace name but includes
        //               absent, then the union is not expressible.
        //        +5.1.4 If the set does not include either the namespace name or absent,
        //               then whichever of O1 or O2 is a pair of not and a namespace name must be
        //               the value.
        //    +5.2 If the negated value is absent, then The appropriate case among the
        //         following must be true:
        //        +5.2.1 If the set includes absent, then any must be the value.
        //        +5.2.2 If the set does not include absent, then whichever of O1 or O2 is
        //               a pair of not and a namespace name must be the value.
        // * when we have not(list), the operation is just not(otherlist-list)
        else if ( ((fType == NSCONSTRAINT_NOT) && (wildcard.fType == NSCONSTRAINT_LIST)) ||
                  ((fType == NSCONSTRAINT_LIST) && (wildcard.fType == NSCONSTRAINT_NOT)) ) {
            String[] other = null;
            String[] list = null;

            if (fType == NSCONSTRAINT_NOT) {
                other = fNamespaceList;
                list = wildcard.fNamespaceList;
            }
            else {
                other = wildcard.fNamespaceList;
                list = fNamespaceList;
            }

            boolean foundAbsent = elementInSet(ABSENT, list);

            if (other[0] != ABSENT) {
                boolean foundNS = elementInSet(other[0], list);
                if (foundNS && foundAbsent) {
                    unionWildcard.fType = NSCONSTRAINT_ANY;
                } else if (foundNS && !foundAbsent) {
                    unionWildcard.fType = NSCONSTRAINT_NOT;
                    unionWildcard.fNamespaceList = new String[2];
                    unionWildcard.fNamespaceList[0] = ABSENT;
                    unionWildcard.fNamespaceList[1] = ABSENT;
                } else if (!foundNS && foundAbsent) {
                    return null;
                } else { // !foundNS && !foundAbsent
                    unionWildcard.fType = NSCONSTRAINT_NOT;
                    unionWildcard.fNamespaceList = other;
                }
            } else { // other[0] == ABSENT
                if (foundAbsent) {
                    unionWildcard.fType = NSCONSTRAINT_ANY;
                } else { // !foundAbsent
                    unionWildcard.fType = NSCONSTRAINT_NOT;
                    unionWildcard.fNamespaceList = other;
                }
            }
        }

        return unionWildcard;

    
booleansubset2sets(java.lang.String[] subSet, java.lang.String[] superSet)

        for (int i=0; i<subSet.length; i++) {
            if (!elementInSet(subSet[i], superSet))
                return false;
        }

        return true;
    
public java.lang.StringtoString()

       
        if (fDescription == null) {
            StringBuffer buffer = new StringBuffer();
            buffer.append("WC[");
            switch (fType) {
            case NSCONSTRAINT_ANY:
                buffer.append(SchemaSymbols.ATTVAL_TWOPOUNDANY);
                break;
            case NSCONSTRAINT_NOT:
                buffer.append(SchemaSymbols.ATTVAL_TWOPOUNDOTHER);
                buffer.append(":\"");
                if (fNamespaceList[0] != null)
                    buffer.append(fNamespaceList[0]);
                buffer.append("\"");
                break;
            case NSCONSTRAINT_LIST:
                if (fNamespaceList.length == 0)
                    break;
                buffer.append("\"");
                if (fNamespaceList[0] != null)
                    buffer.append(fNamespaceList[0]);
                buffer.append("\"");
                for (int i = 1; i < fNamespaceList.length; i++) {
                    buffer.append(",\"");
                    if (fNamespaceList[i] != null)
                        buffer.append(fNamespaceList[i]);
                    buffer.append("\"");
                }
                break;
            }
            buffer.append("]");
            fDescription = buffer.toString();
        }

        return fDescription;
    
java.lang.String[]union2sets(java.lang.String[] one, java.lang.String[] theOther)

        String[] result1 = new String[one.length];

        // simple implemention,
        int count = 0;
        for (int i=0; i<one.length; i++) {
            if (!elementInSet(one[i], theOther))
                result1[count++] = one[i];
        }

        String[] result2 = new String[count+theOther.length];
        System.arraycopy(result1, 0, result2, 0, count);
        System.arraycopy(theOther, 0, result2, count, theOther.length);

        return result2;
    
public booleanweakerProcessContents(org.apache.xerces.impl.xs.XSWildcardDecl superWildcard)
Check whether this wildcard has a weaker process contents than the super.

        return fProcessContents == XSWildcardDecl.PC_LAX &&
               superWildcard.fProcessContents == XSWildcardDecl.PC_STRICT ||
               fProcessContents == XSWildcardDecl.PC_SKIP &&
               superWildcard.fProcessContents != XSWildcardDecl.PC_SKIP;