KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb3 > ProxyFactoryHelper


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.ejb3;
23
24 import org.jboss.annotation.ejb.LocalBinding;
25 import org.jboss.annotation.ejb.RemoteBinding;
26 import org.jboss.annotation.ejb.RemoteBindings;
27 import org.jboss.aop.Advisor;
28 import org.jboss.ejb.LocalImpl;
29 import org.jboss.ejb.RemoteImpl;
30 import org.jboss.logging.Logger;
31 import org.jboss.ejb3.remoting.RemoteProxyFactory;
32
33 import javax.ejb.Local JavaDoc;
34 import javax.ejb.LocalHome JavaDoc;
35 import javax.ejb.Remote JavaDoc;
36 import javax.ejb.RemoteHome JavaDoc;
37 import javax.jws.WebService;
38 import javax.management.ObjectName JavaDoc;
39 import javax.naming.Context JavaDoc;
40 import javax.naming.NameNotFoundException JavaDoc;
41 import javax.naming.NamingException JavaDoc;
42 import java.util.ArrayList JavaDoc;
43 import java.util.Arrays JavaDoc;
44 import java.util.Iterator JavaDoc;
45
46 /**
47  * Comment
48  *
49  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
50  * @version $Revision: 58198 $
51  */

52 public class ProxyFactoryHelper
53 {
54    private static final Logger log = Logger.getLogger(ProxyFactoryHelper.class);
55
56    public static Context JavaDoc getProxyFactoryContext(Context JavaDoc ctx)
57            throws NamingException JavaDoc
58    {
59
60       try
61       {
62          return (Context JavaDoc) ctx.lookup("proxyFactory");
63       }
64       catch (NameNotFoundException JavaDoc e)
65       {
66          return ctx.createSubcontext("proxyFactory");
67       }
68    }
69
70    public static String JavaDoc getEndpointInterface(Container container)
71    {
72       WebService ws = (javax.jws.WebService) ((EJBContainer) container).resolveAnnotation(javax.jws.WebService.class);
73       if (ws != null)
74       {
75          return ws.endpointInterface();
76       }
77       return null;
78
79    }
80
81    public static Class JavaDoc[] getLocalInterfaces(Container container)
82    {
83       Local JavaDoc li = (javax.ejb.Local JavaDoc) ((EJBContainer) container).resolveAnnotation(javax.ejb.Local JavaDoc.class);
84
85       if (li != null)
86       {
87          if (li.value().length > 0) return li.value();
88
89          // We have an emtpy @Local annotated bean class
90

91          ArrayList JavaDoc list = getBusinessInterfaces(container.getBeanClass());
92          if (list.size() == 0)
93             throw new RuntimeException JavaDoc("Use of empty @Local on bean class and there are no valid business interfaces");
94          if (list.size() > 1)
95             throw new RuntimeException JavaDoc("Use of empty @Local on bean class and there are more than one default interface");
96          Class JavaDoc[] rtn = {(Class JavaDoc) list.get(0)};
97          li = new LocalImpl(rtn);
98          ((EJBContainer) container).getAnnotations().addClassAnnotation(javax.ejb.Local JavaDoc.class, li);
99          return rtn;
100       }
101
102       Class JavaDoc beanClass = container.getBeanClass();
103       String JavaDoc endpoint = getEndpointInterface(container);
104       Class JavaDoc[] ri = getRemoteInterfaces(container);
105
106       if (li == null && ri == null && endpoint == null && (beanClass.getInterfaces() == null || beanClass.getInterfaces().length == 0))
107          throw new RuntimeException JavaDoc("bean class has no local, webservice, or remote interfaces defined and does not implement at least one business interface");
108
109       // introspect implemented interfaces.
110
if (li == null)
111       {
112          Class JavaDoc[] intfs = beanClass.getInterfaces();
113          ArrayList JavaDoc<Class JavaDoc> locals = new ArrayList JavaDoc<Class JavaDoc>();
114          for (Class JavaDoc clazz : intfs)
115          {
116             if (clazz.isAnnotationPresent(javax.ejb.Local JavaDoc.class))
117             {
118                locals.add(clazz);
119             }
120          }
121          if (locals.size() > 0)
122          {
123             intfs = locals.toArray(new Class JavaDoc[locals.size()]);
124             li = new LocalImpl(intfs);
125             ((Advisor) container).getAnnotations().addClassAnnotation(javax.ejb.Local JavaDoc.class, li);
126             //return li.value(); ALR Removed (EJBTHREE-751)
127
}
128       }
129       // no @Local interfaces implemented
130
if (li == null)
131       {
132          // search for default
133
ArrayList JavaDoc<Class JavaDoc> interfaces = getBusinessInterfaces(beanClass);
134          if (interfaces.size() != 1) return null; // indeterminate
135

136          Class JavaDoc intf = interfaces.get(0);
137          if (ri != null)
138          {
139             for (Class JavaDoc rintf : ri)
140             {
141                if (intf.getName().equals(rintf.getName()))
142                {
143                   return null;
144                }
145             }
146          }
147          if (intf.getName().equals(endpoint)) return null;
148
149          Class JavaDoc[] rtn = {intf};
150          li = new LocalImpl(rtn);
151          ((EJBContainer) container).getAnnotations().addClassAnnotation(javax.ejb.Local JavaDoc.class, li);
152          return rtn;
153       }
154       
155
156       // Check to ensure @Local and @Remote are not defined on the same interface
157
// JIRA EJBTHREE-751
158
if(ri != null)
159       {
160          for (Class JavaDoc remoteInterface : ri)
161          {
162             for (Class JavaDoc localInterface : li.value())
163             {
164                if (localInterface.equals(remoteInterface))
165                {
166                   throw new RuntimeException JavaDoc("@Remote and @Local may not both be specified on the same interface \""
167                         + remoteInterface.toString() + "\" per EJB3 Spec 4.6.7, Bullet 5.4");
168                }
169             }
170          }
171       }
172       
173       return li.value();
174    }
175
176    public static ArrayList JavaDoc<Class JavaDoc> getBusinessInterfaces(Class JavaDoc beanClass)
177    {
178       ArrayList JavaDoc<Class JavaDoc> interfaces = new ArrayList JavaDoc<Class JavaDoc>(Arrays.asList(beanClass.getInterfaces()));
179       interfaces.remove(java.io.Serializable JavaDoc.class);
180       interfaces.remove(java.io.Externalizable JavaDoc.class);
181       interfaces.remove(javax.ejb.SessionSynchronization JavaDoc.class);
182       interfaces.remove(javax.ejb.TimedObject JavaDoc.class);
183       Iterator JavaDoc<Class JavaDoc> it = interfaces.iterator();
184       while (it.hasNext())
185       {
186          if (it.next().getName().startsWith("javax.ejb")) it.remove();
187       }
188       return interfaces;
189    }
190
191    public static Class JavaDoc getLocalHomeInterface(Container container)
192    {
193       Class JavaDoc beanClass = container.getBeanClass();
194       LocalHome JavaDoc li = (javax.ejb.LocalHome JavaDoc) ((EJBContainer) container).resolveAnnotation(javax.ejb.LocalHome JavaDoc.class);
195       if (li != null) return li.value();
196       return null;
197    }
198
199    public static Class JavaDoc getRemoteHomeInterface(Container container)
200    {
201       Class JavaDoc beanClass = container.getBeanClass();
202       RemoteHome JavaDoc li = (javax.ejb.RemoteHome JavaDoc) ((EJBContainer) container).resolveAnnotation(javax.ejb.RemoteHome JavaDoc.class);
203       if (li != null) return li.value();
204       return null;
205    }
206
207    public static boolean publishesInterface(Container container, Class JavaDoc businessInterface)
208    {
209       if (!(container instanceof SessionContainer)) return false;
210       Class JavaDoc[] remotes = getRemoteInterfaces(container);
211       if (remotes != null)
212       {
213          for (Class JavaDoc intf : remotes)
214          {
215             if (intf.getName().equals(businessInterface.getName())) return true;
216          }
217       }
218
219       Class JavaDoc remoteHome = getRemoteHomeInterface(container);
220       if (remoteHome != null)
221       {
222          if (businessInterface.getName().equals(remoteHome.getName()))
223          {
224             return true;
225          }
226       }
227       Class JavaDoc[] locals = getLocalInterfaces(container);
228       if (locals != null)
229       {
230          for (Class JavaDoc clazz : locals)
231          {
232             if (clazz.getName().equals(businessInterface.getName()))
233             {
234                return true;
235             }
236          }
237       }
238       Class JavaDoc localHome = getLocalHomeInterface(container);
239       if (localHome != null)
240       {
241          if (businessInterface.getName().equals(localHome.getName()))
242          {
243             return true;
244          }
245       }
246
247       return false;
248    }
249
250    public static String JavaDoc getJndiName(Container container, Class JavaDoc businessInterface)
251    {
252       if (!(container instanceof SessionContainer)) return null;
253       Advisor advisor = (Advisor) container;
254       Class JavaDoc[] remotes = getRemoteInterfaces(container);
255       if (remotes != null)
256       {
257          for (Class JavaDoc clazz : remotes)
258          {
259             if (clazz.getName().equals(businessInterface.getName()))
260             {
261                RemoteBindings bindings = (RemoteBindings) advisor.resolveAnnotation(RemoteBindings.class);
262                if (bindings == null)
263                {
264                   RemoteBinding binding = (RemoteBinding) advisor.resolveAnnotation(RemoteBinding.class);
265                   if (binding == null)
266                      throw new RuntimeException JavaDoc("RemoteBindings should not be null: " + container.getEjbName());
267
268                   return getRemoteJndiName(container, binding);
269                }
270                return getRemoteJndiName(container, bindings.value()[0]);
271             }
272          }
273       }
274       Class JavaDoc remoteHome = getRemoteHomeInterface(container);
275       if (remoteHome != null)
276       {
277          if (businessInterface.getName().equals(remoteHome.getName()))
278          {
279             return getRemoteJndiName(container) + "Home";
280          }
281       }
282       Class JavaDoc[] locals = getLocalInterfaces(container);
283       if (locals != null)
284       {
285          for (Class JavaDoc clazz : locals)
286          {
287             if (clazz.getName().equals(businessInterface.getName()))
288             {
289                return getLocalJndiName(container);
290             }
291          }
292       }
293       Class JavaDoc localHome = getLocalHomeInterface(container);
294       if (localHome != null)
295       {
296          if (businessInterface.getName().equals(localHome.getName()))
297          {
298             return getLocalJndiName(container) + "Home";
299          }
300       }
301
302       return null;
303    }
304
305    public static String JavaDoc getLocalJndiName(Container container)
306    {
307       return getLocalJndiName(container, true);
308    }
309
310    public static String JavaDoc getLocalJndiName(Container container, boolean conflictCheck)
311    {
312       Advisor advisor = (Advisor) container;
313       LocalBinding localBinding = (LocalBinding) advisor
314               .resolveAnnotation(LocalBinding.class);
315       if (localBinding == null)
316       {
317          String JavaDoc name = container.getEjbName() + "/local";
318          DeploymentScope deploymentScope = ((EJBContainer) container).getDeployment().getEar();
319          if (deploymentScope != null) return deploymentScope.getBaseName() + "/" + name;
320
321          if (conflictCheck)
322             checkForRemoteJndiConflict(container);
323
324          return name;
325       }
326       else
327       {
328          return localBinding.jndiBinding();
329       }
330    }
331
332    private static void checkForRemoteJndiConflict(Container container)
333    {
334       if (((Advisor) container).resolveAnnotation(Remote JavaDoc.class) != null)
335       {
336          String JavaDoc remoteJndiName = getRemoteJndiName(container, false);
337          String JavaDoc ejbName = container.getEjbName();
338          if ((remoteJndiName.equals(ejbName) || remoteJndiName.startsWith(ejbName + "/")) && (!remoteJndiName.equals(ejbName + "/remote")))
339             throw new javax.ejb.EJBException JavaDoc("Conflict between default local jndi name " + ejbName + "/local and remote jndi name " + remoteJndiName + " for ejb-name:" + ejbName + ", bean class=" + container.getBeanClass());
340       }
341    }
342
343    public static Class JavaDoc[] getRemoteInterfaces(Container container)
344    {
345       Remote JavaDoc ri = (Remote JavaDoc) ((Advisor) container).resolveAnnotation(Remote JavaDoc.class);
346       if (ri == null)
347       {
348          Class JavaDoc beanClass = container.getBeanClass();
349          Class JavaDoc[] intfs = beanClass.getInterfaces();
350          ArrayList JavaDoc<Class JavaDoc> remotes = new ArrayList JavaDoc<Class JavaDoc>();
351          for (Class JavaDoc clazz : intfs)
352          {
353             if (clazz.isAnnotationPresent(Remote JavaDoc.class))
354             {
355                remotes.add(clazz);
356             }
357          }
358          if (remotes.size() > 0)
359          {
360             intfs = remotes.toArray(new Class JavaDoc[remotes.size()]);
361             ri = new RemoteImpl(intfs);
362             ((Advisor) container).getAnnotations().addClassAnnotation(Remote JavaDoc.class, ri);
363             return ri.value();
364          }
365
366          return null;
367       }
368
369       if (ri.value().length > 0) return ri.value();
370
371       // We have an emtpy @Remote annotated bean class
372

373       ArrayList JavaDoc list = getBusinessInterfaces(container.getBeanClass());
374       if (list.size() == 0)
375          throw new RuntimeException JavaDoc("Use of empty @Remote on bean class and there are no valid business interfaces");
376       if (list.size() > 1)
377          throw new RuntimeException JavaDoc("Use of empty @Remote on bean class and there are more than one default interface");
378       Class JavaDoc[] rtn = {(Class JavaDoc) list.get(0)};
379       ri = new RemoteImpl(rtn);
380       ((EJBContainer) container).getAnnotations().addClassAnnotation(javax.ejb.Remote JavaDoc.class, ri);
381       return rtn;
382    }
383
384    public static String JavaDoc getRemoteJndiName(Container container)
385    {
386       return getRemoteJndiName(container, true);
387    }
388
389    public static String JavaDoc getRemoteJndiName(Container container, boolean check)
390    {
391       Advisor advisor = (Advisor) container;
392       RemoteBinding binding = (RemoteBinding) advisor
393               .resolveAnnotation(RemoteBinding.class);
394
395       return getRemoteJndiName(container, binding);
396    }
397
398    private static void checkForLocalJndiConflict(Container container)
399    {
400       if (((Advisor) container).resolveAnnotation(Local JavaDoc.class) != null)
401       {
402          String JavaDoc localJndiName = getLocalJndiName(container, false);
403          String JavaDoc ejbName = container.getEjbName();
404          if ((localJndiName.equals(ejbName) || localJndiName.startsWith(ejbName + "/")) && (!localJndiName.equals(ejbName + "/local")))
405             throw new javax.ejb.EJBException JavaDoc("Conflict between default remote jndi name " + ejbName + "/remote and local jndi name " + localJndiName + " for ejb-name:" + ejbName + ", bean class=" + container.getBeanClass());
406
407       }
408    }
409
410    public static String JavaDoc getRemoteJndiName(Container container, RemoteBinding binding)
411    {
412       return getRemoteJndiName(container, binding, true);
413    }
414
415    public static String JavaDoc getRemoteJndiName(Container container, RemoteBinding binding, boolean conflictCheck)
416    {
417       String JavaDoc jndiName = null;
418       if (binding == null || binding.jndiBinding() == null || binding.jndiBinding().equals(""))
419       {
420          jndiName = getDefaultRemoteJndiName(container);
421
422          if (conflictCheck)
423             checkForLocalJndiConflict(container);
424       }
425       else
426       {
427          jndiName = binding.jndiBinding();
428       }
429
430       return jndiName;
431    }
432
433    public static String JavaDoc getDefaultRemoteJndiName(Container container)
434    {
435       String JavaDoc name = container.getEjbName() + "/remote";
436       DeploymentScope deploymentScope = ((EJBContainer) container).getDeployment().getEar();
437       if (deploymentScope != null) return deploymentScope.getBaseName() + "/" + name;
438       return name;
439    }
440    
441    public static String JavaDoc getClientBindUrl(RemoteBinding binding) throws Exception JavaDoc
442    {
443       String JavaDoc clientBindUrl = binding.clientBindUrl();
444       if (clientBindUrl.trim().length() == 0)
445       {
446          ObjectName JavaDoc connectionON = new ObjectName JavaDoc("jboss.remoting:type=Connector,name=DefaultEjb3Connector,handler=ejb3");
447          KernelAbstraction kernelAbstraction = KernelAbstractionFactory.getInstance();
448          try
449          {
450             clientBindUrl = (String JavaDoc)kernelAbstraction.getAttribute(connectionON, "InvokerLocator");
451          }
452          catch (Exception JavaDoc e)
453          {
454             clientBindUrl = RemoteProxyFactory.DEFAULT_CLIENT_BINDING;
455          }
456       }
457       
458       return clientBindUrl;
459    }
460 }
461
Popular Tags