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