001// Licensed under the Apache License, Version 2.0 (the "License");
002// you may not use this file except in compliance with the License.
003// You may obtain a copy of the License at
004//
005// http://www.apache.org/licenses/LICENSE-2.0
006//
007// Unless required by applicable law or agreed to in writing, software
008// distributed under the License is distributed on an "AS IS" BASIS,
009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
010// See the License for the specific language governing permissions and
011// limitations under the License.
012
013package org.apache.tapestry5.services;
014
015import org.apache.tapestry5.Asset;
016import org.apache.tapestry5.ComponentResources;
017import org.apache.tapestry5.ioc.Resource;
018import org.apache.tapestry5.ioc.annotations.UsesMappedConfiguration;
019import org.apache.tapestry5.ioc.services.SymbolSource;
020import org.apache.tapestry5.ioc.services.ThreadLocale;
021
022import java.util.Locale;
023
024/**
025 * Used to find or create an {@link org.apache.tapestry5.Asset} with a given path.
026 * <p/>
027 * Assets are defined with a domain, and the domain is indicated by a prefix. The two builtin domains are "context:"
028 * (for files inside the web application context) and "classpath:" for files stored on the classpath (typically, inside
029 * a JAR, such as a component library). Other domains can be defined via contributions to the AssetSource service.
030 * <p/>
031 * Since 5.1.0.0, is is preferred that
032 * {@link org.apache.tapestry5.services.AssetFactory#createAsset(org.apache.tapestry5.ioc.Resource)} return an instance
033 * of {@link org.apache.tapestry5.Asset2}.
034 */
035@UsesMappedConfiguration(AssetFactory.class)
036public interface AssetSource
037{
038    /**
039     * Finds the asset. The path may either be a simple file name or a relative path (relative to the base resource)
040     * <em>or</em> it may have a prefix, such as "context:" or "classpath:", in which case it is treated as a complete
041     * path within the indicated domain. The resulting Resource is then localized (to the provided Locale) and returned
042     * as an Asset.
043     * <p/>
044     * The AssetSource caches its results, so a single Asset instance may be shared among many different components.
045     *
046     * @param baseResource
047     *         base resource for computing relative paths, or null to search the classpath
048     * @param path
049     *         relative to the base resource
050     * @param locale
051     *         locale to localize the final resource to, or null for the thread's current locale
052     * @return the asset
053     * @throws RuntimeException
054     *         if the asset can not be found
055     */
056    Asset getAsset(Resource baseResource, String path, Locale locale);
057
058    /**
059     * Finds the asset, either on the classpath or (if prefixed), within the indicated domain. The result is not
060     * localized. The underlying Asset may not exist.
061     *
062     * @param path
063     *         to the resource to provide as an Asset
064     * @return Resource for the path (the Resource may not exist)
065     * @since 5.1.0.0
066     */
067    Resource resourceForPath(String path);
068
069    /**
070     * Convenience for finding assets on the classpath.
071     *
072     * @param path
073     *         path to the base resource, relative to classpath root
074     * @param locale
075     *         to localize the resource to
076     * @return the asset
077     * @throws RuntimeException
078     *         if the asset can not be found
079     */
080    Asset getClasspathAsset(String path, Locale locale);
081
082    /**
083     * Convenience for finding assets in the context.
084     *
085     * @param path
086     *         path relative to the base resource (the context root)
087     * @param locale
088     *         to localize the resource to, or null for the locale for the current request
089     * @return the asset
090     * @throws RuntimeException
091     *         if the asset can not be found
092     * @since 5.1.0.0
093     */
094    Asset getContextAsset(String path, Locale locale);
095
096    /**
097     * Obtains a classpath asset in the current locale (as defined by the {@link ThreadLocale} service).
098     *
099     * @param path
100     *         relative to the classpath root
101     * @return the asset
102     * @throws RuntimeException
103     *         if the asset can not be found
104     */
105    Asset getClasspathAsset(String path);
106
107    /**
108     * Find an asset but does not attempt to localize it. If the path has no prefix, it is assumed to
109     * be on the classpath.
110     *
111     * @throws RuntimeException
112     *         if the asset can not be found
113     * @since 5.2.0
114     */
115    Asset getUnlocalizedAsset(String path);
116
117    /**
118     * As with {@link #getUnlocalizedAsset(String)}, but {@linkplain SymbolSource#expandSymbols(String) symbols}
119     * in the path are expanded}.
120     *
121     * @since 5.2.0
122     */
123    Asset getExpandedAsset(String path);
124
125    /**
126     * Gets an asset that is used with, or injected into, a component, that will be exposed to the client.
127     * This encapsulates the new, in 5.4, standard that assets should all be stored in (sub-folders of)
128     * <code>META-INF/assets/<em>library-name</em>/</code>.
129     * This is the preferred location in 5.4, with compatibility for 5.3 that allows assets to be stored on the classpath
130     * alongside Java classes and server-only resources such as templates and message catalogs.
131     *
132     * <p/>
133     * When resolving a resource in a component that is subclass, the point of injection is the class which contains
134     * the injecting annotation (e.g., {@link org.apache.tapestry5.ioc.annotations.Inject} with {@link org.apache.tapestry5.annotations.Path},
135     * or {@link org.apache.tapestry5.annotations.Import}). In other words, the library name for the library containing the class,
136     * rather than the library name of the instantiated subclass (which can be different).
137     *
138     * @param resources
139     *         resources, used to identify starting location of asset (if path does not include a asset prefix).
140     * @param path
141     *         path to the resource; either fully qualified (with an asset prefix such as "context:"), or relative to the
142     *         component's library asset folder (the 5.4 and beyond way), or the to the component's Java class file (the 5.3 and earlier
143     *         way, still supported until at least 5.5).
144     *         Symbols in the path are {@linkplain org.apache.tapestry5.ioc.services.SymbolSource#expandSymbols(String) expanded}.
145     * @param libraryName
146     *          The name of the library containing the component, as per {@link org.apache.tapestry5.model.ComponentModel#getLibraryName()}.
147     *          For a subclass, the libraryName must reflect the name of the library for the parent class that forms the basis of
148     *          injection.
149     * @return the Asset
150     * @throws RuntimeException
151     *         if Asset can not be found
152     * @since 5.4
153     */
154    Asset getComponentAsset(ComponentResources resources, String path, final String libraryName);
155}