Hi, I've been waiting for several days for a response. Is there something wrong with my suggestions? Are they unacceptable? Should I provide more info? Or did I submit them wrong? I can resubmit them in this case.
I'd appreciate to hear any response. Thanks, Dimitry -----Original Message----- From: Voytenko, Dimitry [mailto:[EMAIL PROTECTED]] Sent: Monday, January 27, 2003 16:27 To: '[EMAIL PROTECTED]' Cc: 'Gary L Peskin'; '[EMAIL PROTECTED]' Subject: RE: xslt/xpath function extension mechanism Hi, I'm sorry for the length of the letter and some material that may look excessive. But I thought that someone might want to comments on this. Basically I'm looking for the answers to the following questions: 1. If any of these points have already been discussed and declined, I'd like to know which ones, so I could find the reasons in the archives. 2. If anyone thinks that changes I made don't fit in the Xalan architecture or common approaches, please post your comments. 3. If anyone believes that proposed changes are not usefull or difficult to use, please post your comments. Otherwise, if these changes seem reasonable enough, I can proceed with further implementation. In this case, could anyone explain the system of posting changes and how they'll be applied? Here's what I've got so far. I want to propose to adopt two level extension resolving system: 1. Global level -- extensions that can be used in any XPath expression within any XPath client (xslt, XPathAPI, etc) 2. Local level -- extensions that can be used only with specific XPath client (only xslt or XPathAPI, etc). Extension functions will be resolved on the level 2 and then, if not found, on level 1. This is what I call resolving stack. I can name two approaches and their combination for extension mechanism. You probably have already discussed them and decided to go with run-time approach. But still, I'd like to present them here. 1. Compile-time extension resolving Here all extensions are resolved during stylesheet calculation. (+): - All extensins resolved only once and then used in many transformers. - This will remove all caches (today's ExtensionHandlerJavaClass.java, etc) - No need in the XPath ExpressionVisitor (functions will be visited automatically) (-): - Compilation and execution environments (in the extension part) must be similar. - XSLT function function-available doesn't really fit into this system, b/c it's runtime by definition, but it's still possible to do. - Limitation will have to be put on all extension functions: thread-safety and idempotent over many transformers of one stylesheet. This may be too big a limitation. - Too many changes will have to be done with the present code 2. Run-time extension resolving All extensions are resolved in run-time (in one transformer, or shared). (+): - the least amount of changes will have to be done with the present code - independent environments for compiling stylesheet and transformations. Btw, present implementation has only one point where this is not true and I believe this can be easily changed. - possibility to change extensions for each transformer (if needed) (-): - multiple (and likely extensive) extension resolving. This can be avoided by sharing ExtFunctionResolver's, but in the expence of extra synchronizations. - multiple (and likely extensive) extension lookups in the structures like Hashtable and HashMap (caches). 3. Mixed approach Here we can give up resolving stack and resolve all global extensions in the compile-time and local in the run-time. In the case when global extensions are primary used functions, this will significantly save resolving and lookup time, as well as expences on caching. I decided to go first with run-time approach, b/c compile-time imposes too serious limitations on function implementation. But it's very easy to switch to mixed approach, if we'd want to sacrifice resolving stack to benefit performance. Attached (in the following letter) are changes I propose for run-time approach (only classes I've changed). These changes are not final, but rather to show how the system will work. The classes and packages names are not final too, b/c some of the classes will be obsolete, when these changes are done and thus names can be reused. The major things that haven't been implemented here, but definetely have to be are: - unified error processing for all extensions - method caches - code concerned with different class loaders (I haven't got a chance to fully investigate the system adopted in the Xalan yet) I'm also considering a way to register extension resolvers before transformer is executed or stylesheet is compiled (similar to Xalan C++). But even w/o this functionality big subset of possible users needs will be covered. I want to stop on the following new/changed classes: 1. org.apache.xpath.extensions.ExtCallContext This is the analog of org.apache.xalan.extensions.ExpressionContext. I just wanted it to be independent from the xalan package. XPath clients (like Xalan) should provide implementation of this interface (or default can be used). I'm still not sure which part of ExpressionContext should be defined in this interface. 2. org.apache.xpath.extensions.ExtFunction All extension functions should implement this interface. I stopped on this model b/c: - it will be easier to organize unified cache for extension methods - it's more coherent with compile-time and mixed approaches - easily organizable in C++ 3. org.apache.xpath.extensions.ExtFunctionResolver This is interface for resolving functions using namespace and function name information. It is part of XPathContext class (getExtFunctionResolver) and is provided by XPath clients. Functions resolved in this interface are local, i.e. can be used only with specific xpath clients. 4. org.apache.xpath.extensions.ExtFunctionFactory This is factory that manages/caches/lookups extension functions. Functions resolved in this class are global, i.e. they can be used in any xpath expression, any xpath client. Functions are groupped into packages (ExtFunctionPackage interface). Packages are referenced by namespace URI. Packages can be installed into the factory using installPackage method. If the referenced package is not found, an attempt to lookup it is made. This mechanism in enclosed into lookupFunctionPackage method. I haven't implemented it yet, but proposed behaviour in this case is: a) check system properties for namespace uri as the property name b) ".properties" file in this package, that will list namespace-uri=java-class c) jar's META-INF/services (PkgString is installed in intializer of default factory only as an example. Most probably it'll be refernced via ".properties" file). 5. org.apache.xpath.extensions.PkgString This is just an example of global extension package for XPath. Most probably it'll be moved into the package "org.apache.xpath.extensions.packages". A number of such global (standard) packages can be defined: PkgString, PkgNumber, PkgDate, PkgNodeSet, PkgHTML, etc. We can use sets of functions defined by JavaScript, Java (java.lang), SQL 92 to define these standard extensions. They are not too numerous, but sufficient for most users needs. If this seams a good idea, I can post the proposed list of packages with functions they incorporate (I already have one). 6. org.apache.xpath.functions.FuncExtFunction I changed implementation. Now it resolves ExtFunction implementation and executes it. For now I disabled existing code for caching methods (using method key). I think, that probably it could be easier to organize it inside of XPathContext or elsewhere, but outside of current ExtensionHandler - this will make cache unified and it'll be possible to use extension resolvers concurrently from several transformers in the future. But I haven't decided on this feature yet. 7. org.apache.xpath.ExtensionsProvider This class will be removed. This also means that FuncExtElementAvailable will have to be moved to xalan package. 8. org.apache.xpath.XPathContext This class now provides access to ExtFunctionResolver and ExtCallContext implementations. 9. org.apache.xalan.transformer.TransformerImpl Now it provides ExtFunctionResolver (ExtensionsTable) implementation for XPathContext. Methods functionAvailable and extFunction will be removed. 12. org.apache.xalan.extensions.ExtensionsTable Now it's an implementation of ExtFunctionResolver. Thus methods functionAvailable and extFunction will be removed 11. org.apache.xalan.extensions.ExtensionHandler Now it's implementation of ExtFunctionPackage. Thus methods isFunctionAvailable and callFunction will be removed. 12. org\apache\xalan\extensions\ExtensionNamespacesManager Here I had to change code a little, so that not all namespaces are instantiated as Java namespaces. About extension elements and functions. I believe that these two can be unified. The same system of package/method can be used for elements. Thus ExtensionHandler class will implement both ExtFunctionPackage and ExtElementPackage interface. And ExtensionsTable will implement both ExtFunctionResolver and ExtElementResolver. About extensions in the Xalan C++. If the same system will be adopted, then, at least, all XPath global (standard) extensions can be fairly easily migrated from Java to C++ and back. This might remove some problems, may be even most of them in case of XPath. Thanks, Dimitry P.S. This is just an example of a stylesheet, that can be used for testing: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:x-str="http://xml.apache.org/xpath/string" xmlns:exslt-str="http://exslt.org/strings" xmlns:jstr="class:java.lang.String" exclude-result-prefixes="x-str exslt-str jstr" > <xsl:template match="/"> <xsl:variable name="text">Hello World!</xsl:variable> <res> <r1> <xsl:value-of select="$text"/> </r1> <r2> <xsl:choose> <xsl:when test="function-available('x-str:upper')"> <xsl:value-of select="x-str:upper($text)"/> </xsl:when> <xsl:otherwise>function unavailable: x-str:upper</xsl:otherwise> </xsl:choose> </r2> <r3> <xsl:choose> <xsl:when test="function-available('exslt-str:padding')"> <xsl:value-of select="exslt-str:padding(10, 'A')"/> </xsl:when> <xsl:otherwise>function unavailable: exslt-str:padding</xsl:otherwise> </xsl:choose> </r3> <r4> <xsl:choose> <xsl:when test="function-available('jstr:valueOf')"> <xsl:value-of select="jstr:valueOf(10.2)"/> </xsl:when> <xsl:otherwise>function unavailable: jstr:valueOf</xsl:otherwise> </xsl:choose> </r4> </res> </xsl:template> </xsl:stylesheet> _____________________________________________________ Sector Data, LLC, is not affiliated with Sector, Inc., or SIAC _____________________________________________________ Sector Data, LLC, is not affiliated with Sector, Inc., or SIAC
