1 /**
2 * Redistribution and use of this software and associated documentation
3 * ("Software"), with or without modification, are permitted provided
4 * that the following conditions are met:
5 *
6 * 1. Redistributions of source code must retain copyright
7 * statements and notices. Redistributions must also contain a
8 * copy of this document.
9 *
10 * 2. Redistributions in binary form must reproduce the
11 * above copyright notice, this list of conditions and the
12 * following disclaimer in the documentation and/or other
13 * materials provided with the distribution.
14 *
15 * 3. The name "Exolab" must not be used to endorse or promote
16 * products derived from this Software without prior written
17 * permission of Intalio, Inc. For written permission,
18 * please contact info@exolab.org.
19 *
20 * 4. Products derived from this Software may not be called "Exolab"
21 * nor may "Exolab" appear in their names without prior written
22 * permission of Intalio, Inc. Exolab is a registered
23 * trademark of Intalio, Inc.
24 *
25 * 5. Due credit should be given to the Exolab Project
26 * (http://www.exolab.org/).
27 *
28 * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32 * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 * OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Copyright 1999-2002 (C) Intalio, Inc. All Rights Reserved.
42 *
43 * $Id$
44 */
45
46 package org.exolab.castor.xml.schema.reader;
47
48 import org.exolab.castor.net.URIResolver;
49 import org.exolab.castor.xml.AttributeSet;
50 import org.exolab.castor.xml.Namespaces;
51 import org.exolab.castor.xml.Unmarshaller;
52 import org.exolab.castor.xml.XMLException;
53 import org.exolab.castor.xml.schema.SchemaContext;
54 import org.exolab.castor.xml.schema.Resolver;
55 import org.xml.sax.Locator;
56
57 /**
58 * The base class for separate component unmarshallers for reading an XML Schema
59 * component.
60 *
61 * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
62 * @version $Revision$ $Date: 2006-04-14 04:14:43 -0600 (Fri, 14 Apr
63 * 2006) $
64 **/
65 public abstract class ComponentReader {
66
67 /** The Castor XML context to use. */
68 private SchemaContext _schemaContext;
69
70 private Locator _documentLocator;
71
72 /**
73 * The resolver to be used for resolving hrefs.
74 */
75 private URIResolver _uriResolver;
76
77 private ComponentReader() {
78 super();
79 }
80
81 /**
82 * To hand down a couple of configuration items to all {@link Unmarshaller} classes.
83 *
84 * @param schemaContext
85 * the {@link SchemaContext} to use
86 */
87 protected ComponentReader(final SchemaContext schemaContext) {
88 this();
89 _schemaContext = schemaContext;
90 }
91
92 /**
93 * Returns the name of the element that this ComponentReader handles
94 *
95 * @return the name of the element that this ComponentReader handles
96 **/
97 public abstract String elementName();
98
99 /**
100 * Returns the Object created by this {@link Unmarshaller}
101 *
102 * @return the Object created by this {@link Unmarshaller}
103 **/
104 public abstract Object getObject();
105
106 /**
107 * Called to signal an end of unmarshalling. This method should be overridden
108 * to perform any necessary clean up by an {@link Unmarshaller}
109 **/
110 public void finish() throws XMLException {
111 }
112
113 /**
114 * Returns the resolver used for resolving id references.
115 *
116 * @return the resolver used for resolving id references.
117 **/
118 public Resolver getResolver() {
119 return _schemaContext.getSchemaResolver();
120 }
121
122 /**
123 * Returns the URIresolver used for resolving hrefs.
124 *
125 * @return the URIresolver used for resolving hrefs.
126 **/
127 public URIResolver getURIResolver() {
128 return _uriResolver;
129 }
130
131 /**
132 * Sets the Resolver to be used for resolving id references
133 *
134 * @param resolver
135 * the Resolver to be used for resolving id references
136 **/
137 public void setResolver(Resolver resolver) {
138 _schemaContext.setSchemaResolver(resolver);
139 }
140
141 /**
142 * Sets the URIResolver to be used for resolving hrefs.
143 *
144 * @param uriResolver
145 * the URIResolver to be used for resolving hrefs.
146 **/
147 public void setURIResolver(URIResolver uriResolver) {
148 _uriResolver = uriResolver;
149 }
150
151 /**
152 * Determines if the given sequence of characters consists of whitespace
153 * characters
154 *
155 * @param chars
156 * an array of characters to check for whitespace
157 * @param start
158 * the start index into the character array
159 * @param length
160 * the number of characters to check
161 * @return true if the characters specficied consist only of whitespace
162 * characters
163 **/
164 public static boolean isWhiteSpace(char[] chars, int start, int length) {
165 int max = start + length;
166 for (int i = start; i < max; i++) {
167 char ch = chars[i];
168 switch (ch) {
169 case ' ':
170 case '\n':
171 case '\t':
172 case '\r':
173 break;
174 default:
175 return false;
176 }
177 }
178 return true;
179 }
180
181 /**
182 * This method is called for a general error.
183 *
184 * @param err
185 * the error message to report
186 **/
187 public void error(String err) throws XMLException {
188 if (getDocumentLocator() != null) {
189 err += "\n line: " + getDocumentLocator().getLineNumber();
190 }
191
192 throw new XMLException(err);
193 }
194
195 /**
196 * This method is called for a general error.
197 *
198 * @param ex
199 * the Exception that caused the error.
200 */
201 public void error(Exception ex) throws XMLException {
202 if (getDocumentLocator() != null) {
203 String err = "An error occured at line: " + getDocumentLocator().getLineNumber();
204 throw new XMLException(err, ex);
205 }
206 throw new XMLException(ex);
207 }
208
209 /**
210 * This method is called when an illegal Attribute is encountered.
211 *
212 * @param attName
213 * the name of the illegal attribute.
214 **/
215 public void illegalAttribute(String attName) throws XMLException {
216 String err = "Illegal attribute '" + attName + "' found on element <" + elementName() + ">.";
217
218 if (getDocumentLocator() != null) {
219 err += "\n line: " + getDocumentLocator().getLineNumber();
220 }
221
222 throw new XMLException(err);
223 }
224
225 /**
226 * This method is called when an illegal Element is encountered.
227 *
228 * @param name
229 * the name of the illegal element
230 **/
231 public void illegalElement(String name) throws XMLException {
232 String err = "Illegal element '" + name + "' found as child of <" + elementName() + ">.";
233
234 if (getDocumentLocator() != null) {
235 err += "\n line: " + getDocumentLocator().getLineNumber();
236 }
237
238 throw new XMLException(err);
239 }
240
241 /**
242 * This method is called when an element which may only be defined once, is
243 * redefined.
244 *
245 * @param name
246 * the name of the element
247 **/
248 public void redefinedElement(String name) throws XMLException {
249 redefinedElement(name, null);
250 }
251
252 /**
253 * This method is called when an element which may only be defined once, is
254 * redefined.
255 *
256 * @param name
257 * the name of the element
258 **/
259 public void redefinedElement(String name, String xtraInfo) throws XMLException {
260 String err = "redefintion of element '" + name + "' within element <" + elementName() + ">.";
261
262 if (getDocumentLocator() != null) {
263 err += "\n line: " + getDocumentLocator().getLineNumber();
264 }
265
266 if (xtraInfo != null) {
267 err += "\n " + xtraInfo;
268 }
269
270 throw new XMLException(err + "\n");
271 }
272
273 /**
274 * This method is called when an out of order element is encountered
275 **/
276 public void outOfOrder(String name) throws XMLException {
277 StringBuffer err = new StringBuffer("out of order element <");
278 err.append(name);
279 err.append("> found in <");
280 err.append(elementName());
281 err.append(">.");
282 throw new XMLException(err.toString());
283 }
284
285 /**
286 * Converts the given String to an int
287 *
288 * @param str
289 * the String to convert to an int
290 * @return the int derived from the given String
291 * @exception IllegalArgumentException
292 * when the given String does not represent a valid int
293 **/
294 public static int toInt(String str) throws IllegalArgumentException {
295 try {
296 return Integer.parseInt(str);
297 } catch (NumberFormatException nfe) {
298 String err = str + " is not a valid integer. ";
299 throw new IllegalArgumentException(err);
300 }
301 }
302
303 public Locator getDocumentLocator() {
304 return _documentLocator;
305 }
306
307 public void setDocumentLocator(Locator documentLocator) {
308 _documentLocator = documentLocator;
309 }
310
311 /**
312 * Signals to recieve charactes
313 *
314 * @param chars
315 * the character array containing the characters
316 * @param start
317 * the starting index into the character array
318 * @param length
319 * the number of characters to recieve
320 **/
321 public void characters(char[] chars, int start, int length) throws XMLException {
322 // -- do nothing, this method is overwritten by subclasses
323 }
324
325 /**
326 * Signals to end of the element with the given name.
327 *
328 * @param name
329 * the NCName of the element. It is an error if the name is a QName
330 * (ie. contains a prefix).
331 * @param namespace
332 * the namespace of the element.
333 **/
334 public void endElement(String name, String namespace) throws XMLException {
335 // -- do nothing, this method is overwritten by subclasses
336 }
337
338 /**
339 * Signals the start of an element with the given name.
340 *
341 * @param name
342 * the NCName of the element. It is an error if the name is a QName
343 * (ie. contains a prefix).
344 * @param namespace
345 * the namespace of the element. This may be null. Note: A null
346 * namespace is not the same as the default namespace unless the
347 * default namespace is also null.
348 * @param atts
349 * the AttributeSet containing the attributes associated with the
350 * element.
351 * @param nsDecls
352 * the namespace declarations being declared for this element. This
353 * may be null.
354 **/
355 public void startElement(String name, String namespace, AttributeSet atts, Namespaces nsDecls) throws XMLException {
356 // -- do nothing, this method is overwritten by subclasses
357 }
358
359 /**
360 * To set the Castor XML schema context to be used.
361 *
362 * @param schemaContext
363 * the Castor XML schema context to be used
364 */
365 public void setSchemaContext(final SchemaContext schemaContext) {
366 _schemaContext = schemaContext;
367 }
368
369 /**
370 * To get the Castor XML schema context used.
371 *
372 * @return the Castor XML schema context used
373 */
374 public SchemaContext getSchemaContext() {
375 return _schemaContext;
376 }
377
378 }