001: /*
002: * Copyright 2002-2006 the original author or authors.
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:
017: package org.springframework.web.portlet.mvc;
018:
019: import java.util.Enumeration;
020: import java.util.Locale;
021: import java.util.Properties;
022: import java.util.ResourceBundle;
023:
024: import javax.portlet.ActionRequest;
025: import javax.portlet.ActionResponse;
026: import javax.portlet.Portlet;
027: import javax.portlet.PortletConfig;
028: import javax.portlet.PortletContext;
029: import javax.portlet.RenderRequest;
030: import javax.portlet.RenderResponse;
031:
032: import org.springframework.beans.factory.BeanNameAware;
033: import org.springframework.beans.factory.DisposableBean;
034: import org.springframework.beans.factory.InitializingBean;
035: import org.springframework.web.portlet.ModelAndView;
036: import org.springframework.web.portlet.context.PortletConfigAware;
037: import org.springframework.web.portlet.context.PortletContextAware;
038:
039: /**
040: * {@link Controller} implementation that wraps a portlet instance which it manages
041: * internally. Such a wrapped portlet is not known outside of this controller;
042: * its entire lifecycle is covered here.
043: *
044: * <p>Useful to invoke an existing portlet via Spring's dispatching infrastructure,
045: * for example to apply Spring
046: * {@link org.springframework.web.portlet.HandlerInterceptor HandlerInterceptors}
047: * to its requests.
048: *
049: * <p><b>Example:</b>
050: *
051: * <pre><bean id="wrappingController" class="org.springframework.web.portlet.mvc.PortletWrappingController">
052: * <property name="portletClass">
053: * <value>org.springframework.web.portlet.sample.HelloWorldPortlet</value>
054: * </property>
055: * <property name="portletName">
056: * <value>hello-world</value>
057: * </property>
058: * <property name="initParameters">
059: * <props>
060: * <prop key="config">/WEB-INF/hello-world-portlet-config.xml</prop>
061: * </props>
062: * </property>
063: * </bean></pre>
064: *
065: * @author Juergen Hoeller
066: * @author John A. Lewis
067: * @since 2.0
068: */
069: public class PortletWrappingController extends AbstractController
070: implements BeanNameAware, InitializingBean, DisposableBean,
071: PortletContextAware, PortletConfigAware {
072:
073: private boolean useSharedPortletConfig = true;
074:
075: private PortletContext portletContext;
076:
077: private PortletConfig portletConfig;
078:
079: private Class portletClass;
080:
081: private String portletName;
082:
083: private Properties initParameters = new Properties();
084:
085: private String beanName;
086:
087: private Portlet portletInstance;
088:
089: /**
090: * Set whether to use the shared PortletConfig object passed in
091: * through <code>setPortletConfig</code>, if available.
092: * <p>Default is "true". Turn this setting to "false" to pass in
093: * a mock PortletConfig object with the bean name as portlet name,
094: * holding the current PortletContext.
095: * @see #setPortletConfig
096: */
097: public void setUseSharedPortletConfig(boolean useSharedPortletConfig) {
098: this .useSharedPortletConfig = useSharedPortletConfig;
099: }
100:
101: public void setPortletContext(PortletContext portletContext) {
102: this .portletContext = portletContext;
103: }
104:
105: public void setPortletConfig(PortletConfig portletConfig) {
106: this .portletConfig = portletConfig;
107: }
108:
109: /**
110: * Set the class of the Portlet to wrap.
111: * Needs to implement <code>javax.portlet.Portlet</code>.
112: * @see javax.portlet.Portlet
113: */
114: public void setPortletClass(Class portletClass) {
115: this .portletClass = portletClass;
116: }
117:
118: /**
119: * Set the name of the Portlet to wrap.
120: * Default is the bean name of this controller.
121: */
122: public void setPortletName(String portletName) {
123: this .portletName = portletName;
124: }
125:
126: /**
127: * Specify init parameters for the portlet to wrap,
128: * as name-value pairs.
129: */
130: public void setInitParameters(Properties initParameters) {
131: this .initParameters = initParameters;
132: }
133:
134: public void setBeanName(String name) {
135: this .beanName = name;
136: }
137:
138: public void afterPropertiesSet() throws Exception {
139: if (this .portletClass == null) {
140: throw new IllegalArgumentException(
141: "portletClass is required");
142: }
143: if (!Portlet.class.isAssignableFrom(this .portletClass)) {
144: throw new IllegalArgumentException(
145: "portletClass ["
146: + this .portletClass.getName()
147: + "] needs to implement interface [javax.portlet.Portlet]");
148: }
149: if (this .portletName == null) {
150: this .portletName = this .beanName;
151: }
152: PortletConfig config = this .portletConfig;
153: if (config == null || !this .useSharedPortletConfig) {
154: config = new DelegatingPortletConfig();
155: }
156: this .portletInstance = (Portlet) this .portletClass
157: .newInstance();
158: this .portletInstance.init(config);
159: }
160:
161: protected void handleActionRequestInternal(ActionRequest request,
162: ActionResponse response) throws Exception {
163:
164: this .portletInstance.processAction(request, response);
165: }
166:
167: protected ModelAndView handleRenderRequestInternal(
168: RenderRequest request, RenderResponse response)
169: throws Exception {
170:
171: this .portletInstance.render(request, response);
172: return null;
173: }
174:
175: public void destroy() {
176: this .portletInstance.destroy();
177: }
178:
179: /**
180: * Internal implementation of the PortletConfig interface, to be passed
181: * to the wrapped portlet.
182: * <p>Delegates to {@link PortletWrappingController} fields
183: * and methods to provide init parameters and other environment info.
184: */
185: private class DelegatingPortletConfig implements PortletConfig {
186:
187: public String getPortletName() {
188: return portletName;
189: }
190:
191: public PortletContext getPortletContext() {
192: return portletContext;
193: }
194:
195: public String getInitParameter(String paramName) {
196: return initParameters.getProperty(paramName);
197: }
198:
199: public Enumeration getInitParameterNames() {
200: return initParameters.keys();
201: }
202:
203: public ResourceBundle getResourceBundle(Locale locale) {
204: return (portletConfig != null ? portletConfig
205: .getResourceBundle(locale) : null);
206: }
207:
208: }
209:
210: }
|