KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tapestry > spec > ExtensionSpecification


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 JavaDoc;
18 import java.util.HashMap JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.Map JavaDoc;
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 JavaDoc _className;
44
45     protected Map JavaDoc _configuration = new HashMap JavaDoc();
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     public ExtensionSpecification(ClassResolver resolver, ValueConverter valueConverter)
58     {
59         _resolver = resolver;
60         _converter = valueConverter;
61     }
62
63     public String JavaDoc getClassName()
64     {
65         return _className;
66     }
67
68     public void setClassName(String JavaDoc className)
69     {
70         _className = className;
71     }
72
73     public void addConfiguration(String JavaDoc propertyName, String JavaDoc value)
74     {
75         if (_configuration.containsKey(propertyName))
76             throw new IllegalArgumentException JavaDoc(Tapestry.format(
77                     "ExtensionSpecification.duplicate-property",
78                     this,
79                     propertyName));
80
81         _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     public Map JavaDoc getConfiguration()
90     {
91         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     public Object JavaDoc instantiateExtension()
100     {
101         if (LOG.isDebugEnabled())
102             LOG.debug("Instantiating extension class " + _className + ".");
103
104         Class JavaDoc extensionClass = null;
105         Object JavaDoc result = null;
106
107         try
108         {
109             extensionClass = _resolver.findClass(_className);
110         }
111         catch (Exception JavaDoc ex)
112         {
113             throw new ApplicationRuntimeException(Tapestry.format(
114                     "ExtensionSpecification.bad-class",
115                     _className), getLocation(), ex);
116         }
117
118         result = instantiateInstance(extensionClass, result);
119
120         initializeProperties(result);
121
122         return result;
123     }
124
125     private void initializeProperties(Object JavaDoc extension)
126     {
127
128         Iterator JavaDoc i = _configuration.entrySet().iterator();
129         while (i.hasNext())
130         {
131             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) i.next();
132
133             String JavaDoc propertyName = (String JavaDoc) entry.getKey();
134             String JavaDoc textValue = (String JavaDoc) entry.getValue();
135
136             try
137             {
138                 Class JavaDoc propertyType = PropertyUtils.getPropertyType(extension, propertyName);
139
140                 Object JavaDoc objectValue = _converter.coerceValue(textValue, propertyType);
141
142                 PropertyUtils.write(extension, propertyName, objectValue);
143             }
144             catch (Exception JavaDoc ex)
145             {
146                 throw new ApplicationRuntimeException(ex.getMessage(), getLocation(), ex);
147             }
148         }
149     }
150
151     private Object JavaDoc instantiateInstance(Class JavaDoc extensionClass, Object JavaDoc result)
152     {
153         try
154         {
155             result = extensionClass.newInstance();
156         }
157         catch (Exception JavaDoc ex)
158         {
159             throw new ApplicationRuntimeException(ex.getMessage(), getLocation(), ex);
160         }
161
162         return result;
163     }
164
165     public String JavaDoc toString()
166     {
167         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("ExtensionSpecification@");
168         buffer.append(Integer.toHexString(hashCode()));
169         buffer.append('[');
170         buffer.append(_className);
171
172         if (_configuration != null)
173         {
174             buffer.append(' ');
175             buffer.append(_configuration);
176         }
177
178         buffer.append(']');
179
180         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     public boolean isImmediate()
190     {
191         return _immediate;
192     }
193
194     public void setImmediate(boolean immediate)
195     {
196         _immediate = immediate;
197     }
198
199 }
Popular Tags