KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > dna > impl > SAXConfigurationHandler


1 /*
2  * Copyright (C) The DNA Group. All rights reserved.
3  *
4  * This software is published under the terms of the DNA
5  * Software License version 1.1, a copy of which has been included
6  * with this distribution in the LICENSE.txt file.
7  */

8 package org.codehaus.dna.impl;
9
10 import java.util.ArrayList JavaDoc;
11 import java.util.List JavaDoc;
12
13 import org.codehaus.dna.Configuration;
14 import org.xml.sax.Attributes JavaDoc;
15 import org.xml.sax.Locator JavaDoc;
16 import org.xml.sax.SAXException JavaDoc;
17 import org.xml.sax.SAXParseException JavaDoc;
18 import org.xml.sax.helpers.DefaultHandler JavaDoc;
19
20 /**
21  * The SAXConfigurationHandler builds a Configuration tree
22  * from SAX events.
23  *
24  * @author Peter Donald
25  * @version $Revision: 1.2 $ $Date: 2004/05/01 09:51:48 $
26  */

27 public class SAXConfigurationHandler
28     extends DefaultHandler JavaDoc
29 {
30     /**
31      * Empty string used for padding out contents array.
32      */

33     private static final String JavaDoc EMPTY_STRING = "";
34
35     /**
36      * Constant to indicate location of
37      * element when parser does not support Locator
38      * interface.
39      */

40     private static final String JavaDoc UNKNOWN = "";
41
42     /**
43      * Stack of configuration elements currently being
44      * constructed.
45      */

46     private final List JavaDoc m_elements = new ArrayList JavaDoc();
47
48     /**
49      * Stakc of content text for elements currently being
50      * constructed.
51      */

52     private final ArrayList JavaDoc m_values = new ArrayList JavaDoc();
53
54     /**
55      * The configuration element created.
56      */

57     private Configuration m_configuration;
58
59     /**
60      * The Locator specified by XML parser.
61      */

62     private Locator JavaDoc m_locator;
63
64     /**
65      * Let the XML parser specify locator for when
66      * events arrive at handler.
67      *
68      * @param locator the locator
69      */

70     public void setDocumentLocator( final Locator JavaDoc locator )
71     {
72         m_locator = locator;
73     }
74
75     /**
76      * Reset internal state of handler in preapration for reuse.
77      */

78     public void clear()
79     {
80         m_elements.clear();
81         m_values.clear();
82         m_locator = null;
83     }
84
85     /**
86      * Return the configuration created by handler.
87      *
88      * @return the configuration created by handler.
89      */

90     public Configuration getConfiguration()
91     {
92         return m_configuration;
93     }
94
95     /**
96      * Start an element and thus a Configuration object.
97      *
98      * @param uri the uri (ignored)
99      * @param localName the localName (ignored)
100      * @param qName the qualified name (used for name of configuration)
101      * @param attributes the attributes of XML element
102      * @throws SAXException if unable to parse element
103      */

104     public void startElement( final String JavaDoc uri,
105                               final String JavaDoc localName,
106                               final String JavaDoc qName,
107                               final Attributes JavaDoc attributes )
108         throws SAXException JavaDoc
109     {
110         DefaultConfiguration parent = null;
111         String JavaDoc path = ConfigurationUtil.ROOT_PATH;
112         if( m_elements.size() > 0 )
113         {
114             final int index = m_elements.size() - 1;
115             parent =
116                 (DefaultConfiguration)m_elements.get( index );
117             path = ConfigurationUtil.
118                 generatePathName( parent.getPath(),
119                                   parent.getName() );
120         }
121         final DefaultConfiguration configuration =
122             new DefaultConfiguration( qName, getLocationDescription(), path );
123         if( null != parent )
124         {
125             parent.addChild( configuration );
126         }
127         final int length = attributes.getLength();
128         for( int i = 0; i < length; i++ )
129         {
130             final String JavaDoc key = attributes.getQName( i );
131             final String JavaDoc value = attributes.getValue( i );
132             final String JavaDoc newValue =
133                 processAttributeText( configuration, key, value );
134             configuration.setAttribute( key, newValue );
135         }
136
137         m_elements.add( configuration );
138     }
139
140     /**
141      * End an element and thus a Configuration object.
142      * Will pop of configuration and value of object from
143      * stack. If the handler detects that element has both
144      * child elements and a text value then it will throw
145      * a SAXException.
146      *
147      * @param uri the uri (ignored)
148      * @param localName the localName (ignored)
149      * @param qName the qualified name (used for name of configuration)
150      * @throws SAXException if element had mixed content
151      */

152     public void endElement( final String JavaDoc uri,
153                             final String JavaDoc localName,
154                             final String JavaDoc qName )
155         throws SAXException JavaDoc
156     {
157         final int index = m_elements.size() - 1;
158         final DefaultConfiguration configuration =
159             (DefaultConfiguration)m_elements.remove( index );
160         if( index < m_values.size() )
161         {
162             final String JavaDoc value = m_values.remove( index ).toString();
163             if( 0 != value.trim().length() )
164             {
165                 if( 0 == configuration.getChildren().length )
166                 {
167                     final String JavaDoc newValue =
168                         processValueText( configuration, value );
169                     configuration.setValue( newValue );
170                 }
171                 else
172                 {
173                     final String JavaDoc message =
174                         "Mixed content (" + value.trim() + ") " +
175                         "not supported @ " + getLocationDescription();
176                     throw new SAXException JavaDoc( message );
177                 }
178             }
179         }
180         m_configuration = configuration;
181     }
182
183     /**
184      * Receive text data for current element.
185      *
186      * @param ch the char array
187      * @param start the start index
188      * @param length the length of data
189      * @throws SAXException if unable ot parse data
190      */

191     public void characters( final char[] ch,
192                             final int start,
193                             final int length )
194         throws SAXException JavaDoc
195     {
196         final int index = m_elements.size() - 1;
197         StringBuffer JavaDoc sb = null;
198         if( index < m_values.size() )
199         {
200             sb = (StringBuffer JavaDoc)m_values.get( index );
201         }
202         if( null == sb )
203         {
204             sb = new StringBuffer JavaDoc();
205             final int minCapacity = index + 1;
206             m_values.ensureCapacity( minCapacity );
207             final int size = m_values.size();
208             for( int i = size; i < minCapacity; i++ )
209             {
210                 m_values.add( EMPTY_STRING );
211             }
212             m_values.set( index, sb );
213         }
214         sb.append( ch, start, length );
215     }
216
217     /**
218      * Rethrow exception and dont attempt to do
219      * any error handling.
220      *
221      * @param spe the input exception
222      * @throws SAXException always thrown
223      */

224     public void warning( final SAXParseException JavaDoc spe )
225         throws SAXException JavaDoc
226     {
227         throw spe;
228     }
229
230     /**
231      * Rethrow exception and dont attempt to do
232      * any error handling.
233      *
234      * @param spe the input exception
235      * @throws SAXException always thrown
236      */

237     public void error( final SAXParseException JavaDoc spe )
238         throws SAXException JavaDoc
239     {
240         throw spe;
241     }
242
243     /**
244      * Rethrow exception and dont attempt to do
245      * any error handling.
246      *
247      * @param spe the input exception
248      * @throws SAXException always thrown
249      */

250     public void fatalError( final SAXParseException JavaDoc spe )
251         throws SAXException JavaDoc
252     {
253         throw spe;
254     }
255
256     /**
257      * Utility method to derive current location of
258      * XML parser. Attempts to build up a string containing
259      * systemID:lineNumber:columnNumber such as
260      * "file.xml:20:3" if parser supports all fields.
261      *
262      * @return the location description
263      */

264     protected final String JavaDoc getLocationDescription()
265     {
266         if( null == m_locator ||
267             null == m_locator.getSystemId() )
268         {
269             return UNKNOWN;
270         }
271         else if( -1 == m_locator.getLineNumber() )
272         {
273             return m_locator.getSystemId();
274         }
275         else if( -1 == m_locator.getColumnNumber() )
276         {
277             return m_locator.getSystemId() + ":" +
278                 m_locator.getLineNumber();
279         }
280         else
281         {
282             return m_locator.getSystemId() + ':' +
283                 m_locator.getLineNumber() + ':' +
284                 m_locator.getColumnNumber();
285         }
286     }
287
288     /**
289      * Users may subclass this method to process attribute
290      * prior to it being set.
291      *
292      * @param configuration the associated configuration
293      * @param name the attribute name
294      * @param value the attribute value
295      * @return the attribute value
296      */

297     protected String JavaDoc processAttributeText( final Configuration configuration,
298                                            final String JavaDoc name,
299                                            final String JavaDoc value )
300     {
301         return value;
302     }
303
304     /**
305      * Users may subclass this method to process content
306      * prior to it being set.
307      *
308      * @param configuration the associated configuration
309      * @param value the value
310      * @return the value
311      */

312     protected String JavaDoc processValueText( final Configuration configuration,
313                                        final String JavaDoc value )
314     {
315         return value;
316     }
317 }
318
Popular Tags