KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > resource > binding > remote > RemoteConnectionFactoryService


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22
23 package org.jboss.resource.binding.remote;
24
25 import java.io.ByteArrayOutputStream JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.ObjectOutputStream JavaDoc;
28 import java.io.Serializable JavaDoc;
29 import java.lang.reflect.Method JavaDoc;
30 import java.util.ArrayList JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.Map JavaDoc;
33
34 import javax.management.ObjectName JavaDoc;
35 import javax.naming.BinaryRefAddr JavaDoc;
36 import javax.naming.InitialContext JavaDoc;
37 import javax.naming.NamingException JavaDoc;
38 import javax.naming.Reference JavaDoc;
39 import javax.naming.StringRefAddr JavaDoc;
40 import javax.resource.Referenceable JavaDoc;
41
42 import org.jboss.deployment.DeploymentException;
43 import org.jboss.invocation.Invocation;
44 import org.jboss.invocation.Invoker;
45 import org.jboss.invocation.InvokerInterceptor;
46 import org.jboss.invocation.MarshalledInvocation;
47 import org.jboss.logging.Logger;
48 import org.jboss.proxy.ClientMethodInterceptor;
49 import org.jboss.proxy.GenericProxyFactory;
50 import org.jboss.resource.adapter.jdbc.remote.DataSourceFactory;
51 import org.jboss.resource.connectionmanager.ConnectionFactoryBindingService;
52 import org.jboss.system.Registry;
53 import org.jboss.util.naming.NonSerializableFactory;
54 import org.jboss.util.naming.Util;
55
56 /**
57  * A RemoteConnectionFactoryService.
58  *
59  * @author <a HREF="weston.price@jboss.com">Weston Price</a>
60  * @version $Revision: 44979 $
61  */

62 public class RemoteConnectionFactoryService extends ConnectionFactoryBindingService implements RemoteConnectionFactoryServiceMBean
63 {
64    //TODO properties -- allow custom overriding of interceptors, lazy method map?
65

66    /** The log */
67    private static Logger log = Logger.getLogger(RemoteConnectionFactoryService.class);
68
69    /** The jmxInvokerName */
70    private ObjectName JavaDoc jmxInvokerName;
71    
72    /** The delegateInvoker */
73    private Invoker delegateInvoker;
74    
75    /** The theProxy */
76    private Object JavaDoc theProxy;
77    
78    /** The marshalledInvocationMapping */
79    private Map JavaDoc marshalledInvocationMapping = new HashMap JavaDoc();
80    
81    /** The objectMap */
82    private Map JavaDoc objectMap = new HashMap JavaDoc();
83   
84    public ObjectName JavaDoc getJMXInvokerName()
85    {
86       return jmxInvokerName;
87    }
88
89    public void setJMXInvokerName(ObjectName JavaDoc jmxInvokerName)
90    {
91       this.jmxInvokerName = jmxInvokerName;
92    }
93    
94    protected void startService() throws Exception JavaDoc
95    {
96       determineBindName();
97       createConnectionFactory();
98       
99       if(jmxInvokerName != null){
100          
101          createProxy();
102          calculateHashes();
103          bindConnectionFactory();
104          
105       }else{
106          
107          super.bindConnectionFactory();
108       }
109    
110    }
111    
112    public Object JavaDoc invoke(Invocation invocation) throws Exception JavaDoc
113    {
114       Object JavaDoc result = null;
115       
116       if(invocation instanceof MarshalledInvocation){
117          
118          MarshalledInvocation mi = (MarshalledInvocation)invocation;
119          mi.setMethodMap(marshalledInvocationMapping);
120       }
121       
122       final Method JavaDoc targetMethod = invocation.getMethod();
123       final Class JavaDoc targetClass = targetMethod.getDeclaringClass();
124       final Object JavaDoc[] targetArguments = invocation.getArguments();
125       
126       final Object JavaDoc retVal = internalInvoke(targetClass, targetMethod, targetArguments, invocation.getId());
127       
128       if(!(retVal instanceof Serializable JavaDoc) && retVal != null){
129          
130          log.debug("Creating proxy for instance " + retVal);
131          result = createProxy(retVal);
132          
133       }
134       
135       return result;
136    }
137    
138    private Object JavaDoc internalInvoke(final Class JavaDoc clazz, final Method JavaDoc method, final Object JavaDoc[] arguments, final Object JavaDoc id)
139          throws Exception JavaDoc
140    {
141
142       Object JavaDoc result = null;
143
144       //First thing, find the right underlying object to invoke the method on
145
//Object to class Map
146
if (clazz.isAssignableFrom(cf.getClass()))
147       {
148
149          InitialContext JavaDoc initCtx = new InitialContext JavaDoc();
150          Object JavaDoc boundCf = initCtx.lookup(bindName);
151          result = method.invoke(boundCf, arguments);
152          
153          
154          objectMap.put(Integer.valueOf(String.valueOf(result.hashCode())), result);
155
156       }
157       else
158       {
159
160          Object JavaDoc target = objectMap.get(id);
161
162          if (target != null)
163          {
164
165             result = method.invoke(target, arguments);
166
167             //HACK!
168
if (method.getName().equals("close"))
169             {
170                objectMap.remove(id);
171             }
172
173          }
174
175       }
176
177       return result;
178
179    }
180   
181    private void calculateHashes(Class JavaDoc clazz){
182       
183       Class JavaDoc[] interfaces = clazz.getInterfaces();
184       
185       for (int i = 0; i < interfaces.length; i++)
186       {
187          Class JavaDoc target = interfaces[i];
188          Map JavaDoc m = MarshalledInvocation.methodToHashesMap(target);
189          marshalledInvocationMapping.putAll(m);
190          
191       }
192    }
193
194    private void calculateHashes(){
195
196       Class JavaDoc[] cfInterfaces = cf.getClass().getInterfaces();
197       
198       for (int i = 0; i < cfInterfaces.length; i++)
199       {
200          Class JavaDoc clazz = cfInterfaces[i];
201          Method JavaDoc[] methods = clazz.getMethods();
202          
203          for (int j = 0; j < methods.length; j++)
204          {
205             
206             Method JavaDoc m = methods[j];
207             Long JavaDoc hash = new Long JavaDoc(MarshalledInvocation.calculateHash(m));
208             marshalledInvocationMapping.put(hash, m);
209             
210          }
211       }
212    }
213
214    private Object JavaDoc createProxy(Object JavaDoc value) throws Exception JavaDoc{
215       
216       delegateInvoker = (Invoker)Registry.lookup(jmxInvokerName);
217       log.debug("Using delegate: " + delegateInvoker + " for invoker=" + jmxInvokerName);
218       
219       //TODO -- Look at this
220
calculateHashes(value.getClass());
221       
222       final Class JavaDoc[] targetInterfaces = value.getClass().getInterfaces();
223       final ArrayList JavaDoc interceptorList = new ArrayList JavaDoc();
224       Object JavaDoc cacheID = new Integer JavaDoc(value.hashCode());
225       String JavaDoc proxyBindingName = null;
226       String JavaDoc jndiName = null;
227       
228       interceptorList.add(ClientMethodInterceptor.class);
229       interceptorList.add(InvokerInterceptor.class);
230       
231       ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
232       GenericProxyFactory proxyFactory = new GenericProxyFactory();
233       
234       Object JavaDoc proxy = proxyFactory.createProxy(cacheID, serviceName,
235             delegateInvoker, jndiName, proxyBindingName, interceptorList,
236             loader, targetInterfaces);
237       
238       objectMap.put(cacheID, value);
239       
240       return proxy;
241       
242    }
243    
244    private void createProxy() throws Exception JavaDoc{
245    
246       delegateInvoker = (Invoker)Registry.lookup(jmxInvokerName);
247       log.debug("Using delegate: " + delegateInvoker + " for invoker=" + jmxInvokerName);
248       
249       final ObjectName JavaDoc serviceName = getServiceName();
250       final Integer JavaDoc nameHash = Integer.valueOf(String.valueOf(serviceName.hashCode()));
251       Registry.bind(nameHash, serviceName);
252
253       Object JavaDoc cacheID = null;
254       String JavaDoc proxyBindingName = null;
255       String JavaDoc jndiName = null;
256       
257       final Class JavaDoc[] connectionFactoryInterface = cf.getClass().getInterfaces();
258       final ArrayList JavaDoc interceptorList = new ArrayList JavaDoc();
259       interceptorList.add(ClientMethodInterceptor.class);
260       interceptorList.add(InvokerInterceptor.class);
261       
262       ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
263       GenericProxyFactory proxyFactory = new GenericProxyFactory();
264       theProxy = proxyFactory.createProxy(cacheID, serviceName,
265             delegateInvoker, jndiName, proxyBindingName, interceptorList,
266             loader, connectionFactoryInterface);
267       
268    }
269  
270    protected void bindConnectionFactory() throws Exception JavaDoc
271    {
272       InitialContext JavaDoc initCtx = new InitialContext JavaDoc();
273
274       try
275       {
276
277          NonSerializableFactory.rebind(bindName, cf);
278          final Referenceable JavaDoc referenceable = (Referenceable JavaDoc) cf;
279
280          final ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
281          final ObjectOutputStream JavaDoc oos = new ObjectOutputStream JavaDoc(baos);
282          oos.writeObject(theProxy);
283          oos.close();
284
285          final byte[] proxyBytes = baos.toByteArray();
286          final BinaryRefAddr JavaDoc dsAddr = new BinaryRefAddr JavaDoc("ProxyData", proxyBytes);
287          final String JavaDoc remoteFactoryName = RemoteConnectionFactoryHelper.class.getName();
288          final String JavaDoc localFactoryName = cf.getClass().getName();
289
290          final Reference JavaDoc dsRef = new Reference JavaDoc(localFactoryName, dsAddr, remoteFactoryName, null);
291          referenceable.setReference(dsRef);
292
293          baos.reset();
294          final ObjectOutputStream JavaDoc oos2 = new ObjectOutputStream JavaDoc(baos);
295          oos2.writeObject(RemoteConnectionFactoryHelper.vmID);
296          oos2.close();
297          final byte[] id = baos.toByteArray();
298          final BinaryRefAddr JavaDoc localAddr = new BinaryRefAddr JavaDoc("VMID", id);
299          dsRef.add(localAddr);
300
301          final StringRefAddr JavaDoc jndiRef = new StringRefAddr JavaDoc("JndiName", bindName);
302          dsRef.add(jndiRef);
303          Util.rebind(initCtx, bindName, cf);
304
305          log.info("Bound ConnectionManager '" + serviceName + "' to JNDI name '" + bindName + "'");
306       }
307       catch (NamingException JavaDoc e)
308       {
309          log.error("Could not bind ConnectionFactory into jndi: " + bindName, e);
310          throw new DeploymentException("Could not bind ConnectionFactory into jndi: " + bindName, e);
311
312       }
313       finally
314       {
315
316          if (initCtx != null)
317          {
318
319             initCtx.close();
320
321          }
322
323       }
324
325    }
326
327
328 }
329
Popular Tags