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    }