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