KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > directwebremoting > impl > DefaultContainer


1 /*
2  * Copyright 2005 Joe Walker
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.directwebremoting.impl;
17
18 import java.lang.reflect.InvocationTargetException JavaDoc;
19 import java.lang.reflect.Method JavaDoc;
20 import java.util.Collection JavaDoc;
21 import java.util.Collections JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.TreeMap JavaDoc;
25
26 import javax.servlet.Servlet JavaDoc;
27
28 import org.directwebremoting.Container;
29 import org.directwebremoting.util.LocalUtil;
30 import org.directwebremoting.util.Logger;
31
32 /**
33  * DefaultContainer is like a mini-IoC container for DWR.
34  * At least it is an IoC container by interface (check: no params that have
35  * anything to do with DWR), but it is hard coded specifically for DWR. If we
36  * want to make more of it we can later, but this is certainly not going to
37  * become a full blown IoC container.
38  * @author Joe Walker [joe at getahead dot ltd dot uk]
39  */

40 public class DefaultContainer extends AbstractContainer implements Container
41 {
42     /**
43      * Set the class that should be used to implement the given interface
44      * @param askFor The interface to implement
45      * @param valueParam The new implementation
46      * @throws IllegalAccessException If the specified beans could not be accessed
47      * @throws InstantiationException If the specified beans could not be created
48      */

49     public void addParameter(Object JavaDoc askFor, Object JavaDoc valueParam) throws InstantiationException JavaDoc, IllegalAccessException JavaDoc
50     {
51         Object JavaDoc value = valueParam;
52
53         // Maybe the value is a classname that needs instansiating
54
if (value instanceof String JavaDoc)
55         {
56             try
57             {
58                 Class JavaDoc impl = LocalUtil.classForName((String JavaDoc) value);
59                 value = impl.newInstance();
60             }
61             catch (ClassNotFoundException JavaDoc ex)
62             {
63                 // it's not a classname, leave it
64
}
65         }
66
67         // If we have an instansiated value object and askFor is an interface
68
// then we can check that one implements the other
69
if (!(value instanceof String JavaDoc) && askFor instanceof String JavaDoc)
70         {
71             try
72             {
73                 Class JavaDoc iface = LocalUtil.classForName((String JavaDoc) askFor);
74                 if (!iface.isAssignableFrom(value.getClass()))
75                 {
76                     log.error("Can't cast: " + value + " to " + askFor);
77                 }
78             }
79             catch (ClassNotFoundException JavaDoc ex)
80             {
81                 // it's not a classname, leave it
82
}
83         }
84
85         if (log.isDebugEnabled())
86         {
87             if (value instanceof String JavaDoc)
88             {
89                 log.debug("Adding IoC setting: " + askFor + "=" + value);
90             }
91             else
92             {
93                 log.debug("Adding IoC implementation: " + askFor + "=" + value.getClass().getName());
94             }
95         }
96
97         beans.put(askFor, value);
98     }
99
100     /**
101      * Called to indicate that we finished adding parameters.
102      * The thread safety of a large part of DWR depends on this function only
103      * being called from {@link Servlet#init(javax.servlet.ServletConfig)},
104      * where all the setup is done, and where we depend on the undocumented
105      * feature of all servlet containers that they complete the init process
106      * of a Servlet before they begin servicing requests.
107      * @see DefaultContainer#addParameter(Object, Object)
108      * @noinspection UnnecessaryLabelOnContinueStatement
109      */

110     public void setupFinished()
111     {
112         // We try to autowire each bean in turn
113
for (Iterator JavaDoc it = beans.entrySet().iterator(); it.hasNext();)
114         {
115             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
116             // Class type = (Class) entry.getKey();
117
Object JavaDoc ovalue = entry.getValue();
118
119             if (!(ovalue instanceof String JavaDoc))
120             {
121                 log.debug("Trying to autowire: " + ovalue.getClass().getName());
122
123                 Method JavaDoc[] methods = ovalue.getClass().getMethods();
124                 methods:
125                 for (int i = 0; i < methods.length; i++)
126                 {
127                     Method JavaDoc setter = methods[i];
128
129                     if (setter.getName().startsWith("set") &&
130                         setter.getName().length() > 3 &&
131                         setter.getParameterTypes().length == 1)
132                     {
133                         String JavaDoc name = Character.toLowerCase(setter.getName().charAt(3)) + setter.getName().substring(4);
134                         Class JavaDoc propertyType = setter.getParameterTypes()[0];
135
136                         // First we try auto-wire by name
137
Object JavaDoc setting = beans.get(name);
138                         if (setting != null)
139                         {
140                             if (propertyType.isAssignableFrom(setting.getClass()))
141                             {
142                                 log.debug("- autowire-by-name: " + name + "=" + setting);
143                                 invoke(setter, ovalue, setting);
144
145                                 continue methods;
146                             }
147                             else if (setting.getClass() == String JavaDoc.class)
148                             {
149                                 try
150                                 {
151                                     Object JavaDoc value = LocalUtil.simpleConvert((String JavaDoc) setting, propertyType);
152
153                                     log.debug("- autowire-by-name: " + name + "=" + value);
154                                     invoke(setter, ovalue, value);
155                                 }
156                                 catch (IllegalArgumentException JavaDoc ex)
157                                 {
158                                     // Ignore - this was a specuative convert anyway
159
}
160
161                                 continue methods;
162                             }
163                         }
164
165                         // Next we try autowire-by-type
166
Object JavaDoc value = beans.get(propertyType.getName());
167                         if (value != null)
168                         {
169                             log.debug("- autowire-by-type: " + name + "=" + value.getClass().getName());
170                             invoke(setter, ovalue, value);
171
172                             continue methods;
173                         }
174
175                         log.debug("- skipped autowire: " + name);
176                     }
177                 }
178             }
179         }
180
181         callInitializingBeans();
182     }
183
184     /**
185      * A helper to do the reflection.
186      * This helper throws away all exceptions, prefering to log.
187      * @param setter The method to invoke
188      * @param bean The object to invoke the method on
189      * @param value The value to assign to the property using the setter method
190      */

191     private static void invoke(Method JavaDoc setter, Object JavaDoc bean, Object JavaDoc value)
192     {
193         try
194         {
195             setter.invoke(bean, new Object JavaDoc[] { value });
196         }
197         catch (IllegalArgumentException JavaDoc ex)
198         {
199             log.error("- Internal error: " + ex.getMessage());
200         }
201         catch (IllegalAccessException JavaDoc ex)
202         {
203             log.error("- Permission error: " + ex.getMessage());
204         }
205         catch (InvocationTargetException JavaDoc ex)
206         {
207             log.error("- Exception during auto-wire: ", ex.getTargetException());
208         }
209     }
210
211     /* (non-Javadoc)
212      * @see org.directwebremoting.Container#getBean(java.lang.String)
213      */

214     public Object JavaDoc getBean(String JavaDoc id)
215     {
216         Object JavaDoc reply = beans.get(id);
217         if (reply == null)
218         {
219             log.debug("DefaultContainer: No bean with id=" + id);
220         }
221
222         return reply;
223     }
224
225     /* (non-Javadoc)
226      * @see org.directwebremoting.Container#getBeanNames()
227      */

228     public Collection JavaDoc getBeanNames()
229     {
230         return Collections.unmodifiableCollection(beans.keySet());
231     }
232
233     /**
234      * The beans that we know of indexed by type
235      */

236     protected Map JavaDoc beans = new TreeMap JavaDoc();
237
238     /**
239      * The log stream
240      */

241     private static final Logger log = Logger.getLogger(DefaultContainer.class);
242 }
243
Popular Tags