001: /*
002: * Copyright 2007 Tim Peierls
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.directwebremoting.guice;
017:
018: import java.util.Collection;
019: import java.util.Map;
020:
021: import org.apache.commons.logging.Log;
022: import org.apache.commons.logging.LogFactory;
023: import org.directwebremoting.extend.Creator;
024: import org.directwebremoting.extend.CreatorManager;
025: import org.directwebremoting.impl.DefaultCreatorManager;
026:
027: import com.google.inject.Injector;
028: import com.google.inject.Key;
029:
030: import static org.directwebremoting.guice.DwrGuiceUtil.getInjector;
031:
032: /**
033: * Extends an existing creator manager with an injected list of creators
034: * specified at Guice bind-time. Only to be used in conjunction with
035: * {@link DwrGuiceServlet}.
036: * @author Tim Peierls [tim at peierls dot net]
037: */
038: public class InternalCreatorManager implements CreatorManager {
039: /**
040: * Retrieves an underlying creator manager from thread-local state
041: * to which this class delegates {@link CreatorManager} calls.
042: * Adds any creators found from the Guice bindings.
043: */
044: public InternalCreatorManager() {
045: this .creatorManager = getCreatorManager();
046: addCreators();
047: }
048:
049: /**
050: * @param debug Are we in debug mode?
051: */
052: public void setDebug(boolean debug) {
053: if (creatorManager instanceof DefaultCreatorManager) {
054: DefaultCreatorManager dcm = (DefaultCreatorManager) creatorManager;
055: dcm.setDebug(debug);
056: }
057: }
058:
059: /* (non-Javadoc)
060: * @see org.directwebremoting.extend.CreatorManager#isDebug()
061: */
062: public boolean isDebug() {
063: return creatorManager.isDebug();
064: }
065:
066: /* (non-Javadoc)
067: * @see org.directwebremoting.extend.CreatorManager#addCreatorType(java.lang.String, java.lang.String)
068: */
069: public void addCreatorType(String type, String className) {
070: creatorManager.addCreatorType(type, className);
071: }
072:
073: /* (non-Javadoc)
074: * @see org.directwebremoting.extend.CreatorManager#addCreator(java.lang.String, java.lang.String, java.util.Map)
075: */
076: public void addCreator(String scriptName, String type,
077: Map<String, String> params) throws InstantiationException,
078: IllegalAccessException, IllegalArgumentException {
079: creatorManager.addCreator(scriptName, type, params);
080: }
081:
082: /* (non-Javadoc)
083: * @see org.directwebremoting.extend.CreatorManager#addCreator(java.lang.String, org.directwebremoting.extend.Creator)
084: */
085: public void addCreator(String scriptName, Creator creator)
086: throws IllegalArgumentException {
087: creatorManager.addCreator(scriptName, creator);
088: }
089:
090: /* (non-Javadoc)
091: * @see org.directwebremoting.extend.CreatorManager#getCreatorNames()
092: */
093: public Collection<String> getCreatorNames()
094: throws SecurityException {
095: return creatorManager.getCreatorNames();
096: }
097:
098: /* (non-Javadoc)
099: * @see org.directwebremoting.extend.CreatorManager#getCreator(java.lang.String)
100: */
101: public Creator getCreator(String scriptName)
102: throws SecurityException {
103: return creatorManager.getCreator(scriptName);
104: }
105:
106: /* (non-Javadoc)
107: * @see org.directwebremoting.extend.CreatorManager#setCreators(java.util.Map)
108: */
109: public void setCreators(Map<String, Creator> creators) {
110: creatorManager.setCreators(creators);
111: }
112:
113: /**
114: * @return accessor for if we create the created objects at startup
115: */
116: public boolean isInitApplicationScopeCreatorsAtStartup() {
117: if (creatorManager instanceof DefaultCreatorManager) {
118: DefaultCreatorManager dcm = (DefaultCreatorManager) creatorManager;
119: return dcm.isInitApplicationScopeCreatorsAtStartup();
120: }
121: return false;
122: }
123:
124: public void setInitApplicationScopeCreatorsAtStartup(
125: boolean initApplicationScopeCreatorsAtStartup) {
126: if (creatorManager instanceof DefaultCreatorManager) {
127: DefaultCreatorManager dcm = (DefaultCreatorManager) creatorManager;
128: dcm
129: .setInitApplicationScopeCreatorsAtStartup(initApplicationScopeCreatorsAtStartup);
130: }
131: }
132:
133: private final CreatorManager creatorManager;
134:
135: private void addCreators() {
136: Injector injector = getInjector();
137: for (Key<?> key : injector.getBindings().keySet()) {
138: Class<?> atype = key.getAnnotationType();
139: if (atype != null && Remoted.class.isAssignableFrom(atype)) {
140: String scriptName = Remoted.class.cast(
141: key.getAnnotation()).value();
142: if ("".equals(scriptName)) {
143: Class<?> cls = (Class<?>) key.getTypeLiteral()
144: .getType();
145: scriptName = cls.getSimpleName();
146: }
147: addCreator(scriptName, new InternalCreator(injector,
148: key, scriptName));
149: }
150: }
151: }
152:
153: /**
154: * Stores a type name in a thread-local variable for later retrieval by
155: * {@code getCreatorManager}.
156: * @param name The new type name
157: */
158: static void setTypeName(String name) {
159: typeName.set(name);
160: }
161:
162: private static CreatorManager getCreatorManager() {
163: String name = typeName.get();
164: try {
165: @SuppressWarnings("unchecked")
166: Class<? extends CreatorManager> cls = (Class<? extends CreatorManager>) Class
167: .forName(name);
168: return cls.newInstance();
169: } catch (Exception e) {
170: if (name != null && !"".equals(name)) {
171: log.warn("Couldn't make CreatorManager from type: "
172: + name);
173: }
174: return new DefaultCreatorManager();
175: }
176: }
177:
178: /**
179: * Place to stash a type name for retrieval in same thread.
180: */
181: private static final ThreadLocal<String> typeName = new ThreadLocal<String>();
182:
183: /**
184: * The log stream
185: */
186: private static final Log log = LogFactory
187: .getLog(InternalCreatorManager.class);
188: }
|