Coverage Report - org.apache.tapestry.spec.ExtensionSpecification
 
Classes in this File Line Coverage Branch Coverage Complexity
ExtensionSpecification
0%
0/56
0%
0/8
2
 
 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 org.apache.commons.logging.Log;
 18  
 import org.apache.commons.logging.LogFactory;
 19  
 import org.apache.hivemind.ApplicationRuntimeException;
 20  
 import org.apache.hivemind.ClassResolver;
 21  
 import org.apache.hivemind.util.PropertyUtils;
 22  
 import org.apache.tapestry.Tapestry;
 23  
 import org.apache.tapestry.coerce.ValueConverter;
 24  
 
 25  
 import java.util.Collections;
 26  
 import java.util.HashMap;
 27  
 import java.util.Iterator;
 28  
 import java.util.Map;
 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 IExtensionSpecification
 39  
 {
 40  0
     private static final Log LOG = LogFactory.getLog(ExtensionSpecification.class);
 41  
     
 42  0
     protected Map _configuration = new HashMap();
 43  
     
 44  
     private String _className;
 45  
     
 46  
     private boolean _immediate;
 47  
 
 48  
     /** @since 4.0 */
 49  
     private ClassResolver _resolver;
 50  
 
 51  
     /** @since 4.0 */
 52  
     private ValueConverter _converter;
 53  
 
 54  
     /**
 55  
      * Creates a new instance which will use the specified resolver to resolve classes and converter
 56  
      * to coerce values to their desired type.
 57  
      *
 58  
      * @param resolver
 59  
      *          The class resolver used to resolve classes safely in a servlet environment.
 60  
      * @param valueConverter
 61  
      *          Converter used to coerce values.
 62  
      */
 63  
     public ExtensionSpecification(ClassResolver resolver, ValueConverter valueConverter)
 64  0
     {
 65  0
         _resolver = resolver;
 66  0
         _converter = valueConverter;
 67  0
     }
 68  
 
 69  
     public String getClassName()
 70  
     {
 71  0
         return _className;
 72  
     }
 73  
 
 74  
     public void setClassName(String className)
 75  
     {
 76  0
         _className = className;
 77  0
     }
 78  
 
 79  
     public void addConfiguration(String propertyName, String value)
 80  
     {
 81  0
         if (_configuration.containsKey(propertyName))
 82  0
             throw new IllegalArgumentException(Tapestry.format("ExtensionSpecification.duplicate-property", this, propertyName));
 83  
 
 84  0
         _configuration.put(propertyName, value);
 85  0
     }
 86  
 
 87  
     /**
 88  
      * Returns an immutable Map of the configuration; keyed on property name, with values as
 89  
      * properties to assign.
 90  
      */
 91  
 
 92  
     public Map getConfiguration()
 93  
     {
 94  0
         return Collections.unmodifiableMap(_configuration);
 95  
     }
 96  
 
 97  
     /**
 98  
      * Invoked to instantiate an instance of the extension and return it. It also configures
 99  
      * properties of the extension.
 100  
      */
 101  
 
 102  
     public Object instantiateExtension()
 103  
     {
 104  0
         if (LOG.isDebugEnabled())
 105  0
             LOG.debug("Instantiating extension class " + _className + ".");
 106  
 
 107  0
         Class extensionClass = null;
 108  0
         Object result = null;
 109  
 
 110  
         try
 111  
         {
 112  0
             extensionClass = _resolver.findClass(_className);
 113  
         }
 114  0
         catch (Exception ex)
 115  
         {
 116  0
             throw new ApplicationRuntimeException(Tapestry.format(
 117  
                     "ExtensionSpecification.bad-class",
 118  
                     _className), getLocation(), ex);
 119  0
         }
 120  
 
 121  0
         result = instantiateInstance(extensionClass, result);
 122  
 
 123  0
         initializeProperties(result);
 124  
 
 125  0
         return result;
 126  
     }
 127  
 
 128  
     private void initializeProperties(Object extension)
 129  
     {
 130  
 
 131  0
         Iterator i = _configuration.entrySet().iterator();
 132  0
         while (i.hasNext())
 133  
         {
 134  0
             Map.Entry entry = (Map.Entry) i.next();
 135  
 
 136  0
             String propertyName = (String) entry.getKey();
 137  0
             String textValue = (String) entry.getValue();
 138  
 
 139  
             try
 140  
             {
 141  0
                 Class propertyType = PropertyUtils.getPropertyType(extension, propertyName);
 142  
 
 143  0
                 Object objectValue = _converter.coerceValue(textValue, propertyType);
 144  
 
 145  0
                 PropertyUtils.write(extension, propertyName, objectValue);
 146  
             }
 147  0
             catch (Exception ex)
 148  
             {
 149  0
                 throw new ApplicationRuntimeException(ex.getMessage(), getLocation(), ex);
 150  0
             }
 151  0
         }
 152  0
     }
 153  
 
 154  
     private Object instantiateInstance(Class extensionClass, Object result)
 155  
     {
 156  0
         Object returnResult = result;
 157  
         try
 158  
         {
 159  0
             returnResult = extensionClass.newInstance();
 160  
         }
 161  0
         catch (Exception ex)
 162  
         {
 163  0
             throw new ApplicationRuntimeException(ex.getMessage(), getLocation(), ex);
 164  0
         }
 165  
 
 166  0
         return returnResult;
 167  
     }
 168  
 
 169  
     public String toString()
 170  
     {
 171  0
         StringBuffer buffer = new StringBuffer("ExtensionSpecification@");
 172  0
         buffer.append(Integer.toHexString(hashCode()));
 173  0
         buffer.append('[');
 174  0
         buffer.append(_className);
 175  
 
 176  0
         if (_configuration != null)
 177  
         {
 178  0
             buffer.append(' ');
 179  0
             buffer.append(_configuration);
 180  
         }
 181  
 
 182  0
         buffer.append(']');
 183  
 
 184  0
         return buffer.toString();
 185  
     }
 186  
 
 187  
     /**
 188  
      * Returns true if the extensions should be instantiated immediately after the containing
 189  
      * {@link org.apache.tapestry.spec.LibrarySpecification}if parsed. Non-immediate extensions are
 190  
      * instantiated only as needed.
 191  
      */
 192  
 
 193  
     public boolean isImmediate()
 194  
     {
 195  0
         return _immediate;
 196  
     }
 197  
 
 198  
     public void setImmediate(boolean immediate)
 199  
     {
 200  0
         _immediate = immediate;
 201  0
     }
 202  
 
 203  
 }