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 015package org.apache.tapestry5.ioc.internal; 016 017import java.lang.reflect.Constructor; 018import java.util.Collection; 019import java.util.List; 020import java.util.Map; 021 022import org.apache.tapestry5.commons.AnnotationProvider; 023import org.apache.tapestry5.commons.ObjectCreator; 024import org.apache.tapestry5.commons.services.PlasticProxyFactory; 025import org.apache.tapestry5.ioc.Invokable; 026import org.apache.tapestry5.ioc.OperationTracker; 027import org.apache.tapestry5.ioc.ServiceBuilderResources; 028import org.apache.tapestry5.ioc.def.ServiceDef; 029import org.apache.tapestry5.ioc.def.ServiceDef3; 030import org.apache.tapestry5.ioc.internal.util.InternalUtils; 031import 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") 041public 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 @Override 066 public String getServiceId() 067 { 068 return serviceDef.getServiceId(); 069 } 070 071 @Override 072 public Class getServiceInterface() 073 { 074 return serviceDef.getServiceInterface(); 075 } 076 077 @Override 078 public Class getServiceImplementation() 079 { 080 return serviceDef.getServiceImplementation(); 081 } 082 083 @Override 084 public Logger getLogger() 085 { 086 return logger; 087 } 088 089 @Override 090 public <T> Collection<T> getUnorderedConfiguration(final Class<T> valueType) 091 { 092 Collection<T> result = registry.invoke( 093 "Collecting unordered configuration for service " + serviceDef.getServiceId(), 094 new Invokable<Collection<T>>() 095 { 096 @Override 097 public Collection<T> invoke() 098 { 099 return registry.getUnorderedConfiguration(serviceDef, valueType); 100 } 101 }); 102 103 logConfiguration(result); 104 105 return result; 106 } 107 108 private void logConfiguration(Collection configuration) 109 { 110 if (logger.isDebugEnabled()) 111 logger.debug(IOCMessages.constructedConfiguration(configuration)); 112 } 113 114 @Override 115 public <T> List<T> getOrderedConfiguration(final Class<T> valueType) 116 { 117 List<T> result = registry.invoke("Collecting ordered configuration for service " + serviceDef.getServiceId(), 118 new Invokable<List<T>>() 119 { 120 @Override 121 public List<T> invoke() 122 { 123 return registry.getOrderedConfiguration(serviceDef, valueType); 124 } 125 }); 126 127 logConfiguration(result); 128 129 return result; 130 } 131 132 @Override 133 public <K, V> Map<K, V> getMappedConfiguration(final Class<K> keyType, final Class<V> valueType) 134 { 135 Map<K, V> result = registry.invoke("Collecting mapped configuration for service " + serviceDef.getServiceId(), 136 new Invokable<Map<K, V>>() 137 { 138 @Override 139 public Map<K, V> invoke() 140 { 141 return registry.getMappedConfiguration(serviceDef, keyType, valueType); 142 } 143 }); 144 145 if (logger.isDebugEnabled()) 146 logger.debug(IOCMessages.constructedConfiguration(result)); 147 148 return result; 149 } 150 151 @Override 152 public Object getModuleBuilder() 153 { 154 return module.getModuleBuilder(); 155 } 156 157 @Override 158 public <T> T autobuild(String description, final Class<T> clazz) 159 { 160 assert clazz != null; 161 162 return registry.invoke(description, new Invokable<T>() 163 { 164 @Override 165 public T invoke() 166 { 167 Constructor constructor = InternalUtils.findAutobuildConstructor(clazz); 168 169 if (constructor == null) 170 throw new RuntimeException(IOCMessages.noAutobuildConstructor(clazz)); 171 172 String description = proxyFactory.getConstructorLocation(constructor).toString(); 173 174 ObjectCreator creator = new ConstructorServiceCreator(ServiceResourcesImpl.this, description, 175 constructor); 176 177 return clazz.cast(creator.createObject()); 178 } 179 }); 180 } 181 182 @Override 183 public <T> T autobuild(final Class<T> clazz) 184 { 185 assert clazz != null; 186 187 return autobuild("Autobuilding instance of class " + clazz.getName(), clazz); 188 } 189 190 @Override 191 public OperationTracker getTracker() 192 { 193 return registry; 194 } 195 196 public Class getImplementationClass() 197 { 198 return null; 199 } 200 201 @Override 202 public AnnotationProvider getClassAnnotationProvider() 203 { 204 return serviceDef.getClassAnnotationProvider(); 205 } 206 207 @Override 208 public AnnotationProvider getMethodAnnotationProvider(String methodName, Class... parameterTypes) 209 { 210 return serviceDef.getMethodAnnotationProvider(methodName, parameterTypes); 211 } 212}