001 // Copyright 2006, 2007, 2008, 2009, 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.internal;
016
017 import java.lang.reflect.Constructor;
018 import java.util.Collection;
019 import java.util.List;
020 import java.util.Map;
021
022 import org.apache.tapestry5.ioc.AnnotationProvider;
023 import org.apache.tapestry5.ioc.Invokable;
024 import org.apache.tapestry5.ioc.ObjectCreator;
025 import org.apache.tapestry5.ioc.OperationTracker;
026 import org.apache.tapestry5.ioc.ServiceBuilderResources;
027 import org.apache.tapestry5.ioc.def.ServiceDef;
028 import org.apache.tapestry5.ioc.def.ServiceDef3;
029 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
030 import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
031 import org.slf4j.Logger;
032
033 /**
034 * Implementation of {@link org.apache.tapestry5.ioc.ServiceBuilderResources}. We just have one
035 * implementation that fills the purposes of methods that need a {@link org.apache.tapestry5.ioc.ServiceResources}
036 * (which includes service decorator methods) as well as methods that need a
037 * {@link org.apache.tapestry5.ioc.ServiceBuilderResources} (which is just service builder methods). Since it is most
038 * commonly used for the former, we'll just leave the name as ServiceResourcesImpl.
039 */
040 @SuppressWarnings("all")
041 public class ServiceResourcesImpl extends ObjectLocatorImpl implements ServiceBuilderResources
042 {
043 private final InternalRegistry registry;
044
045 private final Module module;
046
047 private final ServiceDef3 serviceDef;
048
049 private final Logger logger;
050
051 private final PlasticProxyFactory proxyFactory;
052
053 public ServiceResourcesImpl(InternalRegistry registry, Module module, ServiceDef3 serviceDef,
054 PlasticProxyFactory proxyFactory, Logger logger)
055 {
056 super(registry, module);
057
058 this.registry = registry;
059 this.module = module;
060 this.serviceDef = serviceDef;
061 this.proxyFactory = proxyFactory;
062 this.logger = logger;
063 }
064
065 public String getServiceId()
066 {
067 return serviceDef.getServiceId();
068 }
069
070 public Class getServiceInterface()
071 {
072 return serviceDef.getServiceInterface();
073 }
074
075 public Logger getLogger()
076 {
077 return logger;
078 }
079
080 public <T> Collection<T> getUnorderedConfiguration(final Class<T> valueType)
081 {
082 Collection<T> result = registry.invoke(
083 "Collecting unordered configuration for service " + serviceDef.getServiceId(),
084 new Invokable<Collection<T>>()
085 {
086 public Collection<T> invoke()
087 {
088 return registry.getUnorderedConfiguration(serviceDef, valueType);
089 }
090 });
091
092 logConfiguration(result);
093
094 return result;
095 }
096
097 private void logConfiguration(Collection configuration)
098 {
099 if (logger.isDebugEnabled())
100 logger.debug(IOCMessages.constructedConfiguration(configuration));
101 }
102
103 public <T> List<T> getOrderedConfiguration(final Class<T> valueType)
104 {
105 List<T> result = registry.invoke("Collecting ordered configuration for service " + serviceDef.getServiceId(),
106 new Invokable<List<T>>()
107 {
108 public List<T> invoke()
109 {
110 return registry.getOrderedConfiguration(serviceDef, valueType);
111 }
112 });
113
114 logConfiguration(result);
115
116 return result;
117 }
118
119 public <K, V> Map<K, V> getMappedConfiguration(final Class<K> keyType, final Class<V> valueType)
120 {
121 Map<K, V> result = registry.invoke("Collecting mapped configuration for service " + serviceDef.getServiceId(),
122 new Invokable<Map<K, V>>()
123 {
124 public Map<K, V> invoke()
125 {
126 return registry.getMappedConfiguration(serviceDef, keyType, valueType);
127 }
128 });
129
130 if (logger.isDebugEnabled())
131 logger.debug(IOCMessages.constructedConfiguration(result));
132
133 return result;
134 }
135
136 public Object getModuleBuilder()
137 {
138 return module.getModuleBuilder();
139 }
140
141 @Override
142 public <T> T autobuild(String description, final Class<T> clazz)
143 {
144 assert clazz != null;
145
146 return registry.invoke(description, new Invokable<T>()
147 {
148 public T invoke()
149 {
150 Constructor constructor = InternalUtils.findAutobuildConstructor(clazz);
151
152 if (constructor == null)
153 throw new RuntimeException(IOCMessages.noAutobuildConstructor(clazz));
154
155 String description = proxyFactory.getConstructorLocation(constructor).toString();
156
157 ObjectCreator creator = new ConstructorServiceCreator(ServiceResourcesImpl.this, description,
158 constructor);
159
160 return clazz.cast(creator.createObject());
161 }
162 });
163 }
164
165 @Override
166 public <T> T autobuild(final Class<T> clazz)
167 {
168 assert clazz != null;
169
170 return autobuild("Autobuilding instance of class " + clazz.getName(), clazz);
171 }
172
173 public OperationTracker getTracker()
174 {
175 return registry;
176 }
177
178 public Class getImplementationClass()
179 {
180 return null;
181 }
182
183 public AnnotationProvider getClassAnnotationProvider()
184 {
185 return serviceDef.getClassAnnotationProvider();
186 }
187
188 public AnnotationProvider getMethodAnnotationProvider(String methodName, Class... parameterTypes)
189 {
190 return serviceDef.getMethodAnnotationProvider(methodName, parameterTypes);
191 }
192 }