    001    // Copyright 2006, 2007, 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.ioc;
    016
    017    import org.apache.tapestry5.ioc.annotations.Inject;
    018    import org.apache.tapestry5.ioc.services.MasterObjectProvider;
    019
    020    import java.lang.annotation.Annotation;
    021
    022    /**
    023     * Defines an object which can provide access to services defined within a {@link org.apache.tapestry5.ioc.Registry}, or
    024     * to objects or object instances available by other means. Services are accessed via service id, or
    025     * (when appropriate)
    026     * by just service interface. The Registry itself implements this interface, as does
    027     * {@link org.apache.tapestry5.ioc.ServiceResources}.
    028     */
    029    public interface ObjectLocator
    030    {
    031        /**
    032         * Obtains a service via its unique service id. Returns the service's proxy. The service proxy
    033         * implements the same
    034         * interface as the actual service, and is used to instantiate the actual service only as needed
    035         * (this is
    036         * transparent to the application).
    037         *
    038         * @param <T>
    039         * @param serviceId        unique Service id used to locate the service object (may contain <em>symbols</em>,
    040         *                         which
    041         *                         will be expanded), case is ignored
    042         * @param serviceInterface the interface implemented by the service (or an interface extended by the service
    043         *                         interface)
    044         * @return the service instance
    045         * @throws RuntimeException if the service is not defined, or if an error occurs instantiating it
    046         */
    047        <T> T getService(String serviceId, Class<T> serviceInterface);
    048
    049        /**
    050         * Locates a service given a service interface and (optionally) some marker annotation types. A single service must implement the service
    051         * interface (which                                                   * can be hard to guarantee) and by marked by all the marker types. The search takes into account inheritance of the service interface
    052         * (not the service <em>implementation</em>), which may result in a failure due to extra
    053         * matches.
    054         *
    055         * @param serviceInterface the interface the service implements
    056         * @return the service's proxy
    057         * @throws RuntimeException if the service does not exist (this is considered programmer error), or multiple
    058         *                          services directly implement, or extend from, the service interface
    059         * @see org.apache.tapestry5.ioc.annotations.Marker
    060         */
    061        <T> T getService(Class<T> serviceInterface);
    062
    063        /**
    064         * Locates a service given a service interface and (optionally) some marker annotation types. A single service must implement the service
    065         * interface (which                                                   * can be hard to guarantee) and by marked by all the marker types. The search takes into account inheritance of the service interface
    066         * (not the service <em>implementation</em>), which may result in a failure due to extra
    067         * matches.        The ability to specify marker annotation types was added in 5.3
    068         *
    069         * @param serviceInterface the interface the service implements
    070         * @param markerTypes      Markers used to select a specific service that implements the interface
    071         * @return the service's proxy
    072         * @throws RuntimeException if the service does not exist (this is considered programmer error), or multiple
    073         *                          services directly implement, or extend from, the service interface
    074         * @see org.apache.tapestry5.ioc.annotations.Marker
    075         * @since 5.3
    076         */
    077        <T> T getService(Class<T> serviceInterface, Class<? extends Annotation>... markerTypes);
    078
    079        /**
    080         * Obtains an object indirectly, using the {@link org.apache.tapestry5.ioc.services.MasterObjectProvider} service.
    081         *
    082         * @param objectType         the type of object to be returned
    083         * @param annotationProvider provides access to annotations on the field or parameter for which a value is to
    084         *                           be
    085         *                           obtained, which may be utilized in selecting an appropriate object, use
    086         *                           <strong>null</strong> when annotations are not available (in which case, selection
    087         *                           will
    088         *                           be based only on the object type)
    089         * @param <T>
    090         * @return the requested object
    091         * @see ObjectProvider
    092         */
    093        <T> T getObject(Class<T> objectType, AnnotationProvider annotationProvider);
    094
    095        /**
    096         * Autobuilds a class by finding the public constructor with the most parameters. Services and other resources or
    097         * dependencies will be injected into the parameters of the constructor and into private fields marked with the
    098         * {@link Inject} annotation. There are two cases: constructing a service implementation, and constructing
    099         * an arbitrary object. In the former case, many <em>service resources</em> are also available for injection, not
    100         * just dependencies or objects provided via
    101         * {@link MasterObjectProvider#provide(Class, AnnotationProvider, ObjectLocator, boolean)}.
    102         *
    103         * @param <T>
    104         * @param clazz the type of object to instantiate
    105         * @return the instantiated instance
    106         * @throws RuntimeException if the autobuild fails
    107         * @see MasterObjectProvider
    108         */
    109        <T> T autobuild(Class<T> clazz);
    110
    111        /**
    112         * Preferred version of {@link #autobuild(Class)} that tracks the operation using
    113         * {@link OperationTracker#invoke(String, Invokable)}.
    114         *
    115         * @param <T>
    116         * @param description description used with {@link OperationTracker}
    117         * @param clazz       the type of object to instantiate
    118         * @return the instantiated instance
    119         * @throws RuntimeException if the autobuild fails
    120         * @see MasterObjectProvider
    121         * @since 5.2.0
    122         */
    123        <T> T autobuild(String description, Class<T> clazz);
    124
    125        /**
    126         * Creates a proxy. The proxy will defer invocation of {@link #autobuild(Class)} until
    127         * just-in-time (that is, first method invocation). In a limited number of cases, it is necessary to use such a
    128         * proxy to prevent service construction cycles, particularly when contributing (directly or indirectly) to the
    129         * {@link org.apache.tapestry5.ioc.services.MasterObjectProvider} (which is itself at the heart
    130         * of autobuilding).
    131         * <p/>
    132         * If the class file for the class is a file on the file system (not a file packaged in a JAR), then the proxy will
    133         * <em>autoreload</em>: changing the class file will result in the new class being reloaded and re-instantiated
    134         * (with dependencies).
    135         *
    136         * @param <T>
    137         * @param interfaceClass      the interface implemented by the proxy
    138         * @param implementationClass a concrete class that implements the interface
    139         * @return a proxy
    140         * @see #autobuild(Class)
    141         */
    142        <T> T proxy(Class<T> interfaceClass, Class<? extends T> implementationClass);
    143    }