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 }