| /* |
| * 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.tobago.internal.context; |
| |
| import org.apache.myfaces.tobago.application.ProjectStage; |
| import org.apache.myfaces.tobago.component.RendererTypes; |
| import org.apache.myfaces.tobago.config.Configurable; |
| import org.apache.myfaces.tobago.context.Markup; |
| import org.apache.myfaces.tobago.context.ResourceManager; |
| import org.apache.myfaces.tobago.context.Theme; |
| import org.apache.myfaces.tobago.context.UserAgent; |
| import org.apache.myfaces.tobago.internal.config.TobagoConfigImpl; |
| import org.apache.myfaces.tobago.layout.Measure; |
| import org.apache.myfaces.tobago.util.LocaleUtils; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import javax.faces.component.UIViewRoot; |
| import javax.faces.context.FacesContext; |
| import javax.faces.render.Renderer; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.concurrent.ConcurrentHashMap; |
| |
| public class ResourceManagerImpl implements ResourceManager { |
| |
| private static final Logger LOG = LoggerFactory.getLogger(ResourceManagerImpl.class); |
| private static final String PROPERTY = "property"; |
| private static final String JSP = "jsp"; |
| private static final String TAG = "tag"; |
| private static final String MINIMIZE_SUFFIX = ".min"; |
| |
| public static final String[] EXT_NONE = new String[]{""}; |
| public static final String[] EXT_JS = new String[]{".js"}; |
| public static final String[] EXT_CSS = new String[]{".css"}; |
| public static final String[] EXT_GIF = new String[]{".gif"}; |
| public static final String[] EXT_PNG = new String[]{".png"}; |
| public static final String[] EXT_JPG = new String[]{".jpg"}; |
| public static final String[] EXT_ICO = new String[]{".ico"}; |
| public static final String[] EXT_IMAGES = new String[]{".svg", ".png", ".gif", ".jpg"}; |
| public static final String[] EXT_JSP = new String[]{".jsp"}; |
| public static final String[] EXT_JSPX = new String[]{".jspx"}; |
| public static final String[] EXT_XHTML = new String[]{".xhtml"}; |
| public static final String[] EXT_SVG = new String[]{".svg"}; |
| |
| private boolean production; |
| |
| private final Map<String, String> resourceList |
| = new ConcurrentHashMap<String, String>(100, 0.75f, 1); |
| |
| private final Map<RendererCacheKey, Renderer> rendererCache |
| = new ConcurrentHashMap<RendererCacheKey, Renderer>(100, 0.75f, 1); |
| private final Map<ImageCacheKey, StringValue> imageCache |
| = new ConcurrentHashMap<ImageCacheKey, StringValue>(100, 0.75f, 1); |
| private final Map<JspCacheKey, String> jspCache |
| = new ConcurrentHashMap<JspCacheKey, String>(100, 0.75f, 1); |
| private final Map<MiscCacheKey, String[]> miscCache |
| = new ConcurrentHashMap<MiscCacheKey, String[]>(100, 0.75f, 1); |
| private final Map<PropertyCacheKey, StringValue> propertyCache |
| = new ConcurrentHashMap<PropertyCacheKey, StringValue>(100, 0.75f, 1); |
| private final Map<ThemeConfigCacheKey, MeasureValue> themeCache |
| = new ConcurrentHashMap<ThemeConfigCacheKey, MeasureValue>(100, 0.75f, 1); |
| private final Map<String, String[]> extensionCache |
| = new ConcurrentHashMap<String, String[]>(10, 0.75f, 1); |
| |
| private TobagoConfigImpl tobagoConfig; |
| |
| public ResourceManagerImpl(final TobagoConfigImpl tobagoConfig) { |
| this.tobagoConfig = tobagoConfig; |
| this.production = tobagoConfig.getProjectStage() == ProjectStage.Production; |
| |
| extensionCache.put("", EXT_NONE); |
| extensionCache.put(".js", EXT_JS); |
| extensionCache.put(".css", EXT_CSS); |
| extensionCache.put(".gif", EXT_GIF); |
| extensionCache.put(".png", EXT_PNG); |
| extensionCache.put(".jpg", EXT_JPG); |
| extensionCache.put(".ico", EXT_ICO); |
| extensionCache.put(".jsp", EXT_JSP); |
| extensionCache.put(".jspx", EXT_JSPX); |
| extensionCache.put(".xhtml", EXT_XHTML); |
| extensionCache.put(".svg", EXT_SVG); |
| } |
| |
| public void add(final String resourceKey) { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("adding resourceKey = '{}'", resourceKey); |
| } |
| resourceList.put(resourceKey, ""); |
| } |
| |
| public void add(final String resourceKey, final String value) { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("adding resourceKey = '{}' value= '{}'", resourceKey, value); |
| } |
| resourceList.put(resourceKey, value); |
| } |
| |
| /** |
| * @deprecated by API |
| */ |
| @Deprecated |
| public String getJsp(final UIViewRoot viewRoot, final String name) { |
| String result = null; |
| if (name != null) { |
| |
| final ClientPropertiesKey clientKey = ClientPropertiesKey.get(FacesContext.getCurrentInstance()); |
| final JspCacheKey cacheKey = new JspCacheKey(clientKey, name); |
| |
| result = jspCache.get(cacheKey); |
| if (result != null) { |
| return result; |
| } |
| try { |
| result = (String) getPaths(clientKey, |
| JSP, name, EXT_NONE, false, true, true, null, true, false).get(0); |
| jspCache.put(cacheKey, result); |
| } catch (final Exception e) { |
| LOG.error("name = '" + name + "' clientProperties = '" + clientKey.toString() + "'", e); |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @deprecated by API |
| */ |
| @Deprecated |
| public String getProperty(final UIViewRoot viewRoot, final String bundle, final String propertyKey) { |
| return getProperty(FacesContext.getCurrentInstance(), bundle, propertyKey); |
| } |
| |
| public String getProperty(final FacesContext facesContext, final String bundle, final String propertyKey) { |
| |
| if (bundle != null && propertyKey != null) { |
| final ClientPropertiesKey clientKey = ClientPropertiesKey.get(facesContext); |
| final PropertyCacheKey cacheKey = new PropertyCacheKey(clientKey, bundle, propertyKey); |
| |
| StringValue result = propertyCache.get(cacheKey); |
| if (result == null) { |
| final List properties |
| = getPaths(clientKey, PROPERTY, bundle, EXT_NONE, false, true, false, propertyKey, true, false); |
| if (properties != null) { |
| result = new StringValue((String) properties.get(0)); |
| } else { |
| result = StringValue.NULL; |
| } |
| propertyCache.put(cacheKey, result); |
| } |
| return result.getValue(); |
| } |
| return null; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @deprecated by API |
| */ |
| @Deprecated |
| public Renderer getRenderer(final UIViewRoot viewRoot, final String rendererType) { |
| return getRenderer(FacesContext.getCurrentInstance(), rendererType); |
| } |
| |
| public Renderer getRenderer(final FacesContext facesContext, final String rendererType) { |
| Renderer renderer = null; |
| |
| if (rendererType != null) { |
| final ClientPropertiesKey clientKey = ClientPropertiesKey.get(facesContext); |
| final RendererCacheKey cacheKey = new RendererCacheKey(clientKey, rendererType); |
| |
| renderer = rendererCache.get(cacheKey); |
| if (renderer != null) { |
| return renderer; |
| } |
| String simpleClassName = null; |
| try { |
| simpleClassName = getRendererClassName(rendererType); |
| final List<Class> classes |
| = getPaths(clientKey, TAG, simpleClassName, EXT_NONE, false, true, true, null, false, false); |
| if (classes != null && !classes.isEmpty()) { |
| final Class clazz = classes.get(0); |
| renderer = (Renderer) clazz.newInstance(); |
| rendererCache.put(cacheKey, renderer); |
| } else { |
| LOG.error("Don't find any RendererClass for " + simpleClassName + ". Please check you configuration."); |
| } |
| } catch (final InstantiationException e) { |
| LOG.error("name = '" + simpleClassName + "' clientProperties = '" + clientKey.toString() + "'", e); |
| } catch (final IllegalAccessException e) { |
| LOG.error("name = '" + simpleClassName + "' clientProperties = '" + clientKey.toString() + "'", e); |
| } |
| } |
| return renderer; |
| } |
| |
| /** |
| * @deprecated by API |
| */ |
| @Deprecated |
| public String[] getScripts(final UIViewRoot viewRoot, final String name) { |
| return getScripts(FacesContext.getCurrentInstance(), name); |
| } |
| |
| public String[] getScripts(final FacesContext facesContext, final String name) { |
| return getStrings(facesContext, name, null); |
| } |
| |
| /** |
| * @deprecated by API |
| */ |
| @Deprecated |
| public String[] getStyles(final UIViewRoot viewRoot, final String name) { |
| return getStyles(FacesContext.getCurrentInstance(), name); |
| } |
| |
| public String[] getStyles(final FacesContext facesContext, final String name) { |
| return getStrings(facesContext, name, null); |
| } |
| |
| /** |
| * @deprecated by API |
| */ |
| @Deprecated |
| public String getThemeProperty(final UIViewRoot viewRoot, final String bundle, final String propertyKey) { |
| if (bundle != null && propertyKey != null) { |
| |
| final ClientPropertiesKey clientKey = ClientPropertiesKey.get(FacesContext.getCurrentInstance()); |
| final PropertyCacheKey cacheKey = new PropertyCacheKey(clientKey, bundle, propertyKey); |
| |
| StringValue result = propertyCache.get(cacheKey); |
| if (result == null) { |
| final List properties |
| = getPaths(clientKey, PROPERTY, bundle, EXT_NONE, false, true, false, propertyKey, true, true); |
| if (properties != null) { |
| result = new StringValue((String) properties.get(0)); |
| } else { |
| result = StringValue.NULL; |
| } |
| propertyCache.put(cacheKey, result); |
| } |
| return result.getValue(); |
| } |
| return null; |
| } |
| |
| public Measure getThemeMeasure(final FacesContext facesContext, final Configurable configurable, final String name) { |
| return getThemeMeasure(facesContext, configurable.getRendererType(), configurable.getCurrentMarkup(), name); |
| } |
| |
| public Measure getThemeMeasure( |
| final FacesContext facesContext, final String rendererType, final Markup markup, final String name) { |
| |
| final ClientPropertiesKey clientKey = ClientPropertiesKey.get(facesContext); |
| final ThemeConfigCacheKey cacheKey = new ThemeConfigCacheKey(clientKey, rendererType, markup, name); |
| |
| MeasureValue result = themeCache.get(cacheKey); |
| |
| if (result == null) { |
| final List properties = getPaths(clientKey, PROPERTY, "tobago-theme-config", EXT_NONE, |
| false, true, false, rendererType + "." + name, true, true); |
| |
| Measure measure = null; |
| if (properties != null) { |
| measure = Measure.valueOf(properties.get(0)); |
| } |
| |
| if (markup != null) { |
| for (final String m : markup) { |
| final List mProperties = getPaths(clientKey, PROPERTY, "tobago-theme-config", EXT_NONE, |
| false, true, false, rendererType + "[" + m + "]" + "." + name, true, true); |
| if (mProperties != null) { |
| final Measure summand = Measure.valueOf(mProperties.get(0)); |
| measure = summand.add(measure); |
| } |
| } |
| } |
| |
| if (measure != null) { |
| result = new MeasureValue(measure); |
| } else { |
| result = MeasureValue.NULL; // to mark and cache that this value is undefined. |
| } |
| themeCache.put(cacheKey, result); |
| } |
| return result.getValue(); |
| } |
| |
| /** |
| * @deprecated by API |
| */ |
| @Deprecated |
| public String getImage(final UIViewRoot viewRoot, final String name) { |
| return getImage(FacesContext.getCurrentInstance(), name); |
| } |
| |
| /** |
| * @deprecated by API |
| */ |
| @Deprecated |
| public String getImage(final FacesContext facesContext, final String name) { |
| return getImage(facesContext, name, false); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @deprecated by API |
| */ |
| @Deprecated |
| public String getImage(final UIViewRoot viewRoot, final String name, final boolean ignoreMissing) { |
| return getImage(FacesContext.getCurrentInstance(), name, ignoreMissing); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @deprecated by API |
| */ |
| @Deprecated |
| public String getImage( |
| final FacesContext facesContext, final String nameWithExtension, final boolean ignoreMissing) { |
| if (nameWithExtension != null) { |
| int dot = nameWithExtension.lastIndexOf('.'); |
| if (dot == -1) { |
| dot = nameWithExtension.length(); |
| } |
| return |
| getImage(facesContext, nameWithExtension.substring(0, dot), nameWithExtension.substring(dot), ignoreMissing); |
| } |
| return null; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public String getImage( |
| final FacesContext facesContext, final String name, final String extension, final boolean ignoreMissing) { |
| if (name != null) { |
| final String[] extensions; |
| if (extension == null) { |
| extensions = EXT_IMAGES; |
| } else { |
| extensions = getExtensions(extension); |
| } |
| |
| final ClientPropertiesKey clientKey = ClientPropertiesKey.get(facesContext); |
| final ImageCacheKey cacheKey = new ImageCacheKey(clientKey, name, extension); |
| |
| StringValue result = imageCache.get(cacheKey); |
| if (result == null) { |
| final List paths |
| = getPaths(clientKey, null, name, extensions, false, true, true, null, true, ignoreMissing); |
| if (paths != null) { |
| result = new StringValue((String) paths.get(0)); |
| } else { |
| result = StringValue.NULL; |
| } |
| imageCache.put(cacheKey, result); |
| } |
| if (LOG.isDebugEnabled()) { |
| if (result.getValue() == null) { |
| LOG.debug("Can't find image for '{}'", name); |
| } |
| } |
| |
| return result.getValue(); |
| } |
| |
| return null; |
| } |
| |
| private List getPaths( |
| final ClientPropertiesKey clientKey, final String subDir, final String name, |
| final String[] extensions, final boolean reverseOrder, final boolean single, final boolean returnKey, |
| final String key, final boolean returnStrings, final boolean ignoreMissingParameter) { |
| boolean ignoreMissing = ignoreMissingParameter; |
| final List matches = new ArrayList(); |
| final String contentType = clientKey.getContentType(); |
| final Theme theme = clientKey.getTheme(); |
| final UserAgent browser = clientKey.getUserAgent(); |
| final List<String> locales = LocaleUtils.getLocaleSuffixList(clientKey.getLocale()); |
| |
| // check first the local web application directory |
| for (final String localeSuffix : locales) { |
| for (final String extension : extensions) { |
| if (production) { |
| boolean found = checkPath(reverseOrder, returnKey, returnStrings, matches, |
| name, MINIMIZE_SUFFIX, localeSuffix, extension, key); |
| if (found && (single || !returnStrings)) { |
| return matches; |
| } |
| if (!found) { |
| found = checkPath(reverseOrder, returnKey, returnStrings, matches, |
| name, null, localeSuffix, extension, key); |
| if (found && (single || !returnStrings)) { |
| return matches; |
| } |
| } |
| } else { |
| final boolean found = checkPath(reverseOrder, returnKey, returnStrings, matches, |
| name, null, localeSuffix, extension, key); |
| if (found && (single || !returnStrings)) { |
| return matches; |
| } |
| } |
| } |
| } |
| |
| // after that check the whole resources tree |
| // e.g. 1. application, 2. library or renderkit |
| for (final Theme currentTheme : theme.getFallbackList()) {// theme loop |
| for (final String resourceDirectory : tobagoConfig.getResourceDirs()) { |
| for (final String browserType : browser.getFallbackList()) { // browser loop |
| for (final String localeSuffix : locales) { // locale loop |
| for (final String extension : extensions) { // extensions loop |
| if (production) { |
| boolean found = checkPath(reverseOrder, returnKey, returnStrings, matches, |
| resourceDirectory, contentType, currentTheme, browserType, subDir, name, MINIMIZE_SUFFIX, |
| localeSuffix, extension, key); |
| if (found && (single || !returnStrings)) { |
| return matches; |
| } |
| if (!found) { |
| found = checkPath(reverseOrder, returnKey, returnStrings, matches, |
| resourceDirectory, contentType, currentTheme, browserType, subDir, name, null, |
| localeSuffix, extension, key); |
| if (found && (single || !returnStrings)) { |
| return matches; |
| } |
| } |
| } else { |
| final boolean found = checkPath(reverseOrder, returnKey, returnStrings, matches, |
| resourceDirectory, contentType, currentTheme, browserType, subDir, name, null, |
| localeSuffix, extension, key); |
| if (found && (single || !returnStrings)) { |
| return matches; |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| if (matches.isEmpty()) { |
| |
| // XXX hack for Tobago 2.0.x backward compatibility: renaming of style.css to tobago.css |
| // XXX style.css should be collected, but missing should be ignored |
| if ("style/style".equals(name) && EXT_CSS == extensions) { |
| ignoreMissing = true; |
| } |
| |
| if (!production && !ignoreMissing) { |
| LOG.warn("Path not found, and no fallback (using empty string) " |
| + "resourceDirs='" + tobagoConfig.getResourceDirs() |
| + "' contentType='" + contentType |
| + "' theme='" + theme.getName() |
| + "' browser='" + browser |
| + "' subDir='" + subDir |
| + "' name='" + name |
| + "' extension='" + Arrays.toString(extensions) |
| + "' key='" + key |
| + "'"); |
| } |
| return null; |
| } else { |
| return matches; |
| } |
| } |
| |
| private boolean checkPath( |
| final boolean reverseOrder, final boolean returnKey, final boolean returnStrings, |
| final List matches, final String name, final String minimizeSuffix, final String localeSuffix, |
| final String extension, final String key) { |
| String path = makePath(name, minimizeSuffix, localeSuffix, extension, key); |
| if (returnStrings && resourceList.containsKey(path)) { |
| final String result = returnKey ? path : resourceList.get(path); |
| if (reverseOrder) { |
| matches.add(0, result); |
| } else { |
| matches.add(result); |
| } |
| if (LOG.isTraceEnabled()) { |
| LOG.trace("testing path: {} *", path); // match |
| } |
| |
| return true; |
| } else if (!returnStrings) { |
| try { |
| path = path.substring(1).replace('/', '.'); |
| final Class clazz = Class.forName(path); |
| if (LOG.isTraceEnabled()) { |
| LOG.trace("testing path: " + path + " *"); // match |
| } |
| matches.add(clazz); |
| return true; |
| } catch (final ClassNotFoundException e) { |
| // not found |
| if (LOG.isTraceEnabled()) { |
| LOG.trace("testing path: " + path); // no match |
| } |
| } |
| } else { |
| if (LOG.isTraceEnabled()) { |
| LOG.trace("testing path: " + path); // no match |
| } |
| } |
| return false; |
| } |
| |
| private boolean checkPath( |
| final boolean reverseOrder, final boolean returnKey, final boolean returnStrings, |
| final List matches, final String resourceDirectory, final String contentType, final Theme currentTheme, |
| final String browserType, final String subDir, final String name, final String minimizeSuffix, |
| final String localeSuffix, final String extension, final String key) { |
| String path = makePath(resourceDirectory, contentType, currentTheme, browserType, subDir, name, minimizeSuffix, |
| localeSuffix, extension, key, null); |
| if (returnStrings && resourceList.containsKey(path)) { |
| final String result; |
| if (returnKey && resourceDirectory.equals(currentTheme.getResourcePath())) { |
| result = makePath(resourceDirectory, contentType, currentTheme, browserType, subDir, name, minimizeSuffix, |
| localeSuffix, extension, key, currentTheme.getVersion()); |
| } else { |
| result = returnKey ? path : resourceList.get(path); |
| } |
| if (reverseOrder) { |
| matches.add(0, result); |
| } else { |
| matches.add(result); |
| } |
| if (LOG.isTraceEnabled()) { |
| LOG.trace("testing path: {} *", path); // match |
| } |
| |
| return true; |
| } else if (!returnStrings) { |
| try { |
| path = path.substring(1).replace('/', '.'); |
| final Class clazz = Class.forName(path); |
| if (LOG.isTraceEnabled()) { |
| LOG.trace("testing path: " + path + " *"); // match |
| } |
| matches.add(clazz); |
| return true; |
| } catch (final ClassNotFoundException e) { |
| // not found |
| if (LOG.isTraceEnabled()) { |
| LOG.trace("testing path: " + path); // no match |
| } |
| } |
| } else { |
| if (LOG.isTraceEnabled()) { |
| LOG.trace("testing path: " + path); // no match |
| } |
| } |
| return false; |
| } |
| |
| private String makePath( |
| final String project, final String language, final Theme theme, final String browser, final String subDir, |
| final String name, final String minimizeSuffix, final String localeSuffix, final String extension, |
| final String key, final String version) { |
| final StringBuilder searchtext = new StringBuilder(64); |
| |
| searchtext.append('/'); |
| searchtext.append(project); |
| if (version != null) { |
| searchtext.append('/'); |
| searchtext.append(version); |
| } |
| searchtext.append('/'); |
| searchtext.append(language); |
| searchtext.append('/'); |
| searchtext.append(theme.getName()); |
| searchtext.append('/'); |
| searchtext.append(browser); |
| if (subDir != null) { |
| searchtext.append('/'); |
| searchtext.append(subDir); |
| } |
| searchtext.append('/'); |
| searchtext.append(name); |
| if (minimizeSuffix != null) { |
| searchtext.append(minimizeSuffix); |
| } |
| searchtext.append(localeSuffix); |
| searchtext.append(extension); |
| if (key != null) { |
| searchtext.append('/'); |
| searchtext.append(key); |
| } |
| |
| return searchtext.toString(); |
| } |
| |
| private String makePath( |
| final String name, final String minimizeSuffix, final String localeSuffix, final String extension, |
| final String key) { |
| final StringBuilder searchtext = new StringBuilder(64); |
| |
| searchtext.append('/'); |
| searchtext.append(name); |
| if (minimizeSuffix != null) { |
| searchtext.append(minimizeSuffix); |
| } |
| searchtext.append(localeSuffix); |
| searchtext.append(extension); |
| if (key != null) { |
| searchtext.append('/'); |
| searchtext.append(key); |
| } |
| |
| return searchtext.toString(); |
| } |
| |
| private String getRendererClassName(final String rendererType) { |
| String name; |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("rendererType = '{}'", rendererType); |
| } |
| if ("javax.faces.Text".equals(rendererType)) { // TODO: find a better way |
| name = RendererTypes.OUT; |
| } else { |
| name = rendererType; |
| } |
| name = name + "Renderer"; |
| if (name.startsWith("javax.faces.")) { // FIXME: this is a hotfix from jsf1.0beta to jsf1.0fr |
| LOG.warn("patching renderer from {}", name); |
| name = name.substring("javax.faces.".length()); |
| LOG.warn("patching renderer to {}", name); |
| } |
| return name; |
| } |
| |
| private String[] getStrings(final FacesContext facesContext, final String name, final String type) { |
| String[] result = new String[0]; |
| if (name != null) { |
| final int dot = name.lastIndexOf('.'); |
| final String nameWithoutExtension; |
| final String[] extensions; |
| if (dot == -1) { |
| nameWithoutExtension = name; |
| extensions = EXT_NONE; |
| } else { |
| nameWithoutExtension = name.substring(0, dot); |
| final String extension = name.substring(dot); |
| extensions = getExtensions(extension); |
| } |
| |
| final ClientPropertiesKey key = ClientPropertiesKey.get(facesContext); |
| final MiscCacheKey miscKey = new MiscCacheKey(key, name); |
| final String[] cacheResult = miscCache.get(miscKey); |
| if (cacheResult != null) { |
| return cacheResult; |
| } |
| try { |
| final List matches = getPaths(key, type, |
| nameWithoutExtension, extensions, true, false, true, null, true, false); |
| if (matches != null) { |
| result = (String[]) matches.toArray(new String[matches.size()]); |
| } |
| miscCache.put(miscKey, result); |
| } catch (final Exception e) { |
| LOG.error("name = '" + name + "' clientProperties = '" + key.toString() + "'", e); |
| } |
| } |
| return result; |
| } |
| |
| private String[] getExtensions(final String extension) { |
| final String[] extensions; |
| final String[] cached = extensionCache.get(extension); |
| if (cached != null) { |
| extensions = cached; |
| } else { |
| extensions = new String[]{extension}; |
| extensionCache.put(extension, extensions); |
| if (LOG.isInfoEnabled()) { |
| LOG.info("Adding extension '{}' to cache.", extension); |
| } |
| } |
| return extensions; |
| } |
| |
| @Override |
| public String toString() { |
| return "ResourceManagerImpl{" |
| + "production=" + production |
| + ", resourceList=" + resourceList.size() |
| + ", rendererCache=" + rendererCache.size() |
| + ", imageCache=" + imageCache.size() |
| + ", jspCache=" + jspCache.size() |
| + ", miscCache=" + miscCache.size() |
| + ", propertyCache=" + propertyCache.size() |
| + ", themeCache=" + themeCache.size() |
| + ", extensionCache=" + extensionCache.size() |
| + '}'; |
| } |
| } |