1 55 package org.apache.avalon.framework.configuration; 56 57 import java.util.ArrayList ; 58 import java.util.BitSet ; 59 import java.util.Iterator ; 60 import org.xml.sax.Attributes ; 61 import org.xml.sax.Locator ; 62 import org.xml.sax.SAXException ; 63 import org.xml.sax.SAXParseException ; 64 import org.xml.sax.helpers.AttributesImpl ; 65 import org.xml.sax.helpers.NamespaceSupport ; 66 67 74 public class NamespacedSAXConfigurationHandler 75 extends SAXConfigurationHandler 76 { 77 81 private static final int EXPECTED_DEPTH = 5; 82 private final ArrayList m_elements = new ArrayList ( EXPECTED_DEPTH ); 83 private final ArrayList m_prefixes = new ArrayList ( EXPECTED_DEPTH ); 84 private final ArrayList m_values = new ArrayList ( EXPECTED_DEPTH ); 85 89 private final BitSet m_preserveSpace = new BitSet (); 90 private Configuration m_configuration; 91 private Locator m_locator; 92 private NamespaceSupport m_namespaceSupport = new NamespaceSupport (); 93 94 99 public Configuration getConfiguration() 100 { 101 return m_configuration; 102 } 103 104 107 public void clear() 108 { 109 m_elements.clear(); 110 Iterator i = m_prefixes.iterator(); 111 while( i.hasNext() ) 112 { 113 ( (ArrayList )i.next() ).clear(); 114 } 115 m_prefixes.clear(); 116 m_values.clear(); 117 m_locator = null; 118 } 119 120 125 public void setDocumentLocator( final Locator locator ) 126 { 127 m_locator = locator; 128 } 129 130 135 public void startDocument() 136 throws SAXException 137 { 138 m_namespaceSupport.reset(); 139 super.startDocument(); 140 } 141 142 147 public void endDocument() 148 throws SAXException 149 { 150 super.endDocument(); 151 m_namespaceSupport.reset(); 152 } 153 154 162 public void characters( final char[] ch, int start, int end ) 163 throws SAXException 164 { 165 final int depth = m_values.size() - 1; 170 final StringBuffer valueBuffer = (StringBuffer )m_values.get( depth ); 171 valueBuffer.append( ch, start, end ); 172 } 173 174 182 public void endElement( final String namespaceURI, 183 final String localName, 184 final String rawName ) 185 throws SAXException 186 { 187 final int depth = m_elements.size() - 1; 188 final DefaultConfiguration finishedConfiguration = 189 (DefaultConfiguration)m_elements.remove( depth ); 190 final String accumulatedValue = 191 ( (StringBuffer )m_values.remove( depth ) ).toString(); 192 final ArrayList prefixes = (ArrayList )m_prefixes.remove( depth ); 193 194 final Iterator i = prefixes.iterator(); 195 while( i.hasNext() ) 196 { 197 endPrefixMapping( (String )i.next() ); 198 } 199 prefixes.clear(); 200 201 if( finishedConfiguration.getChildren().length == 0 ) 202 { 203 String finishedValue; 205 if( m_preserveSpace.get( depth ) ) 206 { 207 finishedValue = accumulatedValue; 208 } 209 else if( 0 == accumulatedValue.length() ) 210 { 211 finishedValue = null; 212 } 213 else 214 { 215 finishedValue = accumulatedValue.trim(); 216 } 217 finishedConfiguration.setValue( finishedValue ); 218 } 219 else 220 { 221 final String trimmedValue = accumulatedValue.trim(); 222 if( trimmedValue.length() > 0 ) 223 { 224 throw new SAXException ( "Not allowed to define mixed content in the " 225 + "element " + finishedConfiguration.getName() + " at " 226 + finishedConfiguration.getLocation() ); 227 } 228 } 229 230 if( 0 == depth ) 231 { 232 m_configuration = finishedConfiguration; 233 } 234 235 m_namespaceSupport.popContext(); 236 } 237 238 247 protected DefaultConfiguration createConfiguration( final String localName, 248 final String namespaceURI, 249 final String location ) 250 { 251 String prefix = m_namespaceSupport.getPrefix( namespaceURI ); 252 if( prefix == null ) 253 { 254 prefix = ""; 255 } 256 return new DefaultConfiguration( localName, location, namespaceURI, prefix ); 257 } 258 259 268 public void startElement( final String namespaceURI, 269 final String localName, 270 final String rawName, 271 final Attributes attributes ) 272 throws SAXException 273 { 274 m_namespaceSupport.pushContext(); 275 final DefaultConfiguration configuration = 276 createConfiguration( localName, namespaceURI, getLocationString() ); 277 final int depth = m_elements.size(); 280 boolean preserveSpace = false; 282 if( depth > 0 ) 283 { 284 final DefaultConfiguration parent = 285 (DefaultConfiguration)m_elements.get( depth - 1 ); 286 parent.addChild( configuration ); 287 preserveSpace = m_preserveSpace.get( depth - 1 ); 289 } 290 291 m_elements.add( configuration ); 292 m_values.add( new StringBuffer () ); 293 294 final ArrayList prefixes = new ArrayList (); 295 AttributesImpl componentAttr = new AttributesImpl (); 296 297 for( int i = 0; i < attributes.getLength(); i++ ) 298 { 299 if( attributes.getQName( i ).startsWith( "xmlns" ) ) 300 { 301 prefixes.add( attributes.getLocalName( i ) ); 302 this.startPrefixMapping( attributes.getLocalName( i ), 303 attributes.getValue( i ) ); 304 } 305 else if( attributes.getQName( i ).equals( "xml:space" ) ) 306 { 307 preserveSpace = attributes.getValue( i ).equals( "preserve" ); 308 } 309 else 310 { 311 componentAttr.addAttribute( attributes.getURI( i ), 312 attributes.getLocalName( i ), 313 attributes.getQName( i ), 314 attributes.getType( i ), 315 attributes.getValue( i ) ); 316 } 317 } 318 319 if( preserveSpace ) 320 { 321 m_preserveSpace.set( depth ); 322 } 323 else 324 { 325 m_preserveSpace.clear( depth ); 326 } 327 328 m_prefixes.add( prefixes ); 329 330 final int attributesSize = componentAttr.getLength(); 331 332 for( int i = 0; i < attributesSize; i++ ) 333 { 334 final String name = componentAttr.getQName( i ); 335 final String value = componentAttr.getValue( i ); 336 configuration.setAttribute( name, value ); 337 } 338 } 339 340 345 public void error( final SAXParseException exception ) 346 throws SAXException 347 { 348 throw exception; 349 } 350 351 356 public void warning( final SAXParseException exception ) 357 throws SAXException 358 { 359 throw exception; 360 } 361 362 367 public void fatalError( final SAXParseException exception ) 368 throws SAXException 369 { 370 throw exception; 371 } 372 373 378 protected String getLocationString() 379 { 380 if( null == m_locator ) 381 { 382 return "Unknown"; 383 } 384 else 385 { 386 return 387 m_locator.getSystemId() + ":" 388 + m_locator.getLineNumber() + ":" 389 + m_locator.getColumnNumber(); 390 } 391 } 392 393 400 public void startPrefixMapping( String prefix, String uri ) 401 throws SAXException 402 { 403 m_namespaceSupport.declarePrefix( prefix, uri ); 404 super.startPrefixMapping( prefix, uri ); 405 } 406 } 407 | Popular Tags |