KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > proxy > GenericProxyFactory


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 package org.jboss.proxy;
23
24 import java.lang.reflect.Proxy JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Arrays JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import javax.management.ObjectName JavaDoc;
29
30 import org.jboss.invocation.InvocationContext;
31 import org.jboss.invocation.InvocationKey;
32 import org.jboss.invocation.Invoker;
33 import org.jboss.system.Registry;
34 import org.jboss.util.NestedRuntimeException;
35
36
37 /** A generic factory of java.lang.reflect.Proxy that constructs a proxy
38  * that is a composite of ClientContainer/Interceptors/Invoker
39  *
40  * @todo generalize the proxy/invoker factory object
41  * @author Scott.Stark@jboss.org
42  * @version $Revision: 37459 $
43  */

44 public class GenericProxyFactory
45 {
46
47    /** Create a composite proxy for the given interfaces, invoker.
48     @param id the cache id for the target object if any
49     @param targetName the name of the server side service
50     @param invoker the detached invoker stub to embed in the proxy
51     @param jndiName the JNDI name the proxy will be bound under if not null
52     @param proxyBindingName the invoker-proxy-binding name if not null
53     @param interceptorClasses the Class objects for the interceptors
54     @param loader the ClassLoader to associate the the Proxy
55     @param ifaces the Class objects for the interfaces the Proxy implements
56     */

57    public Object JavaDoc createProxy(Object JavaDoc id, ObjectName JavaDoc targetName,
58       Invoker invoker, String JavaDoc jndiName, String JavaDoc proxyBindingName,
59       ArrayList JavaDoc interceptorClasses, ClassLoader JavaDoc loader, Class JavaDoc[] ifaces)
60    {
61       return createProxy(id, targetName, invoker, jndiName, proxyBindingName, interceptorClasses, loader, ifaces, null);
62    }
63
64    /** Create a composite proxy for the given interfaces, invoker.
65     @param id the cache id for the target object if any
66     @param targetName the name of the server side service
67     @param invokerName the name of the server side JMX invoker
68     @param jndiName the JNDI name the proxy will be bound under if not null
69     @param proxyBindingName the invoker-proxy-binding name if not null
70     @param interceptorClasses the Class objects for the interceptors
71     @param loader the ClassLoader to associate the the Proxy
72     @param ifaces the Class objects for the interfaces the Proxy implements
73     */

74    public Object JavaDoc createProxy(Object JavaDoc id, ObjectName JavaDoc targetName, ObjectName JavaDoc invokerName,
75       String JavaDoc jndiName, String JavaDoc proxyBindingName,
76       ArrayList JavaDoc interceptorClasses, ClassLoader JavaDoc loader, Class JavaDoc[] ifaces)
77    {
78       Invoker invoker = (Invoker) Registry.lookup(invokerName);
79       if (invoker == null)
80          throw new RuntimeException JavaDoc("Failed to find invoker for name: " + invokerName);
81       return createProxy(id, targetName, invoker, jndiName, proxyBindingName, interceptorClasses, loader, ifaces, null);
82    }
83
84    /** Create a composite proxy for the given interfaces, invoker.
85     @param id the cache id for the target object if any
86     @param targetName the name of the server side service
87     @param invoker the detached invoker stub to embed in the proxy
88     @param jndiName the JNDI name the proxy will be bound under if not null
89     @param proxyBindingName the invoker-proxy-binding name if not null
90     @param interceptorClasses the Class objects for the interceptors
91     @param loader the ClassLoader to associate the the Proxy
92     @param ifaces the Class objects for the interfaces the Proxy implements
93     @param ctx any context to add the invocation context proxy
94     */

95    public Object JavaDoc createProxy(Object JavaDoc id, ObjectName JavaDoc targetName,
96       Invoker invoker, String JavaDoc jndiName, String JavaDoc proxyBindingName,
97       ArrayList JavaDoc interceptorClasses, ClassLoader JavaDoc loader, Class JavaDoc[] ifaces, HashMap JavaDoc ctx)
98    {
99       InvocationContext context;
100       if (ctx != null)
101          context = new InvocationContext(ctx);
102       else
103          context = new InvocationContext();
104       Integer JavaDoc nameHash = new Integer JavaDoc(targetName.hashCode());
105       context.setObjectName(nameHash);
106       context.setCacheId(id);
107       if( jndiName != null )
108          context.setValue(InvocationKey.JNDI_NAME, jndiName);
109
110       if( invoker == null )
111          throw new RuntimeException JavaDoc("Null invoker given for name: " + targetName);
112       context.setInvoker(invoker);
113       if( proxyBindingName != null )
114          context.setInvokerProxyBinding(proxyBindingName);
115
116       // If the IClientContainer interceptor was specified, use the ClientContainerEx
117
boolean wantIClientAccess = false;
118       for(int n = 0; wantIClientAccess == false && n < interceptorClasses.size(); n ++)
119       {
120          Class JavaDoc type = (Class JavaDoc) interceptorClasses.get(n);
121          wantIClientAccess = type.isAssignableFrom(IClientContainer.class);
122       }
123       ClientContainer client;
124       if( wantIClientAccess )
125       {
126          client = new ClientContainerEx(context);
127       }
128       else
129       {
130          client = new ClientContainer(context);
131       }
132
133       try
134       {
135          loadInterceptorChain(interceptorClasses, client);
136       }
137       catch(Exception JavaDoc e)
138       {
139          throw new NestedRuntimeException("Failed to load interceptor chain", e);
140       }
141
142       ArrayList JavaDoc tmp = new ArrayList JavaDoc(Arrays.asList(ifaces));
143       Class JavaDoc[] ifaces2 = new Class JavaDoc[tmp.size()];
144       tmp.toArray(ifaces2);
145       return Proxy.newProxyInstance(
146          // Classloaders
147
loader,
148          // Interfaces
149
ifaces2,
150          // Client container as invocation handler
151
client);
152    }
153
154    /** The loadInterceptorChain create instances of interceptor
155     * classes from the list of classes given by the chain array.
156     *
157     * @exception Exception if an error occurs
158     */

159    protected void loadInterceptorChain(ArrayList JavaDoc chain, ClientContainer client)
160       throws Exception JavaDoc
161    {
162       Interceptor last = null;
163       for (int i = 0; i < chain.size(); i++)
164       {
165          Class JavaDoc clazz = (Class JavaDoc)chain.get(i);
166          Interceptor interceptor = (Interceptor) clazz.newInstance();
167          if (last == null)
168          {
169             last = interceptor;
170             client.setNext(interceptor);
171          }
172          else
173          {
174             last.setNext(interceptor);
175             last = interceptor;
176          }
177       }
178    }
179 }
180
Popular Tags