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.List;
019:
020: import org.directwebremoting.AjaxFilter;
021: import org.directwebremoting.extend.Converter;
022:
023: import com.google.inject.AbstractModule;
024: import com.google.inject.TypeLiteral;
025: import com.google.inject.binder.ConstantBindingBuilder;
026: import com.google.inject.binder.LinkedBindingBuilder;
027:
028: import static java.util.Arrays.asList;
029:
030: import static org.directwebremoting.guice.ParamName.CLASSES;
031:
032: /**
033: * An extension of {@link AbstractModule} that adds DWR configuration methods,
034: * in conjunction with {@link DwrGuiceServlet}.
035: * @author Tim Peierls [tim at peierls dot net]
036: */
037: public abstract class AbstractDwrModule extends AbstractModule {
038: /**
039: * Implement this method to configure Guice bindings for a DWR-based
040: * web application.
041: */
042: @Override
043: protected abstract void configure();
044:
045: /**
046: * Configure DWR scopes and bindings for servlet-related types;
047: * incompatible with Guice's ServletModule because their
048: * bindings for request, response, and session conflict.
049: */
050: protected void bindDwrScopes() {
051: install(new DwrGuiceServletModule(true));
052: }
053:
054: /**
055: * Configure DWR scopes and bindings for servlet-related types,
056: * specifying whether to include bindings that conflict with those
057: * provided by Guice's ServletModule.
058: * @param bindPotentiallyConflictingTypes whether to bind request, response,
059: * and session types (risking conflict with Guice)
060: */
061: protected void bindDwrScopes(boolean bindPotentiallyConflictingTypes) {
062: install(new DwrGuiceServletModule(
063: bindPotentiallyConflictingTypes));
064: }
065:
066: /**
067: * Creates a binding for a conversion for types with names matching
068: * {@code match}.
069: * @param match the string describing which types to convert
070: */
071: protected LinkedBindingBuilder<Converter> bindConversion(
072: String match) {
073: return bind(Converter.class).annotatedWith(
074: new ConvertingImpl(match));
075: }
076:
077: /**
078: * Creates a binding for a conversion for {@code type}.
079: * @param type the type to be converted
080: */
081: protected LinkedBindingBuilder<Converter> bindConversion(
082: Class<?> type) {
083: return bind(Converter.class).annotatedWith(
084: new ConvertingImpl(type));
085: }
086:
087: /**
088: * Creates a binding for a conversion for {@code type} using an existing
089: * conversion for {@code impl}, which must be assignable to {@code type}.
090: * The check for an existing conversion happens at run-time.
091: * @param type the type to be converted
092: */
093: protected <T> void bindConversion(Class<T> type,
094: Class<? extends T> impl) {
095: bind(Converter.class).annotatedWith(
096: new ConvertingImpl(type, impl)).to(
097: InternalConverter.class); // never used, subverted by InternalConverterManager
098: }
099:
100: /**
101: * Creates a binding to {@code type} that is used as the target of a
102: * remote method call with the class's unqualified name as the script name.
103: *
104: * <p>Note: if you are scoping the result, don't rely on implicit binding.
105: * Instead, link the type to itself explicitly. For example,
106: * <pre>
107: * bindRemoted(ConcreteService.class)
108: * .to(ConcreteService.class) // this line is required
109: * .in(DwrScopes.SESSION);
110: * </pre>
111: * This could be considered a bug.
112: * @param type the type to bind as a target for remote method calls
113: */
114: protected <T> LinkedBindingBuilder<T> bindRemoted(Class<T> type) {
115: return bind(type).annotatedWith(new RemotedImpl());
116: }
117:
118: /**
119: * Creates a binding to a type that is used as the target of a
120: * remote method call with the given {@code scriptName}.
121: *
122: * <p>Note: if you are scoping the result, don't rely on implicit binding.
123: * Instead, link the type to itself explicitly. For example,
124: * <pre>
125: * bindRemotedAs("Mixer", ConcreteService.class)
126: * .to(ConcreteService.class) // this line is required
127: * .in(DwrScopes.SESSION);
128: * </pre>
129: * This could be considered a bug.
130: * @param type the type to bind as a target for remote method calls
131: * @param scriptName the name by which the target type will be known to script callers
132: */
133: protected <T> LinkedBindingBuilder<T> bindRemotedAs(
134: String scriptName, Class<T> type) {
135: return bind(type).annotatedWith(new RemotedImpl(scriptName));
136: }
137:
138: /**
139: * Creates a binding for an Ajax filter for the script named
140: * {@code scriptName}.
141: * @param scriptName the script to filter
142: */
143: protected LinkedBindingBuilder<AjaxFilter> bindFilter(
144: String scriptName) {
145: return bind(AjaxFilter.class).annotatedWith(
146: new FilteringImpl(scriptName));
147: }
148:
149: /**
150: * Creates a binding for a global Ajax filter.
151: */
152: protected LinkedBindingBuilder<AjaxFilter> bindGlobalFilter() {
153: return bind(AjaxFilter.class)
154: .annotatedWith(new FilteringImpl());
155: }
156:
157: /**
158: * Call this method in
159: * {@link org.directwebremoting.guice.AbstractDwrModule#configure configure}
160: * to create a binding for a DWR parameter.
161: * @param paramName a parameter name supported by DWR
162: */
163: protected ConstantBindingBuilder bindParameter(ParamName paramName) {
164: return bindConstant().annotatedWith(
165: new InitParamImpl(paramName));
166: }
167:
168: /**
169: * Call this method in
170: * {@link org.directwebremoting.guice.AbstractDwrModule#configure configure}
171: * to specify classes that DWR should scan for annotations.
172: * @param classes the classes to be scanned for DWR-specific annotations
173: */
174: protected void bindAnnotatedClasses(Class<?>... classes) {
175: bind(new TypeLiteral<List<Class<?>>>() {
176: }).annotatedWith(new InitParamImpl(CLASSES)).toInstance(
177: asList(classes));
178:
179: }
180: }
|