ResourceLookup.java revision fc407e8870fb0f64f1be3c0aa456b2ab135bcec9
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk/**
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk *
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk *
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * The contents of this file are subject to the terms
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * of the Common Development and Distribution License
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * (the License). You may not use this file except in
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * compliance with the License.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk *
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * You can obtain a copy of the License at
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * https://opensso.dev.java.net/public/CDDLv1.0.html or
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * opensso/legal/CDDLv1.0.txt
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * See the License for the specific language governing
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * permission and limitations under the License.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk *
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * When distributing Covered Code, include this CDDL
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Header Notice in each file and include the License file
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * at opensso/legal/CDDLv1.0.txt.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * If applicable, add the following below the CDDL Header,
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * with the fields enclosed by brackets [] replaced by
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * your own identifying information:
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * "Portions Copyrighted [year] [name of copyright owner]"
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk *
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * $Id: ResourceLookup.java,v 1.7 2009/05/02 22:12:04 kevinserwin Exp $
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk *
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Portions Copyrighted 2014 ForgeRock AS
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkpackage com.sun.identity.common;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.iplanet.am.util.SystemProperties;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.shared.Constants;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.shared.debug.Debug;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.shared.search.FileLookup;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.shared.search.FileLookupException;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport java.io.File;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport java.net.MalformedURLException;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport java.net.URL;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport java.util.concurrent.ConcurrentHashMap;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport java.util.concurrent.ConcurrentMap;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport javax.servlet.ServletContext;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk/**
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * ResourceLookup is a partial replacement for implementation of FileLookup. It
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * performs the equivalent of "fstat" using ServletContext.getResource(), thus
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * increasing web container independence.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkpublic class ResourceLookup {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private static final ConcurrentMap<String, String> RESOURCE_NAME_CACHE;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private static final boolean CACHE_ENABLED;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private static final Debug DEBUG = Debug.getInstance("amResourceLookup");
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk static {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk CACHE_ENABLED = SystemProperties.getAsBoolean(Constants.RESOURCE_LOOKUP_CACHE_ENABLED, true);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk if (CACHE_ENABLED) {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk RESOURCE_NAME_CACHE = new ConcurrentHashMap<String, String>();
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk } else {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk RESOURCE_NAME_CACHE = null;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /**
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Returns the first existing resource in the ordered search paths.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk *
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * @param context Servlet Context Reference.
* @param fileRoot
* @param locale
* @param orgFilePath
* @param clientPath
* @param filename
* @param resourceDir absolute path of template base directory
* @return <code>String</code> first existing resource in the ordered
* search paths.
*/
public static String getFirstExisting(ServletContext context,
String fileRoot, String locale, String orgFilePath,
String clientPath, String filename, String resourceDir) {
String resourceName = null;
String cacheKey = new StringBuffer(fileRoot).append(":").append(locale)
.append(":").append(orgFilePath).append(":").append(clientPath)
.append(":").append(filename).append(":").append(resourceDir)
.toString();
if (CACHE_ENABLED) {
resourceName = RESOURCE_NAME_CACHE.get(cacheKey);
if (resourceName != null) {
return resourceName;
}
}
URL resourceUrl = null;
// calls FileLookup to get the file paths to locate file
try {
File[] orderedPaths = FileLookup.getOrderedPaths(fileRoot, locale,
null, orgFilePath, clientPath, filename);
for (File orderedPath : orderedPaths) {
resourceName = resourceDir + Constants.FILE_SEPARATOR + orderedPath.toString();
resourceName = resourceName.replaceAll("\\\\", "/");
if ((resourceUrl = getResourceURL(context, resourceName)) != null) {
break;
}
}
} catch (FileLookupException fe) {
DEBUG.message("ResourceLookup.getFirstExisting: ", fe);
}
if (DEBUG.messageEnabled()) {
DEBUG.message("amResourceLookup: resourceURL: " + resourceUrl);
DEBUG.message("amResourceLookup: resourceName: " + resourceName);
}
if (resourceUrl != null) {
if (CACHE_ENABLED) {
RESOURCE_NAME_CACHE.put(cacheKey, resourceName);
}
} else {
resourceName = null;
}
return resourceName;
}
/* returns the resourceURL for the resource name for the request */
private static URL getResourceURL(ServletContext context, String resourceName) {
URL resourceURL = null;
try {
if (context != null) {
resourceURL = context.getResource(resourceName);
}
//Only try to lookup XMLs from the classpath as UI files from JAR files cannot be used by RequestDispatcher
if (resourceURL == null && resourceName.endsWith(".xml")) {
// remove leading '/' from resourceName
resourceURL = Thread.currentThread().getContextClassLoader().getResource(resourceName.substring(1));
}
} catch (MalformedURLException murle) {
DEBUG.message("Error getting resource: " + resourceURL + " cause: " + murle.getMessage());
}
return resourceURL;
}
}