001// Copyright 2006, 2007, 2008, 2009, 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
015package org.apache.tapestry5.internal.services;
016
017import org.apache.tapestry5.ioc.annotations.UsesMappedConfiguration;
018import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
019import org.apache.tapestry5.services.transform.ControlledPackageType;
020
021/**
022 * Creates {@link org.apache.tapestry5.internal.services.Instantiator}s for components, based on component class name.
023 * This will involve transforming the component's class before it is loaded.
024 * <p/>
025 * In addition, a source acts as an event hub for {@link org.apache.tapestry5.services.InvalidationListener}s, so that
026 * any information derived from loaded classes can be discarded and rebuilt when classes change.
027 * <p/>
028 * The strategy used is that when <em>any</em> class (in a controlled package) changes, the entire class loader is
029 * discarded, along with any instances derived from those classes. A new class loader is created, and then invalidation
030 * events are fired to listeners.
031 * <p/>
032 * Starting in Tapestry 5.3, the packages that are loaded are controlled by a configuration that maps package names to
033 * {@link ControlledPackageType}s.
034 */
035@UsesMappedConfiguration(key = String.class, value = ControlledPackageType.class)
036public interface ComponentInstantiatorSource
037{
038
039    /**
040     * Given the name of a component class, provides an instantiator for that component. Instantiators are cached, so
041     * repeated calls to this method with the same class name will return the same instance; however, callers should
042     * also be aware that the instantiators may lose validity after an invalidation (caused by changes to external Java
043     * class files).
044     *
045     * @param classname FQCN to find (and perhaps transform and load)
046     * @return an object which can instantiate an instance of the component
047     */
048    Instantiator getInstantiator(String classname);
049
050    /**
051     * Checks to see if a fully qualified class name exists. This method appears to exist only for testing.
052     *
053     * @param className name of class to check
054     * @return true if the class exists (there's a ".class" file), false otherwise
055     */
056    boolean exists(String className);
057
058    /**
059     * Returns a proxy factory that can be used to generate additional classes around enhanced classes, or create
060     * subclasses of enhanced classes.
061     *
062     * @since 5.3
063     */
064    PlasticProxyFactory getProxyFactory();
065
066    /**
067     * Forces invalidation logic, as if a component class on the disk had changed, forcing a reload
068     * of all pages and components.
069     *
070     * @since 5.3
071     */
072    void forceComponentInvalidation();
073}