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 }