You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by st...@apache.org on 2011/10/20 12:49:36 UTC
svn commit: r1186730 [12/22] - in /myfaces/commons/branches/jsf_20: examples/
examples/myfaces-commons-examples/src/main/java/org/apache/myfaces/commons/examples/
examples/myfaces-commons-examples/src/main/java/org/apache/myfaces/commons/examples/acces...
Modified: myfaces/commons/branches/jsf_20/myfaces-commons-resourcehandler/src/main/java/org/apache/myfaces/commons/resourcehandler/ExtendedResourceHandlerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/commons/branches/jsf_20/myfaces-commons-resourcehandler/src/main/java/org/apache/myfaces/commons/resourcehandler/ExtendedResourceHandlerImpl.java?rev=1186730&r1=1186729&r2=1186730&view=diff
==============================================================================
--- myfaces/commons/branches/jsf_20/myfaces-commons-resourcehandler/src/main/java/org/apache/myfaces/commons/resourcehandler/ExtendedResourceHandlerImpl.java (original)
+++ myfaces/commons/branches/jsf_20/myfaces-commons-resourcehandler/src/main/java/org/apache/myfaces/commons/resourcehandler/ExtendedResourceHandlerImpl.java Thu Oct 20 10:49:18 2011
@@ -1,766 +1,766 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.myfaces.commons.resourcehandler;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Locale;
-import java.util.Map;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.zip.GZIPOutputStream;
-
-import javax.faces.FacesException;
-import javax.faces.application.ProjectStage;
-import javax.faces.application.Resource;
-import javax.faces.application.ResourceHandler;
-import javax.faces.application.ResourceHandlerWrapper;
-import javax.faces.application.ResourceWrapper;
-import javax.faces.context.ExternalContext;
-import javax.faces.context.FacesContext;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.myfaces.commons.resourcehandler.config.element.Library;
-import org.apache.myfaces.commons.resourcehandler.resource.ResourceHandlerCache;
-import org.apache.myfaces.commons.resourcehandler.resource.ResourceHandlerCache.ResourceValue;
-import org.apache.myfaces.commons.resourcehandler.resource.ResourceLoader;
-import org.apache.myfaces.commons.resourcehandler.resource.ResourceMeta;
-import org.apache.myfaces.commons.util.ClassUtils;
-import org.apache.myfaces.commons.util.ExternalContextUtils;
-import org.apache.myfaces.commons.util.RequestType;
-import org.apache.myfaces.commons.util.StringUtils;
-
-/**
- *
- * @author Leonardo Uribe
- *
- */
-public class ExtendedResourceHandlerImpl extends ResourceHandlerWrapper
-{
- private static final String IS_RESOURCE_REQUEST = "org.apache.myfaces.commons.IS_RESOURCE_REQUEST";
-
- private static final String RESOURCE_LOCALE = "org.apache.myfaces.commons.RESOURCE_LOCALE";
-
- private ExtendedDefaultResourceHandlerSupport _resourceHandlerSupport;
-
- private ResourceHandlerCache _resourceHandlerCache;
-
- //private static final Log log = LogFactory.getLog(ResourceHandlerImpl.class);
- private static final Logger log = Logger.getLogger(ExtendedResourceHandlerImpl.class.getName());
-
- private static final int _BUFFER_SIZE = 2048;
-
- private ResourceHandler _delegate;
-
- //private volatile Boolean filterOn;
-
- public ExtendedResourceHandlerImpl(ResourceHandler delegate)
- {
- this._delegate = delegate;
- //Eager initialization
- _resourceHandlerSupport = new ExtendedDefaultResourceHandlerSupport();
- }
-
- /*
- @Override
- public Resource createResource(String resourceName)
- {
- return createResource(resourceName, null);
- }*/
-
- @Override
- public Resource createResource(String resourceName, String libraryName)
- {
- if (getResourceHandlerSupport().getMyFacesResourcesConfig().getLibrary(libraryName) != null)
- {
- return createResource(resourceName, libraryName, null);
- }
- else
- {
- return super.createResource(resourceName, libraryName);
- }
- }
-
- @Override
- public Resource createResource(String resourceName, String libraryName,
- String contentType)
- {
- if (getResourceHandlerSupport().getMyFacesResourcesConfig().getLibrary(libraryName) != null)
- {
- return defaultCreateResource(resourceName, libraryName, contentType);
- }
- else
- {
- return super.createResource(resourceName, libraryName, contentType);
- }
- }
-
- private Resource defaultCreateResource(String resourceName, String expectedLibraryName,
- String contentType)
- {
- Resource resource = null;
-
- FacesContext facesContext = FacesContext.getCurrentInstance();
-
- if (contentType == null)
- {
- //Resolve contentType using ExternalContext.getMimeType
- contentType = facesContext.getExternalContext().getMimeType(resourceName);
- }
-
- String localePrefix = (String) facesContext.getAttributes().get(RESOURCE_LOCALE);
-
- if (localePrefix == null)
- {
- localePrefix = getLocalePrefixForLocateResource();
- }
-
- //Calculate the real libraryName
- String redirectedLibraryName = resolveLibraryName(expectedLibraryName);
-
- // check cache
- if(getResourceLoaderCache().containsResource(resourceName, redirectedLibraryName, contentType, localePrefix))
- {
- ResourceValue resourceValue = getResourceLoaderCache().getResource(
- resourceName, redirectedLibraryName, contentType, localePrefix);
-
- //resource = new ResourceImpl(resourceValue.getResourceMeta(), resourceValue.getResourceLoader(),
- // getResourceHandlerSupport(), contentType);
- resource = new ExtendedResourceImpl((ExtendedResourceMeta) resourceValue.getResourceMeta(), resourceValue.getResourceLoader(),
- getResourceHandlerSupport(), contentType, localePrefix, redirectedLibraryName.equals(expectedLibraryName) ? null : expectedLibraryName);
- }
- else
- {
- for (ResourceLoader loader : getResourceHandlerSupport().getResourceLoaders())
- {
- ResourceMeta resourceMeta = deriveResourceMeta(loader, resourceName, redirectedLibraryName, localePrefix);
-
- if (resourceMeta != null)
- {
- //resource = new ResourceImpl(resourceMeta, loader, getResourceHandlerSupport(), contentType);
- resource = new ExtendedResourceImpl((ExtendedResourceMeta) resourceMeta, loader, getResourceHandlerSupport(), contentType, localePrefix,
- redirectedLibraryName.equals(expectedLibraryName) ? null : expectedLibraryName);
-
- // cache it
- getResourceLoaderCache().putResource(resourceName, redirectedLibraryName, contentType,
- localePrefix, resourceMeta, loader);
- break;
- }
- }
- }
-
- return resource;
- }
-
- public String resolveLibraryName(String libraryName)
- {
- String finalLibraryName = libraryName;
- Library library = null;
- boolean resolved = false;
- do
- {
- library = getResourceHandlerSupport().getMyFacesResourcesConfig().getLibrary(finalLibraryName);
- if (library != null)
- {
- if (library.getRedirectName() != null && library.getRedirectName().length() > 0)
- {
- finalLibraryName = library.getRedirectName();
- }
- else
- {
- //No redirect, so this is the real instance
- resolved = true;
- }
- }
- } while (library != null && !resolved);
-
- return finalLibraryName;
- }
-
- /**
- * This method try to create a ResourceMeta for a specific resource
- * loader. If no library, or resource is found, just return null,
- * so the algorithm in createResource can continue checking with the
- * next registered ResourceLoader.
- */
- protected ExtendedResourceMeta deriveResourceMeta(ResourceLoader resourceLoader,
- String resourceName, String libraryName, String localePrefix)
- {
- String resourceVersion = null;
- String libraryVersion = null;
- ExtendedResourceMeta resourceId = null;
-
- //1. Try to locate resource in a localized path
- if (localePrefix != null)
- {
- if (null != libraryName)
- {
- String pathToLib = localePrefix + '/' + libraryName;
- libraryVersion = resourceLoader.getLibraryVersion(pathToLib);
-
- if (null != libraryVersion)
- {
- String pathToResource = localePrefix + '/'
- + libraryName + '/' + libraryVersion + '/'
- + resourceName;
- resourceVersion = resourceLoader
- .getResourceVersion(pathToResource);
- }
- else
- {
- String pathToResource = localePrefix + '/'
- + libraryName + '/' + resourceName;
- resourceVersion = resourceLoader
- .getResourceVersion(pathToResource);
- }
-
- if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
- {
- resourceId = (ExtendedResourceMeta) resourceLoader.createResourceMeta(localePrefix, libraryName,
- libraryVersion, resourceName, resourceVersion);
- }
- }
- else
- {
- resourceVersion = resourceLoader
- .getResourceVersion(localePrefix + '/'+ resourceName);
- if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
- {
- resourceId = (ExtendedResourceMeta) resourceLoader.createResourceMeta(localePrefix, null, null,
- resourceName, resourceVersion);
- }
- }
-
- if (resourceId != null)
- {
- if (!resourceLoader.resourceExists(resourceId))
- {
- resourceId = null;
- }
- }
- }
-
- //2. Try to localize resource in a non localized path
- if (resourceId == null)
- {
- if (null != libraryName)
- {
- libraryVersion = resourceLoader.getLibraryVersion(libraryName);
-
- if (null != libraryVersion)
- {
- String pathToResource = (libraryName + '/' + libraryVersion
- + '/' + resourceName);
- resourceVersion = resourceLoader
- .getResourceVersion(pathToResource);
- }
- else
- {
- String pathToResource = (libraryName + '/'
- + resourceName);
- resourceVersion = resourceLoader
- .getResourceVersion(pathToResource);
- }
-
- if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
- {
- resourceId = (ExtendedResourceMeta) resourceLoader.createResourceMeta(null, libraryName,
- libraryVersion, resourceName, resourceVersion);
- }
- }
- else
- {
- resourceVersion = resourceLoader
- .getResourceVersion(resourceName);
-
- if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
- {
- resourceId = (ExtendedResourceMeta) resourceLoader.createResourceMeta(null, null, null,
- resourceName, resourceVersion);
- }
- }
-
- if (resourceId != null)
- {
- if (!resourceLoader.resourceExists(resourceId))
- {
- resourceId = null;
- }
- }
- }
-
- return resourceId;
- }
-
- /**
- * Handle the resource request, writing in the output.
- *
- * This method implements an algorithm semantically identical to
- * the one described on the javadoc of ResourceHandler.handleResourceRequest
- */
- @Override
- public void handleResourceRequest(FacesContext facesContext) throws IOException
- {
- // Only if filter is on
- //if (!isFilterOn())
- //{
- // super.handleResourceRequest(facesContext);
- //}
-
- // And this is a request handled from the filter first!
- //if (!facesContext.getAttributes().containsKey(ResourceHandlerFilter.RESOURCE_HANDLER_FILTER_REQUEST))
- //{
- // super.handleResourceRequest(facesContext);
- //}
-
- try
- {
- String resourceBasePath = getResourceHandlerSupport()
- .calculateResourceBasePath(facesContext);
-
- if (resourceBasePath == null)
- {
- // No base name could be calculated, so no further
- //advance could be done here. HttpServletResponse.SC_NOT_FOUND
- //cannot be returned since we cannot extract the
- //resource base name
- super.handleResourceRequest(facesContext);
- return;
- }
-
- // We neet to get an instance of HttpServletResponse, but sometimes
- // the response object is wrapped by several instances of
- // ServletResponseWrapper (like ResponseSwitch).
- // Since we are handling a resource, we can expect to get an
- // HttpServletResponse.
- if (!RequestType.SERVLET.equals(ExternalContextUtils.getRequestType(facesContext.getExternalContext())))
- {
- throw new IllegalStateException("Could not obtain an instance of HttpServletResponse.");
- }
- Object response = facesContext.getExternalContext().getResponse();
- HttpServletResponse httpServletResponse = (HttpServletResponse) response;
- if (httpServletResponse == null)
- {
- throw new IllegalStateException("Could not obtain an instance of HttpServletResponse.");
- }
-
- if (isResourceIdentifierExcluded(facesContext, resourceBasePath))
- {
- httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
- return;
- }
-
- String resourceName = null;
- String libraryName = null;
- String requestedLocalePrefix = null;
- if (resourceBasePath.startsWith(getResourceHandlerSupport().getResourceIdentifier()))
- {
- //resourceName = resourceBasePath
- // .substring(ResourceHandler.RESOURCE_IDENTIFIER.length() + 1);
- resourceName = resourceBasePath
- .substring(getResourceHandlerSupport().getResourceIdentifier().length());
-
- if (resourceName.startsWith("/$"))
- {
- //Extract locale prefix, libraryName and resourceName
- int from = 3;
- int to = resourceName.indexOf('/',3);
- requestedLocalePrefix = resourceName.substring(from,to);
- from = to+1;
- to = resourceName.indexOf('/', from);
- libraryName = resourceName.substring(from, to);
- resourceName = resourceName.substring(to+1);
- }
- else
- {
- //No special identifier used, delegate to default algorithm
- resourceName = null;
- //Try to get the library name using the standard form
- //libraryName = facesContext.getExternalContext()
- // .getRequestParameterMap().get("ln");
- }
- }
- else
- {
- //Does not have the conditions for be a resource call, let the base one
- //return not found
- super.handleResourceRequest(facesContext);
- return;
- }
-
- //Only resources with resourceName and advanced libraryName are handled by this handler
- if (resourceName == null)
- {
- super.handleResourceRequest(facesContext);
- return;
- }
- else if (libraryName == null)
- {
- super.handleResourceRequest(facesContext);
- return;
- }
- else if (libraryName != null && getResourceHandlerSupport().getMyFacesResourcesConfig().getLibrary(libraryName) == null)
- {
- super.handleResourceRequest(facesContext);
- return;
- }
-
- if (requestedLocalePrefix != null)
- {
- facesContext.getAttributes().put(RESOURCE_LOCALE, requestedLocalePrefix);
- }
-
- Resource resource = null;
- //if (libraryName != null)
- //{
- //log.info("libraryName=" + libraryName);
- resource = facesContext.getApplication().getResourceHandler().createResource(resourceName, libraryName);
- //}
- //else
- //{
- // resource = facesContext.getApplication().getResourceHandler().createResource(resourceName);
- //}
-
- if (resource == null)
- {
- httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
- return;
- }
-
- if (!resource.userAgentNeedsUpdate(facesContext))
- {
- httpServletResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
- return;
- }
-
- httpServletResponse.setContentType(_getContentType(resource, facesContext.getExternalContext()));
-
- Map<String, String> headers = resource.getResponseHeaders();
-
- for (Map.Entry<String, String> entry : headers.entrySet())
- {
- httpServletResponse.setHeader(entry.getKey(), entry.getValue());
- }
-
- //serve up the bytes (taken from trinidad ResourceServlet)
- try
- {
- // we should serve a compressed version of the resource, if
- // - ProjectStage != Development
- // - a compressed version is available (created in constructor)
- // - the user agent supports compresssion
- // and if there is no caching on disk, do compression here!
- if (!facesContext.isProjectStage(ProjectStage.Development) &&
- getResourceHandlerSupport().isGzipResourcesEnabled() &&
- !getResourceHandlerSupport().isCacheDiskGzipResources() &&
- getResourceHandlerSupport().userAgentSupportsCompression(facesContext) &&
- getResourceHandlerSupport().isCompressable(resource))
- {
- InputStream in = resource.getInputStream();
- OutputStream out = new GZIPOutputStream(httpServletResponse.getOutputStream(), _BUFFER_SIZE);
- byte[] buffer = new byte[_BUFFER_SIZE];
-
- try
- {
- int count = pipeBytes(in, out, buffer);
- //set the content lenght
- httpServletResponse.setContentLength(count);
- }
- finally
- {
- try
- {
- in.close();
- }
- finally
- {
- out.close();
- }
- }
- }
- else
- {
- InputStream in = resource.getInputStream();
- OutputStream out = httpServletResponse.getOutputStream();
- byte[] buffer = new byte[_BUFFER_SIZE];
-
- try
- {
- int count = pipeBytes(in, out, buffer);
- //set the content lenght
- httpServletResponse.setContentLength(count);
- }
- finally
- {
- try
- {
- in.close();
- }
- finally
- {
- out.close();
- }
- }
- }
- }
- catch (IOException e)
- {
- //TODO: Log using a localized message (which one?)
- if (log.isLoggable(Level.SEVERE))
- log.severe("Error trying to load resource " + resourceName
- + " with library " + libraryName + " :"
- + e.getMessage());
- httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
- }
- }
- catch (Throwable ex)
- {
- // handle the Throwable accordingly. Maybe generate an error page.
- // FIXME we are creating a html error page for a non html request here
- // shouln't we do something better? -=Jakob Korherr=-
- throw new FacesException(ex);
- //ErrorPageWriter.handleThrowable(facesContext, ex);
- }
- }
-
- /**
- * Reads the specified input stream into the provided byte array storage and
- * writes it to the output stream.
- */
- private static int pipeBytes(InputStream in, OutputStream out, byte[] buffer)
- throws IOException
- {
- int count = 0;
- int length;
-
- while ((length = (in.read(buffer))) >= 0)
- {
- out.write(buffer, 0, length);
- count += length;
- }
- return count;
- }
-
- @Override
- public boolean isResourceRequest(FacesContext facesContext)
- {
- // Since this method could be called many times we save it
- //on request map so the first time is calculated it remains
- //alive until the end of the request
- Boolean value = (Boolean) facesContext.getAttributes().get(IS_RESOURCE_REQUEST);
-
- if (value != null && value)
- {
- //return the saved value
- return value;
- }
- else
- {
- String resourceBasePath = getResourceHandlerSupport()
- .calculateResourceBasePath(facesContext);
-
- if (resourceBasePath != null
- && resourceBasePath.startsWith(getResourceHandlerSupport().getResourceIdentifier()))
- {
- facesContext.getAttributes().put(IS_RESOURCE_REQUEST, Boolean.TRUE);
- return true;
- }
- else
- {
- value = super.isResourceRequest(facesContext);
- facesContext.getAttributes().put(IS_RESOURCE_REQUEST, value);
- return value;
- }
- }
- }
-
- protected String getLocalePrefixForLocateResource()
- {
- String localePrefix = null;
- FacesContext context = FacesContext.getCurrentInstance();
-
- String bundleName = context.getApplication().getMessageBundle();
-
- if (null != bundleName)
- {
- Locale locale = context.getApplication().getViewHandler()
- .calculateLocale(context);
-
- ResourceBundle bundle = ResourceBundle
- .getBundle(bundleName, locale, ClassUtils.getContextClassLoader());
-
- if (bundle != null)
- {
- try
- {
- localePrefix = bundle.getString(ResourceHandler.LOCALE_PREFIX);
- }
- catch (MissingResourceException e)
- {
- // Ignore it and return null
- }
- }
- }
- return localePrefix;
- }
-
- protected boolean isResourceIdentifierExcluded(FacesContext context,
- String resourceIdentifier)
- {
- String value = context.getExternalContext().getInitParameter(
- RESOURCE_EXCLUDES_PARAM_NAME);
- if (value == null)
- {
- value = RESOURCE_EXCLUDES_DEFAULT_VALUE;
- }
- //TODO: optimize this code
- String[] extensions = StringUtils.splitShortString(value, ' ');
- for (int i = 0; i < extensions.length; i++)
- {
- if (resourceIdentifier.endsWith(extensions[i]))
- {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Check if a library exists or not. This is done delegating
- * to each ResourceLoader used, because each one has a different
- * prefix and way to load resources.
- *
- */
- @Override
- public boolean libraryExists(String libraryName)
- {
- if (getResourceHandlerSupport().getMyFacesResourcesConfig().getLibrary(libraryName) != null)
- {
- String localePrefix = getLocalePrefixForLocateResource();
-
- String pathToLib = null;
-
- if (localePrefix != null)
- {
- //Check with locale
- pathToLib = localePrefix + '/' + libraryName;
-
- for (ResourceLoader loader : getResourceHandlerSupport()
- .getResourceLoaders())
- {
- if (loader.libraryExists(pathToLib))
- {
- return true;
- }
- }
- }
-
- //Check without locale
- for (ResourceLoader loader : getResourceHandlerSupport()
- .getResourceLoaders())
- {
- if (loader.libraryExists(libraryName))
- {
- return true;
- }
- }
- }
- else
- {
- super.libraryExists(libraryName);
- }
-
- return false;
- }
-
- /**
- * @param resourceHandlerSupport
- * the resourceHandlerSupport to set
- */
- public void setResourceHandlerSupport(
- ExtendedDefaultResourceHandlerSupport resourceHandlerSupport)
- {
- _resourceHandlerSupport = resourceHandlerSupport;
- }
-
- /**
- * @return the resourceHandlerSupport
- */
- protected ExtendedDefaultResourceHandlerSupport getResourceHandlerSupport()
- {
- return _resourceHandlerSupport;
- }
-
- private ResourceHandlerCache getResourceLoaderCache()
- {
- if (_resourceHandlerCache == null)
- _resourceHandlerCache = new ResourceHandlerCache();
- return _resourceHandlerCache;
- }
-
- private String _getContentType(Resource resource, ExternalContext externalContext)
- {
- String contentType = resource.getContentType();
-
- // the resource does not provide a content-type --> determine it via mime-type
- if (contentType == null || contentType.length() == 0)
- {
- String resourceName = getWrappedResourceName(resource);
-
- if (resourceName != null)
- {
- contentType = externalContext.getMimeType(resourceName);
- }
- }
-
- return contentType;
- }
-
- /**
- * Recursively unwarp the resource until we find the real resourceName
- * This is needed because the JSF2 specced ResourceWrapper doesn't override
- * the getResourceName() method :(
- * @param resource
- * @return the first non-null resourceName or <code>null</code> if none set
- */
- private String getWrappedResourceName(Resource resource)
- {
- String resourceName = resource.getResourceName();
- if (resourceName != null)
- {
- return resourceName;
- }
-
- if (resource instanceof ResourceWrapper)
- {
- return getWrappedResourceName(((ResourceWrapper) resource).getWrapped());
- }
-
- return null;
- }
-
- @Override
- public ResourceHandler getWrapped()
- {
- return _delegate;
- }
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.commons.resourcehandler;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.zip.GZIPOutputStream;
+
+import javax.faces.FacesException;
+import javax.faces.application.ProjectStage;
+import javax.faces.application.Resource;
+import javax.faces.application.ResourceHandler;
+import javax.faces.application.ResourceHandlerWrapper;
+import javax.faces.application.ResourceWrapper;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.myfaces.commons.resourcehandler.config.element.Library;
+import org.apache.myfaces.commons.resourcehandler.resource.ResourceHandlerCache;
+import org.apache.myfaces.commons.resourcehandler.resource.ResourceHandlerCache.ResourceValue;
+import org.apache.myfaces.commons.resourcehandler.resource.ResourceLoader;
+import org.apache.myfaces.commons.resourcehandler.resource.ResourceMeta;
+import org.apache.myfaces.commons.util.ClassUtils;
+import org.apache.myfaces.commons.util.ExternalContextUtils;
+import org.apache.myfaces.commons.util.RequestType;
+import org.apache.myfaces.commons.util.StringUtils;
+
+/**
+ *
+ * @author Leonardo Uribe
+ *
+ */
+public class ExtendedResourceHandlerImpl extends ResourceHandlerWrapper
+{
+ private static final String IS_RESOURCE_REQUEST = "org.apache.myfaces.commons.IS_RESOURCE_REQUEST";
+
+ private static final String RESOURCE_LOCALE = "org.apache.myfaces.commons.RESOURCE_LOCALE";
+
+ private ExtendedDefaultResourceHandlerSupport _resourceHandlerSupport;
+
+ private ResourceHandlerCache _resourceHandlerCache;
+
+ //private static final Log log = LogFactory.getLog(ResourceHandlerImpl.class);
+ private static final Logger log = Logger.getLogger(ExtendedResourceHandlerImpl.class.getName());
+
+ private static final int _BUFFER_SIZE = 2048;
+
+ private ResourceHandler _delegate;
+
+ //private volatile Boolean filterOn;
+
+ public ExtendedResourceHandlerImpl(ResourceHandler delegate)
+ {
+ this._delegate = delegate;
+ //Eager initialization
+ _resourceHandlerSupport = new ExtendedDefaultResourceHandlerSupport();
+ }
+
+ /*
+ @Override
+ public Resource createResource(String resourceName)
+ {
+ return createResource(resourceName, null);
+ }*/
+
+ @Override
+ public Resource createResource(String resourceName, String libraryName)
+ {
+ if (getResourceHandlerSupport().getMyFacesResourcesConfig().getLibrary(libraryName) != null)
+ {
+ return createResource(resourceName, libraryName, null);
+ }
+ else
+ {
+ return super.createResource(resourceName, libraryName);
+ }
+ }
+
+ @Override
+ public Resource createResource(String resourceName, String libraryName,
+ String contentType)
+ {
+ if (getResourceHandlerSupport().getMyFacesResourcesConfig().getLibrary(libraryName) != null)
+ {
+ return defaultCreateResource(resourceName, libraryName, contentType);
+ }
+ else
+ {
+ return super.createResource(resourceName, libraryName, contentType);
+ }
+ }
+
+ private Resource defaultCreateResource(String resourceName, String expectedLibraryName,
+ String contentType)
+ {
+ Resource resource = null;
+
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+
+ if (contentType == null)
+ {
+ //Resolve contentType using ExternalContext.getMimeType
+ contentType = facesContext.getExternalContext().getMimeType(resourceName);
+ }
+
+ String localePrefix = (String) facesContext.getAttributes().get(RESOURCE_LOCALE);
+
+ if (localePrefix == null)
+ {
+ localePrefix = getLocalePrefixForLocateResource();
+ }
+
+ //Calculate the real libraryName
+ String redirectedLibraryName = resolveLibraryName(expectedLibraryName);
+
+ // check cache
+ if(getResourceLoaderCache().containsResource(resourceName, redirectedLibraryName, contentType, localePrefix))
+ {
+ ResourceValue resourceValue = getResourceLoaderCache().getResource(
+ resourceName, redirectedLibraryName, contentType, localePrefix);
+
+ //resource = new ResourceImpl(resourceValue.getResourceMeta(), resourceValue.getResourceLoader(),
+ // getResourceHandlerSupport(), contentType);
+ resource = new ExtendedResourceImpl((ExtendedResourceMeta) resourceValue.getResourceMeta(), resourceValue.getResourceLoader(),
+ getResourceHandlerSupport(), contentType, localePrefix, redirectedLibraryName.equals(expectedLibraryName) ? null : expectedLibraryName);
+ }
+ else
+ {
+ for (ResourceLoader loader : getResourceHandlerSupport().getResourceLoaders())
+ {
+ ResourceMeta resourceMeta = deriveResourceMeta(loader, resourceName, redirectedLibraryName, localePrefix);
+
+ if (resourceMeta != null)
+ {
+ //resource = new ResourceImpl(resourceMeta, loader, getResourceHandlerSupport(), contentType);
+ resource = new ExtendedResourceImpl((ExtendedResourceMeta) resourceMeta, loader, getResourceHandlerSupport(), contentType, localePrefix,
+ redirectedLibraryName.equals(expectedLibraryName) ? null : expectedLibraryName);
+
+ // cache it
+ getResourceLoaderCache().putResource(resourceName, redirectedLibraryName, contentType,
+ localePrefix, resourceMeta, loader);
+ break;
+ }
+ }
+ }
+
+ return resource;
+ }
+
+ public String resolveLibraryName(String libraryName)
+ {
+ String finalLibraryName = libraryName;
+ Library library = null;
+ boolean resolved = false;
+ do
+ {
+ library = getResourceHandlerSupport().getMyFacesResourcesConfig().getLibrary(finalLibraryName);
+ if (library != null)
+ {
+ if (library.getRedirectName() != null && library.getRedirectName().length() > 0)
+ {
+ finalLibraryName = library.getRedirectName();
+ }
+ else
+ {
+ //No redirect, so this is the real instance
+ resolved = true;
+ }
+ }
+ } while (library != null && !resolved);
+
+ return finalLibraryName;
+ }
+
+ /**
+ * This method try to create a ResourceMeta for a specific resource
+ * loader. If no library, or resource is found, just return null,
+ * so the algorithm in createResource can continue checking with the
+ * next registered ResourceLoader.
+ */
+ protected ExtendedResourceMeta deriveResourceMeta(ResourceLoader resourceLoader,
+ String resourceName, String libraryName, String localePrefix)
+ {
+ String resourceVersion = null;
+ String libraryVersion = null;
+ ExtendedResourceMeta resourceId = null;
+
+ //1. Try to locate resource in a localized path
+ if (localePrefix != null)
+ {
+ if (null != libraryName)
+ {
+ String pathToLib = localePrefix + '/' + libraryName;
+ libraryVersion = resourceLoader.getLibraryVersion(pathToLib);
+
+ if (null != libraryVersion)
+ {
+ String pathToResource = localePrefix + '/'
+ + libraryName + '/' + libraryVersion + '/'
+ + resourceName;
+ resourceVersion = resourceLoader
+ .getResourceVersion(pathToResource);
+ }
+ else
+ {
+ String pathToResource = localePrefix + '/'
+ + libraryName + '/' + resourceName;
+ resourceVersion = resourceLoader
+ .getResourceVersion(pathToResource);
+ }
+
+ if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
+ {
+ resourceId = (ExtendedResourceMeta) resourceLoader.createResourceMeta(localePrefix, libraryName,
+ libraryVersion, resourceName, resourceVersion);
+ }
+ }
+ else
+ {
+ resourceVersion = resourceLoader
+ .getResourceVersion(localePrefix + '/'+ resourceName);
+ if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
+ {
+ resourceId = (ExtendedResourceMeta) resourceLoader.createResourceMeta(localePrefix, null, null,
+ resourceName, resourceVersion);
+ }
+ }
+
+ if (resourceId != null)
+ {
+ if (!resourceLoader.resourceExists(resourceId))
+ {
+ resourceId = null;
+ }
+ }
+ }
+
+ //2. Try to localize resource in a non localized path
+ if (resourceId == null)
+ {
+ if (null != libraryName)
+ {
+ libraryVersion = resourceLoader.getLibraryVersion(libraryName);
+
+ if (null != libraryVersion)
+ {
+ String pathToResource = (libraryName + '/' + libraryVersion
+ + '/' + resourceName);
+ resourceVersion = resourceLoader
+ .getResourceVersion(pathToResource);
+ }
+ else
+ {
+ String pathToResource = (libraryName + '/'
+ + resourceName);
+ resourceVersion = resourceLoader
+ .getResourceVersion(pathToResource);
+ }
+
+ if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
+ {
+ resourceId = (ExtendedResourceMeta) resourceLoader.createResourceMeta(null, libraryName,
+ libraryVersion, resourceName, resourceVersion);
+ }
+ }
+ else
+ {
+ resourceVersion = resourceLoader
+ .getResourceVersion(resourceName);
+
+ if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
+ {
+ resourceId = (ExtendedResourceMeta) resourceLoader.createResourceMeta(null, null, null,
+ resourceName, resourceVersion);
+ }
+ }
+
+ if (resourceId != null)
+ {
+ if (!resourceLoader.resourceExists(resourceId))
+ {
+ resourceId = null;
+ }
+ }
+ }
+
+ return resourceId;
+ }
+
+ /**
+ * Handle the resource request, writing in the output.
+ *
+ * This method implements an algorithm semantically identical to
+ * the one described on the javadoc of ResourceHandler.handleResourceRequest
+ */
+ @Override
+ public void handleResourceRequest(FacesContext facesContext) throws IOException
+ {
+ // Only if filter is on
+ //if (!isFilterOn())
+ //{
+ // super.handleResourceRequest(facesContext);
+ //}
+
+ // And this is a request handled from the filter first!
+ //if (!facesContext.getAttributes().containsKey(ResourceHandlerFilter.RESOURCE_HANDLER_FILTER_REQUEST))
+ //{
+ // super.handleResourceRequest(facesContext);
+ //}
+
+ try
+ {
+ String resourceBasePath = getResourceHandlerSupport()
+ .calculateResourceBasePath(facesContext);
+
+ if (resourceBasePath == null)
+ {
+ // No base name could be calculated, so no further
+ //advance could be done here. HttpServletResponse.SC_NOT_FOUND
+ //cannot be returned since we cannot extract the
+ //resource base name
+ super.handleResourceRequest(facesContext);
+ return;
+ }
+
+ // We neet to get an instance of HttpServletResponse, but sometimes
+ // the response object is wrapped by several instances of
+ // ServletResponseWrapper (like ResponseSwitch).
+ // Since we are handling a resource, we can expect to get an
+ // HttpServletResponse.
+ if (!RequestType.SERVLET.equals(ExternalContextUtils.getRequestType(facesContext.getExternalContext())))
+ {
+ throw new IllegalStateException("Could not obtain an instance of HttpServletResponse.");
+ }
+ Object response = facesContext.getExternalContext().getResponse();
+ HttpServletResponse httpServletResponse = (HttpServletResponse) response;
+ if (httpServletResponse == null)
+ {
+ throw new IllegalStateException("Could not obtain an instance of HttpServletResponse.");
+ }
+
+ if (isResourceIdentifierExcluded(facesContext, resourceBasePath))
+ {
+ httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ String resourceName = null;
+ String libraryName = null;
+ String requestedLocalePrefix = null;
+ if (resourceBasePath.startsWith(getResourceHandlerSupport().getResourceIdentifier()))
+ {
+ //resourceName = resourceBasePath
+ // .substring(ResourceHandler.RESOURCE_IDENTIFIER.length() + 1);
+ resourceName = resourceBasePath
+ .substring(getResourceHandlerSupport().getResourceIdentifier().length());
+
+ if (resourceName.startsWith("/$"))
+ {
+ //Extract locale prefix, libraryName and resourceName
+ int from = 3;
+ int to = resourceName.indexOf('/',3);
+ requestedLocalePrefix = resourceName.substring(from,to);
+ from = to+1;
+ to = resourceName.indexOf('/', from);
+ libraryName = resourceName.substring(from, to);
+ resourceName = resourceName.substring(to+1);
+ }
+ else
+ {
+ //No special identifier used, delegate to default algorithm
+ resourceName = null;
+ //Try to get the library name using the standard form
+ //libraryName = facesContext.getExternalContext()
+ // .getRequestParameterMap().get("ln");
+ }
+ }
+ else
+ {
+ //Does not have the conditions for be a resource call, let the base one
+ //return not found
+ super.handleResourceRequest(facesContext);
+ return;
+ }
+
+ //Only resources with resourceName and advanced libraryName are handled by this handler
+ if (resourceName == null)
+ {
+ super.handleResourceRequest(facesContext);
+ return;
+ }
+ else if (libraryName == null)
+ {
+ super.handleResourceRequest(facesContext);
+ return;
+ }
+ else if (libraryName != null && getResourceHandlerSupport().getMyFacesResourcesConfig().getLibrary(libraryName) == null)
+ {
+ super.handleResourceRequest(facesContext);
+ return;
+ }
+
+ if (requestedLocalePrefix != null)
+ {
+ facesContext.getAttributes().put(RESOURCE_LOCALE, requestedLocalePrefix);
+ }
+
+ Resource resource = null;
+ //if (libraryName != null)
+ //{
+ //log.info("libraryName=" + libraryName);
+ resource = facesContext.getApplication().getResourceHandler().createResource(resourceName, libraryName);
+ //}
+ //else
+ //{
+ // resource = facesContext.getApplication().getResourceHandler().createResource(resourceName);
+ //}
+
+ if (resource == null)
+ {
+ httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ if (!resource.userAgentNeedsUpdate(facesContext))
+ {
+ httpServletResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+ return;
+ }
+
+ httpServletResponse.setContentType(_getContentType(resource, facesContext.getExternalContext()));
+
+ Map<String, String> headers = resource.getResponseHeaders();
+
+ for (Map.Entry<String, String> entry : headers.entrySet())
+ {
+ httpServletResponse.setHeader(entry.getKey(), entry.getValue());
+ }
+
+ //serve up the bytes (taken from trinidad ResourceServlet)
+ try
+ {
+ // we should serve a compressed version of the resource, if
+ // - ProjectStage != Development
+ // - a compressed version is available (created in constructor)
+ // - the user agent supports compresssion
+ // and if there is no caching on disk, do compression here!
+ if (!facesContext.isProjectStage(ProjectStage.Development) &&
+ getResourceHandlerSupport().isGzipResourcesEnabled() &&
+ !getResourceHandlerSupport().isCacheDiskGzipResources() &&
+ getResourceHandlerSupport().userAgentSupportsCompression(facesContext) &&
+ getResourceHandlerSupport().isCompressable(resource))
+ {
+ InputStream in = resource.getInputStream();
+ OutputStream out = new GZIPOutputStream(httpServletResponse.getOutputStream(), _BUFFER_SIZE);
+ byte[] buffer = new byte[_BUFFER_SIZE];
+
+ try
+ {
+ int count = pipeBytes(in, out, buffer);
+ //set the content lenght
+ httpServletResponse.setContentLength(count);
+ }
+ finally
+ {
+ try
+ {
+ in.close();
+ }
+ finally
+ {
+ out.close();
+ }
+ }
+ }
+ else
+ {
+ InputStream in = resource.getInputStream();
+ OutputStream out = httpServletResponse.getOutputStream();
+ byte[] buffer = new byte[_BUFFER_SIZE];
+
+ try
+ {
+ int count = pipeBytes(in, out, buffer);
+ //set the content lenght
+ httpServletResponse.setContentLength(count);
+ }
+ finally
+ {
+ try
+ {
+ in.close();
+ }
+ finally
+ {
+ out.close();
+ }
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ //TODO: Log using a localized message (which one?)
+ if (log.isLoggable(Level.SEVERE))
+ log.severe("Error trying to load resource " + resourceName
+ + " with library " + libraryName + " :"
+ + e.getMessage());
+ httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ }
+ }
+ catch (Throwable ex)
+ {
+ // handle the Throwable accordingly. Maybe generate an error page.
+ // FIXME we are creating a html error page for a non html request here
+ // shouln't we do something better? -=Jakob Korherr=-
+ throw new FacesException(ex);
+ //ErrorPageWriter.handleThrowable(facesContext, ex);
+ }
+ }
+
+ /**
+ * Reads the specified input stream into the provided byte array storage and
+ * writes it to the output stream.
+ */
+ private static int pipeBytes(InputStream in, OutputStream out, byte[] buffer)
+ throws IOException
+ {
+ int count = 0;
+ int length;
+
+ while ((length = (in.read(buffer))) >= 0)
+ {
+ out.write(buffer, 0, length);
+ count += length;
+ }
+ return count;
+ }
+
+ @Override
+ public boolean isResourceRequest(FacesContext facesContext)
+ {
+ // Since this method could be called many times we save it
+ //on request map so the first time is calculated it remains
+ //alive until the end of the request
+ Boolean value = (Boolean) facesContext.getAttributes().get(IS_RESOURCE_REQUEST);
+
+ if (value != null && value)
+ {
+ //return the saved value
+ return value;
+ }
+ else
+ {
+ String resourceBasePath = getResourceHandlerSupport()
+ .calculateResourceBasePath(facesContext);
+
+ if (resourceBasePath != null
+ && resourceBasePath.startsWith(getResourceHandlerSupport().getResourceIdentifier()))
+ {
+ facesContext.getAttributes().put(IS_RESOURCE_REQUEST, Boolean.TRUE);
+ return true;
+ }
+ else
+ {
+ value = super.isResourceRequest(facesContext);
+ facesContext.getAttributes().put(IS_RESOURCE_REQUEST, value);
+ return value;
+ }
+ }
+ }
+
+ protected String getLocalePrefixForLocateResource()
+ {
+ String localePrefix = null;
+ FacesContext context = FacesContext.getCurrentInstance();
+
+ String bundleName = context.getApplication().getMessageBundle();
+
+ if (null != bundleName)
+ {
+ Locale locale = context.getApplication().getViewHandler()
+ .calculateLocale(context);
+
+ ResourceBundle bundle = ResourceBundle
+ .getBundle(bundleName, locale, ClassUtils.getContextClassLoader());
+
+ if (bundle != null)
+ {
+ try
+ {
+ localePrefix = bundle.getString(ResourceHandler.LOCALE_PREFIX);
+ }
+ catch (MissingResourceException e)
+ {
+ // Ignore it and return null
+ }
+ }
+ }
+ return localePrefix;
+ }
+
+ protected boolean isResourceIdentifierExcluded(FacesContext context,
+ String resourceIdentifier)
+ {
+ String value = context.getExternalContext().getInitParameter(
+ RESOURCE_EXCLUDES_PARAM_NAME);
+ if (value == null)
+ {
+ value = RESOURCE_EXCLUDES_DEFAULT_VALUE;
+ }
+ //TODO: optimize this code
+ String[] extensions = StringUtils.splitShortString(value, ' ');
+ for (int i = 0; i < extensions.length; i++)
+ {
+ if (resourceIdentifier.endsWith(extensions[i]))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check if a library exists or not. This is done delegating
+ * to each ResourceLoader used, because each one has a different
+ * prefix and way to load resources.
+ *
+ */
+ @Override
+ public boolean libraryExists(String libraryName)
+ {
+ if (getResourceHandlerSupport().getMyFacesResourcesConfig().getLibrary(libraryName) != null)
+ {
+ String localePrefix = getLocalePrefixForLocateResource();
+
+ String pathToLib = null;
+
+ if (localePrefix != null)
+ {
+ //Check with locale
+ pathToLib = localePrefix + '/' + libraryName;
+
+ for (ResourceLoader loader : getResourceHandlerSupport()
+ .getResourceLoaders())
+ {
+ if (loader.libraryExists(pathToLib))
+ {
+ return true;
+ }
+ }
+ }
+
+ //Check without locale
+ for (ResourceLoader loader : getResourceHandlerSupport()
+ .getResourceLoaders())
+ {
+ if (loader.libraryExists(libraryName))
+ {
+ return true;
+ }
+ }
+ }
+ else
+ {
+ super.libraryExists(libraryName);
+ }
+
+ return false;
+ }
+
+ /**
+ * @param resourceHandlerSupport
+ * the resourceHandlerSupport to set
+ */
+ public void setResourceHandlerSupport(
+ ExtendedDefaultResourceHandlerSupport resourceHandlerSupport)
+ {
+ _resourceHandlerSupport = resourceHandlerSupport;
+ }
+
+ /**
+ * @return the resourceHandlerSupport
+ */
+ protected ExtendedDefaultResourceHandlerSupport getResourceHandlerSupport()
+ {
+ return _resourceHandlerSupport;
+ }
+
+ private ResourceHandlerCache getResourceLoaderCache()
+ {
+ if (_resourceHandlerCache == null)
+ _resourceHandlerCache = new ResourceHandlerCache();
+ return _resourceHandlerCache;
+ }
+
+ private String _getContentType(Resource resource, ExternalContext externalContext)
+ {
+ String contentType = resource.getContentType();
+
+ // the resource does not provide a content-type --> determine it via mime-type
+ if (contentType == null || contentType.length() == 0)
+ {
+ String resourceName = getWrappedResourceName(resource);
+
+ if (resourceName != null)
+ {
+ contentType = externalContext.getMimeType(resourceName);
+ }
+ }
+
+ return contentType;
+ }
+
+ /**
+ * Recursively unwarp the resource until we find the real resourceName
+ * This is needed because the JSF2 specced ResourceWrapper doesn't override
+ * the getResourceName() method :(
+ * @param resource
+ * @return the first non-null resourceName or <code>null</code> if none set
+ */
+ private String getWrappedResourceName(Resource resource)
+ {
+ String resourceName = resource.getResourceName();
+ if (resourceName != null)
+ {
+ return resourceName;
+ }
+
+ if (resource instanceof ResourceWrapper)
+ {
+ return getWrappedResourceName(((ResourceWrapper) resource).getWrapped());
+ }
+
+ return null;
+ }
+
+ @Override
+ public ResourceHandler getWrapped()
+ {
+ return _delegate;
+ }
}
\ No newline at end of file
Propchange: myfaces/commons/branches/jsf_20/myfaces-commons-resourcehandler/src/main/java/org/apache/myfaces/commons/resourcehandler/ExtendedResourceHandlerImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: myfaces/commons/branches/jsf_20/myfaces-commons-resourcehandler/src/main/java/org/apache/myfaces/commons/resourcehandler/ExtendedResourceImpl.java
URL: http://svn.apache.org/viewvc/myfaces/commons/branches/jsf_20/myfaces-commons-resourcehandler/src/main/java/org/apache/myfaces/commons/resourcehandler/ExtendedResourceImpl.java?rev=1186730&r1=1186729&r2=1186730&view=diff
==============================================================================
--- myfaces/commons/branches/jsf_20/myfaces-commons-resourcehandler/src/main/java/org/apache/myfaces/commons/resourcehandler/ExtendedResourceImpl.java (original)
+++ myfaces/commons/branches/jsf_20/myfaces-commons-resourcehandler/src/main/java/org/apache/myfaces/commons/resourcehandler/ExtendedResourceImpl.java Thu Oct 20 10:49:18 2011
@@ -1,323 +1,323 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.myfaces.commons.resourcehandler;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-
-import javax.el.ELContext;
-import javax.el.ELResolver;
-import javax.el.FunctionMapper;
-import javax.el.ValueExpression;
-import javax.el.VariableMapper;
-import javax.faces.application.ResourceHandler;
-import javax.faces.context.FacesContext;
-
-import org.apache.myfaces.commons.resourcehandler.config.element.Library;
-import org.apache.myfaces.commons.resourcehandler.resource.ResourceImpl;
-import org.apache.myfaces.commons.resourcehandler.resource.ResourceLoader;
-import org.apache.myfaces.commons.resourcehandler.resource.ValueExpressionFilterInputStream;
-
-/**
- *
- * @author Leonardo Uribe
- *
- */
-public class ExtendedResourceImpl extends ResourceImpl
-{
- private String _expectedLocalePrefix;
-
- private ExtendedResourceMeta _extendedResourceMeta;
-
- private ExtendedDefaultResourceHandlerSupport _extendedDefaultResourceHandlerSupport;
-
- public ExtendedResourceImpl(ExtendedResourceMeta resourceMeta,
- ResourceLoader resourceLoader, ExtendedDefaultResourceHandlerSupport support,
- String contentType, String expectedLocalePrefix, String expectedLibraryName)
- {
- super(resourceMeta, resourceLoader, support, contentType);
- _extendedResourceMeta = resourceMeta;
- _expectedLocalePrefix = expectedLocalePrefix;
- _extendedDefaultResourceHandlerSupport = support;
- if (expectedLibraryName != null)
- {
- setLibraryName(expectedLibraryName);
- }
- }
-
- @Override
- public InputStream getInputStream() throws IOException
- {
- if ( getExtendedDefaultResourceHandlerSupport().isGzipResourcesEnabled() &&
- getExtendedDefaultResourceHandlerSupport().isCacheDiskGzipResources() &&
- getExtendedDefaultResourceHandlerSupport().isCompressable(this) &&
- getExtendedDefaultResourceHandlerSupport().userAgentSupportsCompression(FacesContext.getCurrentInstance()))
- {
- //GZIPResourceLoader will take care of resources containing ValueExpressions
- return getResourceLoader().getResourceInputStream(getResourceMeta());
- }
- else
- {
- return super.getInputStream();
- }
- }
-
- @Override
- public String getRequestPath()
- {
- String mapping = getResourceHandlerSupport().getMapping() != null ?
- getResourceHandlerSupport().getMapping() :
- "" ;
-
- Library library = getExtendedDefaultResourceHandlerSupport().getMyFacesResourcesConfig().
- getLibrary(getLibraryName());
-
- if (library.getRequestPath() == null)
- {
- String localePrefix = getResourceMeta().getLocalePrefix() != null ?
- getResourceMeta().getLocalePrefix() : _expectedLocalePrefix;
- if (localePrefix == null)
- {
- // calculate current localePrefix (could be different from the one requested, e.g. on locale change)
- localePrefix = getRequestLocalePrefix();
- }
- String path = null;
- if (!getResourceHandlerSupport().isExtensionMapping())
- {
- path = mapping + getResourceHandlerSupport().getResourceIdentifier() + "/$/" +
- localePrefix + '/' +
- getLibraryName() + '/' +
- getResourceName();
- }
- else
- {
- path = getResourceHandlerSupport().getResourceIdentifier() + "/$/" +
- localePrefix + '/' +
- getLibraryName() + '/' +
- getResourceName() + mapping;
- }
-
- FacesContext facesContext = FacesContext.getCurrentInstance();
- return facesContext.getApplication().getViewHandler().getResourceURL(facesContext, path);
- }
- else
- {
- //Redirect url assume prefix mapping.
- FacesContext facesContext = FacesContext.getCurrentInstance();
- return facesContext.getApplication().getViewHandler().getResourceURL(facesContext,
- calculateRequestPath(facesContext, library.getRequestPath()));
- }
- }
-
- public String getLocalePrefix()
- {
- String localePrefix = getResourceMeta().getLocalePrefix() != null ?
- getResourceMeta().getLocalePrefix() : _expectedLocalePrefix;
- if (localePrefix == null)
- {
- // calculate current localePrefix (could be different from the one requested, e.g. on locale change)
- localePrefix = getRequestLocalePrefix();
- }
- return localePrefix;
- }
-
- private String calculateRequestPath(FacesContext context, String expression)
- {
- ValueExpression requestPath = getExtendedResourceMeta().getRequestPathExpression();
- if (requestPath == null)
- {
- ELContext elContext = new ELContextWrapper(context.getELContext(), context, this);
- requestPath = context.getApplication().getExpressionFactory().createValueExpression(
- elContext, expression, String.class);
- getExtendedResourceMeta().setRequestPathExpression(requestPath);
- }
- return (String) requestPath.getValue(context.getELContext());
- }
-
- protected ExtendedResourceMeta getExtendedResourceMeta()
- {
- return _extendedResourceMeta;
- }
-
- protected ExtendedDefaultResourceHandlerSupport getExtendedDefaultResourceHandlerSupport()
- {
- return _extendedDefaultResourceHandlerSupport;
- }
-
- @Override
- public Map<String, String> getResponseHeaders()
- {
- FacesContext facesContext = FacesContext.getCurrentInstance();
-
- if (facesContext.getApplication().getResourceHandler().isResourceRequest(facesContext))
- {
- Map<String, String> headers = super.getResponseHeaders();
-
- if (getExtendedDefaultResourceHandlerSupport().isGzipResourcesEnabled() &&
- getExtendedDefaultResourceHandlerSupport().userAgentSupportsCompression(facesContext) &&
- getExtendedDefaultResourceHandlerSupport().isCompressable(this))
- {
- headers.put("Content-Encoding", "gzip");
- }
-
- return headers;
- }
- else
- {
- //No need to return headers
- return Collections.emptyMap();
- }
- }
-
- /**
- * Returns the String representation of the current locale for the use in the request path.
- *
- * @return
- */
- private static String getRequestLocalePrefix()
- {
- FacesContext facesContext = FacesContext.getCurrentInstance();
- Locale locale = facesContext.getViewRoot().getLocale();
- if (locale == null)
- {
- // fallback to default locale
- locale = Locale.getDefault();
- }
-
- String language = locale.getLanguage();
- String country = locale.getCountry();
-
- if (country != null)
- {
- // de_AT
- return language + "_" + country;
- }
- else
- {
- // de
- return language;
- }
- }
-
- private static class ELContextWrapper extends ELContext
- {
- private ELContext _delegate;
- private VariableMapper _mapper;
-
-
- private ELContextWrapper(ELContext delegate, FacesContext context, ExtendedResourceImpl resource)
- {
- this._delegate = delegate;
- this._mapper = new VariableMapperWrapper(delegate.getVariableMapper(), context, resource);
- }
-
- public void setPropertyResolved(boolean resolved)
- {
- _delegate.setPropertyResolved(resolved);
- }
-
- public boolean isPropertyResolved()
- {
- return _delegate.isPropertyResolved();
- }
-
- public void putContext(Class key, Object contextObject)
- {
- _delegate.putContext(key, contextObject);
- }
-
- public Object getContext(Class key)
- {
- return _delegate.getContext(key);
- }
-
- public ELResolver getELResolver()
- {
- return _delegate.getELResolver();
- }
-
- public FunctionMapper getFunctionMapper()
- {
- return _delegate.getFunctionMapper();
- }
-
- public Locale getLocale()
- {
- return _delegate.getLocale();
- }
-
- public void setLocale(Locale locale)
- {
- _delegate.setLocale(locale);
- }
-
- public VariableMapper getVariableMapper()
- {
- return _mapper;
- }
- }
-
- private static class VariableMapperWrapper extends VariableMapper
- {
- private VariableMapper delegate;
-
- private Map<String, ValueExpression> map;
-
- private VariableMapperWrapper(VariableMapper delegate, FacesContext context, ExtendedResourceImpl resource)
- {
- this.delegate = delegate;
- map = new HashMap<String, ValueExpression>(4,1);
- map.put("localePrefix", context.getApplication().getExpressionFactory().createValueExpression(resource.getLocalePrefix(), String.class));
- map.put("libraryName", context.getApplication().getExpressionFactory().createValueExpression(resource.getLibraryName(), String.class));
- map.put("resourceName", context.getApplication().getExpressionFactory().createValueExpression(resource.getResourceName(), String.class));
- map.put("mapping", context.getApplication().getExpressionFactory().createValueExpression(
- resource.getExtendedDefaultResourceHandlerSupport().getMapping(), String.class));
- map.put("extensionMapping", context.getApplication().getExpressionFactory().createValueExpression(
- resource.getExtendedDefaultResourceHandlerSupport().isExtensionMapping(), Boolean.class));
- }
-
- public ValueExpression resolveVariable(String variable)
- {
- ValueExpression value = map.get(variable);
- if (value != null)
- {
- return value;
- }
- if (delegate != null)
- {
- return delegate.resolveVariable(variable);
- }
- return null;
- }
-
- public ValueExpression setVariable(String variable,
- ValueExpression expression)
- {
- if (delegate != null)
- {
- return delegate.setVariable(variable, expression);
- }
- return null;
- }
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.commons.resourcehandler;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.el.FunctionMapper;
+import javax.el.ValueExpression;
+import javax.el.VariableMapper;
+import javax.faces.application.ResourceHandler;
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.commons.resourcehandler.config.element.Library;
+import org.apache.myfaces.commons.resourcehandler.resource.ResourceImpl;
+import org.apache.myfaces.commons.resourcehandler.resource.ResourceLoader;
+import org.apache.myfaces.commons.resourcehandler.resource.ValueExpressionFilterInputStream;
+
+/**
+ *
+ * @author Leonardo Uribe
+ *
+ */
+public class ExtendedResourceImpl extends ResourceImpl
+{
+ private String _expectedLocalePrefix;
+
+ private ExtendedResourceMeta _extendedResourceMeta;
+
+ private ExtendedDefaultResourceHandlerSupport _extendedDefaultResourceHandlerSupport;
+
+ public ExtendedResourceImpl(ExtendedResourceMeta resourceMeta,
+ ResourceLoader resourceLoader, ExtendedDefaultResourceHandlerSupport support,
+ String contentType, String expectedLocalePrefix, String expectedLibraryName)
+ {
+ super(resourceMeta, resourceLoader, support, contentType);
+ _extendedResourceMeta = resourceMeta;
+ _expectedLocalePrefix = expectedLocalePrefix;
+ _extendedDefaultResourceHandlerSupport = support;
+ if (expectedLibraryName != null)
+ {
+ setLibraryName(expectedLibraryName);
+ }
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException
+ {
+ if ( getExtendedDefaultResourceHandlerSupport().isGzipResourcesEnabled() &&
+ getExtendedDefaultResourceHandlerSupport().isCacheDiskGzipResources() &&
+ getExtendedDefaultResourceHandlerSupport().isCompressable(this) &&
+ getExtendedDefaultResourceHandlerSupport().userAgentSupportsCompression(FacesContext.getCurrentInstance()))
+ {
+ //GZIPResourceLoader will take care of resources containing ValueExpressions
+ return getResourceLoader().getResourceInputStream(getResourceMeta());
+ }
+ else
+ {
+ return super.getInputStream();
+ }
+ }
+
+ @Override
+ public String getRequestPath()
+ {
+ String mapping = getResourceHandlerSupport().getMapping() != null ?
+ getResourceHandlerSupport().getMapping() :
+ "" ;
+
+ Library library = getExtendedDefaultResourceHandlerSupport().getMyFacesResourcesConfig().
+ getLibrary(getLibraryName());
+
+ if (library.getRequestPath() == null)
+ {
+ String localePrefix = getResourceMeta().getLocalePrefix() != null ?
+ getResourceMeta().getLocalePrefix() : _expectedLocalePrefix;
+ if (localePrefix == null)
+ {
+ // calculate current localePrefix (could be different from the one requested, e.g. on locale change)
+ localePrefix = getRequestLocalePrefix();
+ }
+ String path = null;
+ if (!getResourceHandlerSupport().isExtensionMapping())
+ {
+ path = mapping + getResourceHandlerSupport().getResourceIdentifier() + "/$/" +
+ localePrefix + '/' +
+ getLibraryName() + '/' +
+ getResourceName();
+ }
+ else
+ {
+ path = getResourceHandlerSupport().getResourceIdentifier() + "/$/" +
+ localePrefix + '/' +
+ getLibraryName() + '/' +
+ getResourceName() + mapping;
+ }
+
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ return facesContext.getApplication().getViewHandler().getResourceURL(facesContext, path);
+ }
+ else
+ {
+ //Redirect url assume prefix mapping.
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ return facesContext.getApplication().getViewHandler().getResourceURL(facesContext,
+ calculateRequestPath(facesContext, library.getRequestPath()));
+ }
+ }
+
+ public String getLocalePrefix()
+ {
+ String localePrefix = getResourceMeta().getLocalePrefix() != null ?
+ getResourceMeta().getLocalePrefix() : _expectedLocalePrefix;
+ if (localePrefix == null)
+ {
+ // calculate current localePrefix (could be different from the one requested, e.g. on locale change)
+ localePrefix = getRequestLocalePrefix();
+ }
+ return localePrefix;
+ }
+
+ private String calculateRequestPath(FacesContext context, String expression)
+ {
+ ValueExpression requestPath = getExtendedResourceMeta().getRequestPathExpression();
+ if (requestPath == null)
+ {
+ ELContext elContext = new ELContextWrapper(context.getELContext(), context, this);
+ requestPath = context.getApplication().getExpressionFactory().createValueExpression(
+ elContext, expression, String.class);
+ getExtendedResourceMeta().setRequestPathExpression(requestPath);
+ }
+ return (String) requestPath.getValue(context.getELContext());
+ }
+
+ protected ExtendedResourceMeta getExtendedResourceMeta()
+ {
+ return _extendedResourceMeta;
+ }
+
+ protected ExtendedDefaultResourceHandlerSupport getExtendedDefaultResourceHandlerSupport()
+ {
+ return _extendedDefaultResourceHandlerSupport;
+ }
+
+ @Override
+ public Map<String, String> getResponseHeaders()
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+
+ if (facesContext.getApplication().getResourceHandler().isResourceRequest(facesContext))
+ {
+ Map<String, String> headers = super.getResponseHeaders();
+
+ if (getExtendedDefaultResourceHandlerSupport().isGzipResourcesEnabled() &&
+ getExtendedDefaultResourceHandlerSupport().userAgentSupportsCompression(facesContext) &&
+ getExtendedDefaultResourceHandlerSupport().isCompressable(this))
+ {
+ headers.put("Content-Encoding", "gzip");
+ }
+
+ return headers;
+ }
+ else
+ {
+ //No need to return headers
+ return Collections.emptyMap();
+ }
+ }
+
+ /**
+ * Returns the String representation of the current locale for the use in the request path.
+ *
+ * @return
+ */
+ private static String getRequestLocalePrefix()
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ Locale locale = facesContext.getViewRoot().getLocale();
+ if (locale == null)
+ {
+ // fallback to default locale
+ locale = Locale.getDefault();
+ }
+
+ String language = locale.getLanguage();
+ String country = locale.getCountry();
+
+ if (country != null)
+ {
+ // de_AT
+ return language + "_" + country;
+ }
+ else
+ {
+ // de
+ return language;
+ }
+ }
+
+ private static class ELContextWrapper extends ELContext
+ {
+ private ELContext _delegate;
+ private VariableMapper _mapper;
+
+
+ private ELContextWrapper(ELContext delegate, FacesContext context, ExtendedResourceImpl resource)
+ {
+ this._delegate = delegate;
+ this._mapper = new VariableMapperWrapper(delegate.getVariableMapper(), context, resource);
+ }
+
+ public void setPropertyResolved(boolean resolved)
+ {
+ _delegate.setPropertyResolved(resolved);
+ }
+
+ public boolean isPropertyResolved()
+ {
+ return _delegate.isPropertyResolved();
+ }
+
+ public void putContext(Class key, Object contextObject)
+ {
+ _delegate.putContext(key, contextObject);
+ }
+
+ public Object getContext(Class key)
+ {
+ return _delegate.getContext(key);
+ }
+
+ public ELResolver getELResolver()
+ {
+ return _delegate.getELResolver();
+ }
+
+ public FunctionMapper getFunctionMapper()
+ {
+ return _delegate.getFunctionMapper();
+ }
+
+ public Locale getLocale()
+ {
+ return _delegate.getLocale();
+ }
+
+ public void setLocale(Locale locale)
+ {
+ _delegate.setLocale(locale);
+ }
+
+ public VariableMapper getVariableMapper()
+ {
+ return _mapper;
+ }
+ }
+
+ private static class VariableMapperWrapper extends VariableMapper
+ {
+ private VariableMapper delegate;
+
+ private Map<String, ValueExpression> map;
+
+ private VariableMapperWrapper(VariableMapper delegate, FacesContext context, ExtendedResourceImpl resource)
+ {
+ this.delegate = delegate;
+ map = new HashMap<String, ValueExpression>(4,1);
+ map.put("localePrefix", context.getApplication().getExpressionFactory().createValueExpression(resource.getLocalePrefix(), String.class));
+ map.put("libraryName", context.getApplication().getExpressionFactory().createValueExpression(resource.getLibraryName(), String.class));
+ map.put("resourceName", context.getApplication().getExpressionFactory().createValueExpression(resource.getResourceName(), String.class));
+ map.put("mapping", context.getApplication().getExpressionFactory().createValueExpression(
+ resource.getExtendedDefaultResourceHandlerSupport().getMapping(), String.class));
+ map.put("extensionMapping", context.getApplication().getExpressionFactory().createValueExpression(
+ resource.getExtendedDefaultResourceHandlerSupport().isExtensionMapping(), Boolean.class));
+ }
+
+ public ValueExpression resolveVariable(String variable)
+ {
+ ValueExpression value = map.get(variable);
+ if (value != null)
+ {
+ return value;
+ }
+ if (delegate != null)
+ {
+ return delegate.resolveVariable(variable);
+ }
+ return null;
+ }
+
+ public ValueExpression setVariable(String variable,
+ ValueExpression expression)
+ {
+ if (delegate != null)
+ {
+ return delegate.setVariable(variable, expression);
+ }
+ return null;
+ }
+ }
+}
Propchange: myfaces/commons/branches/jsf_20/myfaces-commons-resourcehandler/src/main/java/org/apache/myfaces/commons/resourcehandler/ExtendedResourceImpl.java
------------------------------------------------------------------------------
svn:eol-style = native