All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.jsftemplating.util.fileStreamer.FacesStreamerContext Maven / Gradle / Ivy

/*
 * The contents of this file are subject to the terms 
 * of the Common Development and Distribution License 
 * (the License).  You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the license at 
 * https://jsftemplating.dev.java.net/cddl1.html or
 * jsftemplating/cddl1.txt.
 * See the License for the specific language governing 
 * permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL 
 * Header Notice in each file and include the License file 
 * at jsftemplating/cddl1.txt.  
 * If applicable, add the following below the CDDL Header, 
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information: 
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 */
package com.sun.jsftemplating.util.fileStreamer;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;


/**
 *  

This class encapsulates servlet specific objects so that the * {@link FileStreamer} class is not servlet-specific.

* *

This implementation will look for the following attributes * ({@link BaseContext#setAttribute(String, Object)}):

* *
  • {@link Context#CONTENT_TYPE} -- The "Content-type:" of the response.
  • *
  • {@link Context#CONTENT_DISPOSITION} -- Disposition of the streamed content.
  • *
  • {@link Context#CONTENT_FILENAME} -- Filename of the streamed content.
  • *
  • {@link Context#EXTENSION} -- The file extension of the response.
  • *
*/ public class FacesStreamerContext extends BaseContext { /** *

Constructor.

*/ public FacesStreamerContext(FacesContext ctx) { setFacesContext(ctx); init(); } /** *

This method initializes {@link FileStreamer} * {@link ContentSource}s. It looks for the * {@link Context#CONTENT_SOURCES} context parameter (JSF doesn't * provide a way to get to the ServletConfig init parameters, as of * JSF 1.2).

*/ protected synchronized void init() { FacesContext ctx = getFacesContext(); if (ctx == null) { // Should not happen in a normal env... return; } ExternalContext extCtx = ctx.getExternalContext(); boolean initDone = extCtx.getApplicationMap().containsKey(INIT_DONE); if (initDone) { return; } // Register ContentSources String sources = extCtx.getInitParameter(CONTENT_SOURCES); FileStreamer fs = getFileStreamer(); if ((sources != null) && (sources.trim().length() != 0)) { StringTokenizer tokens = new StringTokenizer(sources, " \t\n\r\f,;:"); while (tokens.hasMoreTokens()) { fs.registerContentSource(tokens.nextToken()); } } // Set Valid path parameters... String allow = extCtx.getInitParameter(ALLOW_PATHS); List paths = new ArrayList(); if (allow != null) { StringTokenizer tok = new StringTokenizer(allow, ",:;"); while (tok.hasMoreTokens()) { paths.add(ResourceContentSource.normalize(tok.nextToken())); } } else { paths.add(""); } setAllowedPaths(extCtx, paths); // Set invalid paths... String deny = extCtx.getInitParameter(DENY_PATHS); paths = new ArrayList(); if (deny != null) { StringTokenizer tok = new StringTokenizer(deny, ",:;"); while (tok.hasMoreTokens()) { paths.add(ResourceContentSource.normalize(tok.nextToken())); } } else { paths.add("WEB-INF/"); paths.add("META-INF/"); } setDeniedPaths(extCtx, paths); if (ctx != null) { // Mark initialization as complete extCtx.getApplicationMap().put(INIT_DONE, true); } } /** *

Accessor to get the {@link FileStreamer} instance.

*/ public FileStreamer getFileStreamer() { return FileStreamer.getFileStreamer(getFacesContext()); } /** *

This method locates the appropriate {@link ContentSource} for this * {@link Context}. It uses the FacesContext's * ExternalContext to look for a request parameter * named {@link Context#CONTENT_SOURCE_ID}. This value is used as the * key when looking up registered {@link ContentSource} * implementations.

*/ public ContentSource getContentSource() { ContentSource src = (ContentSource) getAttribute("_contentSource"); if (src != null) { return src; } // Get the ContentSource id FacesContext ctx = getFacesContext(); String id = ctx.getExternalContext().getRequestParameterMap(). get(Context.CONTENT_SOURCE_ID); if (id == null) { // Use the default ContentSource id = Context.DEFAULT_CONTENT_SOURCE_ID; } // Get the ContentSource src = getFileStreamer().getContentSource(id); if (src == null) { throw new RuntimeException("The ContentSource with id '" + id + "' is not registered!"); } // Return the ContentSource setAttribute("_contentSource", src); return src; } /** *

This method allows the Context to restrict access to resources. * It returns true if the user is allowed to view the * resource. It returns false if the user should not * be allowed access to the resource.

*/ public boolean hasPermission(ContentSource src) { String filename = src.getResourcePath(this); ExternalContext extCtx = getFacesContext().getExternalContext(); boolean ok = false; // Ensure it is in our list of OK paths... List paths = getAllowedPaths(extCtx); for (String path : paths) { if (filename.startsWith(path)) { ok = true; break; } } // ...and ensure it is not in our blacklisted paths... if (ok) { // Only check if ok so far... paths = getDeniedPaths(extCtx); for (String path : paths) { if (filename.startsWith(path)) { ok = false; break; } } } return ok; } /** *

This methods sets the allowed paths for resources. Paths may be * further restricted using the {@link #setDeniedPaths} method.

*/ public List getAllowedPaths(ExternalContext extCtx) { return (List) extCtx.getApplicationMap().get(ALLOWED_PATHS_KEY); } /** *

This methods sets the allowed paths for resources. Paths may be * further restricted using the {@link #setDeniedPaths} method.

*/ public void setAllowedPaths(ExternalContext ctx, List paths) { ctx.getApplicationMap().put(ALLOWED_PATHS_KEY, paths); } /** *

This methods sets the list of paths in which resources should not * be served.

*/ public void setDeniedPaths(ExternalContext ctx, List paths) { ctx.getApplicationMap().put(DENIED_PATHS_KEY, paths); } /** *

This methods sets the list of paths for resources.

*/ public List getDeniedPaths(ExternalContext extCtx) { return (List) extCtx.getApplicationMap().get(DENIED_PATHS_KEY); } /** *

This method is responsible for setting the response header * information.

*/ public void writeHeader(ContentSource source) { // FIXME: Portlet ServletResponse resp = (ServletResponse) getFacesContext().getExternalContext().getResponse(); // Set the "Last-Modified" Header // First check context long longTime = source.getLastModified(this); if (longTime != -1) { HttpServletResponse httpResponse = ((HttpServletResponse) resp); httpResponse.setDateHeader("Last-Modified", longTime); httpResponse.setDateHeader("Expires", new java.util.Date().getTime() + Context.EXPIRY_TIME); } // First check CONTENT_TYPE String contentType = (String) getAttribute(CONTENT_TYPE); if (contentType == null) { // Not found yet, check EXTENSION String ext = (String) getAttribute(EXTENSION); if (ext != null) { contentType = FileStreamer.getMimeType(ext); } if (contentType == null) { // Default Content-type is: application/octet-stream contentType = FileStreamer.getDefaultMimeType(); } } ((HttpServletResponse) resp).setHeader("Content-type", contentType); // Check disposition/filename to associate a name with the stream String disposition = (String) getAttribute(CONTENT_DISPOSITION); String filename = (String) getAttribute(CONTENT_FILENAME); if (disposition == null) { // No disposition set, see if we have a filename if (filename != null) { ((HttpServletResponse) resp).setHeader("Content-Disposition", DEFAULT_DISPOSITION + ";filename=\"" + filename + "\""); } } else { // Disposition set, see if we also have a filename if (filename != null) { disposition += ";filename=\"" + filename + "\""; } ((HttpServletResponse) resp).setHeader("Content-Disposition", disposition); } } /** *

This method is responsible for sending an error.

*/ public void sendError(int code, String msg) throws IOException { // FIXME: JSF 2.0 now provides: externalContext.responseSendError(int, String) // FIXME: Portal HttpServletResponse resp = (HttpServletResponse) getFacesContext().getExternalContext().getResponse(); if (msg == null) { resp.sendError(code); } else { resp.sendError(code, msg); } } /** *

This method is returns the ServletOutputStream.

*/ public OutputStream getOutputStream() throws IOException { return getFacesContext().getExternalContext().getResponseOutputStream(); } /** *

This returns the FacesContext. This is the same * as calling:

* *

getAttribute({@link #FACES_CONTEXT})

*/ public FacesContext getFacesContext() { return (FacesContext) getAttribute(FACES_CONTEXT); } /** *

This sets the FacesContext. This is the same as * calling:

* *

setAttribute({@link #FACES_CONTEXT}, ctx)

*/ protected void setFacesContext(FacesContext ctx) { setAttribute(FACES_CONTEXT, ctx); } /** *

Flag indicating initialization for this class has been completed.

*/ private static final String INIT_DONE = "__jsft_StreamContextInitialized"; /** *

The attribute value to access the FacesContext. See * {@link #getFacesContext()}.

*/ public static final String FACES_CONTEXT = "facesContext"; /** *

The default Content-Disposition. It is only used when a filename * is provided, but a disposition is not. The default is * "attachment". This will normally cause a browser to prompt the * user to save the file. This is the default since setting a * filename implies that the user may want to save this file. You * must explicitly set the disposition for "inline" behavior with a * filename.

*/ public static final String DEFAULT_DISPOSITION = "attachment"; }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy