1 16 package org.apache.cocoon.components.validation.impl; 17 18 import java.io.IOException ; 19 20 import org.apache.avalon.framework.activity.Disposable; 21 import org.apache.avalon.framework.logger.LogEnabled; 22 import org.apache.avalon.framework.logger.Logger; 23 import org.apache.avalon.framework.service.ServiceException; 24 import org.apache.avalon.framework.service.ServiceManager; 25 import org.apache.avalon.framework.service.Serviceable; 26 import org.apache.cocoon.components.validation.Schema; 27 import org.apache.cocoon.components.validation.SchemaParser; 28 import org.apache.cocoon.components.validation.ValidationHandler; 29 import org.apache.cocoon.components.validation.Validator; 30 import org.apache.cocoon.components.validation.ValidatorException; 31 import org.apache.excalibur.source.Source; 32 import org.apache.excalibur.source.SourceResolver; 33 import org.apache.excalibur.xml.sax.NOPContentHandler; 34 import org.apache.excalibur.xml.sax.SAXParser; 35 import org.apache.excalibur.xml.sax.XMLizable; 36 import org.xml.sax.Attributes ; 37 import org.xml.sax.ErrorHandler ; 38 import org.xml.sax.InputSource ; 39 import org.xml.sax.SAXException ; 40 41 59 public abstract class AbstractValidator 60 implements Validator, Serviceable, Disposable, LogEnabled { 61 62 63 protected ServiceManager manager = null; 64 65 protected SourceResolver resolver = null; 66 67 protected Logger logger = null; 68 69 72 public AbstractValidator() { 73 super(); 74 } 75 76 79 public void enableLogging(Logger logger) { 80 this.logger = logger; 81 } 82 83 86 public void service(ServiceManager manager) 87 throws ServiceException { 88 this.manager = manager; 89 this.resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE); 90 } 91 92 95 public void dispose() { 96 if (this.resolver != null) this.manager.release(this.resolver); 97 } 98 99 100 101 102 103 122 public ValidationHandler getValidationHandler(String uri) 123 throws IOException , SAXException , ValidatorException { 124 return this.getValidationHandler(uri, null, null); 125 } 126 127 144 public ValidationHandler getValidationHandler(String uri, String grammar) 145 throws IOException , SAXException , ValidatorException { 146 return this.getValidationHandler(uri, grammar, null); 147 } 148 149 169 public ValidationHandler getValidationHandler(String uri, ErrorHandler errorHandler) 170 throws IOException , SAXException , ValidatorException { 171 return this.getValidationHandler(uri, null, errorHandler); 172 } 173 174 193 public ValidationHandler getValidationHandler(String uri, String grammar, 194 ErrorHandler errorHandler) 195 throws IOException , SAXException , ValidatorException { 196 if (uri == null) throw new IOException ("Specified schema URI was null"); 197 Source source = null; 198 try { 199 source = this.resolver.resolveURI(uri); 200 return this.getValidationHandler(source, grammar, errorHandler); 201 } finally { 202 if (source != null) this.resolver.release(source); 203 } 204 } 205 206 225 public ValidationHandler getValidationHandler(Source source) 226 throws IOException , SAXException , ValidatorException { 227 return this.getValidationHandler(source, null, null); 228 } 229 230 247 public ValidationHandler getValidationHandler(Source source, String grammar) 248 throws IOException , SAXException , ValidatorException { 249 return this.getValidationHandler(source, grammar, null); 250 } 251 252 272 public ValidationHandler getValidationHandler(Source source, 273 ErrorHandler errorHandler) 274 throws IOException , SAXException , ValidatorException { 275 return this.getValidationHandler(source, null, errorHandler); 276 } 277 278 297 public ValidationHandler getValidationHandler(Source source, String grammar, 298 ErrorHandler errorHandler) 299 throws IOException , SAXException , ValidatorException { 300 if (errorHandler == null) errorHandler = DraconianErrorHandler.INSTANCE; 301 302 SchemaParser parser = null; 303 try { 304 305 if (grammar == null) grammar = this.detectGrammar(source); 306 307 308 String language = grammar; 309 parser = this.lookupParserByGrammar(grammar); 310 311 315 if (parser == null) { 316 int index = grammar.indexOf(':'); 317 if (index > 0) { 318 String name = grammar.substring(0, index); 319 language = grammar.substring(index + 1); 320 parser = this.lookupParserByName(name); 321 } 322 } 323 324 325 if (parser == null) { 326 String message = "Unsupported grammar language" + grammar; 327 throw new ValidatorException(message); 328 } 329 330 331 String languages[] = parser.getSupportedGrammars(); 332 for (int x = 0; x < languages.length; x++) { 333 if (! language.equals(languages[x])) continue; 334 335 Schema schema = this.getSchema(parser, source, language); 336 return schema.createValidator(errorHandler); 337 } 338 339 340 String message = "Schema parser " + parser.getClass().getName() + 341 " does not support grammar " + grammar; 342 throw new ValidatorException(message); 343 344 } finally { 345 if (parser != null) this.releaseParser(parser); 346 } 347 } 348 349 350 351 352 353 362 protected abstract SchemaParser lookupParserByGrammar(String grammar); 363 364 371 protected abstract SchemaParser lookupParserByName(String name); 372 373 382 protected abstract void releaseParser(SchemaParser parser); 383 384 385 386 387 388 401 protected Schema getSchema(SchemaParser parser, Source source, String grammar) 402 throws IOException , SAXException { 403 if (this.logger.isDebugEnabled()) { 404 this.logger.debug("Parsing schema \"" + source.getURI() + "\" using " + 405 "grammar \"" + grammar + "\" and SourceParser " + 406 parser.getClass().getName()); 407 } 408 409 try { 410 return parser.parseSchema(source, grammar); 411 } catch (IllegalArgumentException exception) { 412 String message = "Schema parser " + parser.getClass().getName() + 413 " does not support grammar " + grammar; 414 throw new ValidatorException(message, exception); 415 } 416 } 417 418 427 protected String detectGrammar(Source source) 428 throws IOException , SAXException , ValidatorException { 429 if (this.logger.isDebugEnabled()) { 430 this.logger.debug("Detecting grammar for \"" + source.getURI() + "\""); 431 } 432 433 SAXParser xmlParser = null; 434 String grammar = null; 435 436 try { 437 DetectionHandler handler = new DetectionHandler(); 438 if (source instanceof XMLizable) { 439 XMLizable xmlizable = (XMLizable) source; 440 xmlizable.toSAX(handler); 441 } else { 442 xmlParser = (SAXParser) this.manager.lookup((SAXParser.ROLE)); 443 InputSource input = new InputSource (); 444 input.setSystemId(source.getURI()); 445 input.setByteStream(source.getInputStream()); 446 xmlParser.parse(input, handler); 447 } 448 } catch (ServiceException exception) { 449 throw new SAXException ("Unable to access XML parser", exception); 450 } catch (DetectionException exception) { 451 grammar = exception.grammar; 452 } finally { 453 if (xmlParser != null) this.manager.release(xmlParser); 454 } 455 456 if (("".equals(grammar)) || (grammar == null)) { 457 String message = "Unable to detect grammar for schema at "; 458 throw new ValidatorException(message + source.getURI()); 459 } else { 460 if (this.logger.isDebugEnabled()) { 461 this.logger.debug("Grammar \"" + grammar + "\" detected for " + 462 "schema \"" + source.getURI()); 463 } 464 return grammar; 465 } 466 } 467 468 469 470 471 472 476 private static final class DetectionHandler extends NOPContentHandler { 477 478 482 public void startElement(String ns, String lnam, String qnam, Attributes a) 483 throws SAXException { 484 throw new DetectionException(ns); 485 } 486 } 487 488 492 private static final class DetectionException extends SAXException { 493 494 private final String grammar; 495 496 private DetectionException(String grammar) { 497 super ("Grammar detected: " + grammar); 498 this.grammar = grammar; 499 } 500 } 501 } 502 | Popular Tags |