Hello,
I have made a patch that will allow you to write Java extension
functions for the xpath engine, as well as extension elements, that have a
- character in their name. (Hyphens are notallowed in java method names)
When the extension function is implemented in Java, then before selecting
the java method name, the hyphen characters are removed and the letter
following them is uppercased.
This allows you to call a function to-string($object) in xpath,
which results in a call to the toString() method in Java. Or
has-sames-nodes instead of hasSameNodes.
It is of course completely syntactic sugar, but it seems that in the XML
world it is common to use hyphens where Java uses upper-case.
The XT engine does the same with extension functions.
An example:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:date="xalan://java.util.Date">
<xsl:template match="/">
<out>
<xsl:value-of select="date:to-string(date:new())"/>
</out>
</xsl:template>
</xsl:stylesheet>
Attached to this e-mail is the patch.
Is this nice to have in Xalan?
Best,
Erwin Bolwidt
P.s. I sent this earlier from an e-mail address that isn't subscribed to
this list. Is it safe to assume that this list ignores e-mails from
non-subscribers?
diff -u -r --exclude=*~
old/xalan-j_2_1_0/src/org/apache/xalan/extensions/ExtensionHandlerJava.java
src/org/apache/xalan/extensions/ExtensionHandlerJava.java
--- old/xalan-j_2_1_0/src/org/apache/xalan/extensions/ExtensionHandlerJava.java Wed
May 23 14:43:34 2001
+++ src/org/apache/xalan/extensions/ExtensionHandlerJava.java Wed Jul 4 13:55:25
+2001
@@ -75,6 +75,37 @@
private Hashtable m_cachedMethods = new Hashtable();
/**
+ * Converts an xpath function name to a Java name (method name, class name
+ * and/or package name).
+ * Currently, there is one translation. Hyphens are allowed
+ * in XPath function names, but not in Java names. The standard
+ * XPath functions use the hyphen character where a Java name would
+ * have an uppercase character in the name; the XPath function
+ * local-name would be called localName if it where a Java method.
+ * So each hyphen is removed and the letter after it is upper-cased.
+ *
+ * @param functionName name of xpath function
+ * @return java name for specified xpath function name
+ */
+ protected String mangleFunctionName(String functionName)
+ {
+ if (functionName.indexOf('-') == -1) {
+ return functionName;
+ }
+ int l = functionName.length();
+ StringBuffer javaName = new StringBuffer(l);
+ for (int i = 0; i < l; i++) {
+ char c = functionName.charAt(i);
+ // Skip multiple consequtive hyphens
+ while (c == '-' && (++i) < l) {
+ c = Character.toUpperCase(functionName.charAt(i));
+ }
+ javaName.append(c);
+ }
+ return javaName.toString();
+ }
+
+ /**
* Construct a new extension handler given all the information
* needed.
*
diff -u -r --exclude=*~
old/xalan-j_2_1_0/src/org/apache/xalan/extensions/ExtensionHandlerJavaClass.java
src/org/apache/xalan/extensions/ExtensionHandlerJavaClass.java
--- old/xalan-j_2_1_0/src/org/apache/xalan/extensions/ExtensionHandlerJavaClass.java
Wed May 23 14:43:18 2001
+++ src/org/apache/xalan/extensions/ExtensionHandlerJavaClass.java Wed Jul 4
+11:38:35 2001
@@ -138,11 +138,12 @@
public boolean isFunctionAvailable(String function)
{
+ String method = mangleFunctionName(function);
Method[] methods = m_classObj.getMethods();
int nMethods = methods.length;
for (int i = 0; i < nMethods; i++)
{
- if (methods[i].getName().equals(function))
+ if (methods[i].getName().equals(method))
return true;
}
return false;
@@ -159,11 +160,12 @@
public boolean isElementAvailable(String element)
{
+ String method = mangleFunctionName(element);
Method[] methods = m_classObj.getMethods();
int nMethods = methods.length;
for (int i = 0; i < nMethods; i++)
{
- if (methods[i].getName().equals(element))
+ if (methods[i].getName().equals(method))
{
Class[] paramTypes = methods[i].getParameterTypes();
if ( (paramTypes.length == 2)
@@ -317,7 +319,7 @@
}
m = MethodResolver.getMethod(m_classObj,
- funcName,
+ mangleFunctionName(funcName),
methodArgs,
convertedArgs,
exprContext,
@@ -395,7 +397,8 @@
{
try
{
- m = MethodResolver.getElementMethod(m_classObj, localPart);
+ m = MethodResolver.getElementMethod(m_classObj,
+ mangleFunctionName(localPart));
if ( (null == m_defaultInstance) && !Modifier.isStatic(m.getModifiers()) )
m_defaultInstance = m_classObj.newInstance();
}
diff -u -r --exclude=*~
old/xalan-j_2_1_0/src/org/apache/xalan/extensions/ExtensionHandlerJavaPackage.java
src/org/apache/xalan/extensions/ExtensionHandlerJavaPackage.java
--- old/xalan-j_2_1_0/src/org/apache/xalan/extensions/ExtensionHandlerJavaPackage.java
Wed May 23 14:43:20 2001
+++ src/org/apache/xalan/extensions/ExtensionHandlerJavaPackage.java Wed Jul 4
+11:39:28 2001
@@ -131,7 +131,7 @@
{
try
{
- String fullName = m_className + function;
+ String fullName = m_className + mangleFunctionName(function);
int lastDot = fullName.lastIndexOf(".");
if (lastDot >= 0)
{
@@ -164,7 +164,7 @@
{
try
{
- String fullName = m_className + element;
+ String fullName = m_className + mangleFunctionName(element);
int lastDot = fullName.lastIndexOf(".");
if (lastDot >= 0)
{
@@ -250,6 +250,7 @@
Object[][] convertedArgs;
Class[] paramTypes;
+
try
{
@@ -315,7 +316,7 @@
}
}
className = m_className + funcName.substring(0, lastDot);
- methodName = funcName.substring(lastDot + 1);
+ methodName = mangleFunctionName(funcName.substring(lastDot + 1));
try
{
classObj = getClassForName(className);
@@ -428,7 +429,7 @@
{
try
{
- String fullName = m_className + localPart;
+ String fullName = m_className + mangleFunctionName(localPart);
int lastDot = fullName.lastIndexOf(".");
if (lastDot < 0)
throw new TransformerException("Invalid element name specified " +
fullName);