1 16 17 package org.apache.axis.providers.java; 18 19 import org.apache.axis.AxisEngine; 20 import org.apache.axis.AxisFault; 21 import org.apache.axis.Constants; 22 import org.apache.axis.Handler; 23 import org.apache.axis.Message; 24 import org.apache.axis.MessageContext; 25 import org.apache.axis.components.logger.LogFactory; 26 import org.apache.axis.description.JavaServiceDesc; 27 import org.apache.axis.description.OperationDesc; 28 import org.apache.axis.constants.Scope; 29 import org.apache.axis.handlers.soap.SOAPService; 30 import org.apache.axis.message.SOAPEnvelope; 31 import org.apache.axis.providers.BasicProvider; 32 import org.apache.axis.session.Session; 33 import org.apache.axis.utils.ClassUtils; 34 import org.apache.axis.utils.Messages; 35 import org.apache.axis.utils.XMLUtils; 36 import org.apache.axis.utils.cache.ClassCache; 37 import org.apache.axis.utils.cache.JavaClass; 38 import org.apache.commons.logging.Log; 39 import org.xml.sax.SAXException ; 40 41 import javax.xml.rpc.holders.IntHolder ; 42 import javax.xml.rpc.server.ServiceLifecycle ; 43 import javax.xml.soap.SOAPMessage ; 44 import javax.wsdl.OperationType; 45 import java.io.Serializable ; 46 import java.util.ArrayList ; 47 import java.util.StringTokenizer ; 48 49 57 public abstract class JavaProvider extends BasicProvider 58 { 59 protected static Log log = 60 LogFactory.getLog(JavaProvider.class.getName()); 61 62 protected static Log entLog = 66 LogFactory.getLog(Constants.ENTERPRISE_LOG_CATEGORY); 67 68 public static final String OPTION_CLASSNAME = "className"; 69 public static final String OPTION_ALLOWEDMETHODS = "allowedMethods"; 70 public static final String OPTION_SCOPE = "scope"; 71 72 76 public Object getServiceObject (MessageContext msgContext, 77 Handler service, 78 String clsName, 79 IntHolder scopeHolder) 80 throws Exception 81 { 82 String serviceName = msgContext.getService().getName(); 83 84 Scope scope = Scope.getScope((String )service.getOption(OPTION_SCOPE), Scope.DEFAULT); 86 87 scopeHolder.value = scope.getValue(); 88 89 if (scope == Scope.REQUEST) { 90 return getNewServiceObject(msgContext, clsName); 92 } else if (scope == Scope.SESSION) { 93 if (serviceName == null) 95 serviceName = msgContext.getService().toString(); 96 97 Session session = msgContext.getSession(); 99 if (session != null) { 100 return getSessionServiceObject(session, serviceName, 101 msgContext, clsName); 102 } else { 103 scopeHolder.value = Scope.DEFAULT.getValue(); 105 return getNewServiceObject(msgContext, clsName); 106 } 107 } else if (scope == Scope.APPLICATION) { 108 return getApplicationScopedObject(msgContext, serviceName, clsName, scopeHolder); 110 } else if (scope == Scope.FACTORY) { 111 String objectID = msgContext.getStrProp("objectID"); 112 if (objectID == null) { 113 return getApplicationScopedObject(msgContext, serviceName, clsName, scopeHolder); 114 } 115 SOAPService svc = (SOAPService)service; 116 Object ret = svc.serviceObjects.get(objectID); 117 if (ret == null) { 118 throw new AxisFault("NoSuchObject", null, null, null); 119 } 120 return ret; 121 } 122 123 return null; 125 } 126 127 private Object getApplicationScopedObject(MessageContext msgContext, String serviceName, String clsName, IntHolder scopeHolder) throws Exception { 128 AxisEngine engine = msgContext.getAxisEngine(); 129 Session appSession = engine.getApplicationSession(); 130 if (appSession != null) { 131 return getSessionServiceObject(appSession, serviceName, 132 msgContext, clsName); 133 } else { 134 log.error(Messages.getMessage("noAppSession")); 137 scopeHolder.value = Scope.DEFAULT.getValue(); 138 return getNewServiceObject(msgContext, clsName); 139 } 140 } 141 142 145 class LockObject implements Serializable { 146 private boolean completed = false; 147 148 synchronized void waitUntilComplete() throws InterruptedException { 149 while (!completed) { 150 wait(); 151 } 152 } 153 154 synchronized void complete() { 155 completed = true; 156 notifyAll(); 157 } 158 } 159 160 166 private Object getSessionServiceObject(Session session, 167 String serviceName, 168 MessageContext msgContext, 169 String clsName) throws Exception { 170 Object obj = null; 171 boolean makeNewObject = false; 172 173 synchronized (session.getLockObject()) { 175 obj = session.get(serviceName); 177 178 if (obj == null) { 182 obj = new LockObject(); 183 makeNewObject = true; 184 session.set(serviceName, obj); 185 msgContext.getService().addSession(session); 186 } 187 } 188 189 193 if (LockObject.class == obj.getClass()) { 194 LockObject lock = (LockObject)obj; 195 196 if (makeNewObject) { 200 try { 201 obj = getNewServiceObject(msgContext, clsName); 202 session.set(serviceName, obj); 203 msgContext.getService().addSession(session); 204 } catch(final Exception e) { 205 session.remove(serviceName); 206 throw e; 207 } finally { 208 lock.complete(); 209 } 210 } else { 211 lock.waitUntilComplete(); 214 215 obj = session.get(serviceName); 218 } 219 } 220 221 return obj; 222 } 223 224 232 private Object getNewServiceObject(MessageContext msgContext, 233 String clsName) throws Exception 234 { 235 Object serviceObject = makeNewServiceObject(msgContext, clsName); 236 if (serviceObject != null && 237 serviceObject instanceof ServiceLifecycle ) { 238 ((ServiceLifecycle )serviceObject).init( 239 msgContext.getProperty(Constants.MC_SERVLET_ENDPOINT_CONTEXT)); 240 } 241 return serviceObject; 242 } 243 244 252 public abstract void processMessage (MessageContext msgContext, 253 SOAPEnvelope reqEnv, 254 SOAPEnvelope resEnv, 255 Object obj) 256 throws Exception ; 257 258 259 264 public void invoke(MessageContext msgContext) throws AxisFault { 265 if (log.isDebugEnabled()) 266 log.debug("Enter: JavaProvider::invoke (" + this + ")"); 267 268 269 270 String serviceName = msgContext.getTargetService(); 271 Handler service = msgContext.getService(); 272 273 274 275 String clsName = getServiceClassName(service); 276 277 if ((clsName == null) || clsName.equals("")) { 278 throw new AxisFault("Server.NoClassForService", 279 Messages.getMessage("noOption00", getServiceClassNameOptionName(), serviceName), 280 null, null); 281 } 282 283 IntHolder scope = new IntHolder (); 284 Object serviceObject = null; 285 286 try { 287 serviceObject = getServiceObject(msgContext, service, clsName, scope); 288 289 SOAPEnvelope resEnv = null; 290 291 OperationDesc operation = msgContext.getOperation(); 299 if (operation != null && 300 OperationType.ONE_WAY.equals(operation.getMep())) { 301 msgContext.setResponseMessage(null); 302 } else { 303 Message resMsg = msgContext.getResponseMessage(); 304 305 if (resMsg == null) { 308 resEnv = new SOAPEnvelope(msgContext.getSOAPConstants(), 309 msgContext.getSchemaVersion()); 310 311 resMsg = new Message(resEnv); 312 String encoding = XMLUtils.getEncoding(msgContext); 313 resMsg.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, encoding); 314 msgContext.setResponseMessage( resMsg ); 315 } else { 316 resEnv = resMsg.getSOAPEnvelope(); 317 } 318 } 319 320 Message reqMsg = msgContext.getRequestMessage(); 321 SOAPEnvelope reqEnv = reqMsg.getSOAPEnvelope(); 322 323 processMessage(msgContext, reqEnv, resEnv, serviceObject); 324 } catch( SAXException exp ) { 325 entLog.debug( Messages.getMessage("toAxisFault00"), exp); 326 Exception real = exp.getException(); 327 if (real == null) { 328 real = exp; 329 } 330 throw AxisFault.makeFault(real); 331 } catch( Exception exp ) { 332 entLog.debug( Messages.getMessage("toAxisFault00"), exp); 333 AxisFault fault = AxisFault.makeFault(exp); 334 if (exp instanceof RuntimeException ) { 336 fault.addFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION, 337 "true"); 338 } 339 throw fault; 340 } finally { 341 if (serviceObject != null && 344 scope.value == Scope.REQUEST.getValue() && 345 serviceObject instanceof ServiceLifecycle ) 346 { 347 ((ServiceLifecycle )serviceObject).destroy(); 348 } 349 } 350 351 if (log.isDebugEnabled()) 352 log.debug("Exit: JavaProvider::invoke (" + this + ")"); 353 } 354 355 private String getAllowedMethods(Handler service) 356 { 357 String val = (String )service.getOption(OPTION_ALLOWEDMETHODS); 358 if (val == null || val.length() == 0) { 359 val = (String )service.getOption("methodName"); 361 } 362 return val; 363 } 364 365 372 377 protected Object makeNewServiceObject(MessageContext msgContext, 378 String clsName) 379 throws Exception 380 { 381 ClassLoader cl = msgContext.getClassLoader(); 382 ClassCache cache = msgContext.getAxisEngine().getClassCache(); 383 JavaClass jc = cache.lookup(clsName, cl); 384 385 return jc.getJavaClass().newInstance(); 386 } 387 388 391 protected String getServiceClassName(Handler service) 392 { 393 return (String ) service.getOption( getServiceClassNameOptionName() ); 394 } 395 396 400 protected String getServiceClassNameOptionName() 401 { 402 return OPTION_CLASSNAME; 403 } 404 405 408 protected Class getServiceClass(String clsName, 409 SOAPService service, 410 MessageContext msgContext) 411 throws AxisFault { 412 ClassLoader cl = null; 413 Class serviceClass = null; 414 AxisEngine engine = service.getEngine(); 415 416 if (msgContext != null) { 419 cl = msgContext.getClassLoader(); 420 } else { 421 cl = Thread.currentThread().getContextClassLoader(); 422 } 423 424 if (engine != null) { 426 ClassCache cache = engine.getClassCache(); 427 try { 428 JavaClass jc = cache.lookup(clsName, cl); 429 serviceClass = jc.getJavaClass(); 430 } catch (ClassNotFoundException e) { 431 log.error(Messages.getMessage("exception00"), e); 432 throw new AxisFault(Messages.getMessage("noClassForService00", clsName), e); 433 } 434 } else { 435 try { 437 serviceClass = ClassUtils.forName(clsName, true, cl); 438 } catch (ClassNotFoundException e) { 439 log.error(Messages.getMessage("exception00"), e); 440 throw new AxisFault(Messages.getMessage("noClassForService00", clsName), e); 441 } 442 } 443 return serviceClass; 444 } 445 446 452 public void initServiceDesc(SOAPService service, MessageContext msgContext) 453 throws AxisFault 454 { 455 457 String clsName = getServiceClassName(service); 458 if (clsName == null) { 459 throw new AxisFault(Messages.getMessage("noServiceClass")); 460 } 461 Class cls = getServiceClass(clsName, service, msgContext); 462 JavaServiceDesc serviceDescription = (JavaServiceDesc)service.getServiceDescription(); 463 464 if (serviceDescription.getAllowedMethods() == null && service != null) { 466 String allowedMethods = getAllowedMethods(service); 467 if (allowedMethods != null && !"*".equals(allowedMethods)) { 468 ArrayList methodList = new ArrayList (); 469 StringTokenizer tokenizer = new StringTokenizer (allowedMethods, " ,"); 470 while (tokenizer.hasMoreTokens()) { 471 methodList.add(tokenizer.nextToken()); 472 } 473 serviceDescription.setAllowedMethods(methodList); 474 } 475 } 476 477 serviceDescription.loadServiceDescByIntrospection(cls); 478 } 479 480 } 481 | Popular Tags |