Clover coverage report - DNA Site - 1.1
Coverage timestamp: Sun May 2 2004 15:33:21 BST
file stats: LOC: 318   Methods: 12
NCLOC: 171   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
SAXConfigurationHandler.java 100% 100% 100% 100%
coverage
 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;
 11   
 import java.util.List;
 12   
 
 13   
 import org.codehaus.dna.Configuration;
 14   
 import org.xml.sax.Attributes;
 15   
 import org.xml.sax.Locator;
 16   
 import org.xml.sax.SAXException;
 17   
 import org.xml.sax.SAXParseException;
 18   
 import org.xml.sax.helpers.DefaultHandler;
 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
 29   
 {
 30   
     /**
 31   
      * Empty string used for padding out contents array.
 32   
      */
 33   
     private static final String 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 UNKNOWN = "";
 41   
 
 42   
     /**
 43   
      * Stack of configuration elements currently being
 44   
      * constructed.
 45   
      */
 46   
     private final List m_elements = new ArrayList();
 47   
 
 48   
     /**
 49   
      * Stakc of content text for elements currently being
 50   
      * constructed.
 51   
      */
 52   
     private final ArrayList m_values = new ArrayList();
 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 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  24
     public void setDocumentLocator( final Locator locator )
 71   
     {
 72  24
         m_locator = locator;
 73   
     }
 74   
 
 75   
     /**
 76   
      * Reset internal state of handler in preapration for reuse.
 77   
      */
 78  4
     public void clear()
 79   
     {
 80  4
         m_elements.clear();
 81  4
         m_values.clear();
 82  4
         m_locator = null;
 83   
     }
 84   
 
 85   
     /**
 86   
      * Return the configuration created by handler.
 87   
      *
 88   
      * @return the configuration created by handler.
 89   
      */
 90  44
     public Configuration getConfiguration()
 91   
     {
 92  44
         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  68
     public void startElement( final String uri,
 105   
                               final String localName,
 106   
                               final String qName,
 107   
                               final Attributes attributes )
 108   
         throws SAXException
 109   
     {
 110  68
         DefaultConfiguration parent = null;
 111  68
         String path = ConfigurationUtil.ROOT_PATH;
 112  68
         if( m_elements.size() > 0 )
 113   
         {
 114  20
             final int index = m_elements.size() - 1;
 115  20
             parent =
 116   
                 (DefaultConfiguration)m_elements.get( index );
 117  20
             path = ConfigurationUtil.
 118   
                 generatePathName( parent.getPath(),
 119   
                                   parent.getName() );
 120   
         }
 121  68
         final DefaultConfiguration configuration =
 122   
             new DefaultConfiguration( qName, getLocationDescription(), path );
 123  68
         if( null != parent )
 124   
         {
 125  20
             parent.addChild( configuration );
 126   
         }
 127  68
         final int length = attributes.getLength();
 128  68
         for( int i = 0; i < length; i++ )
 129   
         {
 130  8
             final String key = attributes.getQName( i );
 131  8
             final String value = attributes.getValue( i );
 132  8
             final String newValue =
 133   
                 processAttributeText( configuration, key, value );
 134  8
             configuration.setAttribute( key, newValue );
 135   
         }
 136   
 
 137  68
         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  68
     public void endElement( final String uri,
 153   
                             final String localName,
 154   
                             final String qName )
 155   
         throws SAXException
 156   
     {
 157  68
         final int index = m_elements.size() - 1;
 158  68
         final DefaultConfiguration configuration =
 159   
             (DefaultConfiguration)m_elements.remove( index );
 160  68
         if( index < m_values.size() )
 161   
         {
 162  28
             final String value = m_values.remove( index ).toString();
 163  28
             if( 0 != value.trim().length() )
 164   
             {
 165  20
                 if( 0 == configuration.getChildren().length )
 166   
                 {
 167  16
                     final String newValue =
 168   
                         processValueText( configuration, value );
 169  16
                     configuration.setValue( newValue );
 170   
                 }
 171   
                 else
 172   
                 {
 173  4
                     final String message =
 174   
                         "Mixed content (" + value.trim() + ") " +
 175   
                         "not supported @ " + getLocationDescription();
 176  4
                     throw new SAXException( message );
 177   
                 }
 178   
             }
 179   
         }
 180  64
         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  28
     public void characters( final char[] ch,
 192   
                             final int start,
 193   
                             final int length )
 194   
         throws SAXException
 195   
     {
 196  28
         final int index = m_elements.size() - 1;
 197  28
         StringBuffer sb = null;
 198  28
         if( index < m_values.size() )
 199   
         {
 200  4
             sb = (StringBuffer)m_values.get( index );
 201   
         }
 202  28
         if( null == sb )
 203   
         {
 204  24
             sb = new StringBuffer();
 205  24
             final int minCapacity = index + 1;
 206  24
             m_values.ensureCapacity( minCapacity );
 207  24
             final int size = m_values.size();
 208  24
             for( int i = size; i < minCapacity; i++ )
 209   
             {
 210  28
                 m_values.add( EMPTY_STRING );
 211   
             }
 212  24
             m_values.set( index, sb );
 213   
         }
 214  28
         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  4
     public void warning( final SAXParseException spe )
 225   
         throws SAXException
 226   
     {
 227  4
         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  4
     public void error( final SAXParseException spe )
 238   
         throws SAXException
 239   
     {
 240  4
         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  4
     public void fatalError( final SAXParseException spe )
 251   
         throws SAXException
 252   
     {
 253  4
         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  96
     protected final String getLocationDescription()
 265   
     {
 266  96
         if( null == m_locator ||
 267   
             null == m_locator.getSystemId() )
 268   
         {
 269  80
             return UNKNOWN;
 270   
         }
 271  16
         else if( -1 == m_locator.getLineNumber() )
 272   
         {
 273  8
             return m_locator.getSystemId();
 274   
         }
 275  8
         else if( -1 == m_locator.getColumnNumber() )
 276   
         {
 277  4
             return m_locator.getSystemId() + ":" +
 278   
                 m_locator.getLineNumber();
 279   
         }
 280   
         else
 281   
         {
 282  4
             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  4
     protected String processAttributeText( final Configuration configuration,
 298   
                                            final String name,
 299   
                                            final String value )
 300   
     {
 301  4
         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  12
     protected String processValueText( final Configuration configuration,
 313   
                                        final String value )
 314   
     {
 315  12
         return value;
 316   
     }
 317   
 }
 318