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
015package org.apache.tapestry5.ioc;
016
017import org.apache.tapestry5.ioc.annotations.Inject;
018import org.apache.tapestry5.ioc.services.MasterObjectProvider;
019
020import 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 */
029public 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}