View Javadoc

1   /*
2    * Copyright 2007 Tim Peierls
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.guice;
17  
18  import com.google.inject.Key;
19  import com.google.inject.Injector;
20  
21  import java.util.Collection;
22  import java.util.List;
23  import java.util.Map;
24  
25  import org.directwebremoting.extend.Creator;
26  import org.directwebremoting.extend.CreatorManager;
27  import org.directwebremoting.impl.DefaultCreatorManager;
28  import org.directwebremoting.util.Logger;
29  
30  import static org.directwebremoting.guice.DwrGuiceUtil.getInjector;
31  import static org.directwebremoting.guice.DwrGuiceUtil.getServletContext;
32  
33  /**
34   * Extends an existing creator manager with an injected list of creators
35   * specified at Guice bind-time. Only to be used in conjection with {@link DwrGuiceServlet}.
36   * @author Tim Peierls [tim at peierls dot net]
37   */
38  public class InternalCreatorManager implements CreatorManager 
39  {
40      /**
41       * Retrieves an underlying creator manager from thread-local state
42       * to which this class delegates {@link CreatorManager} calls.
43       * Adds any creators found from the Guice bindings.
44       */
45      public InternalCreatorManager()
46      {
47          this.creatorManager = getCreatorManager();
48          addCreators();
49      }
50  
51      public void setDebug(boolean debug)
52      {
53          if (creatorManager instanceof DefaultCreatorManager)
54          {
55              DefaultCreatorManager dcm = (DefaultCreatorManager) creatorManager;
56              dcm.setDebug(debug);
57          }
58      }
59  
60      public boolean isDebug()
61      {
62          return creatorManager.isDebug();
63      }
64  
65      public void addCreatorType(String typeName, String className)
66      {
67          creatorManager.addCreatorType(typeName, className);
68      }
69  
70      public void addCreator(String scriptName, String typeName, Map params) throws InstantiationException, IllegalAccessException, IllegalArgumentException
71      {
72          creatorManager.addCreator(scriptName, typeName, params);
73      }
74  
75      public void addCreator(String scriptName, Creator creator) throws IllegalArgumentException
76      {
77          creatorManager.addCreator(scriptName, creator);
78      }
79  
80      public Collection getCreatorNames() throws SecurityException
81      {
82          return creatorManager.getCreatorNames();
83      }
84  
85      public Creator getCreator(String scriptName) throws SecurityException
86      {
87          return creatorManager.getCreator(scriptName);
88      }
89  
90      public void setCreators(Map creators)
91      {
92          creatorManager.setCreators(creators);
93      }
94      
95      public boolean isInitApplicationScopeCreatorsAtStartup()
96      {
97          if (creatorManager instanceof DefaultCreatorManager)
98          {
99              DefaultCreatorManager dcm = (DefaultCreatorManager) creatorManager;
100             return dcm.isInitApplicationScopeCreatorsAtStartup();
101         }
102         return false;
103     }
104 
105     public void setInitApplicationScopeCreatorsAtStartup(boolean initApplicationScopeCreatorsAtStartup)
106     {
107         if (creatorManager instanceof DefaultCreatorManager)
108         {
109             DefaultCreatorManager dcm = (DefaultCreatorManager) creatorManager;
110             dcm.setInitApplicationScopeCreatorsAtStartup(initApplicationScopeCreatorsAtStartup);
111         }
112     }
113 
114     
115     private final CreatorManager creatorManager;
116 
117     
118     private void addCreators()
119     {
120         Injector injector = getInjector();
121         for (Key<?> key : injector.getBindings().keySet())
122         {
123             Class<?> atype = key.getAnnotationType();
124             if (atype != null && Remoted.class.isAssignableFrom(atype))
125             {
126                 String scriptName = Remoted.class.cast(key.getAnnotation()).value();
127                 if (scriptName.equals(""))
128                 {
129                     Class cls = (Class) key.getTypeLiteral().getType();
130                     scriptName = cls.getSimpleName();
131                 }
132                 addCreator(scriptName, new InternalCreator(injector, key, scriptName));
133             }
134         }
135     }
136 
137     
138     /**
139      * Stores a type name in a thread-local variable for later retrieval by
140      * {@code getCreatorManager}.
141      */
142     static void setTypeName(String name)
143     {
144         typeName.set(name);
145     }
146     
147     private static CreatorManager getCreatorManager()
148     {
149         String name = typeName.get();
150         try
151         {
152             Class<? extends CreatorManager> cls = 
153                 (Class<? extends CreatorManager>) Class.forName(name);
154             return cls.newInstance();
155         }
156         catch (Exception e)
157         {
158             if (name != null && !"".equals(name)) {
159                 log.warn("Couldn't make CreatorManager from type: " + name);
160             }
161             return new DefaultCreatorManager();
162         }
163     }
164 
165     /**
166      * Place to stash a type name for retrieval in same thread.
167      */
168     private static final ThreadLocal<String> typeName = new ThreadLocal<String>();
169 
170 
171     /**
172      * The log stream
173      */
174     private static final Logger log = Logger.getLogger(InternalCreatorManager.class);
175 }