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 }