KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb3 > iiop > IORFactory


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.iiop;
23
24 import java.lang.annotation.Annotation JavaDoc;
25 import java.net.URL JavaDoc;
26
27 import javax.ejb.EJBHome JavaDoc;
28 import javax.ejb.EJBObject JavaDoc;
29 import javax.management.MalformedObjectNameException JavaDoc;
30 import javax.management.ObjectName JavaDoc;
31 import javax.naming.Context JavaDoc;
32 import javax.naming.InitialContext JavaDoc;
33 import javax.naming.NamingException JavaDoc;
34 import javax.rmi.PortableRemoteObject JavaDoc;
35
36 import org.jboss.annotation.ejb.IIOP;
37 import org.jboss.annotation.ejb.RemoteBinding;
38 import org.jboss.aop.Advisor;
39 import org.jboss.ejb3.Container;
40 import org.jboss.ejb3.NonSerializableFactory;
41 import org.jboss.ejb3.ProxyFactoryHelper;
42 import org.jboss.ejb3.SessionContainer;
43 import org.jboss.ejb3.remoting.RemoteProxyFactory;
44 import org.jboss.iiop.CorbaORBService;
45 import org.jboss.iiop.codebase.CodebasePolicy;
46 import org.jboss.iiop.csiv2.CSIv2Policy;
47 import org.jboss.iiop.rmi.InterfaceAnalysis;
48 import org.jboss.iiop.rmi.ir.InterfaceRepository;
49 import org.jboss.invocation.iiop.ReferenceFactory;
50 import org.jboss.invocation.iiop.ServantRegistries;
51 import org.jboss.invocation.iiop.ServantRegistry;
52 import org.jboss.invocation.iiop.ServantRegistryKind;
53 import org.jboss.logging.Logger;
54 import org.jboss.metadata.IorSecurityConfigMetaData;
55 import org.jboss.mx.loading.RepositoryClassLoader;
56 import org.jboss.mx.util.MBeanProxyExt;
57 import org.jboss.proxy.ejb.handle.HandleDelegateImpl;
58 import org.jboss.system.Registry;
59 import org.jboss.web.WebClassLoader;
60 import org.jboss.web.WebServiceMBean;
61 import org.omg.CORBA.Any JavaDoc;
62 import org.omg.CORBA.InterfaceDef JavaDoc;
63 import org.omg.CORBA.InterfaceDefHelper;
64 import org.omg.CORBA.ORB JavaDoc;
65 import org.omg.CORBA.Policy JavaDoc;
66 import org.omg.CORBA.Repository JavaDoc;
67 import org.omg.CORBA.UserException JavaDoc;
68 import org.omg.CosNaming.NameComponent JavaDoc;
69 import org.omg.CosNaming.NamingContext JavaDoc;
70 import org.omg.CosNaming.NamingContextExt JavaDoc;
71 import org.omg.CosNaming.NamingContextExtHelper JavaDoc;
72 import org.omg.CosNaming.NamingContextHelper JavaDoc;
73 import org.omg.CosNaming.NamingContextPackage.AlreadyBound JavaDoc;
74 import org.omg.CosNaming.NamingContextPackage.CannotProceed JavaDoc;
75 import org.omg.CosNaming.NamingContextPackage.InvalidName JavaDoc;
76 import org.omg.CosNaming.NamingContextPackage.NotFound JavaDoc;
77 import org.omg.PortableServer.Current JavaDoc;
78 import org.omg.PortableServer.CurrentHelper JavaDoc;
79 import org.omg.PortableServer.POA JavaDoc;
80 import org.omg.PortableServer.Servant JavaDoc;
81
82 /**
83  * Comment
84  *
85  * @author <a HREF="mailto:carlo.dewolf@jboss.com">Carlo de Wolf</a>
86  * @version $Revision: 56434 $
87  */

88 public class IORFactory
89    implements RemoteProxyFactory
90 {
91    private static final Logger log = Logger.getLogger(IORFactory.class);
92    
93    private Container container;
94    private Advisor advisor;
95    private RemoteBinding binding;
96    private String JavaDoc webServiceName = "jboss:service=WebService"; // TODO: make webServiceName configurable
97

98    // after start available
99
private String JavaDoc beanRepositoryIds[];
100    private String JavaDoc homeRepositoryIds[];
101 // private InterfaceAnalysis interfaceAnalysis;
102
private ORB JavaDoc orb;
103 // private POA poa;
104
private POA JavaDoc irPoa;
105    private InterfaceRepository iri;
106    private ServantRegistry servantRegistry;
107    private ServantRegistry homeServantRegistry;
108    private WebClassLoader wcl;
109    private ReferenceFactory referenceFactory;
110    private ReferenceFactory homeReferenceFactory;
111
112    // TODO: create a default IIOP annotation
113
private static final IIOP defaultIIOP = new IIOP()
114    {
115       public boolean interfaceRepositorySupported()
116       {
117          return false;
118       }
119
120       public String JavaDoc poa()
121       {
122          return POA_PER_SERVANT;
123       }
124       
125       public Class JavaDoc<? extends Annotation JavaDoc> annotationType()
126       {
127          return IIOP.class;
128       }
129    };
130    
131    // TODO: do I really need this method
132
public Object JavaDoc createHomeProxy()
133    {
134       try
135       {
136          org.omg.CORBA.Object JavaDoc corbaRef = homeReferenceFactory.createReference(homeRepositoryIds[0]);
137          
138          EJBHome JavaDoc corbaObj = (EJBHome JavaDoc) PortableRemoteObject.narrow(corbaRef, EJBHome JavaDoc.class);
139          
140          return corbaObj;
141       }
142       catch(Exception JavaDoc e)
143       {
144          throw new RuntimeException JavaDoc(e);
145       }
146    }
147    
148    public Object JavaDoc createProxy()
149    {
150       try
151       {
152          org.omg.CORBA.Object JavaDoc corbaRef = referenceFactory.createReference(beanRepositoryIds[0]);
153          
154          EJBObject JavaDoc corbaObj = (EJBObject JavaDoc) PortableRemoteObject.narrow(corbaRef, EJBObject JavaDoc.class);
155          
156          return corbaObj;
157       }
158       catch(Exception JavaDoc e)
159       {
160          throw new RuntimeException JavaDoc(e);
161       }
162    }
163    
164    public Object JavaDoc createProxy(Object JavaDoc id)
165    {
166       try
167       {
168          org.omg.CORBA.Object JavaDoc corbaRef = referenceFactory.createReferenceWithId(id, beanRepositoryIds[0]);
169          
170          EJBObject JavaDoc corbaObj = (EJBObject JavaDoc) PortableRemoteObject.narrow(corbaRef, EJBObject JavaDoc.class);
171          
172          return corbaObj;
173       }
174       catch(Exception JavaDoc e)
175       {
176          throw new RuntimeException JavaDoc(e);
177       }
178    }
179    
180    private IIOP getIIOP()
181    {
182       IIOP iiop = (IIOP) advisor.resolveAnnotation(IIOP.class);
183       if(iiop != null)
184          return iiop;
185       
186       return defaultIIOP;
187    }
188    
189    private String JavaDoc getJndiName()
190    {
191       return ProxyFactoryHelper.getDefaultRemoteJndiName(container);
192    }
193    
194    private String JavaDoc getServantName()
195    {
196       // TODO: is "Servant/" a good prefix for servant name
197
return "Servant/" + getJndiName();
198    }
199    
200    private WebServiceMBean getWebServer() throws MalformedObjectNameException JavaDoc
201    {
202       if(webServiceName == null)
203          throw new IllegalStateException JavaDoc("iiop is not going to work without a web service");
204       
205       return (WebServiceMBean) MBeanProxyExt.create(WebServiceMBean.class, webServiceName);
206    }
207    
208    /**
209     * Literal copy from org.jboss.proxy.ejb.IORFactory
210     */

211    private void rebind(NamingContextExt JavaDoc ctx, String JavaDoc strName, org.omg.CORBA.Object JavaDoc obj) throws Exception JavaDoc
212    {
213       NameComponent JavaDoc[] name = ctx.to_name(strName);
214       NamingContext JavaDoc intermediateCtx = ctx;
215
216       for (int i = 0; i < name.length - 1; i++ ) {
217          NameComponent JavaDoc[] relativeName = new NameComponent JavaDoc[] { name[i] };
218          try {
219             intermediateCtx = NamingContextHelper.narrow(
220                   intermediateCtx.resolve(relativeName));
221          }
222          catch (NotFound JavaDoc e) {
223             intermediateCtx = intermediateCtx.bind_new_context(relativeName);
224          }
225       }
226       intermediateCtx.rebind(new NameComponent JavaDoc[] { name[name.length - 1] }, obj);
227    }
228    
229    private void removeWebClassLoader() throws MalformedObjectNameException JavaDoc
230    {
231       getWebServer().removeClassLoader(wcl);
232    }
233    
234    public void setContainer(Container container)
235    {
236       this.container = container;
237       this.advisor = (Advisor) container; // TODO: why the cast?
238
}
239    
240    public void setRemoteBinding(RemoteBinding binding)
241    {
242       this.binding = binding;
243    }
244    
245    public void setWebServiceName(String JavaDoc name)
246    {
247       this.webServiceName = name;
248    }
249    
250    public void start() throws Exception JavaDoc
251    {
252       // TODO: IORFactory only supports 1 remote interface
253
Class JavaDoc remoteInterfaces[] = ProxyFactoryHelper.getRemoteInterfaces(container);
254       if(remoteInterfaces.length > 1)
255          log.warn("IIOP binding only works on 1 interface, using: " + remoteInterfaces[0].getName());
256       InterfaceAnalysis interfaceAnalysis = InterfaceAnalysis.getInterfaceAnalysis(remoteInterfaces[0]);
257       this.beanRepositoryIds = interfaceAnalysis.getAllTypeIds();
258       
259       InterfaceAnalysis homeInterfaceAnalysis = null;
260       Class JavaDoc homeInterface = ProxyFactoryHelper.getRemoteHomeInterface(container);
261       if(homeInterface != null)
262       {
263          if(!EJBHome JavaDoc.class.isAssignableFrom(homeInterface))
264             throw new IllegalArgumentException JavaDoc("home interface " + homeInterface.getName() + " must extend javax.ejb.EJBHome (EJB3 4.6.8)");
265          homeInterfaceAnalysis = InterfaceAnalysis.getInterfaceAnalysis(homeInterface);
266          this.homeRepositoryIds = homeInterfaceAnalysis.getAllTypeIds();
267       }
268       // To allow EJB3 Stateless beans to operate we can function without a home interface.
269

270       // Get orb and irPoa references
271
try {
272          orb = (ORB JavaDoc)new InitialContext JavaDoc().lookup("java:/" + CorbaORBService.ORB_NAME);
273       }
274       catch (NamingException JavaDoc e) {
275          throw new Exception JavaDoc("Cannot lookup java:/" + CorbaORBService.ORB_NAME + ": " + e);
276       }
277       try {
278          irPoa = (POA JavaDoc)new InitialContext JavaDoc().lookup("java:/" + CorbaORBService.IR_POA_NAME);
279       }
280       catch (NamingException JavaDoc e) {
281          throw new Exception JavaDoc("Cannot lookup java:/" + CorbaORBService.IR_POA_NAME + ": " + e);
282       }
283       
284       IIOP iiop = getIIOP();
285       if(iiop.interfaceRepositorySupported())
286       {
287          this.iri = new InterfaceRepository(orb, irPoa, getJndiName());
288          iri.mapClass(remoteInterfaces[0]);
289          if(homeInterface != null)
290             iri.mapClass(homeInterface);
291          iri.finishBuild();
292       }
293       
294       // TODO: obtain the iiop invoker name properly
295
ObjectName JavaDoc invokerName = new ObjectName JavaDoc("jboss:service=invoker,type=iiop");
296       ServantRegistries servantRegistries = (ServantRegistries) Registry.lookup(invokerName);
297       if(servantRegistries == null)
298          throw new Exception JavaDoc("can't find iiop invoker");
299       ServantRegistryKind registryWithTransientPOA;
300       ServantRegistryKind registryWithPersistentPOA;
301       if(iiop.poa().equals(IIOP.POA_PER_SERVANT))
302       {
303          registryWithTransientPOA = ServantRegistryKind.TRANSIENT_POA_PER_SERVANT;
304          registryWithPersistentPOA = ServantRegistryKind.PERSISTENT_POA_PER_SERVANT;
305       }
306       else if(iiop.poa().equals(IIOP.POA_SHARED))
307       {
308          registryWithTransientPOA = ServantRegistryKind.SHARED_TRANSIENT_POA;
309          registryWithPersistentPOA = ServantRegistryKind.SHARED_PERSISTENT_POA;
310       }
311       else
312          throw new IllegalArgumentException JavaDoc("@IIOP.poa can only be 'per-servant' or 'shared'");
313       // Only works for session container
314
this.servantRegistry = servantRegistries.getServantRegistry(registryWithTransientPOA);
315       this.homeServantRegistry = servantRegistries.getServantRegistry(registryWithPersistentPOA); // TODO: why is home interface in persistent poa?
316

317       // Hack in a WebCL (from org.jboss.ejb.EjbModule.initializeContainer)
318
// TODO: seting up a WebClassLoader needs to be done somewhere where
319
ObjectName JavaDoc on = container.getObjectName();
320       this.wcl = new EJB3IIOPWebClassLoader(on, (RepositoryClassLoader) ((SessionContainer) container).getClassloader(), getJndiName());
321       WebServiceMBean webServer = getWebServer();
322       URL JavaDoc[] codebaseURLs = {webServer.addClassLoader(wcl)};
323       wcl.setWebURLs(codebaseURLs);
324       
325       // setup a codebase policy, the CodebaseInterceptor will translate this to a TAG_JAVA_CODEBASE
326
String JavaDoc codebaseString = wcl.getCodebaseString();
327       log.debug("codebase = " + codebaseString);
328       Any JavaDoc codebase = orb.create_any();
329       codebase.insert_string(codebaseString);
330       Policy codebasePolicy;
331       codebasePolicy = orb.create_policy(CodebasePolicy.TYPE, codebase);
332       
333       // Create csiv2Policy for both home and remote containing
334
// IorSecurityConfigMetadata
335
Any JavaDoc secPolicy = orb.create_any();
336 // IorSecurityConfigMetaData iorSecurityConfigMetaData =
337
// container.getBeanMetaData().getIorSecurityConfigMetaData();
338
IorSecurityConfigMetaData iorSecurityConfigMetaData = new IorSecurityConfigMetaData(); // TODO: make ior security configurable
339
secPolicy.insert_Value(iorSecurityConfigMetaData);
340       Policy csiv2Policy = orb.create_policy(CSIv2Policy.TYPE, secPolicy);
341       
342       Policy policies[] = { codebasePolicy, csiv2Policy };
343       
344       InterfaceDef JavaDoc interfaceDef = null;
345       if(iri != null)
346       {
347          Repository ir = iri.getReference();
348          interfaceDef = InterfaceDefHelper.narrow(ir.lookup_id(beanRepositoryIds[0]));
349       }
350       
351       Current JavaDoc poaCurrent = CurrentHelper.narrow(orb.resolve_initial_references("POACurrent"));
352
353       NamingContextExt JavaDoc ctx = getNamingContextExt();
354
355       log.debug("binding servant name " + getServantName());
356       
357       Servant JavaDoc servant = new BeanCorbaServant(this, poaCurrent, container, interfaceDef, interfaceAnalysis);
358       this.referenceFactory = servantRegistry.bind(getServantName(), servant, policies);
359       
360       EJBObject JavaDoc corbaObj = (EJBObject JavaDoc) createProxy();
361       
362       rebind(ctx, getJndiName(), (org.omg.CORBA.Object JavaDoc) corbaObj);
363       
364       // TODO: use iri
365
if(homeInterfaceAnalysis != null)
366       {
367          servant = new BeanCorbaServant(this, poaCurrent, container, null, homeInterfaceAnalysis);
368          this.homeReferenceFactory = homeServantRegistry.bind(getServantName() + "Home", servant, policies);
369          
370          Object JavaDoc homeObject = createHomeProxy();
371          
372          rebind(ctx, getJndiName() + "Home", (org.omg.CORBA.Object JavaDoc) homeObject);
373       }
374       
375       // bind HandleDelegate stuff
376
Context JavaDoc compCtx = (Context JavaDoc) new InitialContext JavaDoc().lookup("java:comp");
377       NonSerializableFactory.rebind(compCtx, "ORB", orb);
378       NonSerializableFactory.rebind(compCtx, "HandleDelegate", new HandleDelegateImpl());
379    }
380    
381    public void stop() throws Exception JavaDoc
382    {
383       if(homeReferenceFactory != null)
384       {
385          unbind(getJndiName() + "Home");
386          unbindHomeServant();
387       }
388       unbind(getJndiName());
389       
390       unbindServant();
391       
392       removeWebClassLoader();
393    }
394    
395    /**
396     * Unbind the bean from CosNaming
397     */

398    private void unbind(String JavaDoc strName)
399    {
400       try
401       {
402          NamingContextExt JavaDoc corbaContext = getNamingContextExt();
403          NameComponent JavaDoc n[] = corbaContext.to_name(strName);
404          getNamingContextExt().unbind(n);
405       }
406       catch(Exception JavaDoc e)
407       {
408          log.warn("unable to unbind '" + strName + "'", e);
409       }
410    }
411    
412    private void unbindHomeServant()
413    {
414       try
415       {
416          homeServantRegistry.unbind(getServantName() + "Home");
417       }
418       catch(Exception JavaDoc e)
419       {
420          log.warn("unable to unbind home servant", e);
421       }
422    }
423    
424    private void unbindServant()
425    {
426       try
427       {
428          servantRegistry.unbind(getServantName());
429       }
430       catch(Exception JavaDoc e)
431       {
432          log.warn("unable to unbind servant", e);
433       }
434    }
435
436    private NamingContextExt JavaDoc getNamingContextExt() throws NamingException JavaDoc
437    {
438       Context JavaDoc initialContext = new InitialContext JavaDoc();
439       
440       // NOTE: eclipse editor parser crashes silently on this line (because of org.jboss.iiop.CorbaNamingService) with unknown reason
441
// that's why this method is at the end
442
return NamingContextExtHelper.narrow((org.omg.CORBA.Object JavaDoc) initialContext.lookup("java:/" + org.jboss.iiop.CorbaNamingService.NAMING_NAME));
443    }
444 }
Popular Tags