001: /*
002: * The Apache Software License, Version 1.1
003: *
004: *
005: * Copyright (c) 2001 The Apache Software Foundation.
006: * All rights 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.schema.identity;
059:
060: import org.apache.xerces.framework.XMLAttrList;
061: import org.apache.xerces.validators.schema.SchemaGrammar;
062: import org.apache.xerces.utils.QName;
063: import org.apache.xerces.utils.NamespacesScope;
064: import org.apache.xerces.utils.StringPool;
065:
066: import org.xml.sax.SAXException;
067:
068: /**
069: * Schema identity constraint selector.
070: *
071: * @author Andy Clark, IBM
072: * @version $Id: Selector.java,v 1.12 2001/06/01 20:08:45 neilg Exp $
073: */
074: public class Selector {
075:
076: //
077: // Data
078: //
079:
080: /** XPath. */
081: protected Selector.XPath fXPath;
082:
083: /** Identity constraint. */
084: protected IdentityConstraint fIdentityConstraint;
085:
086: //
087: // Constructors
088: //
089:
090: /** Constructs a selector. */
091: public Selector(Selector.XPath xpath,
092: IdentityConstraint identityConstraint) {
093: fXPath = xpath;
094: fIdentityConstraint = identityConstraint;
095: } // <init>(Selector.XPath,IdentityConstraint)
096:
097: //
098: // Public methods
099: //
100:
101: /** Returns the selector XPath. */
102: public org.apache.xerces.validators.schema.identity.XPath getXPath() {
103: return fXPath;
104: } // getXPath():org.apache.xerces.impl.xpath.XPath
105:
106: /** Returns the identity constraint. */
107: public IdentityConstraint getIdentityConstraint() {
108: return fIdentityConstraint;
109: } // getIdentityConstraint():IdentityConstraint
110:
111: // factory method
112:
113: /** Creates a selector matcher. */
114: public XPathMatcher createMatcher(FieldActivator activator) {
115: return new Selector.Matcher(fXPath, activator);
116: } // createMatcher(FieldActivator):XPathMatcher
117:
118: //
119: // Object methods
120: //
121:
122: /** Returns a string representation of this object. */
123: public String toString() {
124: return fXPath.toString();
125: } // toString():String
126:
127: //
128: // Classes
129: //
130:
131: /**
132: * Schema identity constraint selector XPath expression.
133: *
134: * @author Andy Clark, IBM
135: * @version $Id: Selector.java,v 1.12 2001/06/01 20:08:45 neilg Exp $
136: */
137: public static class XPath extends
138: org.apache.xerces.validators.schema.identity.XPath {
139:
140: //
141: // Constructors
142: //
143:
144: /** Constructs a selector XPath expression. */
145: public XPath(String xpath, StringPool stringPool,
146: NamespacesScope context) throws XPathException {
147: // NOTE: We have to prefix the selector XPath with "./" in
148: // order to handle selectors such as "." that select
149: // the element container because the fields could be
150: // relative to that element. -Ac
151: // Unless xpath starts with a descendant node -Achille Fokoue
152: // ... or a '.' or a '/' - NG
153: super (((xpath.trim().startsWith("/") || xpath.trim()
154: .startsWith(".")) ? xpath : "./" + xpath),
155: stringPool, context);
156:
157: // verify that an attribute is not selected
158: for (int i = 0; i < fLocationPaths.length; i++) {
159: org.apache.xerces.validators.schema.identity.XPath.Axis axis = fLocationPaths[i].steps[fLocationPaths[i].steps.length - 1].axis;
160: if (axis.type == axis.ATTRIBUTE) {
161: throw new XPathException(
162: "selectors cannot select attributes");
163: }
164: }
165:
166: } // <init>(String,StringPool,NamespacesScope)
167:
168: } // class Selector.XPath
169:
170: /**
171: * Selector matcher.
172: *
173: * @author Andy Clark, IBM
174: */
175: protected class Matcher extends XPathMatcher {
176:
177: //
178: // Data
179: //
180:
181: /** Field activator. */
182: protected FieldActivator fFieldActivator;
183:
184: /** Element depth. */
185: protected int fElementDepth;
186:
187: /** Depth at match. */
188: protected int fMatchedDepth;
189:
190: //
191: // Constructors
192: //
193:
194: /** Constructs a selector matcher. */
195: public Matcher(Selector.XPath xpath, FieldActivator activator) {
196: super (xpath, false, Selector.this .fIdentityConstraint);
197: fFieldActivator = activator;
198: } // <init>(Selector.XPath,FieldActivator)
199:
200: //
201: // XMLDocumentFragmentHandler methods
202: //
203:
204: public void startDocumentFragment(StringPool stringPool)
205: throws Exception {
206: super .startDocumentFragment(stringPool);
207: fElementDepth = 0;
208: fMatchedDepth = -1;
209: } // startDocumentFragment(StringPool,NamespacesScope)
210:
211: /**
212: * The start of an element. If the document specifies the start element
213: * by using an empty tag, then the startElement method will immediately
214: * be followed by the endElement method, with no intervening methods.
215: *
216: * @param element The name of the element.
217: * @param attributes The element attributes.
218: * @param handle: beginning of the attribute list
219: * @param elemIndex: index of the element holding these attributes
220: * @param grammar: the SchemaGrammar that all this is being validated by
221: *
222: * @throws SAXException Thrown by handler to signal an error.
223: */
224: public void startElement(QName element, XMLAttrList attributes,
225: int handle, int elemIndex, SchemaGrammar grammar)
226: throws Exception {
227: super .startElement(element, attributes, handle, elemIndex,
228: grammar);
229: fElementDepth++;
230:
231: // activate the fields, if selector is matched
232: if (fMatchedDepth == -1 && isMatched()) {
233: fMatchedDepth = fElementDepth;
234: fFieldActivator.startValueScopeFor(fIdentityConstraint);
235: int count = fIdentityConstraint.getFieldCount();
236: for (int i = 0; i < count; i++) {
237: Field field = fIdentityConstraint.getFieldAt(i);
238: XPathMatcher matcher = fFieldActivator
239: .activateField(field);
240: matcher.startElement(element, attributes, handle,
241: elemIndex, grammar);
242: }
243: }
244:
245: } // startElement(QName,XMLAttrList,int)
246:
247: public void endElement(QName element, int elemIndex,
248: SchemaGrammar grammar) throws Exception {
249: super .endElement(element, elemIndex, grammar);
250: if (fElementDepth-- == fMatchedDepth) {
251: fMatchedDepth = -1;
252: fFieldActivator.endValueScopeFor(fIdentityConstraint);
253: }
254: }
255:
256: } // class Matcher
257:
258: } // class Selector
|