1 53 package org.bsf.remoting.http; 54 55 import org.bsf.remoting.util.naming.PropertiesICFactory; 56 import org.apache.commons.logging.*; 57 import org.bsf.remoting.EJBDefinition; 58 import org.bsf.remoting.http.HttpServiceKey; 59 import org.bsf.remoting.http.HttpServiceRequest; 60 import org.bsf.remoting.http.HttpServiceResponse; 61 62 import javax.ejb.EJBHome ; 63 import javax.ejb.EJBObject ; 64 import javax.ejb.Handle ; 65 import javax.ejb.EJBException ; 66 import javax.naming.Context ; 67 import javax.rmi.PortableRemoteObject ; 68 import javax.servlet.ServletException ; 69 import javax.servlet.http.HttpServlet ; 70 import javax.servlet.http.HttpServletRequest ; 71 import javax.servlet.http.HttpServletResponse ; 72 import javax.servlet.http.HttpSession ; 73 import java.io.IOException ; 74 import java.io.ObjectInputStream ; 75 import java.io.ObjectOutputStream ; 76 import java.io.OutputStream ; 77 import java.lang.reflect.InvocationTargetException ; 78 import java.lang.reflect.Method ; 79 import java.rmi.NoSuchObjectException ; 80 import java.rmi.Remote ; 81 import java.rmi.RemoteException ; 82 import java.util.Hashtable ; 83 import java.util.Map ; 84 import java.security.Principal ; 85 86 97 public class HttpSessionServer extends HttpServlet { 98 99 Log log = LogFactory.getLog( HttpSessionServer.class ); 100 101 protected static Hashtable serviceCache = new Hashtable (); 103 104 private int _maxServiceIndex = 0; 106 107 private static Context _ejbContext; 109 private static String _ejbContextProperties = null; 110 111 112 private static final String STATEFULL_CACHE = "stafullCache"; 113 114 115 119 public void init() throws ServletException { 120 super.init(); 121 122 123 if ( _ejbContextProperties == null ) { 124 _ejbContextProperties = getServletContext() 125 .getInitParameter( "ejbContextProperties" ); 126 } 127 initEjbContext( _ejbContextProperties ); 128 129 } 130 131 135 protected void doPost( HttpServletRequest request, HttpServletResponse response ) 136 throws ServletException , IOException { 137 138 HttpServiceRequest httpServiceRequest = getHttpServiceRequest( request ); 140 HttpServiceResponse httpServiceResponse; 141 EJBObject remoteRef; 142 143 144 HttpSession session = request.getSession( false ); 146 147 if ( session == null ) { 148 session = request.getSession( true ); 150 151 Principal principal = request.getUserPrincipal(); 152 String username = null; 153 if (principal != null){ 154 username = principal.getName(); 155 } 156 if (username == null){ 157 username =""; 158 } 159 log.info("Creation of a new session for : " + request.getContextPath() 160 + " " + username); 161 } 162 163 try { 164 165 166 remoteRef = getEjbReference( httpServiceRequest, request ); 168 169 170 httpServiceResponse = processRemoteCall( remoteRef, httpServiceRequest, request ); 172 173 } catch( NoSuchObjectException e ) { 174 175 initEjbContext( _ejbContextProperties ); 178 serviceCache = new Hashtable (); 179 remoteRef = getEjbReference( httpServiceRequest, request ); 180 try { 181 httpServiceResponse = processRemoteCall( 182 remoteRef, httpServiceRequest, request ); 183 } catch( NoSuchObjectException ex ) { 184 httpServiceResponse = new HttpServiceResponse( 186 new RemoteException ( "Impossible to make the remote call." 187 + "Restart your application." ) ); 188 } 189 } 190 191 response.addHeader( "jsessionid", session.getId() ); 193 writeHttpServiceResponse( response, httpServiceResponse ); 194 } 195 196 200 private EJBObject getEjbReference( HttpServiceRequest httpServiceRequest, HttpServletRequest request ) { 201 EJBObject remoteRef; 202 if ( httpServiceRequest.isStateless() ) 203 remoteRef = getRemote( httpServiceRequest.getRemoteService() ); 204 else 205 remoteRef = getFromCache( httpServiceRequest.getKeyToStatefullService(), 206 request ); 207 return remoteRef; 208 } 209 210 211 213 private HttpServiceResponse processRemoteCall( EJBObject remoteService, 214 HttpServiceRequest httpServiceRequest, HttpServletRequest request ) 215 throws NoSuchObjectException { 216 217 HttpServiceResponse httpServiceResponse; 218 try { 219 String p_methodName = httpServiceRequest.getMethodName(); 220 Class [] paramTypes = httpServiceRequest.getParamTypes(); 221 Object [] p_args = httpServiceRequest.getArgs(); 222 223 HttpServiceKey newServiceKey = null; 224 Object remoteResult = null; 225 226 if ( remoteService == null ) 227 throw new IllegalArgumentException 228 ( "UserSessionBean : The remote must be not null" ); 229 230 if ( p_methodName == null ) 231 throw new IllegalArgumentException 232 ( "UserSessionBean : The invoked method must be not null" ); 233 234 235 Method invokedMethod = remoteService.getClass().getMethod( p_methodName, 236 paramTypes ); 237 238 log.debug( "Invoking : " + p_methodName ); 239 remoteResult = invokedMethod.invoke( remoteService, narrowArgs( p_args ) ); 240 241 if ( remoteResult instanceof EJBObject ) { 242 newServiceKey = new HttpServiceKey( _maxServiceIndex++ ); 245 246 putInCache( newServiceKey, (EJBObject ) remoteResult, request ); 248 249 remoteResult = newServiceKey; 251 } 252 httpServiceResponse = new HttpServiceResponse( remoteResult ); 253 } catch( InvocationTargetException e ) { 254 if ( e.getTargetException() instanceof NoSuchObjectException ) { 255 NoSuchObjectException noSuchObjectException = (NoSuchObjectException ) e.getTargetException(); 256 throw noSuchObjectException; 257 } 258 259 httpServiceResponse = new HttpServiceResponse( e.getTargetException() ); 261 } catch( NoSuchMethodException ex ) { 262 throw new RuntimeException ( ex.getLocalizedMessage() ); 263 } catch( IllegalAccessException ex ) { 264 throw new RuntimeException ( ex.getLocalizedMessage() ); 265 } 266 return httpServiceResponse; 267 } 268 269 272 private void writeHttpServiceResponse( HttpServletResponse response, HttpServiceResponse httpServiceResponse ) throws IOException { 273 OutputStream outputStream = response.getOutputStream(); 274 ObjectOutputStream oos = new ObjectOutputStream ( outputStream ); 275 oos.writeObject( httpServiceResponse ); 276 oos.close(); 277 } 278 279 282 private HttpServiceRequest getHttpServiceRequest( HttpServletRequest request ) 283 throws IOException { 284 ObjectInputStream ois = new ObjectInputStream ( 286 request.getInputStream() ); 287 HttpServiceRequest httpServiceRequest = null; 288 try { 289 httpServiceRequest = (HttpServiceRequest) 290 ois.readObject(); 291 } catch( ClassNotFoundException e ) { 292 throw new RuntimeException (e.getLocalizedMessage()); 293 } 294 ois.close(); 295 return httpServiceRequest; 296 } 297 298 299 303 private Class [] getParamTypes( Object [] p_args ) { 304 int argsLength = 0; 305 if ( p_args != null ) { 306 argsLength = p_args.length; 307 } 308 if ( argsLength == 0 ) 309 return new Class [ 0 ]; 310 Class [] types = new Class [ argsLength ]; 311 for ( int i = 0 ; i < argsLength ; i++ ) { 312 types[ i ] = p_args[ i ].getClass(); 313 } 314 return types; 315 } 316 317 318 323 private EJBObject getRemote( EJBDefinition p_service ) { 324 325 EJBObject result = null; 326 327 Object item = serviceCache.get( p_service.getJndiName() ); 328 if (item != null) 329 result = (EJBObject ) PortableRemoteObject.narrow( item, p_service.getRemoteClass() ); 330 else{ 331 try { 332 EJBHome home = (EJBHome ) PortableRemoteObject.narrow( 333 _ejbContext.lookup( p_service.getJndiName() ), p_service.getHomeClass() ); 334 Method createMethod = home.getClass().getMethod( "create", null ); 335 result = (EJBObject ) createMethod.invoke( home, null ); 336 serviceCache.put( p_service.getJndiName(), result ); 337 } catch( Exception ex ) { 338 log.fatal( "Error while getting the Home : " + p_service.getHomeClass() ); 339 log.fatal( "with the lookup on : " + p_service.getJndiName(), ex ); 340 } 341 } 342 return result; 343 } 344 345 348 private void putInCache( HttpServiceKey p_serviceKey, EJBObject p_stub, 349 HttpServletRequest request ) { 350 try { 351 getStatefulCache(request).put( p_serviceKey, p_stub.getHandle() ); 352 } catch( RemoteException ex ) { 353 log.fatal("Error during the retrieving of the stateful EJB handle." + 354 "\nThe next calls on the EJB will fail!!!", ex); 355 } 356 } 357 358 359 362 private EJBObject getFromCache( HttpServiceKey serviceKey, HttpServletRequest request ) { 363 EJBObject result = null; 364 Class remoteClass = null; 365 Handle handle = null; 366 try { 367 handle = (Handle ) getStatefulCache(request).get( serviceKey ); 368 result = handle.getEJBObject(); 369 remoteClass = result.getEJBHome().getEJBMetaData().getRemoteInterfaceClass(); 371 result = (EJBObject ) PortableRemoteObject.narrow( result, remoteClass ); 372 } catch( Exception ex ) { 373 log.fatal(ex.getLocalizedMessage(), ex); 374 throw new RuntimeException (ex.getLocalizedMessage()); 375 } return result; 377 } 378 379 385 private Map getStatefulCache( HttpServletRequest request){ 386 HttpSession session = request.getSession( false ); 387 if ( session == null ) { 388 log.error( "There is no session, it is not possible" 389 + " to call a statefull service" ); 390 return null; 391 } 392 Map statefulCache = (Map ) session.getAttribute( STATEFULL_CACHE ); 393 if (statefulCache == null){ 394 statefulCache = new Hashtable (); 395 session.setAttribute( STATEFULL_CACHE, statefulCache ); 396 } 397 return statefulCache; 398 } 399 400 403 private static Object [] narrowArgs( Object [] p_args ) { 404 if ( p_args == null ) return null; 405 int length = p_args.length; 406 Object [] result = new Object [ length ]; 407 for ( int i = 0 ; i < length ; i++ ) { 408 if ( p_args[ i ] instanceof Remote ) 409 result[ i ] = PortableRemoteObject.narrow( p_args[ i ], EJBObject .class ); 410 else 411 result[ i ] = p_args[ i ]; 412 } 413 return result; 414 } 415 416 417 private static synchronized void initEjbContext( String jndiProperties ) { 418 419 if ( _ejbContext != null ) { 420 _ejbContext = null; 421 422 System.gc(); 425 } 426 _ejbContext = PropertiesICFactory.createInitialContext( jndiProperties ); 427 } 428 429 } | Popular Tags |