Clover coverage report - Code Coverage for tapestry release 4.0-beta-9
Coverage timestamp: Sat Oct 1 2005 08:36:20 EDT
file stats: LOC: 199   Methods: 11
NCLOC: 121   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ExtensionSpecification.java 50% 65.1% 81.8% 66.1%
coverage coverage
 1    // Copyright 2004, 2005 The Apache Software Foundation
 2    //
 3    // Licensed under the Apache License, Version 2.0 (the "License");
 4    // you may not use this file except in compliance with the License.
 5    // You may obtain a copy of the License at
 6    //
 7    // http://www.apache.org/licenses/LICENSE-2.0
 8    //
 9    // Unless required by applicable law or agreed to in writing, software
 10    // distributed under the License is distributed on an "AS IS" BASIS,
 11    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12    // See the License for the specific language governing permissions and
 13    // limitations under the License.
 14   
 15    package org.apache.tapestry.spec;
 16   
 17    import java.util.Collections;
 18    import java.util.HashMap;
 19    import java.util.Iterator;
 20    import java.util.Map;
 21   
 22    import org.apache.commons.logging.Log;
 23    import org.apache.commons.logging.LogFactory;
 24    import org.apache.hivemind.ApplicationRuntimeException;
 25    import org.apache.hivemind.ClassResolver;
 26    import org.apache.hivemind.util.PropertyUtils;
 27    import org.apache.tapestry.Tapestry;
 28    import org.apache.tapestry.coerce.ValueConverter;
 29   
 30    /**
 31    * Defines an "extension", which is much like a helper bean, but is part of a library or application
 32    * specification (and has the same lifecycle as the application).
 33    *
 34    * @author Howard Lewis Ship
 35    * @since 2.2
 36    */
 37   
 38    public class ExtensionSpecification extends LocatablePropertyHolder implements
 39    IExtensionSpecification
 40    {
 41    private static final Log LOG = LogFactory.getLog(ExtensionSpecification.class);
 42   
 43    private String _className;
 44   
 45    protected Map _configuration = new HashMap();
 46   
 47    private boolean _immediate;
 48   
 49    /** @since 4.0 */
 50   
 51    private ClassResolver _resolver;
 52   
 53    /** @since 4.0 */
 54    private ValueConverter _converter;
 55   
 56    /** @since 4.0 */
 57  10 public ExtensionSpecification(ClassResolver resolver, ValueConverter valueConverter)
 58    {
 59  10 _resolver = resolver;
 60  10 _converter = valueConverter;
 61    }
 62   
 63  0 public String getClassName()
 64    {
 65  0 return _className;
 66    }
 67   
 68  10 public void setClassName(String className)
 69    {
 70  10 _className = className;
 71    }
 72   
 73  30 public void addConfiguration(String propertyName, String value)
 74    {
 75  30 if (_configuration.containsKey(propertyName))
 76  0 throw new IllegalArgumentException(Tapestry.format(
 77    "ExtensionSpecification.duplicate-property",
 78    this,
 79    propertyName));
 80   
 81  30 _configuration.put(propertyName, value);
 82    }
 83   
 84    /**
 85    * Returns an immutable Map of the configuration; keyed on property name, with values as
 86    * properties to assign.
 87    */
 88   
 89  4 public Map getConfiguration()
 90    {
 91  4 return Collections.unmodifiableMap(_configuration);
 92    }
 93   
 94    /**
 95    * Invoked to instantiate an instance of the extension and return it. It also configures
 96    * properties of the extension.
 97    */
 98   
 99  6 public Object instantiateExtension()
 100    {
 101  6 if (LOG.isDebugEnabled())
 102  0 LOG.debug("Instantiating extension class " + _className + ".");
 103   
 104  6 Class extensionClass = null;
 105  6 Object result = null;
 106   
 107  6 try
 108    {
 109  6 extensionClass = _resolver.findClass(_className);
 110    }
 111    catch (Exception ex)
 112    {
 113  0 throw new ApplicationRuntimeException(Tapestry.format(
 114    "ExtensionSpecification.bad-class",
 115    _className), getLocation(), ex);
 116    }
 117   
 118  6 result = instantiateInstance(extensionClass, result);
 119   
 120  6 initializeProperties(result);
 121   
 122  6 return result;
 123    }
 124   
 125  6 private void initializeProperties(Object extension)
 126    {
 127   
 128  6 Iterator i = _configuration.entrySet().iterator();
 129  6 while (i.hasNext())
 130    {
 131  21 Map.Entry entry = (Map.Entry) i.next();
 132   
 133  21 String propertyName = (String) entry.getKey();
 134  21 String textValue = (String) entry.getValue();
 135   
 136  21 try
 137    {
 138  21 Class propertyType = PropertyUtils.getPropertyType(extension, propertyName);
 139   
 140  21 Object objectValue = _converter.coerceValue(textValue, propertyType);
 141   
 142  21 PropertyUtils.write(extension, propertyName, objectValue);
 143    }
 144    catch (Exception ex)
 145    {
 146  0 throw new ApplicationRuntimeException(ex.getMessage(), getLocation(), ex);
 147    }
 148    }
 149    }
 150   
 151  6 private Object instantiateInstance(Class extensionClass, Object result)
 152    {
 153  6 try
 154    {
 155  6 result = extensionClass.newInstance();
 156    }
 157    catch (Exception ex)
 158    {
 159  0 throw new ApplicationRuntimeException(ex.getMessage(), getLocation(), ex);
 160    }
 161   
 162  6 return result;
 163    }
 164   
 165  0 public String toString()
 166    {
 167  0 StringBuffer buffer = new StringBuffer("ExtensionSpecification@");
 168  0 buffer.append(Integer.toHexString(hashCode()));
 169  0 buffer.append('[');
 170  0 buffer.append(_className);
 171   
 172  0 if (_configuration != null)
 173    {
 174  0 buffer.append(' ');
 175  0 buffer.append(_configuration);
 176    }
 177   
 178  0 buffer.append(']');
 179   
 180  0 return buffer.toString();
 181    }
 182   
 183    /**
 184    * Returns true if the extensions should be instantiated immediately after the containing
 185    * {@link org.apache.tapestry.spec.LibrarySpecification}if parsed. Non-immediate extensions are
 186    * instantiated only as needed.
 187    */
 188   
 189  10 public boolean isImmediate()
 190    {
 191  10 return _immediate;
 192    }
 193   
 194  10 public void setImmediate(boolean immediate)
 195    {
 196  10 _immediate = immediate;
 197    }
 198   
 199    }