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 }