001    // Copyright 2006, 2007, 2008, 2009, 2010, 2011 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    // http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry5.services;
016    
017    import java.util.List;
018    import java.util.Map;
019    
020    import org.apache.tapestry5.Asset;
021    import org.apache.tapestry5.ioc.annotations.UsesConfiguration;
022    import org.apache.tapestry5.ioc.services.ClassNameLocator;
023    import org.apache.tapestry5.services.transform.ControlledPackageType;
024    
025    /**
026     * Resolves page names and component types to fully qualified class names. Pages and components may be provided by the
027     * application or inside a <em>mapped package</em>. Page names often appear inside URLs, and component types often
028     * appear in component template (when specifying the type of an embedded component).
029     * <p/>
030     * The service is configured using a collection of {@link LibraryMapping}s. Each mapping maps a prefix, such as "core"
031     * to a root package name, such as "org.apache.tapestry5.corelib". The root package is expected to have sub-packages:
032     * "pages", "components", "mixins" and "base" ("base" is for base classes).
033     * <p/>
034     * The resolver performs a search of the classpath (via {@link ClassNameLocator}), to build up a set of case-insensitive
035     * maps from logical page name, component type, or mixin type to fully qualified class name.
036     * <p/>
037     * Certain ambiguities occur if mapped packages overlap, either in terms of the the prefixes or the package names. Keep
038     * things clearly separate to avoid lookup problems.
039     */
040    @UsesConfiguration(LibraryMapping.class)
041    public interface ComponentClassResolver
042    {
043        /**
044         * Converts a logical page name (such as might be encoded into a URL) into a fully qualified class name. The case of
045         * the page name is irrelevant.
046         * 
047         * @param pageName
048         *            page name
049         * @return fully qualified class name for the page
050         * @throws org.apache.tapestry5.ioc.util.UnknownValueException
051         *             if the name does not match a known page class
052         */
053        String resolvePageNameToClassName(String pageName);
054    
055        /**
056         * For a particular path, determines if the path is a logical page name. The check is case insensitive.
057         * 
058         * @param pageName
059         *            potential logical page name
060         * @return true if the page name is valid
061         */
062        boolean isPageName(String pageName);
063    
064        /**
065         * Returns a list of all page names, in sorted order.
066         */
067        List<String> getPageNames();
068    
069        /**
070         * Converts a fully qualified page class name into a page name (often, for inclusion as part of the URI). This value
071         * may later be passed to {@link #resolvePageNameToClassName(String)}.
072         * 
073         * @param pageClassName
074         *            fully qualified name of a page class
075         * @return equivalent logical page name
076         * @throws IllegalArgumentException
077         *             if the name can not be resolved
078         */
079        String resolvePageClassNameToPageName(String pageClassName);
080    
081        /**
082         * Returns the canonical form of a page name. The canonical form uses character case matching the underlying class
083         * name.
084         * 
085         * @throws org.apache.tapestry5.ioc.util.UnknownValueException
086         *             if the page name does not match a logical page name
087         */
088        String canonicalizePageName(String pageName);
089    
090        /**
091         * Converts a component type (a logical component name such as might be used inside a template or annotation) into a
092         * fully qualified class name. Case is ignored in resolving the name.
093         * 
094         * @param componentType
095         *            a logical component type
096         * @return fully qualified class name
097         * @throws org.apache.tapestry5.ioc.util.UnknownValueException
098         *             if the component type can not be resolved
099         */
100        String resolveComponentTypeToClassName(String componentType);
101    
102        /**
103         * Converts a logical mixin type (as with component types) into a fully qualified class name. Case is ignored when
104         * resolving the name.
105         * 
106         * @param mixinType
107         *            a logical mixin type
108         * @return fully qualified class name
109         * @throws org.apache.tapestry5.ioc.util.UnknownValueException
110         *             if the mixin type can not be resolved
111         */
112        String resolveMixinTypeToClassName(String mixinType);
113    
114        /**
115         * A mapping from virtual folder name to a package name (used for converting classpath {@link Asset}s
116         * to client URLs). This is derived from the contributed {@link LibraryMapping}s.
117         * <p>
118         * It is allowed to contribute multiple root packages as a single folder name. In this case, the best common package
119         * name is used. For example, if both <code>com.example.main</code> and <code>com.example.extras</code> is mapped to
120         * folder "example", then the package mapping for "example" will be <code>com.example</code>.
121         * 
122         * @since 5.2.0
123         * @see ClasspathAssetAliasManager
124         */
125        Map<String, String> getFolderToPackageMapping();
126    
127        /**
128         * Used to identify which packages are controlled packages (from which components are loaded). Future expansion
129         * may allow for additional packages which are live reloaded but not components (or perhaps are transformed, but not
130         * as components).
131         * 
132         * @return a mapping from package name to {@link ControlledPackageType}.
133         * @since 5.3
134         */
135        Map<String, ControlledPackageType> getControlledPackageMapping();
136    
137        /**
138         * Returns true if the class name is specifically a page class, and not a component, mixin or base class.
139         * 
140         * @param pageClassName
141         * @return true if a page class
142         * @since 5.3
143         */
144        boolean isPage(final String pageClassName);
145    }