1 8 package org.apache.avalon.excalibur.xml; 9 10 import org.apache.avalon.excalibur.pool.Poolable; 11 import org.apache.avalon.framework.component.ComponentException; 12 import org.apache.avalon.framework.component.ComponentManager; 13 import org.apache.avalon.framework.component.Composable; 14 import org.apache.avalon.framework.logger.AbstractLogEnabled; 15 import org.apache.avalon.framework.parameters.Parameterizable; 16 import org.apache.avalon.framework.parameters.Parameters; 17 import org.w3c.dom.Document ; 18 import org.xml.sax.*; 19 import org.xml.sax.ext.LexicalHandler ; 20 21 import javax.xml.parsers.*; 22 import java.io.IOException ; 23 24 56 public class JaxpParser 57 extends AbstractLogEnabled 58 implements Parser, ErrorHandler, Composable, Parameterizable, Poolable { 59 60 61 protected SAXParserFactory factory; 62 63 64 protected DocumentBuilderFactory docFactory; 65 66 68 protected XMLReader reader; 69 70 72 protected DocumentBuilder docBuilder; 73 74 75 protected ComponentManager manager; 76 77 78 protected EntityResolver resolver; 79 80 81 protected boolean nsPrefixes; 82 83 84 protected boolean reuseParsers; 85 86 87 protected boolean stopOnWarning; 88 89 90 protected boolean stopOnRecoverableError; 91 92 93 96 public void compose(ComponentManager manager) 97 throws ComponentException 98 { 99 this.manager = manager; 100 if ( this.manager.hasComponent(EntityResolver.ROLE) ) 101 { 102 this.resolver = (EntityResolver)this.manager.lookup(EntityResolver.ROLE); 103 if ( this.getLogger().isDebugEnabled() ) 104 { 105 this.getLogger().debug("JaxpParser: Using EntityResolver: " + this.resolver); 106 } 107 } 108 } 109 110 113 public void parameterize( Parameters params ) 114 { 115 boolean validate = params.getParameterAsBoolean("validate", false); 117 this.nsPrefixes = params.getParameterAsBoolean("namespace-prefixes", false); 118 this.reuseParsers = params.getParameterAsBoolean("reuse-parsers", true); 119 this.stopOnWarning = params.getParameterAsBoolean("stop-on-warning", true); 120 this.stopOnRecoverableError = params.getParameterAsBoolean("stop-on-recoverable-error", true); 121 122 this.factory = SAXParserFactory.newInstance(); 123 this.factory.setNamespaceAware(true); 124 this.factory.setValidating(validate); 125 126 this.docFactory = DocumentBuilderFactory.newInstance(); 127 docFactory.setNamespaceAware(true); 128 docFactory.setValidating(validate); 129 if ( this.getLogger().isDebugEnabled() ) 130 { 131 this.getLogger().debug("JaxpParser: validating: " + validate + 132 ", namespace-prefixes: " + this.nsPrefixes + 133 ", reuse parser: " + this.reuseParsers + 134 ", stop on warning: " + this.stopOnWarning + 135 ", stop on recoverable-error: " + this.stopOnRecoverableError); 136 } 137 } 138 139 public void parse(InputSource in, ContentHandler consumer) 140 throws SAXException, IOException 141 { 142 this.setupXMLReader(); 143 144 XMLReader tmpReader = this.reader; 146 this.reader = null; 147 148 try { 149 if (consumer instanceof LexicalHandler ) 150 { 151 tmpReader.setProperty("http://xml.org/sax/properties/lexical-handler", 152 (LexicalHandler )consumer); 153 } 154 } 155 catch (SAXException e) 156 { 157 this.getLogger().warn("SAX2 driver does not support property: "+ 158 "'http://xml.org/sax/properties/lexical-handler'"); 159 } 160 161 tmpReader.setErrorHandler( this ); 162 tmpReader.setContentHandler( consumer ); 163 if ( null != this.resolver ) 164 { 165 tmpReader.setEntityResolver( this.resolver ); 166 } 167 168 169 tmpReader.parse(in); 170 171 if ( this.reuseParsers ) 173 this.reader = tmpReader; 174 } 175 176 177 180 public Document parseDocument(InputSource input) 181 throws SAXException, IOException 182 { 183 this.setupDocumentBuilder(); 184 185 DocumentBuilder tmpBuilder = this.docBuilder; 187 this.docBuilder = null; 188 189 if ( null != this.resolver ) 190 { 191 tmpBuilder.setEntityResolver(this.resolver); 192 } 193 194 Document result = tmpBuilder.parse(input); 195 196 if ( this.reuseParsers) 198 this.docBuilder = tmpBuilder; 199 200 return result; 201 } 202 203 206 protected void setupXMLReader() 207 throws SAXException 208 { 209 if ( null == this.reader ) 210 { 211 try 213 { 214 this.reader = factory.newSAXParser().getXMLReader(); 215 } 216 catch( ParserConfigurationException pce ) 217 { 218 throw new SAXException( "Cannot produce a valid parser", pce ); 219 } 220 if ( this.nsPrefixes ) { 221 try 222 { 223 this.reader.setFeature("http://xml.org/sax/features/namespace-prefixes", this.nsPrefixes); 224 } 225 catch ( SAXException e ) 226 { 227 this.getLogger().warn("SAX2 XMLReader does not support setting feature: "+ 228 "'http://xml.org/sax/features/namespace-prefixes'"); 229 } 230 } 231 } 232 } 233 234 237 protected void setupDocumentBuilder() 238 throws SAXException 239 { 240 if ( null == this.docBuilder ) 241 { 242 try 243 { 244 this.docBuilder = this.docFactory.newDocumentBuilder(); 245 } 246 catch (ParserConfigurationException pce) 247 { 248 throw new SAXException( "Could not create DocumentBuilder", pce ); 249 } 250 } 251 } 252 253 256 public void error( SAXParseException e ) 257 throws SAXException 258 { 259 final String msg = "Error parsing "+e.getSystemId()+" (line "+ 260 e.getLineNumber()+" col. "+e.getColumnNumber()+ 261 "): "+e.getMessage(); 262 if ( this.stopOnRecoverableError ) 263 { 264 throw new SAXException( msg, e ); 265 } 266 this.getLogger().error( msg, e ); 267 } 268 269 272 public void fatalError( SAXParseException e ) 273 throws SAXException 274 { 275 throw new SAXException("Fatal error parsing "+e.getSystemId()+" (line "+ 276 e.getLineNumber()+" col. "+e.getColumnNumber()+ 277 "): "+e.getMessage(),e); 278 } 279 280 283 public void warning( SAXParseException e ) 284 throws SAXException 285 { 286 final String msg = "Warning parsing "+e.getSystemId()+" (line "+ 287 e.getLineNumber()+" col. "+e.getColumnNumber()+ 288 "): "+e.getMessage(); 289 if ( this.stopOnWarning ) 290 { 291 throw new SAXException( msg, e ); 292 } 293 this.getLogger().warn( msg, e ); 294 } 295 } 296 | Popular Tags |