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 }