Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 366   Methods: 17
NCLOC: 129   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
RuntimeConfigurable.java 86.4% 89.3% 76.5% 86.3%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2000-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, if
 20   
  *    any, must include the following acknowlegement:
 21   
  *       "This product includes software developed by the
 22   
  *        Apache Software Foundation (http://www.apache.org/)."
 23   
  *    Alternately, this acknowlegement may appear in the software itself,
 24   
  *    if and wherever such third-party acknowlegements normally appear.
 25   
  *
 26   
  * 4. The names "Ant" and "Apache Software
 27   
  *    Foundation" must not be used to endorse or promote products derived
 28   
  *    from this software without prior written permission. For written
 29   
  *    permission, please contact apache@apache.org.
 30   
  *
 31   
  * 5. Products derived from this software may not be called "Apache"
 32   
  *    nor may "Apache" appear in their names without prior written
 33   
  *    permission of the Apache Group.
 34   
  *
 35   
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 36   
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 37   
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 38   
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 39   
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 40   
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 41   
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 42   
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 43   
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 44   
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 45   
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 46   
  * SUCH DAMAGE.
 47   
  * ====================================================================
 48   
  *
 49   
  * This software consists of voluntary contributions made by many
 50   
  * individuals on behalf of the Apache Software Foundation.  For more
 51   
  * information on the Apache Software Foundation, please see
 52   
  * <http://www.apache.org/>.
 53   
  */
 54   
 
 55   
 package org.apache.tools.ant;
 56   
 
 57   
 import java.util.Enumeration;
 58   
 import java.util.Locale;
 59   
 import java.util.Vector;
 60   
 import java.util.Hashtable;
 61   
 import java.io.Serializable;
 62   
 
 63   
 import org.xml.sax.AttributeList;
 64   
 import org.xml.sax.helpers.AttributeListImpl;
 65   
 
 66   
 /**
 67   
  * Wrapper class that holds the attributes of an element, its children, and
 68   
  * any text within it. It then takes care of configuring that element at
 69   
  * runtime.
 70   
  *
 71   
  * @author Stefan Bodewig
 72   
  */
 73   
 public class RuntimeConfigurable implements Serializable {
 74   
 
 75   
     /** Name of the element to configure. */
 76   
     private String elementTag = null;
 77   
     
 78   
     /** List of child element wrappers. */
 79   
     private Vector children = new Vector();
 80   
     
 81   
     /** The element to configure. It is only used during
 82   
      * maybeConfigure.
 83   
      */
 84   
     private transient Object wrappedObject = null;
 85   
 
 86   
     /** 
 87   
      * @deprecated
 88   
      * XML attributes for the element. 
 89   
      */
 90   
     private transient AttributeList attributes;
 91   
 
 92   
     /** Attribute names and values. While the XML spec doesn't require
 93   
      *  preserving the order ( AFAIK ), some ant tests do rely on the
 94   
      *  exact order. The following code is copied from AttributeImpl.
 95   
      *  We could also just use SAX2 Attributes and convert to SAX1 ( DOM
 96   
      *  attribute Nodes can also be stored in SAX2 Attributges )
 97   
      */
 98   
     private Vector attributeNames = new Vector();
 99   
     
 100   
     /** Map of attribute names to values */
 101   
     private Hashtable attributeMap = new Hashtable();
 102   
 
 103   
     /** Text appearing within the element. */
 104   
     private StringBuffer characters = new StringBuffer();
 105   
     
 106   
     /** Indicates if the wrapped object has been configured */
 107   
     private boolean proxyConfigured = false;
 108   
 
 109   
     /**
 110   
      * Sole constructor creating a wrapper for the specified object.
 111   
      *
 112   
      * @param proxy The element to configure. Must not be <code>null</code>.
 113   
      * @param elementTag The tag name generating this element.
 114   
      *                   Should not be <code>null</code>.
 115   
      */
 116  22085
     public RuntimeConfigurable(Object proxy, String elementTag) {
 117  22085
         wrappedObject = proxy;
 118  22085
         this.elementTag = elementTag;
 119  22085
         proxyConfigured = false;
 120   
         // Most likely an UnknownElement
 121  22085
         if (proxy instanceof Task) {
 122  22085
             ((Task) proxy).setRuntimeConfigurableWrapper(this);
 123   
         }
 124   
     }
 125   
 
 126   
     /**
 127   
      * Sets the element to configure.
 128   
      *
 129   
      * @param proxy The element to configure. Must not be <code>null</code>.
 130   
      */
 131  4083
     void setProxy(Object proxy) {
 132  4083
         wrappedObject = proxy;
 133  4083
         proxyConfigured = false;
 134   
     }
 135   
 
 136  7448
     public Object getProxy() {
 137  7448
         return wrappedObject;
 138   
     }
 139   
 
 140   
     /**
 141   
      * Sets the attributes for the wrapped element.
 142   
      *
 143   
      * @deprecated
 144   
      * @param attributes List of attributes defined in the XML for this
 145   
      *                   element. May be <code>null</code>.
 146   
      */
 147  0
     public void setAttributes(AttributeList attributes) {
 148  0
         this.attributes = new AttributeListImpl(attributes);
 149  0
         for (int i = 0; i < attributes.getLength(); i++) {
 150  0
             setAttribute(attributes.getName(i), attributes.getValue(i));
 151   
         }
 152   
     }
 153   
 
 154  32396
     public void setAttribute(String name, String value) {
 155  32396
         attributeNames.addElement(name);
 156  32396
         attributeMap.put(name, value);
 157   
     }
 158   
 
 159   
     /** Return the attribute map.
 160   
      *
 161   
      * @return Attribute name to attribute value map
 162   
      */
 163  0
     public Hashtable getAttributeMap() {
 164  0
         return attributeMap;
 165   
     }
 166   
 
 167   
     /**
 168   
      * Returns the list of attributes for the wrapped element.
 169   
      *
 170   
      * @deprecated
 171   
      * @return An AttributeList representing the attributes defined in the
 172   
      *         XML for this element. May be <code>null</code>.
 173   
      */
 174  0
     public AttributeList getAttributes() {
 175  0
         return attributes;
 176   
     }
 177   
 
 178   
     /**
 179   
      * Adds a child element to the wrapped element.
 180   
      *
 181   
      * @param child The child element wrapper to add to this one.
 182   
      *              Must not be <code>null</code>.
 183   
      */
 184  7448
     public void addChild(RuntimeConfigurable child) {
 185  7448
         children.addElement(child);
 186   
     }
 187   
 
 188   
     /**
 189   
      * Returns the child wrapper at the specified position within the list.
 190   
      *
 191   
      * @param index The index of the child to return.
 192   
      *
 193   
      * @return The child wrapper at position <code>index</code> within the
 194   
      *         list.
 195   
      */
 196  933
     RuntimeConfigurable getChild(int index) {
 197  933
         return (RuntimeConfigurable) children.elementAt(index);
 198   
     }
 199   
 
 200   
     /**
 201   
      * Returns an enumeration of all child wrappers.
 202   
      *
 203   
      * @since Ant 1.5.1
 204   
      */
 205  0
     Enumeration getChildren() {
 206  0
         return children.elements();
 207   
     }
 208   
 
 209   
     /**
 210   
      * Adds characters from #PCDATA areas to the wrapped element.
 211   
      *
 212   
      * @param data Text to add to the wrapped element.
 213   
      *        Should not be <code>null</code>.
 214   
      */
 215  15364
     public void addText(String data) {
 216  15364
         characters.append(data);
 217   
     }
 218   
 
 219   
     /**
 220   
      * Adds characters from #PCDATA areas to the wrapped element.
 221   
      *
 222   
      * @param buf A character array of the text within the element.
 223   
      *            Must not be <code>null</code>.
 224   
      * @param start The start element in the array.
 225   
      * @param count The number of characters to read from the array.
 226   
      *
 227   
      */
 228  15364
     public void addText(char[] buf, int start, int count) {
 229  15364
         addText(new String(buf, start, count));
 230   
     }
 231   
 
 232   
     /** Get the text content of this element. Various text chunks are
 233   
      * concatenated, there is no way ( currently ) of keeping track of
 234   
      * multiple fragments.
 235   
      *
 236   
      * @return the text content of this element.
 237   
      */
 238  6
     public StringBuffer getText() {
 239  6
         return characters;
 240   
     }
 241   
 
 242   
     /**
 243   
      * Returns the tag name of the wrapped element.
 244   
      *
 245   
      * @return The tag name of the wrapped element. This is unlikely
 246   
      *         to be <code>null</code>, but may be.
 247   
      */
 248  1775
     public String getElementTag() {
 249  1775
         return elementTag;
 250   
     }
 251   
 
 252   
     /**
 253   
      * Configures the wrapped element and all its children.
 254   
      * The attributes and text for the wrapped element are configured,
 255   
      * and then each child is configured and added. Each time the
 256   
      * wrapper is configured, the attributes and text for it are
 257   
      * reset.
 258   
      *
 259   
      * If the element has an <code>id</code> attribute, a reference
 260   
      * is added to the project as well.
 261   
      *
 262   
      * @param p The project containing the wrapped element.
 263   
      *          Must not be <code>null</code>.
 264   
      *
 265   
      * @exception BuildException if the configuration fails, for instance due
 266   
      *            to invalid attributes or children, or text being added to
 267   
      *            an element which doesn't accept it.
 268   
      */
 269  4125
     public void maybeConfigure(Project p) throws BuildException {
 270  4125
         maybeConfigure(p, true);
 271   
     }
 272   
 
 273   
     /**
 274   
      * Configures the wrapped element.  The attributes and text for
 275   
      * the wrapped element are configured.  Each time the wrapper is
 276   
      * configured, the attributes and text for it are reset.
 277   
      *
 278   
      * If the element has an <code>id</code> attribute, a reference
 279   
      * is added to the project as well.
 280   
      *
 281   
      * @param p The project containing the wrapped element.
 282   
      *          Must not be <code>null</code>.
 283   
      *
 284   
      * @param configureChildren Whether to configure child elements as
 285   
      * well.  if true, child elements will be configured after the
 286   
      * wrapped element.
 287   
      *
 288   
      * @exception BuildException if the configuration fails, for instance due
 289   
      *            to invalid attributes or children, or text being added to
 290   
      *            an element which doesn't accept it.
 291   
      */
 292  4125
     public void maybeConfigure(Project p, boolean configureChildren)
 293   
         throws BuildException {
 294  4125
         String id = null;
 295   
 
 296  4125
         if (proxyConfigured) {
 297  41
             return;
 298   
         }
 299   
 
 300   
         // Configure the object
 301  4084
         Object target = (wrappedObject instanceof TaskAdapter) ?
 302   
                 ((TaskAdapter) wrappedObject).getProxy() : wrappedObject;
 303   
 
 304   
         //PropertyHelper ph=PropertyHelper.getPropertyHelper(p);
 305  4084
         IntrospectionHelper ih =
 306   
             IntrospectionHelper.getHelper(p, target.getClass());
 307   
 
 308  4084
         for (int i = 0; i < attributeNames.size(); i++) {
 309  5756
             String name = (String) attributeNames.elementAt(i);
 310  5756
             String value = (String) attributeMap.get(name);
 311   
 
 312   
             // reflect these into the target
 313  5756
             value = p.replaceProperties(value);
 314  5756
             try {
 315  5756
                 ih.setAttribute(p, target,
 316   
                         name.toLowerCase(Locale.US), value);
 317   
             } catch (BuildException be) {
 318   
                 // id attribute must be set externally
 319  181
                 if (!name.equals("id")) {
 320  11
                     throw be;
 321   
                 }
 322   
             }
 323   
         }
 324  4073
         id = (String) attributeMap.get("id");
 325   
 
 326  4073
         if (characters.length() != 0) {
 327  673
             ProjectHelper.addText(p, wrappedObject, characters.substring(0));
 328   
         }
 329   
 
 330  4073
         Enumeration enum = children.elements();
 331  4073
         while (enum.hasMoreElements()) {
 332  933
             RuntimeConfigurable child
 333   
                     = (RuntimeConfigurable) enum.nextElement();
 334  933
             if (child.wrappedObject instanceof Task) {
 335  114
                 Task childTask = (Task) child.wrappedObject;
 336  114
                 childTask.setRuntimeConfigurableWrapper(child);
 337   
             }
 338   
 
 339  933
             if (configureChildren 
 340   
                 && ih.supportsNestedElement(child.getElementTag())) {
 341  849
                 child.maybeConfigure(p);
 342  842
                 Object container = wrappedObject;
 343  842
                 if (container instanceof TaskAdapter) {
 344  63
                     container = ((TaskAdapter) container).getProxy();
 345   
                 }
 346  842
                 ProjectHelper.storeChild(p, container, child.wrappedObject,
 347   
                         child.getElementTag()
 348   
                         .toLowerCase(Locale.US));
 349   
             }
 350   
         }
 351   
 
 352  4061
         if (id != null) {
 353  170
             p.addReference(id, wrappedObject);
 354   
         }
 355  4061
         proxyConfigured = true;
 356   
     }
 357   
     
 358   
     /**
 359   
      * Reconfigure the element, even if it has already been configured.
 360   
      */
 361  1
     public void reconfigure(Project p) {
 362  1
         proxyConfigured = false;
 363  1
         maybeConfigure(p);
 364   
     }
 365   
 }
 366