KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > framework > configuration > SAXConfigurationHandler


1 /* ====================================================================
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 1997-2003 The Apache Software Foundation. All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. The end-user documentation included with the redistribution,
20  * if any, must include the following acknowledgment:
21  * "This product includes software developed by the
22  * Apache Software Foundation (http://www.apache.org/)."
23  * Alternately, this acknowledgment may appear in the software
24  * itself, if and wherever such third-party acknowledgments
25  * normally appear.
26  *
27  * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation"
28  * must not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation. For more
52  * information on the Apache Software Foundation, please see
53  * <http://www.apache.org/>.
54  */

55 package org.apache.avalon.framework.configuration;
56
57 import java.util.ArrayList JavaDoc;
58 import java.util.BitSet JavaDoc;
59 import org.xml.sax.Attributes JavaDoc;
60 import org.xml.sax.ErrorHandler JavaDoc;
61 import org.xml.sax.Locator JavaDoc;
62 import org.xml.sax.SAXException JavaDoc;
63 import org.xml.sax.SAXParseException JavaDoc;
64 import org.xml.sax.helpers.DefaultHandler JavaDoc;
65
66 /**
67  * A SAXConfigurationHandler helps build Configurations out of sax events.
68  *
69  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
70  * @version CVS $Revision: 1.29 $ $Date: 2003/02/11 15:58:39 $
71  */

72 public class SAXConfigurationHandler
73     extends DefaultHandler JavaDoc
74     implements ErrorHandler JavaDoc
75 {
76     /**
77      * Likely number of nested configuration items. If more is
78      * encountered the lists will grow automatically.
79      */

80     private static final int EXPECTED_DEPTH = 5;
81     private final ArrayList JavaDoc m_elements = new ArrayList JavaDoc( EXPECTED_DEPTH );
82     private final ArrayList JavaDoc m_values = new ArrayList JavaDoc( EXPECTED_DEPTH );
83     /**
84      * Contains true at index n if space in the configuration with
85      * depth n is to be preserved.
86      */

87     private final BitSet JavaDoc m_preserveSpace = new BitSet JavaDoc();
88     private Configuration m_configuration;
89     private Locator JavaDoc m_locator;
90
91     /**
92      * Get the configuration object that was built.
93      *
94      * @return a <code>Configuration</code> object
95      */

96     public Configuration getConfiguration()
97     {
98         return m_configuration;
99     }
100
101     /**
102      * Clears all data from this configuration handler.
103      */

104     public void clear()
105     {
106         m_elements.clear();
107         m_values.clear();
108         m_locator = null;
109     }
110
111     /**
112      * Set the document <code>Locator</code> to use.
113      *
114      * @param locator a <code>Locator</code> value
115      */

116     public void setDocumentLocator( final Locator JavaDoc locator )
117     {
118         m_locator = locator;
119     }
120
121     /**
122      * Handling hook for character data.
123      *
124      * @param ch a <code>char[]</code> of data
125      * @param start offset in the character array from which to start reading
126      * @param end length of character data
127      * @throws SAXException if an error occurs
128      */

129     public void characters( final char[] ch, int start, int end )
130         throws SAXException JavaDoc
131     {
132         // it is possible to play micro-optimization here by doing
133
// manual trimming and thus preserve some precious bits
134
// of memory, but it's really not important enough to justify
135
// resulting code complexity
136
final int depth = m_values.size() - 1;
137         final StringBuffer JavaDoc valueBuffer = (StringBuffer JavaDoc)m_values.get( depth );
138         valueBuffer.append( ch, start, end );
139     }
140
141     /**
142      * Handling hook for finishing parsing of an element.
143      *
144      * @param namespaceURI a <code>String</code> value
145      * @param localName a <code>String</code> value
146      * @param rawName a <code>String</code> value
147      * @throws SAXException if an error occurs
148      */

149     public void endElement( final String JavaDoc namespaceURI,
150                             final String JavaDoc localName,
151                             final String JavaDoc rawName )
152         throws SAXException JavaDoc
153     {
154         final int depth = m_elements.size() - 1;
155         final DefaultConfiguration finishedConfiguration =
156             (DefaultConfiguration)m_elements.remove( depth );
157         final String JavaDoc accumulatedValue =
158             ( (StringBuffer JavaDoc)m_values.remove( depth ) ).toString();
159
160         if( finishedConfiguration.getChildren().length == 0 )
161         {
162             // leaf node
163
String JavaDoc finishedValue;
164             if( m_preserveSpace.get( depth ) )
165             {
166                 finishedValue = accumulatedValue;
167             }
168             else if( 0 == accumulatedValue.length() )
169             {
170                 finishedValue = null;
171             }
172             else
173             {
174                 finishedValue = accumulatedValue.trim();
175             }
176             finishedConfiguration.setValue( finishedValue );
177         }
178         else
179         {
180             final String JavaDoc trimmedValue = accumulatedValue.trim();
181             if( trimmedValue.length() > 0 )
182             {
183                 throw new SAXException JavaDoc( "Not allowed to define mixed content in the "
184                                         + "element " + finishedConfiguration.getName() + " at "
185                                         + finishedConfiguration.getLocation() );
186             }
187         }
188
189         if( 0 == depth )
190         {
191             m_configuration = finishedConfiguration;
192         }
193     }
194
195     /**
196      * Create a new <code>DefaultConfiguration</code> with the specified
197      * local name and location.
198      *
199      * @param localName a <code>String</code> value
200      * @param location a <code>String</code> value
201      * @return a <code>DefaultConfiguration</code> value
202      */

203     protected DefaultConfiguration createConfiguration( final String JavaDoc localName,
204                                                         final String JavaDoc location )
205     {
206         return new DefaultConfiguration( localName, location );
207     }
208
209     /**
210      * Handling hook for starting parsing of an element.
211      *
212      * @param namespaceURI a <code>String</code> value
213      * @param localName a <code>String</code> value
214      * @param rawName a <code>String</code> value
215      * @param attributes an <code>Attributes</code> value
216      * @throws SAXException if an error occurs
217      */

218     public void startElement( final String JavaDoc namespaceURI,
219                               final String JavaDoc localName,
220                               final String JavaDoc rawName,
221                               final Attributes JavaDoc attributes )
222         throws SAXException JavaDoc
223     {
224         final DefaultConfiguration configuration =
225             createConfiguration( rawName, getLocationString() );
226         // depth of new configuration (not decrementing here, configuration
227
// is to be added)
228
final int depth = m_elements.size();
229         boolean preserveSpace = false; // top level element trims space by default
230

231         if( depth > 0 )
232         {
233             final DefaultConfiguration parent =
234                 (DefaultConfiguration)m_elements.get( depth - 1 );
235             parent.addChild( configuration );
236             // inherits parent's space preservation policy
237
preserveSpace = m_preserveSpace.get( depth - 1 );
238         }
239
240         m_elements.add( configuration );
241         m_values.add( new StringBuffer JavaDoc() );
242
243         final int attributesSize = attributes.getLength();
244
245         for( int i = 0; i < attributesSize; i++ )
246         {
247             final String JavaDoc name = attributes.getQName( i );
248             final String JavaDoc value = attributes.getValue( i );
249
250             if( !name.equals( "xml:space" ) )
251             {
252                 configuration.setAttribute( name, value );
253             }
254             else
255             {
256                 preserveSpace = value.equals( "preserve" );
257             }
258         }
259
260         if( preserveSpace )
261         {
262             m_preserveSpace.set( depth );
263         }
264         else
265         {
266             m_preserveSpace.clear( depth );
267         }
268     }
269
270     /**
271      * This just throws an exception on a parse error.
272      * @param exception the parse error
273      * @throws SAXException if an error occurs
274      */

275     public void error( final SAXParseException JavaDoc exception )
276         throws SAXException JavaDoc
277     {
278         throw exception;
279     }
280
281     /**
282      * This just throws an exception on a parse error.
283      * @param exception the parse error
284      * @throws SAXException if an error occurs
285      */

286     public void warning( final SAXParseException JavaDoc exception )
287         throws SAXException JavaDoc
288     {
289         throw exception;
290     }
291
292     /**
293      * This just throws an exception on a parse error.
294      * @param exception the parse error
295      * @throws SAXException if an error occurs
296      */

297     public void fatalError( final SAXParseException JavaDoc exception )
298         throws SAXException JavaDoc
299     {
300         throw exception;
301     }
302
303     /**
304      * Returns a string showing the current system ID, line number and column number.
305      *
306      * @return a <code>String</code> value
307      */

308     protected String JavaDoc getLocationString()
309     {
310         if( null == m_locator )
311         {
312             return "Unknown";
313         }
314         else
315         {
316             return
317                 m_locator.getSystemId() + ":"
318                 + m_locator.getLineNumber() + ":"
319                 + m_locator.getColumnNumber();
320         }
321     }
322 }
323
Popular Tags