KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > apache > xerces > validators > schema > SubstitutionGroupComparator


1
2 /*
3  * The Apache Software License, Version 1.1
4  *
5  *
6  * Copyright (c) 2000 The Apache Software Foundation. All rights
7  * reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed by the
24  * Apache Software Foundation (http://www.apache.org/)."
25  * Alternately, this acknowledgment may appear in the software itself,
26  * if and wherever such third-party acknowledgments normally appear.
27  *
28  * 4. The names "Xerces" and "Apache Software Foundation" must
29  * not be used to endorse or promote products derived from this
30  * software without prior written permission. For written
31  * permission, please contact apache@apache.org.
32  *
33  * 5. Products derived from this software may not be called "Apache",
34  * nor may "Apache" appear in their name, without prior written
35  * permission of the Apache Software Foundation.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals on behalf of the Apache Software Foundation and was
53  * originally based on software copyright (c) 1999, International
54  * Business Machines, Inc., http://www.apache.org. For more
55  * information on the Apache Software Foundation, please see
56  * <http://www.apache.org/>.
57  */

58 package org.enhydra.apache.xerces.validators.schema;
59
60 import java.util.Vector JavaDoc;
61
62 import org.enhydra.apache.xerces.framework.XMLErrorReporter;
63 import org.enhydra.apache.xerces.utils.QName;
64 import org.enhydra.apache.xerces.utils.StringPool;
65 import org.enhydra.apache.xerces.utils.XMLMessages;
66 import org.enhydra.apache.xerces.validators.common.GrammarResolver;
67 import org.enhydra.apache.xerces.validators.common.XMLElementDecl;
68 import org.enhydra.apache.xerces.validators.datatype.DatatypeValidator;
69 import org.xml.sax.SAXException JavaDoc;
70
71 /*
72  * @version 1.0. ericye, neilg
73  *
74   * Modified by neilg, 01/18/01
75   * Note: this class, formerly called equivClassComparator.java, has
76   * been renamed to comply with schema CR changes. It still contains
77   * some outmoded terminology--such as use of the term "exemplar", now
78   * referred to as the head of the substitution group. I have
79   * changed as much terminology as possible, but I thought future
80   * maintainers could deal with simple and not necessarily-ill-named
81   * concepts like exemplar.
82  */

83
84 public class SubstitutionGroupComparator {
85
86     // constants
87
private final int TOP_LEVEL_SCOPE = -1;
88
89     // private data members
90
private StringPool fStringPool = null;
91     private GrammarResolver fGrammarResolver = null;
92     private XMLErrorReporter fErrorReporter = null;
93
94     // constructors
95
private SubstitutionGroupComparator(){
96         // can never be instantiated without passing in a GrammarResolver.
97
}
98     public SubstitutionGroupComparator(GrammarResolver grammarResolver, StringPool stringPool, XMLErrorReporter errorReporter){
99         fGrammarResolver = grammarResolver;
100         fStringPool = stringPool;
101         fErrorReporter = errorReporter;
102     }
103
104     public StringPool getStringPool() {
105         return fStringPool;
106     }
107
108     public XMLErrorReporter getErrorReporter () {
109         return fErrorReporter;
110     }
111
112     //public methods
113
public boolean isEquivalentTo(QName anElement, QName exemplar) throws Exception JavaDoc{
114         if (anElement.localpart==exemplar.localpart && anElement.uri==exemplar.uri ) {
115             return true; // they're the same!
116
}
117
118         if (fGrammarResolver == null || fStringPool == null) {
119             throw new SAXException JavaDoc("Internal error; tried to check an element against a substitutionGroup, but no GrammarResolver is defined");
120         }
121
122         // ??? TODO: first try to use
123
// sGrammar.getElementDeclAllSubstitutionGroupQNames();
124
// which should save lots of time
125

126         int uriIndex = anElement.uri;
127         int localpartIndex = anElement.localpart;
128         String JavaDoc uri = fStringPool.toString(anElement.uri);
129         String JavaDoc localpart = fStringPool.toString(anElement.localpart);
130
131         // In addition to simply trying to find a chain between anElement and exemplar,
132
// we need to make sure that no steps in the chain are blocked.
133
// That is, at every step, we need to make sure that the element
134
// being substituted for will permit being substituted
135
// for, and whether the type of the element will permit derivations in
136
// instance documents of this sort.
137
if(uri==null) {
138             return false;
139         }
140         SchemaGrammar sGrammar = null;
141         try {
142             sGrammar = (SchemaGrammar) fGrammarResolver.getGrammar(uri);
143         }
144         catch ( ClassCastException JavaDoc ce) {
145             //since the return Grammar is not a SchemaGrammar, bail out
146
String JavaDoc er = "Grammar with URI " + uri + " is not a schema grammar!";
147             Object JavaDoc [] a = {er};
148             fErrorReporter.reportError(fErrorReporter.getLocator(),
149                     XMLMessages.XML_DOMAIN,
150                     XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
151                     XMLMessages.SCHEMA_GENERIC_ERROR,
152                     a, XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
153             return false;
154         }
155         if(sGrammar == null) {
156             return false;
157         }
158
159         // this will be the index of anElement
160
int elementIndex = sGrammar.getElementDeclIndex(uriIndex, localpartIndex, TOP_LEVEL_SCOPE);
161         int anElementIndex = elementIndex;
162
163         String JavaDoc substitutionGroupFullName = sGrammar.getElementDeclSubstitutionGroupAffFullName(elementIndex);
164         boolean foundIt = false;
165         while (substitutionGroupFullName != null) {
166             int commaAt = substitutionGroupFullName.indexOf(",");
167             uri = "";
168             localpart = substitutionGroupFullName;
169             if ( commaAt >= 0 ) {
170                 if (commaAt > 0 ) {
171                     uri = substitutionGroupFullName.substring(0,commaAt);
172                 }
173                 localpart = substitutionGroupFullName.substring(commaAt+1);
174             }
175             if(uri==null) {
176                 return false;
177             }
178             try {
179                 sGrammar = (SchemaGrammar) fGrammarResolver.getGrammar(uri);
180             }
181             catch ( ClassCastException JavaDoc ce) {
182                 //since the return Grammar is not a SchemaGrammar, bail out
183
String JavaDoc er = "Grammar with URI " + uri + " is not a schema grammar!";
184                 Object JavaDoc [] a = {er};
185                 fErrorReporter.reportError(fErrorReporter.getLocator(),
186                      XMLMessages.XML_DOMAIN,
187                      XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
188                      XMLMessages.SCHEMA_GENERIC_ERROR,
189                      a, XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
190                 return false;
191             }
192             if(sGrammar == null) {
193                 return false;
194             }
195             uriIndex = fStringPool.addSymbol(uri);
196             localpartIndex = fStringPool.addSymbol(localpart);
197             elementIndex = sGrammar.getElementDeclIndex(uriIndex, localpartIndex, TOP_LEVEL_SCOPE);
198             if (elementIndex == -1) {
199                 return false;
200             }
201
202             if (uriIndex == exemplar.uri && localpartIndex == exemplar.localpart) {
203                 // time to check for block value on element
204
if((sGrammar.getElementDeclBlockSet(elementIndex) & SchemaSymbols.SUBSTITUTION) != 0) {
205                     return false;
206                 }
207                 foundIt = true;
208                 break;
209             }
210
211             substitutionGroupFullName = sGrammar.getElementDeclSubstitutionGroupAffFullName(elementIndex);
212
213         }
214
215         if (!foundIt) {
216             return false;
217         }
218         // this will contain anElement's complexType information.
219
TraverseSchema.ComplexTypeInfo aComplexType = sGrammar.getElementComplexTypeInfo(anElementIndex);
220         // elementIndex contains the index of the substitutionGroup head
221
int exemplarBlockSet = sGrammar.getElementDeclBlockSet(elementIndex);
222         if(aComplexType == null) {
223             // check on simpleType case
224
XMLElementDecl anElementDecl = new XMLElementDecl();
225             sGrammar.getElementDecl(anElementIndex, anElementDecl);
226             DatatypeValidator anElementDV = anElementDecl.datatypeValidator;
227             XMLElementDecl exemplarDecl = new XMLElementDecl();
228             sGrammar.getElementDecl(elementIndex, exemplarDecl);
229             DatatypeValidator exemplarDV = exemplarDecl.datatypeValidator;
230             return((anElementDV == null) ||
231                 ((anElementDV == exemplarDV) ||
232                 ((exemplarBlockSet & SchemaSymbols.RESTRICTION) == 0)));
233         }
234         // now we have to make sure there are no blocks on the complexTypes that this is based upon
235
int anElementDerivationMethod = aComplexType.derivedBy;
236         if((anElementDerivationMethod & exemplarBlockSet) != 0) return false;
237         // this will contain exemplar's complexType information.
238
TraverseSchema.ComplexTypeInfo exemplarComplexType = sGrammar.getElementComplexTypeInfo(elementIndex);
239         for(TraverseSchema.ComplexTypeInfo tempType = aComplexType;
240                 tempType != null && tempType != exemplarComplexType;
241                 tempType = tempType.baseComplexTypeInfo) {
242             if((tempType.blockSet & anElementDerivationMethod) != 0) {
243                 return false;
244             }
245         }
246         return true;
247     }
248
249     /**
250      * check whether one element or any element in its substitution group
251      * is allowed by a given wildcard uri
252      *
253      * @param element the QName of a given element
254      * @param wuri the uri of the wildcard
255      * @param wother whether the uri is from ##other, so wuri is excluded
256      *
257      * @return whether the element is allowed by the wildcard
258      */

259     public boolean isAllowedByWildcard(QName element, int wuri, boolean wother) throws Exception JavaDoc{
260         // whether the uri is allowed directly by the wildcard
261
if (!wother && element.uri == wuri ||
262             //wother && element.uri != wuri && element.uri != fStringPool.EMPTY_STRING) { // ??? TODO
263
wother && element.uri != wuri) {
264             return true;
265         }
266
267         if (fGrammarResolver == null || fStringPool == null) {
268             throw new SAXException JavaDoc("Internal error; tried to check an element against a substitutionGroup, but no GrammarResolver is defined");
269         }
270
271         // get the corresponding grammar
272
String JavaDoc uri = fStringPool.toString(element.uri);
273         if(uri==null)
274             return false;
275         SchemaGrammar sGrammar = null;
276         try {
277             sGrammar = (SchemaGrammar) fGrammarResolver.getGrammar(uri);
278         }
279         catch ( ClassCastException JavaDoc ce) {
280             //since the return Grammar is not a SchemaGrammar, bail out
281
String JavaDoc er = "Grammar with URI " + uri + " is not a schema grammar!";
282             Object JavaDoc [] a = {er};
283             fErrorReporter.reportError(fErrorReporter.getLocator(),
284                     XMLMessages.XML_DOMAIN,
285                     XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
286                     XMLMessages.SCHEMA_GENERIC_ERROR,
287                     a, XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
288             return false;
289         }
290         if(sGrammar == null)
291             return false;
292
293         // then get the element decl index for the element
294
int elementIndex = sGrammar.getElementDeclIndex(element, TOP_LEVEL_SCOPE);
295
296         // get all elements that can substitute the current element
297
Vector JavaDoc substitutionGroupQNames = sGrammar.getElementDeclAllSubstitutionGroupQNames(elementIndex, fGrammarResolver, fStringPool);
298
299         // then check whether there exists one elemet that is allowed by the wildcard
300
int size = substitutionGroupQNames == null ? 0 : substitutionGroupQNames.size();
301         for (int i = 0; i < size; i++) {
302             QName name = ((SchemaGrammar.OneSubGroup)substitutionGroupQNames.elementAt(i)).name;
303             if (!wother && name.uri == wuri ||
304                 //wother && name.uri != wuri && name.uri != fStringPool.EMPTY_STRING) { // ??? TODO
305
wother && name.uri != wuri) {
306                 return true;
307             }
308         }
309
310         return false;
311     }
312 }
313
Popular Tags