001// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012 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 015package org.apache.tapestry5.services; 016 017import org.apache.tapestry5.Asset; 018import org.apache.tapestry5.ioc.annotations.IncompatibleChange; 019import org.apache.tapestry5.ioc.annotations.UsesConfiguration; 020import org.apache.tapestry5.ioc.services.ClassNameLocator; 021import org.apache.tapestry5.services.transform.ControlledPackageType; 022 023import java.util.Collection; 024import java.util.List; 025import java.util.Map; 026 027/** 028 * Resolves page names and component types to fully qualified class names. Pages and components may be provided by the 029 * application or inside a <em>mapped package</em>. Page names often appear inside URLs, and component types often 030 * appear in component templates (when specifying the type of an embedded component). 031 * <p/> 032 * The service is configured using a collection of {@link LibraryMapping}s. Each mapping maps a prefix, such as "core" 033 * to a root package name, such as "org.apache.tapestry5.corelib". The root package is expected to have sub-packages: 034 * "pages", "components", "mixins" and "base" ("base" is for base classes). 035 * <p/> 036 * The resolver performs a search of the classpath (via {@link ClassNameLocator}), to build up a set of case-insensitive 037 * maps from logical page name, component type, or mixin type to fully qualified class name. 038 * <p/> 039 * Certain ambiguities occur if mapped packages overlap, either in terms of the the prefixes or the package names. Keep 040 * things clearly separate to avoid lookup problems. 041 */ 042@UsesConfiguration(LibraryMapping.class) 043public interface ComponentClassResolver 044{ 045 /** 046 * Converts a logical page name (such as might be encoded into a URL) into a fully qualified class name. The case of 047 * the page name is irrelevant. 048 * 049 * @param pageName 050 * page name 051 * @return fully qualified class name for the page 052 * @throws org.apache.tapestry5.ioc.util.UnknownValueException 053 * if the name does not match a known page class 054 */ 055 String resolvePageNameToClassName(String pageName); 056 057 /** 058 * For a particular path, determines if the path is a logical page name. The check is case insensitive. 059 * 060 * @param pageName 061 * potential logical page name 062 * @return true if the page name is valid 063 */ 064 boolean isPageName(String pageName); 065 066 /** 067 * Returns a list of all page names, in sorted order. These are the "canonical" page names. 068 */ 069 List<String> getPageNames(); 070 071 /** 072 * Returns a list of all component names, in sorted order. These are the "canonical" component names. 073 * @since 5.4 074 */ 075 @IncompatibleChange(release = "5.4", details = "added method") 076 List<String> getComponentNames(); 077 078 /** 079 * Returns a list of all mixin names, in sorted order. These are the "canonical" mixin names. 080 * @since 5.4 081 */ 082 @IncompatibleChange(release = "5.4", details = "added method") 083 List<String> getMixinNames(); 084 085 /** 086 * Converts a fully qualified page class name into a page name (often, for inclusion as part of the URI). This value 087 * may later be passed to {@link #resolvePageNameToClassName(String)}. 088 * 089 * @param pageClassName 090 * fully qualified name of a page class 091 * @return equivalent logical page name 092 * @throws IllegalArgumentException 093 * if the name can not be resolved 094 */ 095 String resolvePageClassNameToPageName(String pageClassName); 096 097 /** 098 * Returns the canonical form of a page name. The canonical form uses character case matching the underlying class 099 * name. 100 * 101 * @throws org.apache.tapestry5.ioc.util.UnknownValueException 102 * if the page name does not match a logical page name 103 */ 104 String canonicalizePageName(String pageName); 105 106 /** 107 * Converts a component type (a logical component name such as might be used inside a template or annotation) into a 108 * fully qualified class name. Case is ignored in resolving the name. 109 * 110 * @param componentType 111 * a logical component type 112 * @return fully qualified class name 113 * @throws org.apache.tapestry5.ioc.util.UnknownValueException 114 * if the component type can not be resolved 115 */ 116 String resolveComponentTypeToClassName(String componentType); 117 118 /** 119 * Converts a logical mixin type (as with component types) into a fully qualified class name. Case is ignored when 120 * resolving the name. 121 * 122 * @param mixinType 123 * a logical mixin type 124 * @return fully qualified class name 125 * @throws org.apache.tapestry5.ioc.util.UnknownValueException 126 * if the mixin type can not be resolved 127 */ 128 String resolveMixinTypeToClassName(String mixinType); 129 130 /** 131 * A mapping from virtual folder name to a package name (used for converting classpath {@link Asset}s 132 * to client URLs). This is derived from the contributed {@link LibraryMapping}s. 133 * <p/> 134 * It is allowed to contribute multiple root packages as a single folder name. In this case, the best common package 135 * name is used. For example, if both <code>com.example.main</code> and <code>com.example.extras</code> is mapped to 136 * folder "example", then the package mapping for "example" will be <code>com.example</code>. 137 * 138 * @see ClasspathAssetAliasManager 139 * @since 5.2.0 140 */ 141 Map<String, String> getFolderToPackageMapping(); 142 143 /** 144 * Returns the names of all libraries (as {@linkplain org.apache.tapestry5.services.LibraryMapping#getPathPrefix() configured}). 145 * This does not include the application itself (which is a library with the virtual path of empty string). 146 * 147 * @return sorted names of libraries 148 * @since 5.4 149 */ 150 List<String> getLibraryNames(); 151 152 /** 153 * Used to identify which packages are controlled packages (from which components are loaded). Future expansion 154 * may allow for additional packages which are live reloaded but not components (or perhaps are transformed, but not 155 * as components). 156 * 157 * @return a mapping from package name to {@link ControlledPackageType}. 158 * @since 5.3 159 */ 160 Map<String, ControlledPackageType> getControlledPackageMapping(); 161 162 /** 163 * Returns true if the class name is specifically a page class, and not a component, mixin or base class. 164 * 165 * @param pageClassName 166 * @return true if a page class 167 * @since 5.3 168 */ 169 boolean isPage(final String pageClassName); 170 171 /** 172 * Given a class name of a component class, returns the library name (as defined by a 173 * {@linkplain org.apache.tapestry5.services.LibraryMapping#getPathPrefix() contributed library name}). 174 * 175 * @param className 176 * @return library name 177 * @throws IllegalArgumentException 178 * if the class can't be matched to a contributed root package 179 */ 180 String getLibraryNameForClass(String className); 181 182 /** 183 * Returns the library mappings. 184 * @return 185 */ 186 @IncompatibleChange(release = "5.4", details = "Added method") 187 Collection<LibraryMapping> getLibraryMappings(); 188 189}