Clover coverage report - DNA - 1.0
Coverage timestamp: Sun Oct 12 2003 11:23:26 BST
file stats: LOC: 317   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 JContainer Group. All rights reserved.
 3   
  *
 4   
  * This software is published under the terms of the JContainer
 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.jcontainer.dna.impl;
 9   
 
 10   
 import java.util.ArrayList;
 11   
 import java.util.List;
 12   
 import org.jcontainer.dna.Configuration;
 13   
 import org.xml.sax.Attributes;
 14   
 import org.xml.sax.Locator;
 15   
 import org.xml.sax.SAXException;
 16   
 import org.xml.sax.SAXParseException;
 17   
 import org.xml.sax.helpers.DefaultHandler;
 18   
 
 19   
 /**
 20   
  * The SAXConfigurationHandler builds a Configuration tree
 21   
  * from SAX events.
 22   
  *
 23   
  * @author <a href="mailto:peter at realityforge.org">Peter Donald</a>
 24   
  * @version $Revision: 1.21 $ $Date: 2003/10/05 09:04:55 $
 25   
  */
 26   
 public class SAXConfigurationHandler
 27   
     extends DefaultHandler
 28   
 {
 29   
     /**
 30   
      * Empty string used for padding out contents array.
 31   
      */
 32   
     private static final String EMPTY_STRING = "";
 33   
 
 34   
     /**
 35   
      * Constant to indicate location of
 36   
      * element when parser does not support Locator
 37   
      * interface.
 38   
      */
 39   
     private static final String UNKNOWN = "";
 40   
 
 41   
     /**
 42   
      * Stack of configuration elements currently being
 43   
      * constructed.
 44   
      */
 45   
     private final List m_elements = new ArrayList();
 46   
 
 47   
     /**
 48   
      * Stakc of content text for elements currently being
 49   
      * constructed.
 50   
      */
 51   
     private final ArrayList m_values = new ArrayList();
 52   
 
 53   
     /**
 54   
      * The configuration element created.
 55   
      */
 56   
     private Configuration m_configuration;
 57   
 
 58   
     /**
 59   
      * The Locator specified by XML parser.
 60   
      */
 61   
     private Locator m_locator;
 62   
 
 63   
     /**
 64   
      * Let the XML parser specify locator for when
 65   
      * events arrive at handler.
 66   
      *
 67   
      * @param locator the locator
 68   
      */
 69  12
     public void setDocumentLocator( final Locator locator )
 70   
     {
 71  12
         m_locator = locator;
 72   
     }
 73   
 
 74   
     /**
 75   
      * Reset internal state of handler in preapration for reuse.
 76   
      */
 77  2
     public void clear()
 78   
     {
 79  2
         m_elements.clear();
 80  2
         m_values.clear();
 81  2
         m_locator = null;
 82   
     }
 83   
 
 84   
     /**
 85   
      * Return the configuration created by handler.
 86   
      *
 87   
      * @return the configuration created by handler.
 88   
      */
 89  22
     public Configuration getConfiguration()
 90   
     {
 91  22
         return m_configuration;
 92   
     }
 93   
 
 94   
     /**
 95   
      * Start an element and thus a Configuration object.
 96   
      *
 97   
      * @param uri the uri (ignored)
 98   
      * @param localName the localName (ignored)
 99   
      * @param qName the qualified name (used for name of configuration)
 100   
      * @param attributes the attributes of XML element
 101   
      * @throws SAXException if unable to parse element
 102   
      */
 103  34
     public void startElement( final String uri,
 104   
                               final String localName,
 105   
                               final String qName,
 106   
                               final Attributes attributes )
 107   
         throws SAXException
 108   
     {
 109  34
         DefaultConfiguration parent = null;
 110  34
         String path = ConfigurationUtil.ROOT_PATH;
 111  34
         if( m_elements.size() > 0 )
 112   
         {
 113  10
             final int index = m_elements.size() - 1;
 114  10
             parent =
 115   
                 (DefaultConfiguration)m_elements.get( index );
 116  10
             path = ConfigurationUtil.
 117   
                 generatePathName( parent.getPath(),
 118   
                                   parent.getName() );
 119   
         }
 120  34
         final DefaultConfiguration configuration =
 121   
             new DefaultConfiguration( qName, getLocationDescription(), path );
 122  34
         if( null != parent )
 123   
         {
 124  10
             parent.addChild( configuration );
 125   
         }
 126  34
         final int length = attributes.getLength();
 127  34
         for( int i = 0; i < length; i++ )
 128   
         {
 129  4
             final String key = attributes.getQName( i );
 130  4
             final String value = attributes.getValue( i );
 131  4
             final String newValue =
 132   
                 processAttributeText( configuration, key, value );
 133  4
             configuration.setAttribute( key, newValue );
 134   
         }
 135   
 
 136  34
         m_elements.add( configuration );
 137   
     }
 138   
 
 139   
     /**
 140   
      * End an element and thus a Configuration object.
 141   
      * Will pop of configuration and value of object from
 142   
      * stack. If the handler detects that element has both
 143   
      * child elements and a text value then it will throw
 144   
      * a SAXException.
 145   
      *
 146   
      * @param uri the uri (ignored)
 147   
      * @param localName the localName (ignored)
 148   
      * @param qName the qualified name (used for name of configuration)
 149   
      * @throws SAXException if element had mixed content
 150   
      */
 151  34
     public void endElement( final String uri,
 152   
                             final String localName,
 153   
                             final String qName )
 154   
         throws SAXException
 155   
     {
 156  34
         final int index = m_elements.size() - 1;
 157  34
         final DefaultConfiguration configuration =
 158   
             (DefaultConfiguration)m_elements.remove( index );
 159  34
         if( index < m_values.size() )
 160   
         {
 161  14
             final String value = m_values.remove( index ).toString();
 162  14
             if( 0 != value.trim().length() )
 163   
             {
 164  10
                 if( 0 == configuration.getChildren().length )
 165   
                 {
 166  8
                     final String newValue =
 167   
                         processValueText( configuration, value );
 168  8
                     configuration.setValue( newValue );
 169   
                 }
 170   
                 else
 171   
                 {
 172  2
                     final String message =
 173   
                         "Mixed content (" + value.trim() + ") " +
 174   
                         "not supported @ " + getLocationDescription();
 175  2
                     throw new SAXException( message );
 176   
                 }
 177   
             }
 178   
         }
 179  32
         m_configuration = configuration;
 180   
     }
 181   
 
 182   
     /**
 183   
      * Receive text data for current element.
 184   
      *
 185   
      * @param ch the char array
 186   
      * @param start the start index
 187   
      * @param length the length of data
 188   
      * @throws SAXException if unable ot parse data
 189   
      */
 190  14
     public void characters( final char[] ch,
 191   
                             final int start,
 192   
                             final int length )
 193   
         throws SAXException
 194   
     {
 195  14
         final int index = m_elements.size() - 1;
 196  14
         StringBuffer sb = null;
 197  14
         if( index < m_values.size() )
 198   
         {
 199  2
             sb = (StringBuffer)m_values.get( index );
 200   
         }
 201  14
         if( null == sb )
 202   
         {
 203  12
             sb = new StringBuffer();
 204  12
             final int minCapacity = index + 1;
 205  12
             m_values.ensureCapacity( minCapacity );
 206  12
             final int size = m_values.size();
 207  12
             for( int i = size; i < minCapacity; i++ )
 208   
             {
 209  14
                 m_values.add( EMPTY_STRING );
 210   
             }
 211  12
             m_values.set( index, sb );
 212   
         }
 213  14
         sb.append( ch, start, length );
 214   
     }
 215   
 
 216   
     /**
 217   
      * Rethrow exception and dont attempt to do
 218   
      * any error handling.
 219   
      *
 220   
      * @param spe the input exception
 221   
      * @throws SAXException always thrown
 222   
      */
 223  2
     public void warning( final SAXParseException spe )
 224   
         throws SAXException
 225   
     {
 226  2
         throw spe;
 227   
     }
 228   
 
 229   
     /**
 230   
      * Rethrow exception and dont attempt to do
 231   
      * any error handling.
 232   
      *
 233   
      * @param spe the input exception
 234   
      * @throws SAXException always thrown
 235   
      */
 236  2
     public void error( final SAXParseException spe )
 237   
         throws SAXException
 238   
     {
 239  2
         throw spe;
 240   
     }
 241   
 
 242   
     /**
 243   
      * Rethrow exception and dont attempt to do
 244   
      * any error handling.
 245   
      *
 246   
      * @param spe the input exception
 247   
      * @throws SAXException always thrown
 248   
      */
 249  2
     public void fatalError( final SAXParseException spe )
 250   
         throws SAXException
 251   
     {
 252  2
         throw spe;
 253   
     }
 254   
 
 255   
     /**
 256   
      * Utility method to derive current location of
 257   
      * XML parser. Attempts to build up a string containing
 258   
      * systemID:lineNumber:columnNumber such as
 259   
      * "file.xml:20:3" if parser supports all fields.
 260   
      *
 261   
      * @return the location description
 262   
      */
 263  49
     protected final String getLocationDescription()
 264   
     {
 265  49
         if( null == m_locator ||
 266   
             null == m_locator.getSystemId() )
 267   
         {
 268  41
             return UNKNOWN;
 269   
         }
 270  8
         else if( -1 == m_locator.getLineNumber() )
 271   
         {
 272  4
             return m_locator.getSystemId();
 273   
         }
 274  4
         else if( -1 == m_locator.getColumnNumber() )
 275   
         {
 276  2
             return m_locator.getSystemId() + ":" +
 277   
                 m_locator.getLineNumber();
 278   
         }
 279   
         else
 280   
         {
 281  2
             return m_locator.getSystemId() + ':' +
 282   
                 m_locator.getLineNumber() + ':' +
 283   
                 m_locator.getColumnNumber();
 284   
         }
 285   
     }
 286   
 
 287   
     /**
 288   
      * Users may subclass this method to process attribute
 289   
      * prior to it being set.
 290   
      *
 291   
      * @param configuration the associated configuration
 292   
      * @param name the attribute name
 293   
      * @param value the attribute value
 294   
      * @return the attribute value
 295   
      */
 296  2
     protected String processAttributeText( final Configuration configuration,
 297   
                                            final String name,
 298   
                                            final String value )
 299   
     {
 300  2
         return value;
 301   
     }
 302   
 
 303   
     /**
 304   
      * Users may subclass this method to process content
 305   
      * prior to it being set.
 306   
      *
 307   
      * @param configuration the associated configuration
 308   
      * @param value the value
 309   
      * @return the value
 310   
      */
 311  6
     protected String processValueText( final Configuration configuration,
 312   
                                        final String value )
 313   
     {
 314  6
         return value;
 315   
     }
 316   
 }
 317