Hello Glen: I appreciate and agree with your concerns, but here's where I was coming from. My goal was to auto-deploy Java code that was itself automatically generated (or precompiled), i.e. I don't have control over the code. This makes it impossible to add a meta-data method through the AxisServiceConfig mechanism, although I agree that this would be another way to do it. BTW, it seems to me that AxisServiceConfig should return something more like a ServiceDesc, i.e.
public interface AxisServiceConfig { /** Get a service descriptor */ public ServiceDesc getServiceDesc(); } otherwise it's going to end up being constantly modified to allow java-code to have the control they need over their representation as a service. Thus, the only way I had to differentiate the kind of scoping I wanted was by the filename (i.e. URL access). A hack, but I think an acceptable one since if you wanted to add application scope, you could do it like this right now without changing any code! <handler type="java:org.apache.axis.handlers.JWSHandler"> <parameter name="scope" value="application"/> <parameter name="extension" value=".jwa"/> </handler> i.e. yet another filename extension. What's going on here is weakly typed association between the filename and a set of parameters, quite powerful I think. Your thoughts appreciated. P.S. Sorry for the delay in responding, I filter my mail into sub-folders, and only caught this one by accident since it went into my 'cvs' folder. Simon. ----- Original Message ----- From: "Glen Daniels" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Thursday, June 06, 2002 7:22 AM Subject: Re: cvs commit: xml-axis/java/src/org/apache/axis/server server-config.wsdd > Hi guys! > > I'm sorry not to have been tuned in enough to this yesterday, but I'm still > travelling in San Jose and haven't been checking mail regularly. > > The idea behind what you want here is fine, Simon, but I don't think this is > the way to do it. > > We already have an interface called AxisServiceConfig. The idea of this is > that you can have a static method on your JWS class which returns one of these, > and the system uses that as the configuration metadata to determine stuff about > your class. Right now this is just for allowedMethods (which we support and > test - look at AltStockQuoteService.jws), but this is, I think, the right place > for things like scope options to go. Having different JWSHandlers for > different extensions seems to me like a heavyweight and somewhat confusing way > to do this, since we want JWS to be about the JWS file, not about the > deploy.wsdd. > > I would vastly prefer that we used the preexisting mechanism to get these > options in there (i.e. add a method to AxisServiceConfig/Impl "int getScope()" > which returns SCOPE_DEFAULT by default). > > So... > > +1 to the caching stuff in JWSProcessor! > > Tentative -1 to the scoped-JWSHandler/extension changes. > > Does this make sense? I'm open to discussion as to why your method might be > better, but it seemed to me that you just didn't notice the AxisServiceConfig > mechanism could be used to get what you want (or at least what I think you > want!). > > --Glen > > ----- Original Message ----- > From: <[EMAIL PROTECTED]> > To: <[EMAIL PROTECTED]> > Sent: Wednesday, June 05, 2002 4:26 PM > Subject: cvs commit: xml-axis/java/src/org/apache/axis/server > server-config.wsdd > > > > rsitze 2002/06/05 16:26:07 > > > > Modified: java/src/org/apache/axis/providers/java JavaProvider.java > > java/src/org/apache/axis/handlers JWSHandler.java > > JWSProcessor.java > > java/src/org/apache/axis/server server-config.wsdd > > Log: > > "Simon Tuffs" <[EMAIL PROTECTED]> > > ************************************ > > I'd like to submit a patch that makes the following changes to the JWS > processing supported by Axis. I needed these changes to implement a small > project I've been working on: > > > > o Allows the scope of a JWS hander service object to be specified in > the server-config.wsdd file, e.g. > > > > <globalConfiguration> > > <requestFlow> > > <handler type="java:org.apache.axis.handlers.JWSHandler"> > > <parameter name="scope" value="session"/> > > </handler> > > > > o Allows multiple kinds of JWS handler to be set on the global > chain, associated with a file-extension (so for example allowing .jwr files to > be scoped as request scope): > > > > <handler type="java:org.apache.axis.handlers.JWSHandler"> > > <parameter name="scope" value="request"/> > > <parameter name="extension" value=".jwr"/> > > </handler> > > > > o Cleans up various constant strings used in the JavaProvider > > > > o Uses a cache for JWS rpc objects to they don't have to be > re-instantiated on each request. > > > > Revision Changes Path > > 1.57 +34 -15 > xml-axis/java/src/org/apache/axis/providers/java/JavaProvider.java > > > > Index: JavaProvider.java > > =================================================================== > > RCS file: > /home/cvs/xml-axis/java/src/org/apache/axis/providers/java/JavaProvider.java,v > > retrieving revision 1.56 > > retrieving revision 1.57 > > diff -u -r1.56 -r1.57 > > --- JavaProvider.java 31 May 2002 19:08:09 -0000 1.56 > > +++ JavaProvider.java 5 Jun 2002 23:26:07 -0000 1.57 > > @@ -70,6 +70,7 @@ > > import org.apache.axis.encoding.TypeMapping; > > import org.apache.axis.Constants; > > import org.apache.axis.handlers.soap.SOAPService; > > +import org.apache.axis.deployment.wsdd.WSDDConstants; > > import org.apache.commons.logging.Log; > > import org.apache.commons.logging.LogFactory; > > import org.w3c.dom.Document; > > @@ -98,12 +99,30 @@ > > public static final String OPTION_ALLOWEDMETHODS = "allowedMethods"; > > public static final String OPTION_IS_STATIC = "isStatic"; > > public static final String OPTION_CLASSPATH = "classPath"; > > + > > + public static final String OPTION_SCOPE = "scope"; > > > > + // Values for the OPTION_SCOPE > > + public static final String OPTION_SCOPE_REQUEST = "Request"; > > + public static final String OPTION_SCOPE_SESSION = "Session"; > > + public static final String OPTION_SCOPE_APPLICATION = "Application"; > > + public static final String OPTION_SCOPE_DEFAULT = > OPTION_SCOPE_REQUEST; > > + > > + public static final byte BYTE_SCOPE_NOT_EXPLICIT = 0x00; > > + public static final byte BYTE_SCOPE_APPLICATION = 0x01; > > + public static final byte BYTE_SCOPE_REQUEST = 0x10; > > + public static final byte BYTE_SCOPE_SESSION = 0x11; > > + public static final byte BYTE_SCOPE_DEFAULT = BYTE_SCOPE_REQUEST; > > > > - public static final int SCOPE_REQUEST = 0; > > - public static final int SCOPE_SESSION = 1; > > - public static final int SCOPE_APPLICATION = 2; > > - > > + public static boolean isValidScope(String scope) > > + { > > + return scope == null || > > + scope.length() == 0 || > > + scope.equalsIgnoreCase(OPTION_SCOPE_REQUEST) || > > + scope.equalsIgnoreCase(OPTION_SCOPE_APPLICATION) || > > + scope.equalsIgnoreCase(OPTION_SCOPE_SESSION); > > + } > > + > > > > /** > > * Get the service object whose method actually provides the service. > > @@ -119,22 +138,22 @@ > > > > // scope can be "Request", "Session", "Application" > > // (as with Apache SOAP) > > - String scope = (String)service.getOption("scope"); > > + String scope = (String)service.getOption(OPTION_SCOPE); > > if (scope == null) { > > // default is Request scope > > - scope = "Request"; > > + scope = OPTION_SCOPE_DEFAULT; > > } > > > > - if (scope.equalsIgnoreCase("Request")) { > > + if (scope.equalsIgnoreCase(OPTION_SCOPE_REQUEST)) { > > // Convey the scope upwards > > - scopeHolder.value = SCOPE_REQUEST; > > + scopeHolder.value = BYTE_SCOPE_REQUEST; > > > > // make a one-off > > return getNewServiceObject(msgContext, clsName); > > > > - } else if (scope.equalsIgnoreCase("Session")) { > > + } else if (scope.equalsIgnoreCase(OPTION_SCOPE_SESSION)) { > > // Convey the scope upwards > > - scopeHolder.value = SCOPE_SESSION; > > + scopeHolder.value = BYTE_SCOPE_SESSION; > > > > // What do we do if serviceName is null at this point??? > > if (serviceName == null) > > @@ -154,12 +173,12 @@ > > } > > } else { > > // was no incoming session, sigh, treat as request scope > > - scopeHolder.value = SCOPE_REQUEST; > > + scopeHolder.value = BYTE_SCOPE_REQUEST; > > return getNewServiceObject(msgContext, clsName); > > } > > > > - } else if (scope.equalsIgnoreCase("Application")) { > > - scopeHolder.value = SCOPE_APPLICATION; > > + } else if (scope.equalsIgnoreCase(OPTION_SCOPE_APPLICATION)) { > > + scopeHolder.value = BYTE_SCOPE_APPLICATION; > > > > // MUST be AxisEngine here! > > AxisEngine engine = msgContext.getAxisEngine(); > > @@ -178,7 +197,7 @@ > > } else { > > // was no application session, sigh, treat as request > scope > > // FIXME : Should we bomb in this case? > > - scopeHolder.value = SCOPE_REQUEST; > > + scopeHolder.value = BYTE_SCOPE_REQUEST; > > return getNewServiceObject(msgContext, clsName); > > } > > > > @@ -304,7 +323,7 @@ > > } finally { > > // If this is a request scoped service object which > implements > > // ServiceLifecycle, let it know that it's being destroyed > now. > > - if (scope.value == SCOPE_REQUEST && > > + if (scope.value == BYTE_SCOPE_REQUEST && > > obj instanceof ServiceLifecycle) { > > ((ServiceLifecycle)obj).destroy(); > > } > > > > > > > > 1.17 +20 -3 > xml-axis/java/src/org/apache/axis/handlers/JWSHandler.java > > > > Index: JWSHandler.java > > =================================================================== > > RCS file: > /home/cvs/xml-axis/java/src/org/apache/axis/handlers/JWSHandler.java,v > > retrieving revision 1.16 > > retrieving revision 1.17 > > diff -u -r1.16 -r1.17 > > --- JWSHandler.java 9 May 2002 18:25:17 -0000 1.16 > > +++ JWSHandler.java 5 Jun 2002 23:26:07 -0000 1.17 > > @@ -63,6 +63,7 @@ > > import org.apache.commons.logging.Log; > > import org.apache.commons.logging.LogFactory; > > > > +import java.util.Hashtable; > > > > /** A <code>JWSHandler</code> sets the target service and JWS filename > > * in the context depending on the JWS configuration and the target URL. > > @@ -76,9 +77,15 @@ > > protected static Log log = > > LogFactory.getLog(JWSHandler.class.getName()); > > > > + public final String OPTION_JWS_FILE_EXTENSION = "extension"; > > + public final String DEFAULT_JWS_FILE_EXTENSION = ".jws"; > > + > > // Keep the processor Handler around so we can make it the service > > - // Handler for this request if appropriate. > > - static SOAPService processor = new SOAPService(new JWSProcessor()); > > + // Handler for this request if appropriate. No need for these to be > > + // static, since it may be desirable to have JWS handlers with > different > > + // behaviours for different file extensions. > > + JWSProcessor jws = new JWSProcessor(); > > + SOAPService processor = new SOAPService(jws); > > > > public void invoke(MessageContext msgContext) throws AxisFault > > { > > @@ -88,8 +95,10 @@ > > > > // FORCE the targetService to be JWS if the URL is right. > > String realpath = msgContext.getStrProp(Constants.MC_REALPATH); > > + String extension = (String)getOption(OPTION_JWS_FILE_EXTENSION); > > + if (extension == null) extension = DEFAULT_JWS_FILE_EXTENSION; > > > > - if ((realpath!=null) && (realpath.endsWith(".jws"))) { > > + if ((realpath!=null) && (realpath.endsWith(extension))) { > > msgContext.setService(processor); > > } > > > > @@ -100,5 +109,13 @@ > > > > public void generateWSDL(MessageContext msgContext) throws AxisFault { > > invoke(msgContext); > > + } > > + > > + /** > > + * Propagate options set on this handler into the processor. > > + */ > > + public void setOptions(Hashtable opts) { > > + super.setOptions(opts); > > + jws.setOptions(opts); > > } > > } > > > > > > > > 1.48 +31 -14 > xml-axis/java/src/org/apache/axis/handlers/JWSProcessor.java > > > > Index: JWSProcessor.java > > =================================================================== > > RCS file: > /home/cvs/xml-axis/java/src/org/apache/axis/handlers/JWSProcessor.java,v > > retrieving revision 1.47 > > retrieving revision 1.48 > > diff -u -r1.47 -r1.48 > > --- JWSProcessor.java 30 May 2002 03:06:10 -0000 1.47 > > +++ JWSProcessor.java 5 Jun 2002 23:26:07 -0000 1.48 > > @@ -83,6 +83,7 @@ > > import java.util.jar.JarFile; > > import java.util.jar.JarInputStream; > > import java.util.jar.Manifest; > > +import java.util.HashMap; > > > > /** > > * This handler will use the MC_REALPATH property of the MsgContext to > > @@ -100,6 +101,7 @@ > > protected static Log log = > > LogFactory.getLog(JWSProcessor.class.getName()); > > > > + protected static HashMap soapServices = new HashMap(); > > > > public void invoke(MessageContext msgContext) throws AxisFault > > { > > @@ -153,7 +155,7 @@ > > > > if (log.isDebugEnabled()) > > log.debug("jwsFile: " + jwsFile ); > > - > > + > > String jFile = outdir + File.separator + file.substring(0, > file.length()-3) + > > "java" ; > > String cFile = outdir + File.separator + file.substring(0, > file.length()-3) + > > @@ -249,6 +251,8 @@ > > null, new Element[] { root } ); > > } > > JWSClassLoader.removeClassLoader( clsName ); > > + // And clean out the cached service. > > + soapServices.remove(clsName); > > } > > > > JWSClassLoader cl = JWSClassLoader.getClassLoader(clsName); > > @@ -263,24 +267,37 @@ > > /* Create a new RPCProvider - this will be the "service" */ > > /* that we invoke. > */ > > > /******************************************************************/ > > - SOAPService rpc = new SOAPService(new RPCProvider()); > > - msgContext.setService( rpc ); > > + // Cache the rpc service created to handle the class. The > cache > > + // is based on class name, so only one .jws/.jwr class can be > active > > + // in the system at a time. > > + SOAPService rpc = (SOAPService)soapServices.get(clsName); > > + if (rpc == null) { > > + rpc = new SOAPService(new RPCProvider()); > > + rpc.setOption(RPCProvider.OPTION_CLASSNAME, clsName ); > > + > > + // Support specification of "allowedMethods" as a > parameter. > > + String allowed = > (String)getOption(RPCProvider.OPTION_ALLOWEDMETHODS); > > + if (allowed == null) allowed = "*"; > > + rpc.setOption(RPCProvider.OPTION_ALLOWEDMETHODS, allowed); > > + // Take the setting for the scope option from the handler > > + // parameter named "scope" > > + String scope = > (String)getOption(RPCProvider.OPTION_SCOPE); > > + if (scope == null) scope = > RPCProvider.OPTION_SCOPE_DEFAULT; > > + rpc.setOption(RPCProvider.OPTION_SCOPE, scope); > > + > > + // Set up service description > > + ServiceDesc sd = rpc.getServiceDescription(); > > + sd.setImplClass(cl.loadClass(clsName)); > > + sd.setTypeMapping(msgContext.getTypeMapping()); > > > > - rpc.setOption(RPCProvider.OPTION_CLASSNAME, clsName ); > > + soapServices.put(clsName, rpc); > > > > - /** For now, allow all methods - we probably want to have a > way to > > - * configure this in the future. > > - */ > > - rpc.setOption(RPCProvider.OPTION_ALLOWEDMETHODS, "*"); > > - > > - // Set up service description > > - ServiceDesc sd = rpc.getServiceDescription(); > > - sd.setImplClass(cl.loadClass(clsName)); > > - sd.setTypeMapping(msgContext.getTypeMapping()); > > + } > > + msgContext.setService( rpc ); > > > > // Set engine, which hooks up type mappings. > > rpc.setEngine(msgContext.getAxisEngine()); > > - > > + > > rpc.init(); // ?? > > if (doWsdl) > > rpc.generateWSDL(msgContext); > > > > > > > > 1.12 +9 -3 > xml-axis/java/src/org/apache/axis/server/server-config.wsdd > > > > Index: server-config.wsdd > > =================================================================== > > RCS file: > /home/cvs/xml-axis/java/src/org/apache/axis/server/server-config.wsdd,v > > retrieving revision 1.11 > > retrieving revision 1.12 > > diff -u -r1.11 -r1.12 > > --- server-config.wsdd 14 Feb 2002 23:01:48 -0000 1.11 > > +++ server-config.wsdd 5 Jun 2002 23:26:07 -0000 1.12 > > @@ -6,7 +6,13 @@ > > > > <globalConfiguration> > > <requestFlow> > > - <handler type="java:org.apache.axis.handlers.JWSHandler"/> > > + <handler type="java:org.apache.axis.handlers.JWSHandler"> > > + <parameter name="scope" value="session"/> > > + </handler> > > + <handler type="java:org.apache.axis.handlers.JWSHandler"> > > + <parameter name="scope" value="request"/> > > + <parameter name="extension" value=".jwr"/> > > + </handler> > > </requestFlow> > > </globalConfiguration> > > > > @@ -22,7 +28,7 @@ > > <parameter name="enableRemoteAdmin" value="false"/> > > <parameter name="className" value="org.apache.axis.utils.Admin"/> > > </service> > > - > > + > > <service name="Version" provider="java:RPC"> > > <parameter name="allowedMethods" value="getVersion"/> > > <parameter name="className" value="org.apache.axis.Version"/> > > @@ -34,7 +40,7 @@ > > <handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/> > > </requestFlow> > > </transport> > > - > > + > > <transport name="local"> > > <responseFlow> > > <handler type="java:org.apache.axis.transport.local.LocalResponder"/> > > > > > > > > > >