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 }