001    // Copyright 2006, 2007, 2008, 2009 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 org.apache.tapestry5.ioc.services.ClassNameLocator;
018    
019    import java.util.List;
020    
021    /**
022     * Resolves page names and component types to fully qualified class names. Pages and components may be provided by the
023     * application or inside a <em>mapped package</em>. Page names often appear inside URLs, and component types often
024     * appear in component template (when specifying the type of an embedded component).
025     * <p/>
026     * The service is configured using a collection of {@link LibraryMapping}s. Each mapping maps a prefix, such as "core"
027     * to a root package name, such as "org.apache.tapestry5.corelib". The root package is expected to have sub-packages:
028     * "pages", "components", "mixins" and "base" ("base" is for base classes).
029     * <p/>
030     * The resolver performs a search of the classpath (via {@link ClassNameLocator}), to build up a set of case-insensitive
031     * maps from logical page name, component type, or mixin type to fully qualified class name.
032     * <p/>
033     * Certain ambiguities occur if mapped packages overlap, either in terms of the the prefixes or the package names. Keep
034     * things clearly seperate to avoid lookup problems.
035     */
036    public interface ComponentClassResolver
037    {
038        /**
039         * Converts a logical page name (such as might be encoded into a URL) into a fully qualified class name. The case of
040         * the page name is irrelevant.
041         *
042         * @param pageName page name
043         * @return fully qualified class name for the page
044         * @throws IllegalArgumentException if the name does not match a known page class
045         */
046        String resolvePageNameToClassName(String pageName);
047    
048        /**
049         * For a particular path, determines if the path is a logical page name. The check is case insensitive.
050         *
051         * @param pageName potential logical page name
052         * @return true if the page name is valid
053         */
054        boolean isPageName(String pageName);
055    
056        /**
057         * Returns a list of all  page names, in sorted order.
058         */
059        List<String> getPageNames();
060    
061        /**
062         * Converts a fully qualified page class name into a page name (often, for inclusion as part of the URI). This value
063         * may later be passed to {@link #resolvePageNameToClassName(String)}.
064         *
065         * @param pageClassName fully qualified name of a page class
066         * @return equivalent logical page name
067         * @throws IllegalArgumentException if the name can not be resolved
068         */
069        String resolvePageClassNameToPageName(String pageClassName);
070    
071        /**
072         * Returns the canonical form of a page name. The canonical form uses character case matching the underlying class
073         * name.
074         *
075         * @throws IllegalArgumentException if the page name does not match a logical page name
076         */
077        String canonicalizePageName(String pageName);
078    
079        /**
080         * Converts a component type (a logical component name such as might be used inside a template or annotation) into a
081         * fully qualified class name. Case is ignored in resolving the name.
082         *
083         * @param componentType a logical component type
084         * @return fully qualified class name
085         * @throws IllegalArgumentException if the component type can not be resolved
086         */
087        String resolveComponentTypeToClassName(String componentType);
088    
089        /**
090         * Converts a logical mixin type (as with component types) into a fully qualified class name. Case is ignored when
091         * resolving the name.
092         *
093         * @param mixinType a logical mixin type
094         * @return fully qualified class name
095         * @throws IllegalArgumentException if the mixin type can not be resolved
096         */
097        String resolveMixinTypeToClassName(String mixinType);
098    }