001: /*
002: * The Apache Software License, Version 1.1
003: *
004: *
005: * Copyright (c) 1999,2000 The Apache Software Foundation. All rights
006: * reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: *
012: * 1. Redistributions of source code must retain the above copyright
013: * notice, this list of conditions and the following disclaimer.
014: *
015: * 2. Redistributions in binary form must reproduce the above copyright
016: * notice, this list of conditions and the following disclaimer in
017: * the documentation and/or other materials provided with the
018: * distribution.
019: *
020: * 3. The end-user documentation included with the redistribution,
021: * if any, must include the following acknowledgment:
022: * "This product includes software developed by the
023: * Apache Software Foundation (http://www.apache.org/)."
024: * Alternately, this acknowledgment may appear in the software itself,
025: * if and wherever such third-party acknowledgments normally appear.
026: *
027: * 4. The names "Xerces" and "Apache Software Foundation" must
028: * not be used to endorse or promote products derived from this
029: * software without prior written permission. For written
030: * permission, please contact apache@apache.org.
031: *
032: * 5. Products derived from this software may not be called "Apache",
033: * nor may "Apache" appear in their name, without prior written
034: * permission of the Apache Software Foundation.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
040: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: * ====================================================================
049: *
050: * This software consists of voluntary contributions made by many
051: * individuals on behalf of the Apache Software Foundation and was
052: * originally based on software copyright (c) 1999, International
053: * Business Machines, Inc., http://www.apache.org. For more
054: * information on the Apache Software Foundation, please see
055: * <http://www.apache.org/>.
056: */
057:
058: package org.apache.xerces.validators.common;
059:
060: import org.apache.xerces.utils.QName;
061: import org.apache.xerces.utils.StringPool;
062: import org.apache.xerces.framework.XMLContentSpec;
063: import org.apache.xerces.validators.schema.SubstitutionGroupComparator;
064: import org.apache.xerces.framework.XMLErrorReporter;
065: import org.apache.xerces.validators.schema.SchemaMessageProvider;
066:
067: /**
068: * ElementWildcard is used to check whether two element declarations conflict
069: */
070: public class ElementWildcard {
071: private ElementWildcard() {
072: }
073:
074: private static boolean uriInWildcard(QName qname, int wildcard,
075: int wtype, SubstitutionGroupComparator comparator)
076: throws Exception {
077: int type = wtype & 0x0f;
078:
079: if (type == XMLContentSpec.CONTENTSPECNODE_ANY) {
080: return true;
081: } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_NS) {
082: // substitution of "uri" satisfies "wtype:wildcard"
083: if (comparator != null) {
084: if (comparator.isAllowedByWildcard(qname, wildcard,
085: false))
086: return true;
087: } else {
088: if (qname.uri == wildcard)
089: return true;
090: }
091: } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
092: // substitution of "uri" satisfies "wtype:wildcard"
093: if (comparator != null) {
094: if (comparator.isAllowedByWildcard(qname, wildcard,
095: true))
096: return true;
097: } else {
098: //if (wildcard != uri && uri != StringPool.EMPTY_STRING) // ???
099: if (wildcard != qname.uri)
100: return true;
101: }
102: }
103:
104: return false;
105: }
106:
107: private static boolean wildcardIntersect(int w1, int t1, int w2,
108: int t2) {
109: int type1 = t1 & 0x0f, type2 = t2 & 0x0f;
110:
111: // if either one is "##any", then intersects
112: if (type1 == XMLContentSpec.CONTENTSPECNODE_ANY
113: || type2 == XMLContentSpec.CONTENTSPECNODE_ANY) {
114: return true;
115: }
116:
117: // if both are "some_namespace" and equal, then intersects
118: if (type1 == XMLContentSpec.CONTENTSPECNODE_ANY_NS
119: && type2 == XMLContentSpec.CONTENTSPECNODE_ANY_NS
120: && w1 == w2) {
121: return true;
122: }
123:
124: // if both are "##other", and equal, then intersects
125: if (type1 == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER
126: && type2 == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
127: return true;
128: }
129:
130: // if one "##other" and one namespace, if not equal, then intersects
131: if ((type1 == XMLContentSpec.CONTENTSPECNODE_ANY_NS
132: && type2 == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER || type1 == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER
133: && type2 == XMLContentSpec.CONTENTSPECNODE_ANY_NS)
134: && w1 != w2) {
135: return true;
136: }
137:
138: return false;
139: }
140:
141: // check whether two elements conflict
142: private static boolean conflic(int type1, int local1, int uri1,
143: int type2, int local2, int uri2,
144: SubstitutionGroupComparator comparator) throws Exception {
145: QName q1 = new QName(), q2 = new QName();
146: q1.localpart = local1;
147: q1.uri = uri1;
148: q2.localpart = local2;
149: q2.uri = uri2;
150:
151: if (type1 == XMLContentSpec.CONTENTSPECNODE_LEAF
152: && type2 == XMLContentSpec.CONTENTSPECNODE_LEAF) {
153: if (comparator != null) {
154: if (comparator.isEquivalentTo(q1, q2)
155: || comparator.isEquivalentTo(q2, q1))
156: return true;
157: } else {
158: if (q1.localpart == q2.localpart && q1.uri == q2.uri)
159: return true;
160: }
161: } else if (type1 == XMLContentSpec.CONTENTSPECNODE_LEAF) {
162: if (uriInWildcard(q1, uri2, type2, comparator))
163: return true;
164: } else if (type2 == XMLContentSpec.CONTENTSPECNODE_LEAF) {
165: if (uriInWildcard(q2, uri1, type1, comparator))
166: return true;
167: } else {
168: if (wildcardIntersect(uri1, type1, uri2, type2))
169: return true;
170: }
171:
172: return false;
173: }
174:
175: public static boolean conflict(int type1, int local1, int uri1,
176: int type2, int local2, int uri2,
177: SubstitutionGroupComparator comparator) throws Exception {
178: boolean ret = conflic(type1, local1, uri1, type2, local2, uri2,
179: comparator);
180:
181: if (ret && comparator != null) {
182: StringPool stringPool = comparator.getStringPool();
183: XMLErrorReporter err = comparator.getErrorReporter();
184: err
185: .reportError(
186: err.getLocator(),
187: SchemaMessageProvider.SCHEMA_DOMAIN,
188: SchemaMessageProvider.UniqueParticleAttribution,
189: SchemaMessageProvider.MSG_NONE,
190: new Object[] {
191: eleString(type1, local1, uri1,
192: stringPool),
193: eleString(type2, local2, uri2,
194: stringPool) },
195: XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
196: }
197:
198: return ret;
199: }
200:
201: private static String eleString(int type, int local, int uri,
202: StringPool stringPool) {
203: switch (type & 0x0f) {
204: case XMLContentSpec.CONTENTSPECNODE_LEAF:
205: return stringPool.toString(uri) + ","
206: + stringPool.toString(local);
207: case XMLContentSpec.CONTENTSPECNODE_ANY:
208: return "##any,*";
209: case XMLContentSpec.CONTENTSPECNODE_ANY_NS:
210: return "##any(" + stringPool.toString(uri) + "),*";
211: case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER:
212: return "##other(" + stringPool.toString(uri) + "),*";
213: }
214:
215: return "";
216: }
217: } // class ElementWildcard
|