001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jetspeed.container.invoker;
018:
019: import java.io.IOException;
020:
021: import javax.portlet.ActionRequest;
022: import javax.portlet.ActionResponse;
023: import javax.portlet.PortletException;
024: import javax.portlet.PortletRequest;
025: import javax.portlet.PortletResponse;
026: import javax.portlet.RenderRequest;
027: import javax.portlet.RenderResponse;
028: import javax.portlet.UnavailableException;
029: import javax.servlet.ServletConfig;
030: import javax.servlet.ServletContext;
031: import javax.servlet.ServletRequest;
032:
033: import org.apache.commons.logging.Log;
034: import org.apache.commons.logging.LogFactory;
035: import org.apache.jetspeed.PortalReservedParameters;
036: import org.apache.jetspeed.container.ContainerConstants;
037: import org.apache.jetspeed.container.PortletRequestContext;
038: import org.apache.jetspeed.factory.PortletFactory;
039: import org.apache.jetspeed.factory.PortletInstance;
040: import org.apache.jetspeed.om.common.portlet.PortletApplication;
041: import org.apache.jetspeed.request.RequestContext;
042: import org.apache.pluto.om.portlet.PortletDefinition;
043:
044: /**
045: * LocalPortletInvoker invokes local (internal) portlet applications.
046: * Local portlet applications are stored within the Jetspeed Portlet application.
047: * They are not separate web applications; but are stored under Jetspeed's
048: * WEB-INF/apps directory.
049: * <h3>Sample Configuration</h3>
050: * <pre>
051: * <code>
052: * factory.invoker.local = org.apache.jetspeed.container.invoker.LocalPortletInvoker
053: * factory.invoker.local.pool.size = 50
054: * </code>
055: * </pre>
056: * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
057: * @version $Id: LocalPortletInvoker.java 565870 2007-08-14 19:40:03Z taylor $
058: */
059: public class LocalPortletInvoker implements JetspeedPortletInvoker {
060: private final static Log log = LogFactory
061: .getLog(LocalPortletInvoker.class);
062:
063: protected PortletFactory portletFactory;
064: protected ServletContext jetspeedContext;
065: protected ServletConfig jetspeedConfig;
066: protected PortletDefinition portletDefinition;
067: protected boolean activated = false;
068:
069: /* (non-Javadoc)
070: * @see org.apache.jetspeed.container.invoker.JetspeedPortletInvoker#activate(PortletFactory,org.apache.pluto.om.portlet.PortletDefinition, javax.servlet.ServletConfig)
071: */
072: public void activate(PortletFactory portletFactory,
073: PortletDefinition portletDefinition,
074: ServletConfig servletConfig) {
075: this .portletFactory = portletFactory;
076: this .jetspeedConfig = servletConfig;
077: jetspeedContext = servletConfig.getServletContext();
078: this .portletDefinition = portletDefinition;
079: activated = true;
080: }
081:
082: /* (non-Javadoc)
083: * @see org.apache.jetspeed.container.invoker.JetspeedPortletInvoker#passivate()
084: */
085: public void passivate() {
086: activated = false;
087: }
088:
089: /* (non-Javadoc)
090: * @see org.apache.jetspeed.container.invoker.JetspeedPortletInvoker#isActivated()
091: */
092: public boolean isActivated() {
093: return activated;
094: }
095:
096: public LocalPortletInvoker() {
097: activated = false;
098: }
099:
100: /* (non-Javadoc)
101: * @see org.apache.pluto.invoker.PortletInvoker#action(javax.portlet.ActionRequest, javax.portlet.ActionResponse)
102: */
103: public void action(ActionRequest request, ActionResponse response)
104: throws PortletException, IOException {
105: invoke(request, response, ContainerConstants.METHOD_ACTION);
106: }
107:
108: /* (non-Javadoc)
109: * @see org.apache.pluto.invoker.PortletInvoker#render(javax.portlet.RenderRequest, javax.portlet.RenderResponse)
110: */
111: public void render(RenderRequest request, RenderResponse response)
112: throws PortletException, IOException {
113: invoke(request, response, ContainerConstants.METHOD_RENDER);
114: }
115:
116: /* (non-Javadoc)
117: * @see org.apache.pluto.invoker.PortletInvoker#load(javax.portlet.PortletRequest, javax.portlet.RenderResponse)
118: */
119: public void load(PortletRequest request, RenderResponse response)
120: throws PortletException {
121: try {
122: invoke(request, response, ContainerConstants.METHOD_NOOP);
123: } catch (IOException e) {
124: log
125: .error(
126: "LocalPortletInvokerImpl.load() - Error while dispatching portlet.",
127: e);
128: throw new PortletException(e);
129: }
130: }
131:
132: /**
133: * Invokes the specific request denoted by the <code>method</code> parameter on a portlet.
134: * The portlet is invoked with a direct method call on the portlet. It is not invoked in another web application.
135: * This requires manipulation of the current thread's classpath.
136: *
137: * @param portletRequest
138: * @param portletResponse
139: * @param methodID
140: * @throws PortletException
141: * @throws IOException
142: */
143: protected void invoke(PortletRequest portletRequest,
144: PortletResponse portletResponse, Integer method)
145: throws PortletException, IOException {
146: ClassLoader paClassLoader = portletFactory
147: .getPortletApplicationClassLoader((PortletApplication) portletDefinition
148: .getPortletApplicationDefinition());
149: PortletInstance portletInstance = portletFactory
150: .getPortletInstance(jetspeedContext, portletDefinition);
151:
152: if (method == ContainerConstants.METHOD_NOOP) {
153: return;
154: }
155:
156: // gather all required data from request and response
157: ServletRequest servletRequest = ((javax.servlet.http.HttpServletRequestWrapper) portletRequest)
158: .getRequest();
159:
160: ClassLoader oldLoader = Thread.currentThread()
161: .getContextClassLoader();
162: try {
163: PortletRequestContext.createContext(portletDefinition,
164: portletInstance, portletRequest, portletResponse);
165:
166: servletRequest.setAttribute(
167: ContainerConstants.PORTLET_CONFIG, portletInstance
168: .getConfig());
169: servletRequest.setAttribute(
170: ContainerConstants.PORTLET_REQUEST, portletRequest);
171: servletRequest.setAttribute(
172: ContainerConstants.PORTLET_RESPONSE,
173: portletResponse);
174: RequestContext requestContext = (RequestContext) servletRequest
175: .getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
176: servletRequest.setAttribute(
177: ContainerConstants.PORTAL_CONTEXT, requestContext
178: .getRequest().getContextPath());
179:
180: Thread.currentThread().setContextClassLoader(paClassLoader);
181:
182: if (method == ContainerConstants.METHOD_ACTION) {
183: ActionRequest actionRequest = (ActionRequest) portletRequest;
184: ActionResponse actionResponse = (ActionResponse) portletResponse;
185:
186: portletInstance.processAction(actionRequest,
187: actionResponse);
188: } else if (method == ContainerConstants.METHOD_RENDER) {
189: RenderRequest renderRequest = (RenderRequest) portletRequest;
190: RenderResponse renderResponse = (RenderResponse) portletResponse;
191: renderResponse.setContentType(requestContext
192: .getMimeType());
193: portletInstance.render(renderRequest, renderResponse);
194: }
195: } catch (Throwable t) {
196: if (t instanceof UnavailableException) {
197: // take it out of service
198: try {
199: portletInstance.destroy();
200: } catch (Throwable ignore) {
201: // never mind, it won't be used anymore
202: }
203: }
204: if (t instanceof PortletException) {
205: throw (PortletException) t;
206: }
207: if (t instanceof IOException) {
208: throw (IOException) t;
209: } else {
210: throw new PortletException(t);
211: }
212: } finally {
213: PortletRequestContext.clearContext();
214: servletRequest
215: .removeAttribute(ContainerConstants.PORTLET_CONFIG);
216: servletRequest
217: .removeAttribute(ContainerConstants.PORTLET_REQUEST);
218: servletRequest
219: .removeAttribute(ContainerConstants.PORTLET_RESPONSE);
220: servletRequest
221: .removeAttribute(ContainerConstants.PORTAL_CONTEXT);
222:
223: Thread.currentThread().setContextClassLoader(oldLoader);
224: }
225: }
226:
227: /* (non-Javadoc)
228: * @see org.apache.jetspeed.container.invoker.JetspeedPortletInvoker#activate(PortletFactory,org.apache.pluto.om.portlet.PortletDefinition, javax.servlet.ServletConfig, java.lang.String)
229: */
230: public void activate(PortletFactory portletFactory,
231: PortletDefinition portletDefinition,
232: ServletConfig servletConfig, String servletMappingName) {
233: activate(portletFactory, portletDefinition, servletConfig);
234: }
235:
236: }
|