001: package org.apache.struts.action;
002:
003: import java.util.HashMap;
004: import java.util.Map;
005:
006: import javax.portlet.Portlet;
007: import javax.portlet.PortletMode;
008: import javax.portlet.PortletContext;
009: import javax.portlet.PortletConfig;
010: import javax.portlet.PortletException;
011: import javax.portlet.PortletRequest;
012: import javax.portlet.ActionRequest;
013: import javax.portlet.ActionResponse;
014: import javax.portlet.RenderRequest;
015: import javax.portlet.RenderResponse;
016: import javax.portlet.PortletRequestDispatcher;
017:
018: import javax.servlet.ServletException;
019: import javax.servlet.http.HttpServletRequest;
020: import javax.servlet.http.HttpServletResponse;
021: import javax.servlet.ServletContext;
022: import javax.servlet.ServletConfig;
023:
024: import org.apache.struts.config.ModuleConfig;
025: import org.apache.struts.util.RequestUtils;
026: import org.apache.struts.Globals;
027: import org.apache.struts.StrutsConstants;
028: import org.apache.struts.wrapper.ServletObjectsFactory;
029:
030: /**
031: * StrutsPortlet
032: * Portlet class for Struts application
033: */
034: public class StrutsPortlet extends ActionServlet implements Portlet {
035:
036: private static final String INIT_CALLED = "struts.portlet.initCalled";
037: private static final String EDIT_INIT_CALLED = "struts.portlet.editInitCalled";
038: private static final String HELP_INIT_CALLED = "struts.portlet.helpInitCalled";
039:
040: //private static final String[] INIT_CALLED_VAL = new String[] {"VIEW_INIT_CALLED", "EDIT_INIT_CALLED"};
041:
042: private PortletContext _pContext;
043: private PortletConfig _pConfig;
044: private ServletContext _sContext;
045: private ServletConfig _sConfig;
046: private String _initPage;
047: private String _initHelpPage;
048: private String _initEditPage;
049: private ServletObjectsFactory _factory;
050: private boolean _isPortlet = false;
051: private String _servletMapping;
052:
053: public void init(PortletConfig config) throws PortletException {
054: _isPortlet = true;
055:
056: //Obtain initialization parameters
057: _initPage = config.getInitParameter("initPage");
058: _initHelpPage = config.getInitParameter("helpPage");
059: _initEditPage = config.getInitParameter("editPage");
060: _servletMapping = config.getInitParameter("servletMapping");
061:
062: //Obtain portlet config and context
063: _pConfig = config;
064: _pContext = config.getPortletContext();
065:
066: // A Struts Portlet should have at least the initial ViewPage defined!
067: if (_initPage == null) {
068: throw new PortletException("Portlet "
069: + config.getPortletName()
070: + " is not configured properly");
071: }
072:
073: String factoryName = config.getInitParameter("factoryName");
074: try {
075: Class fclass = Class.forName(factoryName);
076: _factory = (ServletObjectsFactory) fclass.newInstance();
077: } catch (Exception e) {
078: throw new PortletException("Unable to instantiate factory");
079: }
080:
081: _sContext = _factory.getServletContext(_pContext);
082: _sConfig = _factory.getServletConfig(_pConfig, _sContext);
083:
084: /* Since most of the init save initialized data to context, we don't
085: need to initialize again. We can leave the init to the ActionServlet
086: try {
087: super.init();
088: } catch (Exception e) {
089: throw new PortletException(e.getMessage());
090: }
091: */
092: }
093:
094: public void processAction(ActionRequest request,
095: ActionResponse response) throws PortletException {
096:
097: request.setAttribute(StrutsConstants.STRUTS_TYPE,
098: StrutsConstants.STRUTS_TYPE_PORTLET);
099: request.setAttribute(StrutsConstants.SERVLET_MAPPING,
100: getServletContext().getAttribute(Globals.SERVLET_KEY));
101:
102: HttpServletRequest sRequest = _factory
103: .getServletRequest(request);
104: HttpServletResponse sResponse = _factory.getServletResponse(
105: request, response);
106:
107: try {
108: RequestUtils.selectModule(sRequest, getServletContext());
109: IPortletStrutsLifecycle requestProcessor = (IPortletStrutsLifecycle) getRequestProcessor(getModuleConfig(sRequest));
110: requestProcessor.processAction(sRequest, sResponse);
111: } catch (Exception e) {
112: throw new PortletException(e.getMessage());
113: }
114:
115: response.setRenderParameters(prepareRenderParams(request
116: .getParameterMap(), request.getPortletMode()));
117: }
118:
119: public void render(RenderRequest request, RenderResponse response)
120: throws PortletException {
121:
122: request.setAttribute(StrutsConstants.STRUTS_TYPE,
123: StrutsConstants.STRUTS_TYPE_PORTLET);
124: response.setContentType("text/html");
125: response.setTitle(getTitle(request));
126: try {
127: if (isDispatchRequest(request)) {
128: String dispatchPath = getDispatchPath(request);
129: PortletRequestDispatcher dispatcher = _pContext
130: .getRequestDispatcher(dispatchPath);
131: dispatcher.include(request, response);
132: } else {
133: request.setAttribute(StrutsConstants.SERVLET_MAPPING,
134: getServletContext().getAttribute(
135: Globals.SERVLET_KEY));
136: HttpServletRequest sRequest = _factory
137: .getServletRequest(request);
138: HttpServletResponse sResponse = _factory
139: .getServletResponse(request, response);
140:
141: RequestUtils
142: .selectModule(sRequest, getServletContext());
143: IPortletStrutsLifecycle requestProcessor = (IPortletStrutsLifecycle) getRequestProcessor(getModuleConfig(sRequest));
144:
145: requestProcessor.render(sRequest, sResponse);
146: }
147: } catch (Exception e) {
148: throw new PortletException(e.getMessage());
149: }
150: }
151:
152: public ServletContext getServletContext() {
153: if (_sContext == null) {
154: return super .getServletContext();
155: } else {
156: return _sContext;
157: }
158: }
159:
160: public ServletConfig getServletConfig() {
161: if (_sConfig == null) {
162: return super .getServletConfig();
163: } else {
164: return _sConfig;
165: }
166: }
167:
168: // since we only want to process plugin once, we will rely on the
169: // ActionServlet to process it and skip it in this portlet
170: protected void initModulePlugIns(ModuleConfig config)
171: throws ServletException {
172:
173: if (!_isPortlet) {
174: super .initModulePlugIns(config);
175: }
176: }
177:
178: protected Map prepareRenderParams(Map renderParam, PortletMode mode) {
179:
180: Map paramMap = null;
181:
182: if (renderParam != null) {
183: paramMap = new HashMap(renderParam.size());
184: paramMap.putAll(renderParam);
185: // paramMap.remove(StrutsConstants.STRUTS_PATH);
186: } else {
187: paramMap = new HashMap(1);
188: }
189: //Following setting of *_INIT_CALLED in the paramMap
190: //Will help during render() method call.
191: //This parameter setting will be helpful when user
192: //is changing the mode. For example, if user is interacting
193: //with VIEW mode and clicks on EDIT button, the page in the
194: //EDIT mode should be the initial page of EDIT mode and not
195: //the last page of VIEW mode.
196: if (mode.equals(PortletMode.EDIT)) {
197: paramMap.put(EDIT_INIT_CALLED,
198: new String[] { EDIT_INIT_CALLED });
199: } else if (mode.equals(PortletMode.HELP)) {
200: paramMap.put(HELP_INIT_CALLED,
201: new String[] { HELP_INIT_CALLED });
202: } else {
203: paramMap.put(INIT_CALLED, new String[] { INIT_CALLED });
204: }
205:
206: return paramMap;
207: }
208:
209: protected boolean isDispatchRequest(PortletRequest request) {
210:
211: String initCalled = null;
212: String forwardPath = request
213: .getParameter(StrutsConstants.FORWARD_PATH);
214: PortletMode mode = request.getPortletMode();
215: if (mode.equals(PortletMode.EDIT)) {
216: initCalled = request.getParameter(EDIT_INIT_CALLED);
217: } else if (mode.equals(PortletMode.HELP)) {
218: initCalled = request.getParameter(HELP_INIT_CALLED);
219: } else {
220: initCalled = request.getParameter(INIT_CALLED);
221: }
222:
223: if (initCalled == null || forwardPath != null) {
224: return true;
225: } else {
226: return false;
227: }
228: }
229:
230: protected String getDispatchPath(PortletRequest request) {
231:
232: String forwardPath = request
233: .getParameter(StrutsConstants.FORWARD_PATH);
234: String dispatchPath = _initPage;
235:
236: PortletMode mode = request.getPortletMode();
237:
238: if (mode.equals(PortletMode.HELP)) {
239: dispatchPath = _initHelpPage;
240: return dispatchPath;
241: }
242: if (mode.equals(PortletMode.EDIT)) {
243: dispatchPath = _initEditPage;
244: }
245:
246: if (forwardPath != null) {
247: String forwardPathMode = request
248: .getParameter(StrutsConstants.FORWARD_PATH_MODE);
249: if (forwardPathMode != null
250: && !forwardPathMode.equals(request.getPortletMode()
251: .toString())) {
252: //This means, the forwardPath is set for other than current mode.
253: return dispatchPath;
254: }
255: // filter out the context path if it's there
256: if (forwardPath.startsWith(request.getContextPath())) {
257: int secondSlash = forwardPath.substring(1).indexOf("/");
258: dispatchPath = forwardPath.substring(secondSlash + 1);
259: } else {
260: dispatchPath = forwardPath;
261: }
262: }
263: return dispatchPath;
264: }
265:
266: protected java.lang.String getTitle(RenderRequest request) {
267: return _pConfig.getResourceBundle(request.getLocale())
268: .getString("javax.portlet.title");
269: }
270:
271: }
|