Richfaces integration.

This commit is contained in:
Jeremy Grelle
2008-03-12 20:57:39 +00:00
parent 9f9e9234e9
commit 30ea4171b0
17 changed files with 193 additions and 66 deletions

View File

@@ -0,0 +1,16 @@
package org.springframework.faces.mvc;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
public class JsfController extends AbstractController {
protected ModelAndView handleRequestInternal(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Auto-generated method stub");
}
}

View File

@@ -85,7 +85,7 @@ public class JsfView extends AbstractUrlBasedView {
private void populateRequestMap(FacesContext facesContext, Map model) {
Iterator i = model.keySet().iterator();
while (i.hasNext()) {
Object key = i.next();
String key = i.next().toString();
facesContext.getExternalContext().getRequestMap().put(key, model.get(key));
}
}

View File

@@ -0,0 +1,67 @@
package org.springframework.faces.mvc.richfaces;
import java.io.IOException;
import javax.faces.FactoryFinder;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.ajax4jsf.context.AjaxContext;
import org.springframework.faces.webflow.FlowLifecycle;
import org.springframework.webflow.mvc.SpringJavascriptAjaxHandler;
public class RichFacesAjaxHandler extends SpringJavascriptAjaxHandler {
public boolean isAjaxRequest(ServletContext context, HttpServletRequest request, HttpServletResponse response) {
FacesContextHelper helper = new FacesContextHelper();
if (AjaxContext.getCurrentInstance(helper.getFacesContext(context, request, response)).isAjaxRequest(
helper.getFacesContext(context, request, response))) {
helper.cleanup();
return true;
} else {
helper.cleanup();
return super.isAjaxRequest(context, request, response);
}
}
public void sendAjaxRedirect(ServletContext context, HttpServletRequest request, HttpServletResponse response,
String targetUrl, boolean popup) throws IOException {
FacesContextHelper helper = new FacesContextHelper();
if (AjaxContext.getCurrentInstance(helper.getFacesContext(context, request, response)).isAjaxRequest(
helper.getFacesContext(context, request, response))) {
helper.cleanup();
response.sendRedirect(response.encodeRedirectURL(targetUrl));
} else {
helper.cleanup();
super.sendAjaxRedirect(context, request, response, targetUrl, popup);
}
}
private static class FacesContextHelper {
private boolean created = false;
protected FacesContext getFacesContext(ServletContext context, HttpServletRequest request,
HttpServletResponse response) {
if (FacesContext.getCurrentInstance() != null) {
return FacesContext.getCurrentInstance();
} else {
created = true;
FacesContextFactory facesContextFactory = (FacesContextFactory) FactoryFinder
.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
FacesContext defaultFacesContext = facesContextFactory.getFacesContext(context, request, response,
FlowLifecycle.newInstance());
return defaultFacesContext;
}
}
protected void cleanup() {
if (created) {
FacesContext.getCurrentInstance().release();
}
}
}
}

View File

@@ -19,13 +19,16 @@ import java.lang.reflect.Method;
import java.util.Iterator;
import javax.el.ELContext;
import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.context.ResponseStream;
import javax.faces.context.ResponseWriter;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.render.RenderKit;
import org.springframework.binding.message.Message;
@@ -47,12 +50,12 @@ public class FlowFacesContext extends FacesContext {
/**
* The key for storing the responseComplete flag
*/
static final String RESPONSE_COMPLETE_KEY = "responseComplete";
static final String RESPONSE_COMPLETE_KEY = "webFlowResponseComplete";
/**
* The key for storing the renderResponse flag
*/
static final String RENDER_RESPONSE_KEY = "renderResponse";
static final String RENDER_RESPONSE_KEY = "webFlowRenderResponse";
/**
* The key for storing the renderResponse flag
@@ -64,6 +67,21 @@ public class FlowFacesContext extends FacesContext {
*/
private FacesContext delegate;
public static FlowFacesContext newInstance(RequestContext context, Lifecycle lifecycle) {
FacesContextFactory facesContextFactory = (FacesContextFactory) FactoryFinder
.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
FacesContext defaultFacesContext = facesContextFactory.getFacesContext(context.getExternalContext()
.getNativeContext(), context.getExternalContext().getNativeRequest(), context.getExternalContext()
.getNativeResponse(), lifecycle);
FlowFacesContext instance = new FlowFacesContext(context, defaultFacesContext);
// Ensure that FlowViewStateManager is first in the chain
FlowViewStateManager sm = new FlowViewStateManager(instance.getApplication().getStateManager());
instance.getApplication().setStateManager(sm);
return instance;
}
public FlowFacesContext(RequestContext context, FacesContext delegate) {
this.context = context;
this.delegate = delegate;

View File

@@ -16,10 +16,12 @@
package org.springframework.faces.webflow;
import javax.faces.FacesException;
import javax.faces.FactoryFinder;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -33,13 +35,21 @@ import org.apache.commons.logging.LogFactory;
*
* @author Jeremy Grelle
*/
class FlowLifecycle extends Lifecycle {
public class FlowLifecycle extends Lifecycle {
private static final Log logger = LogFactory.getLog(FlowLifecycle.class);
private final Lifecycle delegate;
public FlowLifecycle(Lifecycle delegate) {
public static Lifecycle newInstance() {
LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
Lifecycle defaultLifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
return new FlowLifecycle(defaultLifecycle);
}
FlowLifecycle(Lifecycle delegate) {
this.delegate = delegate;
}

View File

@@ -18,10 +18,8 @@ package org.springframework.faces.webflow;
import java.io.IOException;
import javax.faces.FacesException;
import javax.faces.FactoryFinder;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.event.PhaseId;
import javax.faces.lifecycle.Lifecycle;
@@ -51,8 +49,11 @@ public class JsfView implements View {
private RequestContext context;
private String viewId;
public JsfView(UIViewRoot viewRoot, Lifecycle facesLifecycle, RequestContext context) {
this.viewRoot = viewRoot;
this.viewId = viewRoot.getViewId();
this.facesLifecycle = facesLifecycle;
this.context = context;
}
@@ -74,7 +75,7 @@ public class JsfView implements View {
* This implementation performs the standard duties of the JSF RENDER_RESPONSE phase.
*/
public void render() throws IOException {
FacesContext facesContext = createFlowFacesContext();
FacesContext facesContext = FlowFacesContext.newInstance(context, facesLifecycle);
facesContext.setViewRoot(viewRoot);
facesContext.renderResponse();
try {
@@ -91,16 +92,7 @@ public class JsfView implements View {
}
}
private FacesContext createFlowFacesContext() {
FacesContextFactory facesContextFactory = (FacesContextFactory) FactoryFinder
.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
FacesContext defaultFacesContext = facesContextFactory.getFacesContext(context.getExternalContext()
.getNativeContext(), context.getExternalContext().getNativeRequest(), context.getExternalContext()
.getNativeResponse(), facesLifecycle);
return new FlowFacesContext(context, defaultFacesContext);
}
public String toString() {
return "[JSFView = '" + viewRoot.getViewId() + "']";
return "[JSFView = '" + viewId + "']";
}
}

View File

@@ -17,15 +17,16 @@ package org.springframework.faces.webflow;
import java.util.Iterator;
import javax.faces.FactoryFinder;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.el.ValueBinding;
import javax.faces.event.PhaseId;
import javax.faces.lifecycle.Lifecycle;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -33,9 +34,12 @@ import org.springframework.binding.expression.Expression;
import org.springframework.core.io.ContextResource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.faces.ui.AjaxViewRoot;
import org.springframework.webflow.context.ExternalContext;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.View;
import org.springframework.webflow.execution.ViewFactory;
import org.springframework.webflow.mvc.AjaxHandler;
import org.springframework.webflow.mvc.SpringJavascriptAjaxHandler;
/**
* JSF-specific {@link ViewFactory} implementation.
@@ -64,7 +68,7 @@ public class JsfViewFactory implements ViewFactory {
public View getView(RequestContext context) {
FacesContext facesContext = createFlowFacesContext(context, lifecycle);
FacesContext facesContext = FlowFacesContext.newInstance(context, lifecycle);
try {
boolean restored = false;
@@ -118,20 +122,21 @@ public class JsfViewFactory implements ViewFactory {
}
private JsfView createJsfView(UIViewRoot root, Lifecycle lifecycle, RequestContext context) {
if (context.getExternalContext().isAjaxRequest()) {
if (isSpringJavascriptAjaxRequest(context.getExternalContext())) {
return new JsfView(new AjaxViewRoot(root), lifecycle, context);
} else {
return new JsfView(root, lifecycle, context);
}
}
private FacesContext createFlowFacesContext(RequestContext context, Lifecycle lifecycle) {
FacesContextFactory facesContextFactory = (FacesContextFactory) FactoryFinder
.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
FacesContext defaultFacesContext = facesContextFactory.getFacesContext(context.getExternalContext()
.getNativeContext(), context.getExternalContext().getNativeRequest(), context.getExternalContext()
.getNativeResponse(), lifecycle);
return new FlowFacesContext(context, defaultFacesContext);
private boolean isSpringJavascriptAjaxRequest(ExternalContext context) {
if (context.getNativeContext() instanceof ServletContext) {
AjaxHandler handler = new SpringJavascriptAjaxHandler();
return handler.isAjaxRequest((ServletContext) context.getNativeContext(), (HttpServletRequest) context
.getNativeRequest(), (HttpServletResponse) context.getNativeResponse());
} else {
return false;
}
}
private String resolveViewName(RequestContext context) {

View File

@@ -15,9 +15,7 @@
*/
package org.springframework.faces.webflow;
import javax.faces.FactoryFinder;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;
import org.springframework.binding.expression.Expression;
import org.springframework.core.io.ResourceLoader;
@@ -43,16 +41,9 @@ public class JsfViewFactoryCreator implements ViewFactoryCreator {
return viewStateId + FACELETS_EXTENSION;
}
private Lifecycle createFlowFacesLifecycle() {
LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
Lifecycle defaultLifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
return new FlowLifecycle(defaultLifecycle);
}
private Lifecycle getLifecycle() {
if (lifecycle == null) {
lifecycle = createFlowFacesLifecycle();
lifecycle = FlowLifecycle.newInstance();
}
return lifecycle;
}