com/icesoft/faces/webapp/http/common/Request.java0000644000175000017500000000267111113010761021704 0ustar rbenserbensepackage com.icesoft.faces.webapp.http.common; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.util.Date; public interface Request { String getContextPath(); String getMethod(); URI getURI(); String getHeader(String name); String[] getHeaderAsStrings(String name); Date getHeaderAsDate(String name); int getHeaderAsInteger(String name); boolean containsParameter(String name); String[] getParameterNames(); String getParameter(String name); String[] getParameterAsStrings(String name); int getParameterAsInteger(String name); boolean getParameterAsBoolean(String name); String getParameter(String name, String defaultValue); int getParameterAsInteger(String name, int defaultValue); boolean getParameterAsBoolean(String name, boolean defaultValue); InputStream readBody() throws IOException; void readBodyInto(OutputStream out) throws IOException; void respondWith(ResponseHandler handler) throws Exception; void detectEnvironment(Environment environment) throws Exception; //avoid runtime dependency on Portlet interfaces, //and for the symmetry's sake, same for the Servlet interfaces interface Environment { void servlet(Object request, Object response) throws Exception; void portlet(Object request, Object response, Object config) throws Exception; } } com/icesoft/faces/webapp/http/common/RequestProxy.java0000644000175000017500000000465611113011004022742 0ustar rbenserbensepackage com.icesoft.faces.webapp.http.common; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.util.Date; public class RequestProxy implements Request { protected Request request; public RequestProxy(Request request) { this.request = request; } public String getMethod() { return request.getMethod(); } public URI getURI() { return request.getURI(); } public String getHeader(String name) { return request.getHeader(name); } public String[] getHeaderAsStrings(String name) { return request.getHeaderAsStrings(name); } public Date getHeaderAsDate(String name) { return request.getHeaderAsDate(name); } public int getHeaderAsInteger(String name) { return request.getHeaderAsInteger(name); } public boolean containsParameter(String name) { return request.containsParameter(name); } public String[] getParameterNames() { return request.getParameterNames(); } public String getParameter(String name) { return request.getParameter(name); } public String[] getParameterAsStrings(String name) { return request.getParameterAsStrings(name); } public int getParameterAsInteger(String name) { return request.getParameterAsInteger(name); } public boolean getParameterAsBoolean(String name) { return request.getParameterAsBoolean(name); } public String getParameter(String name, String defaultValue) { return request.getParameter(name, defaultValue); } public int getParameterAsInteger(String name, int defaultValue) { return request.getParameterAsInteger(name, defaultValue); } public boolean getParameterAsBoolean(String name, boolean defaultValue) { return request.getParameterAsBoolean(name, defaultValue); } public InputStream readBody() throws IOException { return request.readBody(); } public void readBodyInto(OutputStream out) throws IOException { request.readBodyInto(out); } public void respondWith(ResponseHandler handler) throws Exception { request.respondWith(handler); } public void detectEnvironment(Environment environment) throws Exception { request.detectEnvironment(environment); } public String getContextPath() { return request.getContextPath(); } } com/icesoft/faces/webapp/http/servlet/ServletRequestResponse.java0000644000175000017500000002471511113011034025161 0ustar rbenserbensepackage com.icesoft.faces.webapp.http.servlet; import com.icesoft.faces.webapp.http.common.Request; import com.icesoft.faces.webapp.http.common.Response; import com.icesoft.faces.webapp.http.common.ResponseHandler; import com.icesoft.faces.webapp.http.portlet.PortletArtifactWrapper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Enumeration; import java.util.TimeZone; import java.util.regex.Pattern; public class ServletRequestResponse implements Request, Response { private final static Log log = LogFactory.getLog(ServletRequestResponse.class); private final static DateFormat DATE_FORMAT = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz"); private static Pattern HEADER_FIXER = null; private URI requestURI; static { DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT")); HEADER_FIXER = Pattern.compile("[\r\n]"); } protected HttpServletRequest request; protected HttpServletResponse response; public ServletRequestResponse(HttpServletRequest request, HttpServletResponse response) throws Exception { this.request = request; this.response = response; //Need to determine the type of request URI we are using based on the //environment we are running in (servlet vs portlet). detectEnvironment(new Environment() { public void servlet(Object request, Object response) { HttpServletRequest req = (HttpServletRequest) request; String query = req.getQueryString(); URI uri = null; while (null == uri) { try { uri = URI.create(req.getRequestURL().toString()); } catch (NullPointerException e) { //TODO remove this catch block when GlassFish bug is addressed if (log.isDebugEnabled()) { log.debug("Null Protocol Scheme in request", e); } uri = URI.create("http://" + req.getServerName() + ":" + req.getServerPort() + req.getRequestURI()); } } requestURI = (query == null ? uri : URI.create(uri + "?" + query)); } public void portlet(Object request, Object response, Object portletConfig) { javax.portlet.PortletRequest req = (javax.portlet.PortletRequest) request; String reqURI = (String) req.getAttribute(com.icesoft.jasper.Constants.INC_REQUEST_URI); requestURI = URI.create(reqURI); } }); } public String getMethod() { return request.getMethod(); } public URI getURI() { return requestURI; } public String getHeader(String name) { return request.getHeader(name); } public String[] getHeaderAsStrings(String name) { Enumeration e = request.getHeaders(name); ArrayList values = new ArrayList(); while (e.hasMoreElements()) values.add(e.nextElement()); return (String[]) values.toArray(new String[values.size()]); } public Date getHeaderAsDate(String name) { try { return DATE_FORMAT.parse(request.getHeader(name)); } catch (ParseException e) { throw new RuntimeException(e); } } public int getHeaderAsInteger(String name) { return Integer.parseInt(request.getHeader(name)); } public boolean containsParameter(String name) { return request.getParameter(name) != null; } public String[] getParameterNames() { Collection result = request.getParameterMap().keySet(); return (String[]) result.toArray(new String[result.size()]); } public String getParameter(String name) { checkExistenceOf(name); return (String) request.getParameter(name); } public String[] getParameterAsStrings(String name) { checkExistenceOf(name); return request.getParameterValues(name); } public int getParameterAsInteger(String name) { return Integer.parseInt(getParameter(name)); } public boolean getParameterAsBoolean(String name) { return Boolean.valueOf(getParameter(name)).booleanValue(); } public String getParameter(String name, String defaultValue) { try { return getParameter(name); } catch (Exception e) { return defaultValue; } } public int getParameterAsInteger(String name, int defaultValue) { try { return getParameterAsInteger(name); } catch (Exception e) { return defaultValue; } } public boolean getParameterAsBoolean(String name, boolean defaultValue) { try { return getParameterAsBoolean(name); } catch (Exception e) { return defaultValue; } } public InputStream readBody() throws IOException { return request.getInputStream(); } public void readBodyInto(OutputStream out) throws IOException { copy(readBody(), out); } public void respondWith(ResponseHandler handler) throws Exception { handler.respond(this); } public void setStatus(int code) { response.setStatus(code); } public void setHeader(String name, String value) { if (ignoreHeader(name, value)) return; //CR and LF embedded in headers can corrupt the HTTP response value = HEADER_FIXER.matcher(value).replaceAll(""); if ("Content-Type".equals(name)) { response.setContentType(value); } else if ("Content-Length".equals(name)) { response.setContentLength(Integer.parseInt(value)); } else { response.setHeader(name, value); } } public void setHeader(String name, String[] values) { if (ignoreHeader(name, values)) return; for (int i = 0; i < values.length; i++) { String safeValue = HEADER_FIXER.matcher(values[i]).replaceAll(""); response.addHeader(name, safeValue); } } public void setHeader(String name, Date value) { if (ignoreHeader(name, value)) return; response.setDateHeader(name, value.getTime()); } public void setHeader(String name, int value) { response.setIntHeader(name, value); } public void setHeader(String name, long value) { response.setHeader(name, String.valueOf(value)); } public void addCookie(Cookie cookie) { response.addCookie(cookie); } public OutputStream writeBody() throws IOException { return response.getOutputStream(); } public void writeBodyFrom(InputStream in) throws IOException { try { copy(in, writeBody()); } finally { in.close(); } } public void detectEnvironment(Environment environment) throws Exception { Object portletEnvironment = request.getAttribute(PortletArtifactWrapper.PORTLET_ARTIFACT_KEY); if (portletEnvironment == null) { environment.servlet(request, response); } else { PortletArtifactWrapper portletArtifact = (PortletArtifactWrapper) portletEnvironment; environment.portlet(portletArtifact.getRequest(), portletArtifact.getResponse(), portletArtifact.getPortletConfig()); //Due to the fact that the original portlet request used a RequestDispatcher to //connect to the ICEfaces framework, we need to adjust the java.servlet.include* //attributes in the original portlet request to match the dispatched request. String[] incKeys = com.icesoft.jasper.Constants.INC_CONSTANTS; for (int index = 0; index < incKeys.length; index++) { String incVal = (String) request.getAttribute(incKeys[index]); if (incVal != null) { portletArtifact.getRequest().setAttribute(incKeys[index], incVal); } else { portletArtifact.getRequest().removeAttribute(incKeys[index]); } } } } private static void copy(InputStream input, OutputStream output) throws IOException { byte[] buf = new byte[4096]; int len = 0; while ((len = input.read(buf)) > -1) output.write(buf, 0, len); } private void checkExistenceOf(String name) { if (request.getParameter(name) == null) { // This block is removable once we find out why sometimes the request // object appears a little corrupted. int port = request.getRemotePort(); String host = request.getRemoteHost(); StringBuffer data = new StringBuffer("+ Request does not contain parameter '" + name + "' host: \n"); data.append(" Originator: ").append(host).append(":").append(port).append("\n"); data.append(" Path: ").append(requestURI.toString()).append("\n"); Enumeration e = request.getParameterNames(); String key; int i = 0; while (e.hasMoreElements()) { key = (String) e.nextElement(); if (i == 0) { data.append(" Available request parameters are: \n"); } data.append(" - parameter name: ").append(key).append(", value: ").append(request.getParameter(key)).append("\n"); i++; } if (i == 0) { data.append(" Request map is empty!\n"); } data.append("- SRR hashcode: ").append(this.hashCode()).append(" Servlet request hash: ").append(request.hashCode()); log.debug(data.toString()); // we can't just carry on. We seriously need those paramters ... throw new RuntimeException("Query does not contain parameter named: " + name); } } private static boolean ignoreHeader(String name, Object value) { return name == null || value == null; } public String getContextPath() { return request.getContextPath(); } } com/icesoft/faces/webapp/http/common/FileLocator.java0000644000175000017500000000022511113017012022444 0ustar rbenserbensepackage com.icesoft.faces.webapp.http.common; import java.io.File; public interface FileLocator { File locate(Request request, String path); } com/icesoft/faces/webapp/http/core/FileServer.java0000644000175000017500000000323311113016751021762 0ustar rbenserbensepackage com.icesoft.faces.webapp.http.core; import com.icesoft.faces.webapp.http.common.FileLocator; import com.icesoft.faces.webapp.http.common.MimeTypeMatcher; import com.icesoft.faces.webapp.http.common.Request; import com.icesoft.faces.webapp.http.common.Response; import com.icesoft.faces.webapp.http.common.ResponseHandler; import com.icesoft.faces.webapp.http.common.Server; import com.icesoft.faces.webapp.http.common.standard.NotFoundHandler; import java.io.File; import java.io.FileInputStream; import java.util.Date; public class FileServer implements Server { private FileLocator locator; private MimeTypeMatcher mimeTypeMatcher; public FileServer(FileLocator locator, MimeTypeMatcher mimeTypeMatcher) { this.locator = locator; this.mimeTypeMatcher = mimeTypeMatcher; } public void service(Request request) throws Exception { final String path = request.getURI().getPath(); final File file = locator.locate(request, path); if (file.exists()) { request.respondWith(new ResponseHandler() { public void respond(Response response) throws Exception { String mimeType = mimeTypeMatcher.mimeTypeFor(path); Date lastModified = new Date(file.lastModified()); response.setHeader("Content-Type", mimeType); response.setHeader("Last-Modified", lastModified); response.writeBodyFrom(new FileInputStream(file)); } }); } else { request.respondWith(new NotFoundHandler("Cannot find file " + file)); } } public void shutdown() { } } com/icesoft/faces/webapp/http/servlet/MainServlet.java0000644000175000017500000001511011113017151022671 0ustar rbenserbensepackage com.icesoft.faces.webapp.http.servlet; import com.icesoft.faces.async.render.RenderManager; import com.icesoft.faces.webapp.http.common.Configuration; import com.icesoft.faces.webapp.http.common.FileLocator; import com.icesoft.faces.webapp.http.common.MimeTypeMatcher; import com.icesoft.faces.webapp.http.common.Request; import com.icesoft.faces.webapp.http.common.Server; import com.icesoft.faces.webapp.http.core.DisposeBeans; import com.icesoft.faces.webapp.http.core.ResourceServer; import com.icesoft.net.messaging.MessageServiceClient; import com.icesoft.net.messaging.MessageServiceException; import com.icesoft.net.messaging.jms.JMSAdapter; import com.icesoft.util.IdGenerator; import com.icesoft.util.MonitorRunner; import com.icesoft.util.SeamUtilities; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.File; import java.io.IOException; import java.net.URI; public class MainServlet extends HttpServlet { private static final Log LOG = LogFactory.getLog(MainServlet.class); static { final String headless = "java.awt.headless"; if (null == System.getProperty(headless)) { System.setProperty(headless, "true"); } } public MainServlet() { logger.debug("In MainServlet()"); } private PathDispatcher dispatcher = new PathDispatcher(); private ServletContext context; private MonitorRunner monitorRunner; private MessageServiceClient messageServiceClient; private final Log logger = LogFactory.getLog(MainServlet.class); public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); this.context = servletConfig.getServletContext(); try { final Configuration configuration = new ServletContextConfiguration("com.icesoft.faces", context); final IdGenerator idGenerator = new IdGenerator(context.getResource("/WEB-INF/web.xml").getPath()); final MimeTypeMatcher mimeTypeMatcher = new MimeTypeMatcher() { public String mimeTypeFor(String extension) { return context.getMimeType(extension); } }; final FileLocator localFileLocator = new FileLocator() { public File locate(Request request, String path) { String cp = request.getContextPath(); if (logger.isDebugEnabled()) { logger.debug("FileLocator contextPath reference = " + cp); } URI contextURI = URI.create(cp); URI pathURI = URI.create(path); String result = contextURI.relativize(pathURI).getPath(); String fileLocation = context.getRealPath(result); return new File(fileLocation); } }; monitorRunner = new MonitorRunner(configuration.getAttributeAsLong("monitorRunnerInterval", 10000)); setUpMessageServiceClient(); RenderManager.setServletConfig(servletConfig); PseudoServlet resourceServer = new BasicAdaptingServlet(new ResourceServer(configuration, mimeTypeMatcher, localFileLocator)); PseudoServlet sessionDispatcher = new SessionDispatcher(configuration, context) { protected Server newServer(HttpSession session, Monitor sessionMonitor) { return new MainSessionBoundServlet(session, sessionMonitor, idGenerator, mimeTypeMatcher, monitorRunner, configuration, messageServiceClient); } }; if (SeamUtilities.isSpringEnvironment()) { //Need to dispatch to the Spring resource server dispatcher.dispatchOn("/spring/resources/", resourceServer); } //don't create new sessions for XMLHTTPRequests identified by "block/*" prefixed paths dispatcher.dispatchOn(".*(block\\/)", new SessionVerifier(sessionDispatcher)); dispatcher.dispatchOn(".*(\\.iface$|\\.jsf|\\.faces$|\\.jsp$|\\.jspx$|\\.html$|\\.xhtml$|\\.seam$|uploadHtml$|/spring/)", sessionDispatcher); dispatcher.dispatchOn(".*", resourceServer); } catch (Exception e) { throw new ServletException(e); } } public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { dispatcher.service(request, response); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new ServletException(e); } } public void destroy() { monitorRunner.stop(); DisposeBeans.in(context); dispatcher.shutdown(); tearDownMessageServiceClient(); } private boolean isAsyncHttpServiceAvailable() { try { this.getClass().getClassLoader().loadClass("com.icesoft.faces.async.server.AsyncHttpServerAdaptingServlet"); return true; } catch (ClassNotFoundException exception) { return false; } } private boolean isJMSAvailable() { try { this.getClass().getClassLoader().loadClass("javax.jms.TopicConnectionFactory"); return true; } catch (ClassNotFoundException exception) { return false; } } private void setUpMessageServiceClient() { if (!isAsyncHttpServiceAvailable() || !isJMSAvailable()) { return; } try { messageServiceClient = new MessageServiceClient(new JMSAdapter(context), context); //todo: make message selector static to avoid instantiating the message handler messageServiceClient.subscribe(MessageServiceClient.CONTEXT_EVENT_TOPIC_NAME, new DisposeViewsHandler().getMessageSelector()); messageServiceClient.start(); } catch (Exception exception) { LOG.info("Did not start Ajax Push JMS services: " + exception); messageServiceClient = null; } } private void tearDownMessageServiceClient() { if (messageServiceClient == null) { return; } try { messageServiceClient.stop(); } catch (MessageServiceException exception) { LOG.error("Failed to close connection due to some internal error!", exception); } } }