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.kernel.Kernel; 037 import org.apache.geronimo.management.geronimo.JCAManagedConnectionFactory; 038 039 /** 040 * @version $Rev: 550546 $ $Date: 2007-06-25 12:52:11 -0400 (Mon, 25 Jun 2007) $ 041 */ 042 public class ManagedConnectionFactoryWrapper implements GBeanLifecycle, DynamicGBean, JCAManagedConnectionFactory, ConnectionFactorySource { 043 044 private static final Log log = LogFactory.getLog(ManagedConnectionFactoryWrapper.class); 045 046 private final String managedConnectionFactoryClass; 047 private final String connectionFactoryInterface; 048 private final String[] implementedInterfaces; 049 private final String connectionFactoryImplClass; 050 private final String connectionInterface; 051 private final String connectionImplClass; 052 053 private final LinkedHashSet<Class> allImplementedInterfaces = new LinkedHashSet<Class>(); 054 055 private final ResourceAdapterWrapper resourceAdapterWrapper; 056 private final ConnectionManagerContainer connectionManagerContainer; 057 058 private ManagedConnectionFactory managedConnectionFactory; 059 060 private DynamicGBeanDelegate delegate; 061 062 063 private boolean registered = false; 064 private final Kernel kernel; 065 private final AbstractName abstractName; 066 private final String objectName; 067 private final ClassLoader classLoader; 068 069 //default constructor for enhancement proxy endpoint 070 public ManagedConnectionFactoryWrapper() { 071 managedConnectionFactoryClass = null; 072 connectionFactoryInterface = null; 073 implementedInterfaces = null; 074 connectionFactoryImplClass = null; 075 connectionInterface = null; 076 connectionImplClass = null; 077 kernel = null; 078 abstractName = null; 079 objectName = null; 080 classLoader = null; 081 resourceAdapterWrapper = null; 082 connectionManagerContainer = null; 083 } 084 085 public ManagedConnectionFactoryWrapper(String managedConnectionFactoryClass, 086 String connectionFactoryInterface, 087 String[] implementedInterfaces, 088 String connectionFactoryImplClass, 089 String connectionInterface, 090 String connectionImplClass, 091 ResourceAdapterWrapper resourceAdapterWrapper, 092 ConnectionManagerContainer connectionManagerContainer, 093 Kernel kernel, 094 AbstractName abstractName, 095 String objectName, 096 ClassLoader cl) throws InstantiationException, IllegalAccessException, ClassNotFoundException { 097 this.managedConnectionFactoryClass = managedConnectionFactoryClass; 098 this.connectionFactoryInterface = connectionFactoryInterface; 099 this.implementedInterfaces = implementedInterfaces; 100 this.connectionFactoryImplClass = connectionFactoryImplClass; 101 this.connectionInterface = connectionInterface; 102 this.connectionImplClass = connectionImplClass; 103 104 allImplementedInterfaces.add(cl.loadClass(connectionFactoryInterface)); 105 for (String interfaceName: implementedInterfaces) { 106 allImplementedInterfaces.add(cl.loadClass(interfaceName)); 107 } 108 109 this.resourceAdapterWrapper = resourceAdapterWrapper; 110 this.connectionManagerContainer = connectionManagerContainer; 111 112 //set up that must be done before start 113 classLoader = cl; 114 Class clazz = cl.loadClass(managedConnectionFactoryClass); 115 managedConnectionFactory = (ManagedConnectionFactory) clazz.newInstance(); 116 delegate = new DynamicGBeanDelegate(); 117 delegate.addAll(managedConnectionFactory); 118 this.kernel = kernel; 119 this.abstractName = abstractName; 120 this.objectName = objectName; 121 } 122 123 public String getManagedConnectionFactoryClass() { 124 return managedConnectionFactoryClass; 125 } 126 127 public String getConnectionFactoryInterface() { 128 return connectionFactoryInterface; 129 } 130 131 public String[] getImplementedInterfaces() { 132 return implementedInterfaces; 133 } 134 135 public String getConnectionFactoryImplClass() { 136 return connectionFactoryImplClass; 137 } 138 139 public String getConnectionInterface() { 140 return connectionInterface; 141 } 142 143 public String getConnectionImplClass() { 144 return connectionImplClass; 145 } 146 147 public ResourceAdapterWrapper getResourceAdapterWrapper() { 148 return resourceAdapterWrapper; 149 } 150 151 public Object getConnectionManagerContainer() { 152 return connectionManagerContainer; 153 } 154 155 public void doStart() throws Exception { 156 //register with resource adapter if not yet done 157 if (!registered && (managedConnectionFactory instanceof ResourceAdapterAssociation)) { 158 if (resourceAdapterWrapper == null) { 159 throw new IllegalStateException("Managed connection factory expects to be registered with a ResourceAdapter, but there is no ResourceAdapter"); 160 } 161 resourceAdapterWrapper.registerResourceAdapterAssociation((ResourceAdapterAssociation) managedConnectionFactory); 162 registered = true; 163 log.debug("Registered managedConnectionFactory with ResourceAdapter " + resourceAdapterWrapper.toString()); 164 } 165 connectionManagerContainer.doRecovery(managedConnectionFactory); 166 } 167 168 public void doStop() { 169 } 170 171 public void doFail() { 172 doStop(); 173 } 174 175 //DynamicGBean implementation 176 public Object getAttribute(String name) throws Exception { 177 Thread thread = Thread.currentThread(); 178 ClassLoader oldTCL = thread.getContextClassLoader(); 179 thread.setContextClassLoader(classLoader); 180 try { 181 return delegate.getAttribute(name); 182 } finally { 183 thread.setContextClassLoader(oldTCL); 184 } 185 } 186 187 public void setAttribute(String name, Object value) throws Exception { 188 Thread thread = Thread.currentThread(); 189 ClassLoader oldTCL = thread.getContextClassLoader(); 190 thread.setContextClassLoader(classLoader); 191 try { 192 delegate.setAttribute(name, value); 193 } finally { 194 thread.setContextClassLoader(oldTCL); 195 } 196 } 197 198 public Object invoke(String name, Object[] arguments, String[] types) throws Exception { 199 //we have no dynamic operations. 200 return null; 201 } 202 203 public Object getConnectionFactory() throws ResourceException { 204 return $getConnectionFactory(); 205 } 206 207 public Object $getResource() throws ResourceException { 208 return $getConnectionFactory(); 209 } 210 211 public Object $getConnectionFactory() throws ResourceException { 212 Object connectionFactory = connectionManagerContainer.createConnectionFactory(managedConnectionFactory); 213 for (Class intf: allImplementedInterfaces) { 214 if (!intf.isAssignableFrom(connectionFactory.getClass())) { 215 throw new ResourceException("ConnectionFactory does not implement expected interface: " + intf.getName()); 216 } 217 } 218 return connectionFactory; 219 } 220 221 public ManagedConnectionFactory $getManagedConnectionFactory() { 222 return managedConnectionFactory; 223 } 224 225 /** 226 * Gets the config properties in the form of a map where the key is the 227 * property name and the value is property type (as a Class). 228 */ 229 public Map<String, Class> getConfigProperties() { 230 String[] props = delegate.getProperties(); 231 Map<String, Class> map = new HashMap<String, Class>(); 232 for (String prop : props) { 233 if (prop.equals("logWriter")) { 234 continue; 235 } 236 map.put(prop, delegate.getPropertyType(prop)); 237 } 238 return map; 239 } 240 241 public void setConfigProperty(String property, Object value) throws Exception { 242 Class cls = delegate.getPropertyType(property); 243 if(value != null && value instanceof String && !cls.getName().equals("java.lang.String")) { 244 if(cls.isPrimitive()) { 245 if(cls.equals(int.class)) { 246 cls = Integer.class; 247 } else if(cls.equals(boolean.class)) { 248 cls = Boolean.class; 249 } else if(cls.equals(float.class)) { 250 cls = Float.class; 251 } else if(cls.equals(double.class)) { 252 cls = Double.class; 253 } else if(cls.equals(long.class)) { 254 cls = Long.class; 255 } else if(cls.equals(short.class)) { 256 cls = Short.class; 257 } else if(cls.equals(byte.class)) { 258 cls = Byte.class; 259 } else if(cls.equals(char.class)) { 260 cls = Character.class; 261 } 262 } 263 Constructor con = cls.getConstructor(new Class[]{String.class}); 264 value = con.newInstance(new Object[]{value}); 265 } 266 kernel.setAttribute(abstractName, property, value); 267 } 268 269 public Object getConfigProperty(String property) throws Exception { 270 return delegate.getAttribute(property); 271 } 272 273 public String getObjectName() { 274 return objectName; 275 } 276 277 public boolean isStateManageable() { 278 return false; 279 } 280 281 public boolean isStatisticsProvider() { 282 return false; 283 } 284 285 public boolean isEventProvider() { 286 return false; 287 } 288 }