    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}