KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > webservice > EjbRuntimeEndpointInfo


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.webservice;
24
25 import java.io.ByteArrayOutputStream JavaDoc;
26 import java.io.ByteArrayInputStream JavaDoc;
27 import java.io.OutputStreamWriter JavaDoc;
28 import java.io.OutputStream JavaDoc;
29 import java.io.InputStream JavaDoc;
30 import java.io.File JavaDoc;
31 import java.util.Iterator JavaDoc;
32
33 import java.rmi.Remote JavaDoc;
34
35 import com.sun.enterprise.deployment.WebServiceEndpoint;
36 import com.sun.enterprise.deployment.WebService;
37 import com.sun.enterprise.Switch;
38 import com.sun.ejb.Container;
39 import com.sun.ejb.containers.StatelessSessionContainer;
40 import com.sun.ejb.Invocation;
41 import com.sun.enterprise.InvocationManager;
42
43 import com.sun.enterprise.security.jauth.ServerAuthConfig;
44 import com.sun.enterprise.webservice.WSSCallbackHandler;
45 import com.sun.enterprise.webservice.monitoring.JAXWSEndpointImpl;
46
47 import javax.xml.rpc.handler.MessageContext JavaDoc;
48 import javax.xml.ws.soap.SOAPBinding;
49
50 import com.sun.xml.ws.spi.runtime.RuntimeEndpointInfo;
51 import com.sun.xml.ws.spi.runtime.SystemHandlerDelegate;
52 import com.sun.xml.ws.spi.runtime.WSRtObjectFactory;
53 import com.sun.xml.ws.spi.runtime.WebServiceContext;
54 import com.sun.enterprise.deployment.EjbDescriptor;
55 import com.sun.enterprise.deployment.EjbBundleDescriptor;
56 import com.sun.enterprise.deployment.ResourceReferenceDescriptor;
57
58 import com.sun.xml.ws.server.Tie;
59
60 import java.util.logging.Logger JavaDoc;
61 import java.util.logging.Level JavaDoc;
62 import com.sun.logging.LogDomains;
63
64
65 /**
66  * Runtime dispatch information about one ejb web service
67  * endpoint. This class must support concurrent access,
68  * since a single instance will be used for all web
69  * service invocations through the same ejb endpoint.
70  *
71  * @author Jerome Dochez
72  */

73 public class EjbRuntimeEndpointInfo {
74
75     protected static Logger JavaDoc logger =
76         LogDomains.getLogger(LogDomains.EJB_LOGGER);
77
78     protected WebServiceEndpoint endpoint;
79
80     protected StatelessSessionContainer container;
81
82     protected Object JavaDoc webServiceEndpointServant;
83     
84     protected ServerAuthConfig serverAuthConfig;
85
86     protected InvocationManager invManager;
87     
88     private WSRtObjectFactory rpcFactory = WSRtObjectFactory.newInstance();
89     
90     private RuntimeEndpointInfo jaxWSRuntimeInfo = null;
91     
92     private boolean handlersConfigured = false;
93     
94     protected EjbMessageDispatcher messageDispatcher = null;
95
96     public EjbRuntimeEndpointInfo(WebServiceEndpoint webServiceEndpoint,
97                                   StatelessSessionContainer ejbContainer,
98                                   Object JavaDoc servant) {
99                                   
100         endpoint = webServiceEndpoint;
101         container = ejbContainer;
102         webServiceEndpointServant = servant;
103
104         Switch theSwitch = Switch.getSwitch();
105         invManager = theSwitch.getInvocationManager();
106
107     try {
108         // merge message security policy from domain.xml and sun-specific
109
// deployment descriptor
110
serverAuthConfig = ServerAuthConfig.getConfig
111         (com.sun.enterprise.security.jauth.AuthConfig.SOAP,
112          endpoint.getMessageSecurityBinding(),
113          WSSCallbackHandler.getInstance());
114     } catch (com.sun.enterprise.security.jauth.AuthException ae) {
115             logger.log(Level.SEVERE,
116                "EJB Webservice security configuration Failure", ae);
117     }
118     }
119
120     public Container getContainer() {
121         return container;
122     }
123
124     public WebServiceEndpoint getEndpoint() {
125         return endpoint;
126     }
127
128     public ServerAuthConfig getServerAuthConfig() {
129         return serverAuthConfig;
130     }
131
132     public String JavaDoc getEndpointAddressUri() {
133         return endpoint.getEndpointAddressUri();
134     }
135
136     public RuntimeEndpointInfo prepareInvocation(boolean doPreInvoke)
137         throws Exception JavaDoc {
138
139         // For proper injection of handlers, we have to configure handler
140
// after invManager.preInvoke but the Invocation.contextData has to be set
141
// before invManager.preInvoke. So the steps of configuring jaxws handlers and
142
// init'ing jaxws is done here - this sequence is important
143
if (jaxWSRuntimeInfo==null) {
144             synchronized(this) {
145                 if(jaxWSRuntimeInfo == null) {
146                     populateRuntimeEndpointInfo();
147                 }
148             }
149         }
150
151         if(doPreInvoke) {
152             // We need to split the preInvoke tasks into stages since handlers
153
// need access to java:comp/env and method authorization must take
154
// place before handlers are run. Note that the application
155
// classloader was set much earlier when the invocation first arrived
156
// so we don't need to set it here.
157
Invocation inv = new Invocation();
158
159             // Do the portions of preInvoke that don't need a Method object.
160
inv.isWebService = true;
161             inv.container = container;
162             // XXX JD we used to do it here but now this will have to move until
163
// we actually have the msg context
164
// inv.messageContext = msgContext;
165

166             inv.transactionAttribute = Container.TX_NOT_INITIALIZED;
167
168             // If the endpoint has at least one handler, method
169
// authorization will be performed by a container-provided handler
170
// before any application handler handleRequest methods are called.
171
// Otherwise, the ejb container will do the authorization.
172
inv.securityPermissions = Container.SEC_NOT_INITIALIZED;
173
174             // AS per latest spec change, the MessageContext object ni WebSvcCtxt
175
// should be the same one as used in the ejb's interceptors'
176
javax.xml.ws.handler.MessageContext msgCtxt = rpcFactory.createMessageContext();
177             jaxWSRuntimeInfo.getWebServiceContext().setMessageContext(msgCtxt);
178             inv.setContextData(jaxWSRuntimeInfo.getWebServiceContext());
179
180             // In all cases, the WebServiceInvocationHandler will do the
181
// remaining preInvoke tasks : getContext, preInvokeTx, etc.
182
invManager.preInvoke(inv);
183         }
184
185         // Now process handlers and init jaxws RI
186
if(!handlersConfigured && doPreInvoke) {
187             synchronized(this) {
188                 if(!handlersConfigured) {
189                     // Process handlers
190
(new WsUtil()).configureJAXWSServiceHandlers(endpoint, jaxWSRuntimeInfo);
191                     jaxWSRuntimeInfo.init();
192                     handlersConfigured=true;
193                 }
194             }
195         }
196         return jaxWSRuntimeInfo;
197     }
198
199     /**
200      * Force initialization of the endpoint runtime information
201      * as well as the handlers injection
202      */

203     public RuntimeEndpointInfo initRuntimeInfo() throws Exception JavaDoc{
204         try {
205             return prepareInvocation(true);
206         } finally {
207             invManager.postInvoke(invManager.getCurrentInvocation());
208         }
209          
210     }
211      
212     /*
213      * Do NOT call this method directly since it is doing resource injection
214      * it needs access to the jndi env. call the initRuntimeInfo() instead
215      */

216     private void populateRuntimeEndpointInfo() {
217         // new to create the jax-ws runtime info if necessary
218
if (jaxWSRuntimeInfo==null) {
219             jaxWSRuntimeInfo = rpcFactory.createRuntimeEndpointInfo();
220
221             jaxWSRuntimeInfo.setPortName(endpoint.getWsdlPort());
222             jaxWSRuntimeInfo.setServiceName(endpoint.getServiceName());
223             String JavaDoc implClassName = endpoint.getEjbComponentImpl().getEjbClassName();
224             try {
225                 Class JavaDoc clazz = container.getClassLoader().loadClass(implClassName);
226                 jaxWSRuntimeInfo.setImplementorClass(clazz);
227             } catch(Exception JavaDoc cnfe) {
228                 logger.severe("Cannot load or instanciate " + implClassName);
229             }
230
231             jaxWSRuntimeInfo.setImplementor(webServiceEndpointServant);
232
233             // Set webservice context here
234
// If the endpoint has a WebServiceContext with @Resource then
235
// that has to be used
236
WebServiceContext wsc = null;
237             EjbDescriptor ejbDesc = endpoint.getEjbComponentImpl();
238             Iterator JavaDoc<ResourceReferenceDescriptor> it = ejbDesc.getResourceReferenceDescriptors().iterator();
239             while(it.hasNext()) {
240                 ResourceReferenceDescriptor r = it.next();
241                 if(r.isWebServiceContext()) {
242                     try {
243                         javax.naming.InitialContext JavaDoc ic = new javax.naming.InitialContext JavaDoc();
244                         wsc = (WebServiceContext) ic.lookup("java:comp/env/" + r.getName());
245                         break;
246                     } catch (Throwable JavaDoc t) {}//Swallow intentionally
247
}
248             }
249             if(wsc == null) {
250                 wsc = new WebServiceContextImpl();
251             }
252             jaxWSRuntimeInfo.setWebServiceContext(wsc);
253
254             // Setting Binding info
255
jaxWSRuntimeInfo.setBinding(rpcFactory.createBinding(endpoint.getProtocolBinding()));
256
257             // MTOM setting depends on this
258
WsUtil wsu = new WsUtil();
259             wsu.setMtom(jaxWSRuntimeInfo.getBinding(), endpoint);
260
261             // Set wsdl and catalog info
262
java.net.URL JavaDoc catalogURL = null;
263             File JavaDoc catalogFile = new File JavaDoc(endpoint.getBundleDescriptor().getDeploymentDescriptorDir() +
264                     File.separator + "jax-ws-catalog.xml");
265             if(catalogFile.exists()) {
266                 try {
267                     catalogURL = catalogFile.toURL();
268                 } catch(java.net.MalformedURLException JavaDoc mfue) {
269                     logger.warning(" Malformed URL " + mfue.getMessage());
270                 }
271             }
272             jaxWSRuntimeInfo.setWsdlInfo(endpoint.getWebService().getWsdlFileUrl(),
273                     rpcFactory.createEntityResolver(catalogURL));
274
275             JAXWSEndpointImpl endpointImpl = (JAXWSEndpointImpl)
276                 endpoint.getExtraAttribute(JAXWSEndpointImpl.NAME);
277             SystemHandlerDelegate delegate =
278                 JAXWSSystemHandlerDelegateFactory.getEjbDelegate
279                     (serverAuthConfig, endpoint,endpointImpl);
280
281             // set the appropriate delegate in the SOAPMessageDispatcher
282
if (endpointImpl != null) {
283                 endpointImpl.setParent(delegate);
284                 jaxWSRuntimeInfo.getBinding().setSystemHandlerDelegate(endpointImpl);
285             } else {
286                 jaxWSRuntimeInfo.getBinding().setSystemHandlerDelegate(delegate);
287             }
288         }
289     }
290
291     /**
292      * Called after attempt to handle message. This is coded defensively
293      * so we attempt to clean up no matter how much progress we made in
294      * getImplementor. One important thing is to complete the invocation
295      * manager preInvoke().
296      */

297     public void releaseImplementor() {
298         try {
299             Invocation inv = (Invocation) invManager.getCurrentInvocation();
300
301             // Only use container version of postInvoke if we got past
302
// assigning an ejb instance to this invocation. This is
303
// because the web service invocation does an InvocationManager
304
// preInvoke *before* assigning an ejb instance. So, we need
305
// to ensure that InvocationManager.postInvoke is always
306
// called. It was cleaner to keep this logic in this class
307
// and WebServiceInvocationHandler rather than change the
308
// behavior of BaseContainer.preInvoke and
309
// BaseContainer.postInvoke.
310

311             if( inv != null ) {
312                 if( inv.ejb != null ) {
313                     container.postInvoke(inv);
314                 } else {
315                     invManager.postInvoke(inv);
316                 }
317             }
318         } catch(Throwable JavaDoc t) {
319             logger.log(Level.FINE, "", t);
320         }
321
322     }
323     
324     public EjbMessageDispatcher getMessageDispatcher() {
325         if (messageDispatcher==null) {
326             messageDispatcher = new Ejb3MessageDispatcher();
327         }
328         return messageDispatcher;
329     }
330
331 }
332
Popular Tags