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.commons.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 *
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 *
031 * Since 5.1.0.0, is is preferred that
032 * {@link org.apache.tapestry5.services.AssetFactory#createAsset(org.apache.tapestry5.commons.Resource)} return an instance
033 * of <code>org.apache.tapestry5.Asset2</code>.
034 * 
035 * Since 5.7.0, Asset2 was merged into Asset and removed.
036 */
037@UsesMappedConfiguration(AssetFactory.class)
038public interface AssetSource
039{
040    /**
041     * Finds the asset. The path may either be a simple file name or a relative path (relative to the base resource)
042     * <em>or</em> it may have a prefix, such as "context:" or "classpath:", in which case it is treated as a complete
043     * path within the indicated domain. The resulting Resource is then localized (to the provided Locale) and returned
044     * as an Asset.
045     *
046     * The AssetSource caches its results, so a single Asset instance may be shared among many different components.
047     *
048     * @param baseResource
049     *         base resource for computing relative paths, or null to search the classpath
050     * @param path
051     *         relative to the base resource
052     * @param locale
053     *         locale to localize the final resource to, or null for the thread's current locale
054     * @return the asset
055     * @throws RuntimeException
056     *         if the asset can not be found
057     */
058    Asset getAsset(Resource baseResource, String path, Locale locale);
059
060    /**
061     * Finds the asset, either on the classpath or (if prefixed), within the indicated domain. The result is not
062     * localized. The underlying Asset may not exist.
063     *
064     * @param path
065     *         to the resource to provide as an Asset
066     * @return Resource for the path (the Resource may not exist)
067     * @since 5.1.0.0
068     */
069    Resource resourceForPath(String path);
070
071    /**
072     * Convenience for finding assets on the classpath.
073     *
074     * @param path
075     *         path to the base resource, relative to classpath root
076     * @param locale
077     *         to localize the resource to
078     * @return the asset
079     * @throws RuntimeException
080     *         if the asset can not be found
081     */
082    Asset getClasspathAsset(String path, Locale locale);
083
084    /**
085     * Convenience for finding assets in the context.
086     *
087     * @param path
088     *         path relative to the base resource (the context root)
089     * @param locale
090     *         to localize the resource to, or null for the locale for the current request
091     * @return the asset
092     * @throws RuntimeException
093     *         if the asset can not be found
094     * @since 5.1.0.0
095     */
096    Asset getContextAsset(String path, Locale locale);
097
098    /**
099     * Obtains a classpath asset in the current locale (as defined by the {@link ThreadLocale} service).
100     *
101     * @param path
102     *         relative to the classpath root
103     * @return the asset
104     * @throws RuntimeException
105     *         if the asset can not be found
106     */
107    Asset getClasspathAsset(String path);
108
109    /**
110     * Find an asset but does not attempt to localize it. If the path has no prefix, it is assumed to
111     * be on the classpath.
112     *
113     * @throws RuntimeException
114     *         if the asset can not be found
115     * @since 5.2.0
116     */
117    Asset getUnlocalizedAsset(String path);
118
119    /**
120     * As with {@link #getUnlocalizedAsset(String)}, but {@linkplain SymbolSource#expandSymbols(String) symbols}
121     * in the path are expanded}.
122     *
123     * @since 5.2.0
124     */
125    Asset getExpandedAsset(String path);
126
127    /**
128     * Gets an asset that is used with, or injected into, a component, that will be exposed to the client.
129     * This encapsulates the new, in 5.4, standard that assets should all be stored in (sub-folders of)
130     * <code>META-INF/assets/<em>library-name</em>/</code>.
131     * This is the preferred location in 5.4, with compatibility for 5.3 that allows assets to be stored on the classpath
132     * alongside Java classes and server-only resources such as templates and message catalogs.
133     *
134     *
135     * When resolving a resource in a component that is subclass, the point of injection is the class which contains
136     * the injecting annotation (e.g., {@link org.apache.tapestry5.ioc.annotations.Inject} with {@link org.apache.tapestry5.annotations.Path},
137     * or {@link org.apache.tapestry5.annotations.Import}). In other words, the library name for the library containing the class,
138     * rather than the library name of the instantiated subclass (which can be different).
139     *
140     * @param resources
141     *         resources, used to identify starting location of asset (if path does not include a asset prefix).
142     * @param path
143     *         path to the resource; either fully qualified (with an asset prefix such as "context:"), or relative to the
144     *         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
145     *         way, still supported until at least 5.5).
146     *         Symbols in the path are {@linkplain org.apache.tapestry5.ioc.services.SymbolSource#expandSymbols(String) expanded}.
147     * @param libraryName
148     *          The name of the library containing the component, as per {@link org.apache.tapestry5.model.ComponentModel#getLibraryName()}.
149     *          For a subclass, the libraryName must reflect the name of the library for the parent class that forms the basis of
150     *          injection.
151     * @return the Asset
152     * @throws RuntimeException
153     *         if Asset can not be found
154     * @since 5.4
155     */
156    Asset getComponentAsset(ComponentResources resources, String path, final String libraryName);
157}