001: /*
002: * This file is part of the WfMOpen project.
003: * Copyright (C) 2001-2005 Danet GmbH (www.danet.de), BU BTS.
004: * All rights reserved.
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU General Public License as published by
008: * the Free Software Foundation; either version 2 of the License, or
009: * (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * $Id: MyFacesAjaxServlet.java,v 1.2 2006/12/12 09:53:20 drmlipp Exp $
021: *
022: * $Log: MyFacesAjaxServlet.java,v $
023: * Revision 1.2 2006/12/12 09:53:20 drmlipp
024: * Added Ajax support.
025: *
026: * Revision 1.1.2.6 2006/11/28 13:08:42 drmlipp
027: * Started Ajax response handling.
028: *
029: * Revision 1.1.2.5 2006/11/27 14:28:33 drmlipp
030: * Continuing.
031: *
032: * Revision 1.1.2.4 2006/11/26 21:16:15 mlipp
033: * Getting Ajax call back to component.
034: *
035: * Revision 1.1.2.3 2006/11/25 22:45:56 mlipp
036: * Got request through to JSF.
037: *
038: * Revision 1.1.2.2 2006/11/24 16:15:31 drmlipp
039: * Continuing Ajax support.
040: *
041: * Revision 1.1.2.1 2006/11/23 23:00:53 mlipp
042: * Started AJAX handling.
043: *
044: * Revision 1.2 2006/09/29 12:32:11 drmlipp
045: * Consistently using WfMOpen as projct name now.
046: *
047: * Revision 1.1 2006/09/11 15:29:28 drmlipp
048: * Improved portlet support.
049: *
050: */
051: package de.danet.an.util.jsf;
052:
053: import java.io.IOException;
054: import java.util.Map;
055:
056: import javax.faces.FactoryFinder;
057: import javax.faces.application.ViewHandler;
058: import javax.faces.component.UIComponent;
059: import javax.faces.context.FacesContext;
060: import javax.faces.context.FacesContextFactory;
061: import javax.faces.lifecycle.Lifecycle;
062: import javax.faces.lifecycle.LifecycleFactory;
063: import javax.portlet.RenderResponse;
064: import javax.servlet.ServletException;
065: import javax.servlet.http.HttpServlet;
066: import javax.servlet.http.HttpServletRequest;
067: import javax.servlet.http.HttpServletResponse;
068:
069: import org.apache.myfaces.context.servlet.ServletFacesContextImpl;
070: import org.apache.myfaces.portlet.MyFacesGenericPortlet;
071: import org.apache.myfaces.shared_tomahawk.util._ComponentUtils;
072:
073: /**
074: * This class provides a servlet that provides MyFaces resources.
075: *
076: * @author Michael Lipp
077: *
078: */
079: public class MyFacesAjaxServlet extends HttpServlet {
080:
081: private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
082: .getLog(MyFacesAjaxServlet.class);
083:
084: public static final String RENDER_NAMESPACE = MyFacesAdaptedPortlet.class
085: .getName()
086: + ".RENDER_NAMESPACE";
087:
088: public static final String AJAX_CALL_TO = MyFacesAdaptedPortlet.class
089: .getName()
090: + ".AJAX_CALL_TO";
091:
092: protected LifecycleFactory lifecycleFactory;
093: protected FacesContextFactory facesContextFactory;
094:
095: /* (non-Javadoc)
096: * @see javax.servlet.GenericServlet#init()
097: */
098: public void init() throws ServletException {
099: super .init();
100: lifecycleFactory = (LifecycleFactory) FactoryFinder
101: .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
102: facesContextFactory = (FacesContextFactory) FactoryFinder
103: .getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
104: }
105:
106: /* (non-Javadoc)
107: * @see javax.servlet.http.HttpServlet#doGet
108: */
109: protected void doPost(HttpServletRequest request,
110: HttpServletResponse response) throws ServletException,
111: IOException {
112: if (logger.isDebugEnabled()) {
113: logger.debug("Ajax request: " + request.getRequestURL());
114: }
115: if (request.getSession(false) == null) {
116: response.sendError(HttpServletResponse.SC_GONE);
117: return;
118: }
119:
120: // make external context
121: AjaxExternalContext externalContext = AjaxExternalContext
122: .makeContext(request, response);
123: // use session map to access portlet session
124: Map sessionMap = externalContext.getSessionMap();
125: // restore faces context
126: String lifecycleId = (String) sessionMap
127: .get(MyFacesAdaptedPortlet.LIFECYCLE_ID);
128: if (lifecycleId == null) {
129: response.sendError(HttpServletResponse.SC_NOT_FOUND);
130: return;
131: }
132: Lifecycle lifecycle = lifecycleFactory
133: .getLifecycle(lifecycleId);
134: ServletFacesContextImpl facesContext = (ServletFacesContextImpl) facesContextFactory
135: .getFacesContext(getServletContext(), request,
136: response, lifecycle);
137: facesContext.setExternalContext(externalContext);
138: lifecycle.execute(facesContext);
139: facesContext.getApplication().getStateManager()
140: .saveSerializedView(facesContext);
141: }
142:
143: protected void doGet(HttpServletRequest request,
144: HttpServletResponse response) throws ServletException,
145: IOException {
146: doPost(request, response);
147: }
148:
149: public static String getAjaxActionUrl(FacesContext context,
150: UIComponent component) {
151: // We have to bypass the portal because an Ajax request does not
152: // fit in the action/render pattern. Therfore we provide access to
153: // this servlet as a resource
154: ViewHandler viewHandler = context.getApplication()
155: .getViewHandler();
156: String path = viewHandler.getResourceURL(context, "/ajax");
157: StringBuffer res = new StringBuffer(path);
158: if (res.indexOf("?") < 0) {
159: res.append("?");
160: } else {
161: res.append("&");
162: }
163: // MyFaces retrieves the view id of request from a special request
164: // parameter, add it.
165: String viewId = context.getViewRoot().getViewId();
166: res.append(MyFacesGenericPortlet.VIEW_ID);
167: res.append("=");
168: res.append(viewId);
169: // Add a hint that allows us to identify the portlets session data.
170: res.append("&");
171: res.append(MyFacesAjaxServlet.RENDER_NAMESPACE);
172: res.append("=");
173: res.append(((RenderResponse) context.getExternalContext()
174: .getResponse()).getNamespace());
175: // Special request parameter required by MyFaces to pass the request
176: // to the form's children.
177: res.append("&");
178: String hiddenFieldName = _ComponentUtils.findNestingForm(
179: component, context).getForm().getClientId(context)
180: + "_SUBMIT";
181: res.append(hiddenFieldName);
182: res.append("=1");
183: // Finally, allow component to find out that it's being addressed.
184: res.append("&");
185: res.append(AJAX_CALL_TO);
186: res.append("=");
187: res.append(component.getClientId(context));
188:
189: return res.toString();
190: }
191: }
|