001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.wicket.util.resource.locator;
018:
019: import java.net.URL;
020: import java.util.Locale;
021:
022: import org.apache.wicket.Application;
023: import org.apache.wicket.util.file.IResourceFinder;
024: import org.apache.wicket.util.resource.IResourceStream;
025: import org.apache.wicket.util.resource.UrlResourceStream;
026: import org.slf4j.Logger;
027: import org.slf4j.LoggerFactory;
028:
029: /**
030: * Locate Wicket resource.
031: * <p>
032: * Contains the logic to locate a resource based on a path, a style (see
033: * {@link org.apache.wicket.Session}), a locale and an extension string. The
034: * full filename will be built like:
035: * <path>_<style>_<locale>.<extension>.
036: * <p>
037: * Resource matches will be attempted in the following order:
038: * <ol>
039: * <li>1. <path>_<style>_<locale>.<extension></li>
040: * <li>2. <path>_<locale>.<extension></li>
041: * <li>3. <path>_<style>.<extension></li>
042: * <li>4. <path>.<extension></li>
043: * </ol>
044: * <p>
045: * Locales may contain a language, a country and a region or variant.
046: * Combinations of these components will be attempted in the following order:
047: * <ol>
048: * <li>locale.toString() see javadoc for Locale for more details</li>
049: * <li><language>_<country></li>
050: * <li><language></li>
051: * </ol>
052: *
053: * @author Juergen Donnerstag
054: * @author Jonathan Locke
055: */
056: public class ResourceStreamLocator implements IResourceStreamLocator {
057: /** Logging */
058: private static final Logger log = LoggerFactory
059: .getLogger(ResourceStreamLocator.class);
060:
061: /** If null, the application registered finder will be used */
062: private IResourceFinder finder;
063:
064: /**
065: * Constructor
066: */
067: public ResourceStreamLocator() {
068: }
069:
070: /**
071: * Constructor
072: *
073: * @param finder
074: * resource finder
075: */
076: public ResourceStreamLocator(final IResourceFinder finder) {
077: this .finder = finder;
078: }
079:
080: /**
081: *
082: * @see org.apache.wicket.util.resource.locator.IResourceStreamLocator#locate(java.lang.Class,
083: * java.lang.String)
084: */
085: public IResourceStream locate(final Class clazz, final String path) {
086: // First try with the resource finder registered with the application
087: // (allows for markup reloading)
088: IResourceStream stream = locateByResourceFinder(clazz, path);
089: if (stream != null) {
090: return stream;
091: }
092:
093: // Then search the resource on the classpath
094: stream = locateByClassLoader(clazz, path);
095: if (stream != null) {
096: return stream;
097: }
098:
099: return null;
100: }
101:
102: /**
103: *
104: * @see org.apache.wicket.util.resource.locator.IResourceStreamLocator#locate(java.lang.Class,
105: * java.lang.String, java.lang.String, java.util.Locale,
106: * java.lang.String)
107: */
108: public IResourceStream locate(final Class clazz, String path,
109: final String style, final Locale locale,
110: final String extension) {
111: // Try the various combinations of style, locale and extension to find
112: // the resource.
113: ResourceNameIterator iter = new ResourceNameIterator(path,
114: style, locale, extension);
115: while (iter.hasNext()) {
116: String newPath = (String) iter.next();
117:
118: IResourceStream stream = locate(clazz, newPath);
119: if (stream != null) {
120: stream.setLocale(iter.getLocale());
121: return stream;
122: }
123: }
124:
125: return null;
126: }
127:
128: /**
129: * Search the the resource my means of the various classloaders available
130: *
131: * @param clazz
132: * @param path
133: * @return resource stream
134: */
135: protected IResourceStream locateByClassLoader(final Class clazz,
136: final String path) {
137: ClassLoader classLoader = null;
138: if (clazz != null) {
139: classLoader = clazz.getClassLoader();
140: }
141:
142: if (classLoader == null) {
143: // use context classloader when no specific classloader is set
144: // (package resources for instance)
145: classLoader = Thread.currentThread()
146: .getContextClassLoader();
147: }
148:
149: if (classLoader == null) {
150: // use Wicket classloader when no specific classloader is set
151: classLoader = getClass().getClassLoader();
152: }
153:
154: // Log attempt
155: if (log.isDebugEnabled()) {
156: log.debug("Attempting to locate resource '" + path
157: + "' using classloader " + classLoader);
158: }
159:
160: // Try loading path using classloader
161: final URL url = classLoader.getResource(path);
162: if (url != null) {
163: return new UrlResourceStream(url);
164: }
165: return null;
166: }
167:
168: /**
169: * Search the resource by means of the application registered resource
170: * finder
171: *
172: * @param clazz
173: * @param path
174: * @return resource stream
175: */
176: protected IResourceStream locateByResourceFinder(final Class clazz,
177: final String path) {
178: if (this .finder == null) {
179: finder = Application.get().getResourceSettings()
180: .getResourceFinder();
181: }
182:
183: // Log attempt
184: if (log.isDebugEnabled()) {
185: log.debug("Attempting to locate resource '" + path
186: + "' on path " + finder);
187: }
188:
189: // Try to find file resource on the path supplied
190: return finder.find(clazz, path);
191: }
192: }
|