| /* |
| * 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.test.mock.resource; |
| |
| import java.io.IOException; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.security.AccessController; |
| import java.security.PrivilegedActionException; |
| import java.security.PrivilegedExceptionAction; |
| import java.util.Locale; |
| import java.util.MissingResourceException; |
| import java.util.ResourceBundle; |
| |
| import javax.faces.FacesException; |
| import javax.faces.application.Resource; |
| import javax.faces.application.ResourceHandler; |
| import javax.faces.context.FacesContext; |
| |
| /** |
| * <p>Mock implementation of <code>ResourceHandler</code>.</p> |
| * <p>This ResourceHandler implementation try to follow the default algorithm |
| * defined by the spec, so it try to load resources using the current |
| * ExternalContext and the specified ClassLoader, in the same locations |
| * it is expected ("resources" and "META-INF/resources").</p> |
| * |
| * @author Leonardo Uribe (latest modification by $Author$) |
| * @version $Revision$ $Date$ |
| */ |
| public class MockResourceHandler extends ResourceHandler |
| { |
| |
| private boolean _resourceRequest; |
| |
| private MockResourceHandlerSupport resourceHandlerSupport; |
| |
| private ClassLoader _classLoader; |
| |
| public MockResourceHandler() |
| { |
| _classLoader = getContextClassLoader(); |
| resourceHandlerSupport = new MockResourceHandlerSupport(true, ".jsf",_classLoader); |
| } |
| |
| public MockResourceHandler(ClassLoader classLoader) |
| { |
| if (classLoader == null) |
| _classLoader = getContextClassLoader(); |
| else |
| _classLoader = classLoader; |
| |
| resourceHandlerSupport = new MockResourceHandlerSupport(true, ".jsf",_classLoader); |
| } |
| |
| public MockResourceHandler(boolean extensionMapping, String mapping, ClassLoader classLoader) |
| { |
| if (classLoader == null) |
| _classLoader = getContextClassLoader(); |
| else |
| _classLoader = classLoader; |
| |
| resourceHandlerSupport = new MockResourceHandlerSupport(extensionMapping, mapping,_classLoader); |
| } |
| |
| @Override |
| public Resource createResource(String resourceName) |
| { |
| return createResource(resourceName, null); |
| } |
| |
| @Override |
| public Resource createResource(String resourceName, String libraryName) |
| { |
| return createResource(resourceName, libraryName, null); |
| } |
| |
| @Override |
| public Resource createResource(String resourceName, String libraryName, String contentType) |
| { |
| Resource resource = null; |
| |
| if (contentType == null) |
| { |
| //Resolve contentType using ExternalContext.getMimeType |
| contentType = FacesContext.getCurrentInstance().getExternalContext().getMimeType(resourceName); |
| } |
| |
| for (MockResourceLoader loader : getResourceHandlerSupport() |
| .getResourceLoaders()) |
| { |
| MockResourceMeta resourceMeta = deriveResourceMeta(loader, |
| resourceName, libraryName); |
| |
| if (resourceMeta != null) |
| { |
| resource = new MockResource(resourceMeta, loader, |
| getResourceHandlerSupport(), contentType); |
| break; |
| } |
| } |
| return resource; |
| } |
| |
| /** |
| * 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 MockResourceMeta deriveResourceMeta(MockResourceLoader resourceLoader, |
| String resourceName, String libraryName) |
| { |
| String localePrefix = getLocalePrefixForLocateResource(); |
| String resourceVersion = null; |
| String libraryVersion = null; |
| MockResourceMeta 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 && MockResourceLoader.VERSION_INVALID.equals(resourceVersion))) |
| { |
| resourceId = resourceLoader.createResourceMeta(localePrefix, libraryName, |
| libraryVersion, resourceName, resourceVersion); |
| } |
| } |
| else |
| { |
| resourceVersion = resourceLoader |
| .getResourceVersion(localePrefix + '/'+ resourceName); |
| if (!(resourceVersion != null && MockResourceLoader.VERSION_INVALID.equals(resourceVersion))) |
| { |
| resourceId = resourceLoader.createResourceMeta(localePrefix, null, null, |
| resourceName, resourceVersion); |
| } |
| } |
| |
| if (resourceId != null) |
| { |
| URL url = resourceLoader.getResourceURL(resourceId); |
| if (url == null) |
| { |
| 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 && MockResourceLoader.VERSION_INVALID.equals(resourceVersion))) |
| { |
| resourceId = resourceLoader.createResourceMeta(null, libraryName, |
| libraryVersion, resourceName, resourceVersion); |
| } |
| } |
| else |
| { |
| resourceVersion = resourceLoader |
| .getResourceVersion(resourceName); |
| |
| if (!(resourceVersion != null && MockResourceLoader.VERSION_INVALID.equals(resourceVersion))) |
| { |
| resourceId = resourceLoader.createResourceMeta(null, null, null, |
| resourceName, resourceVersion); |
| } |
| } |
| |
| if (resourceId != null) |
| { |
| URL url = resourceLoader.getResourceURL(resourceId); |
| if (url == null) |
| { |
| resourceId = null; |
| } |
| } |
| } |
| |
| return resourceId; |
| } |
| |
| @Override |
| public String getRendererTypeForResourceName(String resourceName) |
| { |
| if (resourceName.endsWith(".js")) { |
| return "javax.faces.resource.Script"; |
| } |
| else if (resourceName.endsWith(".css")) { |
| return "javax.faces.resource.Stylesheet"; |
| } |
| return null; |
| } |
| |
| @Override |
| public void handleResourceRequest(FacesContext context) throws IOException |
| { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public boolean isResourceRequest(FacesContext facesContext) |
| { |
| return _resourceRequest; |
| } |
| |
| @Override |
| public boolean libraryExists(String libraryName) |
| { |
| String localePrefix = getLocalePrefixForLocateResource(); |
| |
| String pathToLib; |
| |
| if (localePrefix != null) { |
| //Check with locale |
| pathToLib = localePrefix + '/' + libraryName; |
| } |
| else { |
| pathToLib = libraryName; |
| } |
| |
| try { |
| URL url = FacesContext.getCurrentInstance().getExternalContext().getResource("/" + pathToLib); |
| return (url != null); |
| } |
| catch (MalformedURLException e) { |
| return false; |
| } |
| } |
| |
| 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, getContextClassLoader()); |
| |
| if (bundle != null) { |
| try { |
| localePrefix = bundle.getString(ResourceHandler.LOCALE_PREFIX); |
| } |
| catch (MissingResourceException e) { |
| // Ignore it and return null |
| } |
| } |
| } |
| return localePrefix; |
| } |
| |
| /** |
| * Gets the ClassLoader associated with the current thread. Includes a check for priviledges |
| * against java2 security to ensure no security related exceptions are encountered. |
| * |
| * @return ClassLoader |
| */ |
| static ClassLoader getContextClassLoader() |
| { |
| if (System.getSecurityManager() != null) { |
| try { |
| ClassLoader cl = AccessController.doPrivileged(new PrivilegedExceptionAction<ClassLoader>() |
| { |
| public ClassLoader run() throws PrivilegedActionException |
| { |
| return Thread.currentThread().getContextClassLoader(); |
| } |
| }); |
| return cl; |
| } |
| catch (PrivilegedActionException pae) { |
| throw new FacesException(pae); |
| } |
| } |
| else { |
| return Thread.currentThread().getContextClassLoader(); |
| } |
| } |
| |
| public MockResourceHandlerSupport getResourceHandlerSupport() |
| { |
| return resourceHandlerSupport; |
| } |
| |
| public void setResourceHandlerSupport( |
| MockResourceHandlerSupport resourceHandlerSupport) |
| { |
| this.resourceHandlerSupport = resourceHandlerSupport; |
| } |
| |
| public void setResourceRequest(boolean resourceRequest) |
| { |
| this._resourceRequest = resourceRequest; |
| } |
| |
| public boolean isResourceRequest() |
| { |
| return _resourceRequest; |
| } |
| } |