This content has been marked as final.
Show 2 replies
-
1. Re: G4jsf and Seam success
detiber Mar 8, 2007 11:44 AM (in response to detiber)Accidentally hit Submit instead of Preview. Here is the custom phase listener:
package gwtseamtest.seam; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.StringReader; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.zip.GZIPOutputStream; import javax.faces.FacesException; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.faces.event.PhaseEvent; import javax.servlet.Servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.ajax4jsf.gwt.client.ComponentEntryPoint; import org.ajax4jsf.gwt.server.GwtFacesServlet; import org.jboss.seam.contexts.Lifecycle; import org.jboss.seam.jsf.SeamPhaseListener; import org.jboss.seam.log.LogProvider; import org.jboss.seam.log.Logging; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * Manages the Seam and GWT contexts associated with a JSF request. * * @author Jason DeTiberus */ public class GwtSeamPhaseListener extends SeamPhaseListener { private static final long serialVersionUID = 3962145500728890731L; private static final LogProvider log = Logging.getLogProvider(GwtSeamPhaseListener.class); public static final String GWT_RESOURCE_PREFIX = "gwt/"; private static final int BUFFER_SIZE = 1024; static protected final long DEFAULT_EXPIRE = 1000L * 60L * 60L * 12L;// 12 Hours private Map<String,Servlet> serviceServlets = Collections.synchronizedMap(new HashMap<String,Servlet>()); private Servlet _defaultSrviceServlet; /* WebModuleConfigHandler class Taken from GwtPhaseListener written by shura */ private static final class WebModuleConfigHandler extends DefaultHandler { private String _servletClassName = null; /* (non-Javadoc) * @see org.xml.sax.helpers.DefaultHandler#resolveEntity(java.lang.String, java.lang.String) */ public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException { // Dummy resolver - disable all entity references return new InputSource(new StringReader("")); } /* (non-Javadoc) * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) */ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if ("servlet".equals(qName)) { _servletClassName = attributes.getValue("class"); } } /** * @return Returns the servletClassName. */ String getServletClassName() { return _servletClassName; } } /* getServletForModule() taken from GwtPhaseListener written by shura */ private Servlet getServletForModule(FacesContext context, String moduleName) { // First - check for existing instances if (serviceServlets.containsKey(moduleName)) { log.debug("Found existing servlet for module "+moduleName); return (Servlet) serviceServlets.get(moduleName); } // Second -attempt to read module config and, if in contain servlet // definition - // create instance and store in Map String servletClass = getServletClassForModule(moduleName); if(null != servletClass){ Servlet servlet = createServlet(context,servletClass); serviceServlets.put(moduleName,servlet); return servlet; } // last - return default service servlet Servlet defaultServiceServlet = getDefaultServiceServlet(context); serviceServlets.put(moduleName,defaultServiceServlet); return defaultServiceServlet; } /* getServletClassForModule() taken from GwtPhaseListener written by shura */ private String getServletClassForModule(String moduleName) { ClassLoader classLoader = Thread.currentThread() .getContextClassLoader(); String servletClassName = null; // for module foo.bar.Module config file will be placed at foo/bar/Module.gwt.xml String gwtModuleConfigPath = moduleName.replace('.','/')+".gwt.xml"; InputStream stream = classLoader.getResourceAsStream(gwtModuleConfigPath); if(null != stream){ // We have module confir to read - parce it for servlen name. SAXParserFactory parserFactory = SAXParserFactory.newInstance(); try { SAXParser parser = parserFactory.newSAXParser(); WebModuleConfigHandler handler = new WebModuleConfigHandler(); parser.parse(stream,handler); servletClassName = handler.getServletClassName(); } catch (Exception e) { log.debug("Exception in parsing web module config "+e.getMessage()); } } return servletClassName; } /* createServlet() taken from GwtPhaseListener written by shura */ private Servlet createServlet(FacesContext context, String className) { ClassLoader classLoader = Thread.currentThread() .getContextClassLoader(); try { Class clazz = classLoader.loadClass(className); Servlet servlet = (Servlet) clazz.newInstance(); final ServletContext servletContext = (ServletContext) context.getExternalContext() .getContext(); servlet.init(new ServletConfig() { public String getServletName() { return "gwtFacesService"; } public ServletContext getServletContext() { return servletContext; } public String getInitParameter(String arg0) { return null; } public Enumeration getInitParameterNames() { return null; } }); return servlet; } catch (Exception e) { e.printStackTrace(); throw new FacesException("Error to create gwt service servlet", e); } } /* getDefaultServiceServlet() taken from GwtPhaseListener written by shura */ public Servlet getDefaultServiceServlet(FacesContext context) { if (_defaultSrviceServlet == null) { _defaultSrviceServlet = createServlet(context, GwtFacesServlet.class.getName()); } return _defaultSrviceServlet; } @Override public void beforePhase(PhaseEvent event) { log.debug("before phase: " + event.getPhaseId()); Lifecycle.setPhaseId(event.getPhaseId()); /* The following code was taken from beforePhase() in GwtPhaseListener written by shura */ FacesContext facesContext = event.getFacesContext(); ExternalContext externalContext = facesContext.getExternalContext(); String mime = "text/html"; String resourceName = null; // assume that mapping have /faces/* prefix String pathInfo = externalContext .getRequestPathInfo(); if (null != pathInfo ) { if(pathInfo.charAt(0) == '/'){ pathInfo = pathInfo.substring(1); } if (pathInfo.startsWith(GWT_RESOURCE_PREFIX) ) { resourceName = pathInfo; if (pathInfo.endsWith(".js")) { mime = "text/javascript"; } else if (pathInfo.endsWith(".xml")) { // xml with module cache entries mime = "text/xml"; } else if (pathInfo.endsWith(".css")) { // xml with module cache entries mime = "text/css"; } else if (pathInfo.endsWith(".gif")) { mime = "image/gif"; } else if (pathInfo.endsWith(".jpg") || pathInfo.endsWith(".jpeg")) { mime = "image/jpeg"; } try { HttpServletResponse response = (HttpServletResponse) externalContext.getResponse(); ClassLoader loader = Thread.currentThread() .getContextClassLoader(); InputStream in = loader.getResourceAsStream("META-INF/" + resourceName); if (null != in) { OutputStream out = response.getOutputStream(); response.setContentType(mime); // Set cachimg/nocaching headers. if (resourceName.endsWith(".nocache.html")) { response.setHeader("Cache-control", "no-cache"); response.setHeader("Cache-control", "no-store"); response.setHeader("Pragma", "no-cache"); response.setIntHeader("Expires", 0); } else if (resourceName.contains(".cache.")){ // TODO - send notmodified if request contain If-Modified-Since // ? HttpServletRequest request = (HttpServletRequest) externalContext.getRequest(); long ifModifiedSince = request .getDateHeader("If-Modified-Since"); if (ifModifiedSince >= 0) { response.setStatus(304);// Not modified in.close(); out.close(); facesContext.responseComplete(); return ; } else { response.setDateHeader("Expires", System .currentTimeMillis() + DEFAULT_EXPIRE); } } // Set output compression if(mime.contains("text") || mime.contains("xml")){ String encoding = (String) externalContext.getRequestHeaderMap().get("Accept-Encoding"); if(null != encoding && encoding.contains("gzip")){ // TODO - use cache ? response.setHeader("Content-Encoding","gzip"); out = new GZIPOutputStream(out,BUFFER_SIZE); } } byte[] buffer = new byte[BUFFER_SIZE]; int buffersCount = -1; int length; for (length = in.read(buffer); length > 0; length = in .read(buffer)) { out.write(buffer, 0, length); buffersCount++; } // For cacheable resources, store size. // if(isCacheable()){ // setContentLength(buffersCount*BUFFER_SIZE+length); // } in.close(); out.flush(); out.close(); } else { response.sendError(404); } } catch (IOException e) { throw new FacesException("Error then send resource", e); } finally { facesContext.responseComplete(); } } } /* End code by shura */ // Call the SeamPhaseListener beforePhase() super.beforePhase(event); } @Override public void afterPhase(PhaseEvent event) { log.debug("after phase: " + event.getPhaseId()); /* Following code taken from afterPhase() from GwtPhaseListener written by shura */ FacesContext facesContext = event.getFacesContext(); ExternalContext externalContext = facesContext.getExternalContext(); String requestContentType = externalContext.getRequestContentType(); Map requestParameterMap = externalContext.getRequestParameterMap(); if (null != requestContentType && requestContentType.contains("text/plain")) { // GWT module name. Due to differences in browsers and containers, compare with ignore case. String module = (String) requestParameterMap.get(ComponentEntryPoint.GWT_MODULE_NAME_PARAMETER); Servlet servletForModule; if(null != module){ servletForModule = getServletForModule(facesContext, module); } else { servletForModule = getDefaultServiceServlet(facesContext); } try { servletForModule.service((ServletRequest) externalContext .getRequest(), (ServletResponse) externalContext .getResponse()); } catch (ServletException e) { log.info("Servlet exception in GWT service method "+e.getMessage()); throw new FacesException( "Servlet exception in GWT service method", e); } catch (IOException e) { log.info("IO exception in GWT service method "+e.getMessage()); throw new FacesException("IO exception in GWT service method", e); } facesContext.responseComplete(); } /* end code by shura */ super.afterPhase(event); } }
-
2. Re: G4jsf and Seam success
ishabalov Mar 8, 2007 12:57 PM (in response to detiber)Seems similar to the problem with Seam EL resolver, see
http://jira.jboss.org/jira/browse/AJSF-6