001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.connector.outbound; 019 020 import java.lang.reflect.Constructor; 021 import java.util.HashMap; 022 import java.util.LinkedHashSet; 023 import java.util.Map; 024 025 import javax.resource.ResourceException; 026 import javax.resource.spi.ManagedConnectionFactory; 027 import javax.resource.spi.ResourceAdapterAssociation; 028 029 import org.apache.commons.logging.Log; 030 import org.apache.commons.logging.LogFactory; 031 import org.apache.geronimo.connector.ResourceAdapterWrapper; 032 import org.apache.geronimo.gbean.AbstractName; 033 import org.apache.geronimo.gbean.DynamicGBean; 034 import org.apache.geronimo.gbean.DynamicGBeanDelegate; 035 import org.apache.geronimo.gbean.GBeanLifecycle; 036 import org.apache.geronimo.naming.ResourceSource; 037 import org.apache.geronimo.kernel.Kernel; 038 import org.apache.geronimo.management.geronimo.JCAManagedConnectionFactory; 039 040 /** 041 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 042 */ 043 public class ManagedConnectionFactoryWrapper implements GBeanLifecycle, DynamicGBean, JCAManagedConnectionFactory, ResourceSource<ResourceException> { 044 045 private static final Log log = LogFactory.getLog(ManagedConnectionFactoryWrapper.class); 046 047 private final String managedConnectionFactoryClass; 048 private final String connectionFactoryInterface; 049 private final String[] implementedInterfaces; 050 private final String connectionFactoryImplClass; 051 private final String connectionInterface; 052 private final String connectionImplClass; 053 054 private final LinkedHashSet<Class> allImplementedInterfaces = new LinkedHashSet<Class>(); 055 056 private final ResourceAdapterWrapper resourceAdapterWrapper; 057 private final ConnectionManagerContainer connectionManagerContainer; 058 059 private ManagedConnectionFactory managedConnectionFactory; 060 061 private DynamicGBeanDelegate delegate; 062 063 064 private boolean registered = false; 065 private final Kernel kernel; 066 private final AbstractName abstractName; 067 private final String objectName; 068 private final ClassLoader classLoader; 069 070 //default constructor for enhancement proxy endpoint 071 public ManagedConnectionFactoryWrapper() { 072 managedConnectionFactoryClass = null; 073 connectionFactoryInterface = null; 074 implementedInterfaces = null; 075 connectionFactoryImplClass = null; 076 connectionInterface = null; 077 connectionImplClass = null; 078 kernel = null; 079 abstractName = null; 080 objectName = null; 081 classLoader = null; 082 resourceAdapterWrapper = null; 083 connectionManagerContainer = null; 084 } 085 086 public ManagedConnectionFactoryWrapper(String managedConnectionFactoryClass, 087 String connectionFactoryInterface, 088 String[] implementedInterfaces, 089 String connectionFactoryImplClass, 090 String connectionInterface, 091 String connectionImplClass, 092 ResourceAdapterWrapper resourceAdapterWrapper, 093 ConnectionManagerContainer connectionManagerContainer, 094 Kernel kernel, 095 AbstractName abstractName, 096 String objectName, 097 ClassLoader cl) throws InstantiationException, IllegalAccessException, ClassNotFoundException { 098 this.managedConnectionFactoryClass = managedConnectionFactoryClass; 099 this.connectionFactoryInterface = connectionFactoryInterface; 100 this.implementedInterfaces = implementedInterfaces; 101 this.connectionFactoryImplClass = connectionFactoryImplClass; 102 this.connectionInterface = connectionInterface; 103 this.connectionImplClass = connectionImplClass; 104 105 allImplementedInterfaces.add(cl.loadClass(connectionFactoryInterface)); 106 for (String interfaceName: implementedInterfaces) { 107 allImplementedInterfaces.add(cl.loadClass(interfaceName)); 108 } 109 110 this.resourceAdapterWrapper = resourceAdapterWrapper; 111 this.connectionManagerContainer = connectionManagerContainer; 112 113 //set up that must be done before start 114 classLoader = cl; 115 Class clazz = cl.loadClass(managedConnectionFactoryClass); 116 managedConnectionFactory = (ManagedConnectionFactory) clazz.newInstance(); 117 delegate = new DynamicGBeanDelegate(); 118 delegate.addAll(managedConnectionFactory); 119 this.kernel = kernel; 120 this.abstractName = abstractName; 121 this.objectName = objectName; 122 } 123 124 public String getManagedConnectionFactoryClass() { 125 return managedConnectionFactoryClass; 126 } 127 128 public String getConnectionFactoryInterface() { 129 return connectionFactoryInterface; 130 } 131 132 public String[] getImplementedInterfaces() { 133 return implementedInterfaces; 134 } 135 136 public String getConnectionFactoryImplClass() { 137 return connectionFactoryImplClass; 138 } 139 140 public String getConnectionInterface() { 141 return connectionInterface; 142 } 143 144 public String getConnectionImplClass() { 145 return connectionImplClass; 146 } 147 148 public ResourceAdapterWrapper getResourceAdapterWrapper() { 149 return resourceAdapterWrapper; 150 } 151 152 public Object getConnectionManagerContainer() { 153 return connectionManagerContainer; 154 } 155 156 public void doStart() throws Exception { 157 //register with resource adapter if not yet done 158 if (!registered && (managedConnectionFactory instanceof ResourceAdapterAssociation)) { 159 if (resourceAdapterWrapper == null) { 160 throw new IllegalStateException("Managed connection factory expects to be registered with a ResourceAdapter, but there is no ResourceAdapter"); 161 } 162 resourceAdapterWrapper.registerResourceAdapterAssociation((ResourceAdapterAssociation) managedConnectionFactory); 163 registered = true; 164 log.debug("Registered managedConnectionFactory with ResourceAdapter " + resourceAdapterWrapper.toString()); 165 } 166 connectionManagerContainer.doRecovery(managedConnectionFactory); 167 } 168 169 public void doStop() { 170 } 171 172 public void doFail() { 173 doStop(); 174 } 175 176 //DynamicGBean implementation 177 public Object getAttribute(String name) throws Exception { 178 Thread thread = Thread.currentThread(); 179 ClassLoader oldTCL = thread.getContextClassLoader(); 180 thread.setContextClassLoader(classLoader); 181 try { 182 return delegate.getAttribute(name); 183 } finally { 184 thread.setContextClassLoader(oldTCL); 185 } 186 } 187 188 public void setAttribute(String name, Object value) throws Exception { 189 Thread thread = Thread.currentThread(); 190 ClassLoader oldTCL = thread.getContextClassLoader(); 191 thread.setContextClassLoader(classLoader); 192 try { 193 delegate.setAttribute(name, value); 194 } finally { 195 thread.setContextClassLoader(oldTCL); 196 } 197 } 198 199 public Object invoke(String name, Object[] arguments, String[] types) throws Exception { 200 //we have no dynamic operations. 201 return null; 202 } 203 204 public Object getConnectionFactory() throws ResourceException { 205 return $getConnectionFactory(); 206 } 207 208 public Object $getResource() throws ResourceException { 209 return $getConnectionFactory(); 210 } 211 212 public Object $getConnectionFactory() throws ResourceException { 213 Object connectionFactory = connectionManagerContainer.createConnectionFactory(managedConnectionFactory); 214 for (Class intf: allImplementedInterfaces) { 215 if (!intf.isAssignableFrom(connectionFactory.getClass())) { 216 throw new ResourceException("ConnectionFactory does not implement expected interface: " + intf.getName()); 217 } 218 } 219 return connectionFactory; 220 } 221 222 public ManagedConnectionFactory $getManagedConnectionFactory() { 223 return managedConnectionFactory; 224 } 225 226 /** 227 * Gets the config properties in the form of a map where the key is the 228 * property name and the value is property type (as a Class). 229 */ 230 public Map<String, Class> getConfigProperties() { 231 String[] props = delegate.getProperties(); 232 Map<String, Class> map = new HashMap<String, Class>(); 233 for (String prop : props) { 234 if (prop.equals("logWriter")) { 235 continue; 236 } 237 map.put(prop, delegate.getPropertyType(prop)); 238 } 239 return map; 240 } 241 242 public void setConfigProperty(String property, Object value) throws Exception { 243 Class cls = delegate.getPropertyType(property); 244 if(value != null && value instanceof String && !cls.getName().equals("java.lang.String")) { 245 if(cls.isPrimitive()) { 246 if(cls.equals(int.class)) { 247 cls = Integer.class; 248 } else if(cls.equals(boolean.class)) { 249 cls = Boolean.class; 250 } else if(cls.equals(float.class)) { 251 cls = Float.class; 252 } else if(cls.equals(double.class)) { 253 cls = Double.class; 254 } else if(cls.equals(long.class)) { 255 cls = Long.class; 256 } else if(cls.equals(short.class)) { 257 cls = Short.class; 258 } else if(cls.equals(byte.class)) { 259 cls = Byte.class; 260 } else if(cls.equals(char.class)) { 261 cls = Character.class; 262 } 263 } 264 Constructor con = cls.getConstructor(new Class[]{String.class}); 265 value = con.newInstance(new Object[]{value}); 266 } 267 kernel.setAttribute(abstractName, property, value); 268 } 269 270 public Object getConfigProperty(String property) throws Exception { 271 return delegate.getAttribute(property); 272 } 273 274 public String getObjectName() { 275 return objectName; 276 } 277 278 public boolean isStateManageable() { 279 return false; 280 } 281 282 public boolean isStatisticsProvider() { 283 return false; 284 } 285 286 public boolean isEventProvider() { 287 return false; 288 } 289 }