changes for jaxp 1.2.0_01 update
git-svn-id: https://svn.apache.org/repos/asf/xalan/java/branches/jaxp-ri-1_2_0-fcs-branch@336565 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/org/apache/xalan/xsltc/TransletOutputHandler.java b/src/org/apache/xalan/xsltc/TransletOutputHandler.java
index f53fa11..59a5150 100644
--- a/src/org/apache/xalan/xsltc/TransletOutputHandler.java
+++ b/src/org/apache/xalan/xsltc/TransletOutputHandler.java
@@ -73,6 +73,7 @@
public void endDocument() throws TransletException;
public void startElement(String elementName) throws TransletException;
public void endElement(String elementName) throws TransletException;
+ public void characters(String characters) throws TransletException;
public void characters(char[] characters, int offset, int length)
throws TransletException;
public void attribute(String attributeName, String attributeValue)
@@ -86,5 +87,10 @@
public void omitHeader(boolean value);
public boolean setEscaping(boolean escape) throws TransletException;
public void setCdataElements(Hashtable elements);
+ public void setDoctype(String system, String pub);
+ public void setMediaType(String mediaType);
+ public void setStandalone(String standalone);
+ public void setVersion(String version);
public void close();
+
}
diff --git a/src/org/apache/xalan/xsltc/cmdline/Compile.java b/src/org/apache/xalan/xsltc/cmdline/Compile.java
index c7598a2..89d317e 100644
--- a/src/org/apache/xalan/xsltc/cmdline/Compile.java
+++ b/src/org/apache/xalan/xsltc/cmdline/Compile.java
@@ -80,6 +80,12 @@
public final class Compile {
+ // Versioning numbers for the compiler -v option output
+ private static int VERSION_MAJOR = 1;
+ private static int VERSION_MINOR = 1;
+ private static int VERSION_DELTA = 0;
+
+
// This variable should be set to false to prevent any methods in this
// class from calling System.exit(). As this is a command-line tool,
// calling System.exit() is normally OK, but we also want to allow for
@@ -87,7 +93,11 @@
private static boolean _allowExit = true;
public static void printUsage() {
- System.err.println(new ErrorMsg(ErrorMsg.COMPILE_USAGE_STR));
+ StringBuffer vers = new StringBuffer("XSLTC version " +
+ VERSION_MAJOR + "." + VERSION_MINOR +
+ ((VERSION_DELTA > 0) ? ("."+VERSION_DELTA) : ("")));
+ System.err.println(vers + "\n" +
+ new ErrorMsg(ErrorMsg.COMPILE_USAGE_STR));
if (_allowExit) System.exit(-1);
}
@@ -103,8 +113,7 @@
boolean inputIsURL = false;
boolean useStdIn = false;
boolean classNameSet = false;
-
- final GetOpt getopt = new GetOpt(args, "o:d:j:p:uxhsi");
+ final GetOpt getopt = new GetOpt(args, "o:d:j:p:uxhsinv");
if (args.length < 1) printUsage();
final XSLTC xsltc = new XSLTC();
@@ -138,6 +147,11 @@
case 's':
_allowExit = false;
break;
+ case 'n':
+ xsltc.setTemplateInlining(false);
+ break;
+ case 'v':
+ // fall through to case h
case 'h':
default:
printUsage();
diff --git a/src/org/apache/xalan/xsltc/cmdline/Transform.java b/src/org/apache/xalan/xsltc/cmdline/Transform.java
index 55ac4e2..57b6430 100644
--- a/src/org/apache/xalan/xsltc/cmdline/Transform.java
+++ b/src/org/apache/xalan/xsltc/cmdline/Transform.java
@@ -92,8 +92,13 @@
import org.apache.xalan.xsltc.dom.DTDMonitor;
import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
+import org.apache.xalan.xsltc.runtime.output.*;
+
final public class Transform {
+ // Temporary
+ static private boolean _useOldOutputSystem = false;
+
private TransletOutputHandler _handler;
private String _fileName;
@@ -102,15 +107,17 @@
private boolean _isJarFileSpecified = false;
private Vector _params = null;
private boolean _uri, _debug;
+ private int _iterations;
private static boolean _allowExit = true;
public Transform(String className, String fileName,
- boolean uri, boolean debug) {
+ boolean uri, boolean debug, int iterations) {
_fileName = fileName;
_className = className;
_uri = uri;
_debug = debug;
+ _iterations = iterations;
}
public void setParameters(Vector params) {
@@ -196,18 +203,31 @@
}
// Transform the document
- String encoding = _translet._encoding;
+ TransletOutputHandlerFactory tohFactory =
+ TransletOutputHandlerFactory.newInstance();
+ tohFactory.setOutputType(TransletOutputHandlerFactory.STREAM);
+ tohFactory.setEncoding(_translet._encoding);
+ tohFactory.setOutputMethod(_translet._method);
- // Create our default SAX/DTD handler
- DefaultSAXOutputHandler saxHandler =
- new DefaultSAXOutputHandler(System.out, encoding);
- // Create a translet output handler and plug in the SAX/DTD handler
- TextOutput textOutput =
- new TextOutput((ContentHandler)saxHandler,
- (LexicalHandler)saxHandler, encoding);
+ if (_iterations == -1) {
+ translet.transform(dom, _useOldOutputSystem ?
+ tohFactory.getOldTransletOutputHandler() :
+ tohFactory.getTransletOutputHandler());
+ }
+ else if (_iterations > 0) {
+ long mm = System.currentTimeMillis();
+ for (int i = 0; i < _iterations; i++) {
+ translet.transform(dom, _useOldOutputSystem ?
+ tohFactory.getOldTransletOutputHandler() :
+ tohFactory.getTransletOutputHandler());
+ }
+ mm = System.currentTimeMillis() - mm;
- // Transform and pass output to the translet output handler
- translet.transform(dom, textOutput);
+ System.err.println("\n<!--");
+ System.err.println(" transform = " + (mm / _iterations) + " ms");
+ System.err.println(" throughput = " + (1000.0 / (mm / _iterations)) + " tps");
+ System.err.println("-->");
+ }
}
catch (TransletException e) {
if (_debug) e.printStackTrace();
@@ -279,6 +299,7 @@
try {
if (args.length > 0) {
int i;
+ int iterations = -1;
boolean uri = false, debug = false;
boolean isJarFileSpecified = false;
String jarFile = null;
@@ -298,6 +319,17 @@
isJarFileSpecified = true;
jarFile = args[++i];
}
+ else if (args[i].equals("-e")) {
+ _useOldOutputSystem = true;
+ }
+ else if (args[i].equals("-n")) {
+ try {
+ iterations = Integer.parseInt(args[++i]);
+ }
+ catch (NumberFormatException e) {
+ // ignore
+ }
+ }
else {
printUsage();
}
@@ -307,7 +339,8 @@
if (args.length - i < 2) printUsage();
// Get document file and class name
- Transform handler = new Transform(args[i+1],args[i],uri,debug);
+ Transform handler = new Transform(args[i+1], args[i], uri,
+ debug, iterations);
handler.setJarFileInputSrc(isJarFileSpecified, jarFile);
// Parse stylesheet parameters
diff --git a/src/org/apache/xalan/xsltc/compiler/AbsolutePathPattern.java b/src/org/apache/xalan/xsltc/compiler/AbsolutePathPattern.java
index 665b0ad..cf03c43 100644
--- a/src/org/apache/xalan/xsltc/compiler/AbsolutePathPattern.java
+++ b/src/org/apache/xalan/xsltc/compiler/AbsolutePathPattern.java
@@ -123,31 +123,44 @@
else {
_left.translate(classGen, methodGen);
}
- _trueList.append(_left._trueList);
- _falseList.append(_left._falseList);
}
+
final int getParent = cpg.addInterfaceMethodref(DOM_INTF,
GET_PARENT,
GET_PARENT_SIG);
final int getType = cpg.addInterfaceMethodref(DOM_INTF,
"getType", "(I)I");
- il.append(methodGen.loadDOM());
+
+ InstructionHandle begin = il.append(methodGen.loadDOM());
il.append(SWAP);
il.append(new INVOKEINTERFACE(getParent, 2));
- if (_left instanceof AncestorPattern) {
+ if (_left instanceof AncestorPattern) {
il.append(methodGen.loadDOM());
il.append(SWAP);
}
il.append(new INVOKEINTERFACE(getType, 2));
il.append(new PUSH(cpg, DOM.ROOT));
- // long jump: _falseList.add(il.append(new IF_ICMPNE(null)));
final BranchHandle skip = il.append(new IF_ICMPEQ(null));
_falseList.add(il.append(new GOTO_W(null)));
skip.setTarget(il.append(NOP));
+
+ if (_left != null) {
+ _left.backPatchTrueList(begin);
+
+ /*
+ * If _left is an ancestor pattern, backpatch this pattern's false
+ * list to the loop that searches for more ancestors.
+ */
+ if (_left instanceof AncestorPattern) {
+ final AncestorPattern ancestor = (AncestorPattern) _left;
+ _falseList.backPatch(ancestor.getLoopHandle()); // clears list
+ }
+ _falseList.append(_left._falseList);
+ }
}
public String toString() {
- return "absolutePathPattern(" + (_left!=null ? _left.toString() : ")");
+ return "absolutePathPattern(" + (_left != null ? _left.toString() : ")");
}
}
diff --git a/src/org/apache/xalan/xsltc/compiler/AncestorPattern.java b/src/org/apache/xalan/xsltc/compiler/AncestorPattern.java
index f99b678..9fe38ae 100644
--- a/src/org/apache/xalan/xsltc/compiler/AncestorPattern.java
+++ b/src/org/apache/xalan/xsltc/compiler/AncestorPattern.java
@@ -69,8 +69,10 @@
import org.apache.xalan.xsltc.compiler.util.*;
final class AncestorPattern extends RelativePathPattern {
+
private final Pattern _left; // may be null
private final RelativePathPattern _right;
+ private InstructionHandle _loop;
public AncestorPattern(RelativePathPattern right) {
this(null, right);
@@ -84,6 +86,10 @@
}
}
+ public InstructionHandle getLoopHandle() {
+ return _loop;
+ }
+
public void setParser(Parser parser) {
super.setParser(parser);
if (_left != null) {
@@ -106,17 +112,23 @@
}
public Type typeCheck(SymbolTable stable) throws TypeCheckError {
- if (_left != null) _left.typeCheck(stable);
+ if (_left != null) {
+ _left.typeCheck(stable);
+ }
return _right.typeCheck(stable);
}
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
- InstructionHandle loop, eloop;
+ InstructionHandle parent;
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
+
+ /*
+ * The scope of this local var must be the entire method since
+ * a another pattern may decide to jump back into the loop
+ */
final LocalVariableGen local =
- methodGen.addLocalVariable2("app",
- Util.getJCRefType(NODE_SIG),
+ methodGen.addLocalVariable2("app", Util.getJCRefType(NODE_SIG),
il.getEnd());
final org.apache.bcel.generic.Instruction loadLocal =
@@ -133,13 +145,18 @@
}
else {
_right.translate(classGen, methodGen);
+
+ if (_right instanceof AncestorPattern) {
+ il.append(methodGen.loadDOM());
+ il.append(SWAP);
+ }
}
if (_left != null) {
final int getParent = cpg.addInterfaceMethodref(DOM_INTF,
GET_PARENT,
GET_PARENT_SIG);
- loop = il.append(new INVOKEINTERFACE(getParent, 2));
+ parent = il.append(new INVOKEINTERFACE(getParent, 2));
il.append(DUP);
il.append(storeLocal);
@@ -148,11 +165,10 @@
_left.translate(classGen, methodGen);
-
final SyntaxTreeNode p = getParent();
- if ((p == null) ||
- (p instanceof Instruction) ||
- (p instanceof TopLevelElement)) {
+ if (p == null || p instanceof Instruction ||
+ p instanceof TopLevelElement)
+ {
// do nothing
}
else {
@@ -160,19 +176,27 @@
}
final BranchHandle exit = il.append(new GOTO(null));
- eloop = il.append(methodGen.loadDOM());
+ _loop = il.append(methodGen.loadDOM());
il.append(loadLocal);
- local.setEnd(eloop);
- il.append(new GOTO(loop));
+ local.setEnd(_loop);
+ il.append(new GOTO(parent));
exit.setTarget(il.append(NOP));
- _left.backPatchFalseList(eloop);
+ _left.backPatchFalseList(_loop);
_trueList.append(_left._trueList);
}
else {
il.append(POP2);
}
- methodGen.removeLocalVariable(local);
+
+ /*
+ * If _right is an ancestor pattern, backpatch this pattern's false
+ * list to the loop that searches for more ancestors.
+ */
+ if (_right instanceof AncestorPattern) {
+ final AncestorPattern ancestor = (AncestorPattern) _right;
+ _falseList.backPatch(ancestor.getLoopHandle()); // clears list
+ }
_trueList.append(_right._trueList);
_falseList.append(_right._falseList);
diff --git a/src/org/apache/xalan/xsltc/compiler/ApplyImports.java b/src/org/apache/xalan/xsltc/compiler/ApplyImports.java
index 852b0bc..5d41236 100644
--- a/src/org/apache/xalan/xsltc/compiler/ApplyImports.java
+++ b/src/org/apache/xalan/xsltc/compiler/ApplyImports.java
@@ -136,7 +136,7 @@
// Indicate to the top-level stylesheet that all templates must be
// compiled into separate methods.
Stylesheet stylesheet = getStylesheet();
- stylesheet.compileTemplatesAsMethods();
+ stylesheet.setTemplateInlining(false);
// Get the mode we are currently in (might not be any)
Template template = getTemplate();
diff --git a/src/org/apache/xalan/xsltc/compiler/ApplyTemplates.java b/src/org/apache/xalan/xsltc/compiler/ApplyTemplates.java
index 985f683..746f0cd 100644
--- a/src/org/apache/xalan/xsltc/compiler/ApplyTemplates.java
+++ b/src/org/apache/xalan/xsltc/compiler/ApplyTemplates.java
@@ -106,7 +106,7 @@
}
if (mode.length() > 0) {
- _modeName = parser.getQName(mode);
+ _modeName = parser.getQNameIgnoreDefaultNs(mode);
}
// instantiate Mode if needed, cache (apply temp) function name
diff --git a/src/org/apache/xalan/xsltc/compiler/AttributeSet.java b/src/org/apache/xalan/xsltc/compiler/AttributeSet.java
index b484604..6bbba08 100644
--- a/src/org/apache/xalan/xsltc/compiler/AttributeSet.java
+++ b/src/org/apache/xalan/xsltc/compiler/AttributeSet.java
@@ -84,6 +84,7 @@
// Element contents
private QName _name;
private UseAttributeSets _useSets;
+ private AttributeSet _mergeSet;
private String _method;
private boolean _ignore = false;
@@ -119,7 +120,7 @@
public void parseContents(Parser parser) {
// Get this attribute set's name
- _name = parser.getQName(getAttribute("name"));
+ _name = parser.getQNameIgnoreDefaultNs(getAttribute("name"));
if ((_name == null) || (_name.equals(EMPTYSTRING))) {
ErrorMsg msg = new ErrorMsg(ErrorMsg.UNNAMED_ATTRIBSET_ERR, this);
parser.reportError(Constants.ERROR, msg);
@@ -161,15 +162,10 @@
if (_ignore) return (Type.Void);
- final AttributeSet other = stable.addAttributeSet(this);
- if (other != null) {
- _method = other.getMethodName();
- merge(other);
- other.ignore();
- }
- else {
- _method = AttributeSetPrefix + getXSLTC().nextAttributeSetSerial();
- }
+ // _mergeSet Point to any previous definition of this attribute set
+ _mergeSet = stable.addAttributeSet(this);
+
+ _method = AttributeSetPrefix + getXSLTC().nextAttributeSetSerial();
if (_useSets != null) _useSets.typeCheck(stable);
typeCheckContents(stable);
@@ -177,26 +173,6 @@
}
/**
- * Merge this attribute set with some other one
- */
- private void merge(AttributeSet other) {
- // Both attribute sets may inherit from other sets...
- if (_useSets == null)
- _useSets = other._useSets;
- else
- _useSets.addAttributeSets(other.getAttribute("use-attribute-sets"));
-
- // Merge the contents of the two attribute sets...
- final Enumeration attributes = other.elements();
- while (attributes.hasMoreElements()) {
- SyntaxTreeNode element = (SyntaxTreeNode)attributes.nextElement();
- if (element instanceof XslAttribute) {
- setFirstElement((XslAttribute)element);
- }
- }
- }
-
- /**
* Compile a method that outputs the attributes in this set
*/
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
@@ -206,6 +182,21 @@
// Create a new method generator for an attribute set method
methodGen = new AttributeSetMethodGenerator(_method, classGen);
+ // Generate a reference to previous attribute-set definitions with the
+ // same name first. Those later in the stylesheet take precedence.
+ if (_mergeSet != null) {
+ final ConstantPoolGen cpg = classGen.getConstantPool();
+ final InstructionList il = methodGen.getInstructionList();
+ final String methodName = _mergeSet.getMethodName();
+
+ il.append(classGen.loadTranslet());
+ il.append(methodGen.loadHandler());
+ il.append(methodGen.loadIterator());
+ final int method = cpg.addMethodref(classGen.getClassName(),
+ methodName, ATTR_SET_SIG);
+ il.append(new INVOKESPECIAL(method));
+ }
+
// Translate other used attribute sets first, as local attributes
// take precedence (last attributes overrides first)
if (_useSets != null) _useSets.translate(classGen, methodGen);
diff --git a/src/org/apache/xalan/xsltc/compiler/CallTemplate.java b/src/org/apache/xalan/xsltc/compiler/CallTemplate.java
index 84b1e4d..00ff83e 100644
--- a/src/org/apache/xalan/xsltc/compiler/CallTemplate.java
+++ b/src/org/apache/xalan/xsltc/compiler/CallTemplate.java
@@ -87,7 +87,7 @@
}
public void parseContents(Parser parser) {
- _name = parser.getQName(getAttribute("name"));
+ _name = parser.getQNameIgnoreDefaultNs(getAttribute("name"));
parseChildren(parser);
}
diff --git a/src/org/apache/xalan/xsltc/compiler/CastExpr.java b/src/org/apache/xalan/xsltc/compiler/CastExpr.java
index e028905..8063340 100644
--- a/src/org/apache/xalan/xsltc/compiler/CastExpr.java
+++ b/src/org/apache/xalan/xsltc/compiler/CastExpr.java
@@ -88,25 +88,16 @@
InternalTypeMap.put(Type.Real, Type.Real);
InternalTypeMap.put(Type.Real, Type.Int);
- InternalTypeMap.put(Type.Real, Type.Lng);
InternalTypeMap.put(Type.Real, Type.Boolean);
InternalTypeMap.put(Type.Real, Type.String);
InternalTypeMap.put(Type.Real, Type.Reference);
InternalTypeMap.put(Type.Int, Type.Int);
InternalTypeMap.put(Type.Int, Type.Real);
- InternalTypeMap.put(Type.Int, Type.Lng);
InternalTypeMap.put(Type.Int, Type.Boolean);
InternalTypeMap.put(Type.Int, Type.String);
InternalTypeMap.put(Type.Int, Type.Reference);
- // GTM, bug 3592 fix.
- InternalTypeMap.put(Type.Lng, Type.Int);
- InternalTypeMap.put(Type.Lng, Type.Real);
- InternalTypeMap.put(Type.Lng, Type.Boolean);
- InternalTypeMap.put(Type.Lng, Type.String);
- InternalTypeMap.put(Type.Lng, Type.Reference);
-
InternalTypeMap.put(Type.String, Type.String);
InternalTypeMap.put(Type.String, Type.Boolean);
InternalTypeMap.put(Type.String, Type.Real);
diff --git a/src/org/apache/xalan/xsltc/compiler/Constants.java b/src/org/apache/xalan/xsltc/compiler/Constants.java
index 4e6acc7..12258b1 100644
--- a/src/org/apache/xalan/xsltc/compiler/Constants.java
+++ b/src/org/apache/xalan/xsltc/compiler/Constants.java
@@ -127,6 +127,8 @@
= org.apache.bcel.Constants.ACC_PRIVATE;
public static final int ACC_PROTECTED
= org.apache.bcel.Constants.ACC_PROTECTED;
+ public static final int ACC_STATIC
+ = org.apache.bcel.Constants.ACC_STATIC;
public static final String STRING_SIG
= "Ljava/lang/String;";
@@ -147,6 +149,8 @@
= "int";
public static final String NODE_ITERATOR
= "org.apache.xalan.xsltc.NodeIterator";
+ public static final String NODE_ITERATOR_BASE
+ = "org.apache.xalan.xsltc.dom.NodeIteratorBase";
public static final String SORT_ITERATOR
= "org.apache.xalan.xsltc.dom.SortingIterator";
public static final String SORT_ITERATOR_SIG
@@ -169,10 +173,6 @@
= "org/apache/xalan/xsltc/TransletOutputHandler";
public static final String OUTPUT_HANDLER_SIG
= "Lorg/apache/xalan/xsltc/TransletOutputHandler;";
- public static final String TEXT_OUTPUT
- = "org/apache/xalan/xsltc/runtime/TextOutput";
- public static final String TEXT_OUTPUT_SIG
- = "Lorg/apache/xalan/xsltc/runtime/TextOutput;";
public static final String FILTER_INTERFACE
= "org.apache.xalan.xsltc.dom.Filter";
public static final String FILTER_INTERFACE_SIG
@@ -286,8 +286,6 @@
= "java.lang.Double";
public static final String INTEGER_CLASS
= "java.lang.Integer";
- public static final String LONG_CLASS
- = "java.lang.Long";
public static final String RUNTIME_NODE_CLASS
= "org.apache.xalan.xsltc.runtime.Node";
public static final String MATH_CLASS
@@ -301,10 +299,6 @@
= "intValue";
public static final String INT_VALUE_SIG
= "()I";
- public static final String LONG_VALUE
- = "longValue";
- public static final String LONG_VALUE_SIG
- = "()J";
public static final String DOUBLE_VALUE
= "doubleValue";
public static final String DOUBLE_VALUE_SIG
diff --git a/src/org/apache/xalan/xsltc/compiler/DecimalFormatting.java b/src/org/apache/xalan/xsltc/compiler/DecimalFormatting.java
index 874e031..c4fa876 100644
--- a/src/org/apache/xalan/xsltc/compiler/DecimalFormatting.java
+++ b/src/org/apache/xalan/xsltc/compiler/DecimalFormatting.java
@@ -84,7 +84,7 @@
private static final String DFS_CLASS = "java.text.DecimalFormatSymbols";
private static final String DFS_SIG = "Ljava/text/DecimalFormatSymbols;";
- private String _name = null;
+ private QName _name = null;
/**
* No type check needed for the <xsl:decimal-formatting/> element
@@ -98,14 +98,20 @@
*/
public void parseContents(Parser parser) {
// Get the name of these decimal formatting symbols
- if ((_name = getAttribute("name")) == null) _name = EMPTYSTRING;
+ _name = parser.getQNameIgnoreDefaultNs(getAttribute("name"));
+ if (_name == null) {
+ _name = parser.getQNameIgnoreDefaultNs(EMPTYSTRING);
+ }
// Check if a set of symbols has already been registered under this name
SymbolTable stable = parser.getSymbolTable();
- if (stable.getDecimalFormatting(_name) != null)
- reportWarning(this, parser, ErrorMsg.SYMBOLS_REDEF_ERR,_name.toString());
- else
+ if (stable.getDecimalFormatting(_name) != null) {
+ reportWarning(this, parser, ErrorMsg.SYMBOLS_REDEF_ERR,
+ _name.toString());
+ }
+ else {
stable.addDecimalFormatting(_name, this);
+ }
}
/**
@@ -122,7 +128,7 @@
// Push the format name on the stack for call to addDecimalFormat()
il.append(classGen.loadTranslet());
- il.append(new PUSH(cpg, _name));
+ il.append(new PUSH(cpg, _name.toString()));
// Manufacture a DecimalFormatSymbols on the stack
// for call to addDecimalFormat()
diff --git a/src/org/apache/xalan/xsltc/compiler/ElementAvailableCall.java b/src/org/apache/xalan/xsltc/compiler/ElementAvailableCall.java
index cc14b58..55d0e73 100644
--- a/src/org/apache/xalan/xsltc/compiler/ElementAvailableCall.java
+++ b/src/org/apache/xalan/xsltc/compiler/ElementAvailableCall.java
@@ -88,14 +88,30 @@
}
/**
+ * Returns an object representing the compile-time evaluation
+ * of an expression. We are only using this for function-available
+ * and element-available at this time.
+ */
+ public Object evaluateAtCompileTime() {
+ return getResult() ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ /**
* Returns the result that this function will return
*/
public boolean getResult() {
- final LiteralExpr arg = (LiteralExpr) argument();
- final String qname = arg.getValue();
- final int index = qname.indexOf(':');
- final String localName = (index > 0) ? qname.substring(index + 1) : qname;
- return getParser().elementSupported(arg.getNamespace(), localName);
+ try {
+ final LiteralExpr arg = (LiteralExpr) argument();
+ final String qname = arg.getValue();
+ final int index = qname.indexOf(':');
+ final String localName = (index > 0) ?
+ qname.substring(index + 1) : qname;
+ return getParser().elementSupported(arg.getNamespace(),
+ localName);
+ }
+ catch (ClassCastException e) {
+ return false;
+ }
}
/**
diff --git a/src/org/apache/xalan/xsltc/compiler/EqualityExpr.java b/src/org/apache/xalan/xsltc/compiler/EqualityExpr.java
index 4b8bb9b..6af9494 100644
--- a/src/org/apache/xalan/xsltc/compiler/EqualityExpr.java
+++ b/src/org/apache/xalan/xsltc/compiler/EqualityExpr.java
@@ -101,10 +101,7 @@
}
public boolean getOp() {
- if (_op == Operators.NE)
- return false;
- else
- return true;
+ return (_op != Operators.NE);
}
/**
diff --git a/src/org/apache/xalan/xsltc/compiler/Expression.java b/src/org/apache/xalan/xsltc/compiler/Expression.java
index 727dc3b..6b58c8f 100644
--- a/src/org/apache/xalan/xsltc/compiler/Expression.java
+++ b/src/org/apache/xalan/xsltc/compiler/Expression.java
@@ -111,6 +111,15 @@
}
/**
+ * Returns an object representing the compile-time evaluation
+ * of an expression. We are only using this for function-available
+ * and element-available at this time.
+ */
+ public Object evaluateAtCompileTime() {
+ return null;
+ }
+
+ /**
* Type check all the children of this node.
*/
public Type typeCheck(SymbolTable stable) throws TypeCheckError {
diff --git a/src/org/apache/xalan/xsltc/compiler/FilterParentPath.java b/src/org/apache/xalan/xsltc/compiler/FilterParentPath.java
index 1562c60..4f320b7 100644
--- a/src/org/apache/xalan/xsltc/compiler/FilterParentPath.java
+++ b/src/org/apache/xalan/xsltc/compiler/FilterParentPath.java
@@ -149,9 +149,9 @@
// This is a special case for the //* path with or without predicates
if (_hasDescendantAxis) {
- final int incl = cpg.addMethodref(STEP_ITERATOR_CLASS,
+ final int incl = cpg.addMethodref(NODE_ITERATOR_BASE,
"includeSelf",
- "()"+NODE_ITERATOR_SIG);
+ "()" + NODE_ITERATOR_SIG);
il.append(new INVOKEVIRTUAL(incl));
}
diff --git a/src/org/apache/xalan/xsltc/compiler/FormatNumberCall.java b/src/org/apache/xalan/xsltc/compiler/FormatNumberCall.java
index 124576d..b4ee8e2 100644
--- a/src/org/apache/xalan/xsltc/compiler/FormatNumberCall.java
+++ b/src/org/apache/xalan/xsltc/compiler/FormatNumberCall.java
@@ -74,6 +74,7 @@
private Expression _value;
private Expression _format;
private Expression _name;
+ private QName _resolvedQName = null;
public FormatNumberCall(QName fname, Vector arguments) {
super(fname, arguments);
@@ -83,9 +84,8 @@
}
public Type typeCheck(SymbolTable stable) throws TypeCheckError {
- // The stylesheet element only adds code to instanciate the
- // default DecimalFormat object if at least one format-number()
- // call exists in the stylesheet. We must signal this call...
+
+ // Inform stylesheet to instantiate a DecimalFormat object
getStylesheet().numberFormattingUsed();
final Type tvalue = _value.typeCheck(stable);
@@ -98,7 +98,13 @@
}
if (argumentCount() == 3) {
final Type tname = _name.typeCheck(stable);
- if (tname instanceof StringType == false) {
+
+ if (_name instanceof LiteralExpr) {
+ final LiteralExpr literal = (LiteralExpr) _name;
+ _resolvedQName =
+ getParser().getQNameIgnoreDefaultNs(literal.getValue());
+ }
+ else if (tname instanceof StringType == false) {
_name = new CastExpr(_name, Type.String);
}
}
@@ -126,6 +132,9 @@
if (_name == null) {
il.append(new PUSH(cpg, EMPTYSTRING));
}
+ else if (_resolvedQName != null) {
+ il.append(new PUSH(cpg, _resolvedQName.toString()));
+ }
else {
_name.translate(classGen, methodGen);
}
diff --git a/src/org/apache/xalan/xsltc/compiler/FunctionAvailableCall.java b/src/org/apache/xalan/xsltc/compiler/FunctionAvailableCall.java
index 1987549..35e0501 100644
--- a/src/org/apache/xalan/xsltc/compiler/FunctionAvailableCall.java
+++ b/src/org/apache/xalan/xsltc/compiler/FunctionAvailableCall.java
@@ -73,39 +73,34 @@
final class FunctionAvailableCall extends FunctionCall {
- private boolean _isFunctionAvailable = false;
private Expression _arg;
- private String _namespaceOfFunct =null;
- private String _nameOfFunct =null;
-
+ private String _nameOfFunct = null;
+ private String _namespaceOfFunct = null;
+ private boolean _isFunctionAvailable = false;
/**
* Constructs a FunctionAvailableCall FunctionCall. Takes the
- * function name qname, for example, 'function-available', and a list
- * of arguments where the arguments must be instances of
- * LiteralExpression. The test for availability considers
- * internal xsl functions such as 'floor' as well as external
- * Java functions, such as 'java.lang.Math.sin'. The case of
- * external functions is handled here, the case of internal
- * functions is handled in getResult.
+ * function name qname, for example, 'function-available', and
+ * a list of arguments where the arguments must be instances of
+ * LiteralExpression.
*/
public FunctionAvailableCall(QName fname, Vector arguments) {
super(fname, arguments);
_arg = (Expression)arguments.elementAt(0);
_type = null;
+
if (_arg instanceof LiteralExpr) {
- LiteralExpr arg = (LiteralExpr)_arg;
+ LiteralExpr arg = (LiteralExpr) _arg;
_namespaceOfFunct = arg.getNamespace();
_nameOfFunct = arg.getValue();
- if ((_namespaceOfFunct != null) &&
- (!_namespaceOfFunct.equals(Constants.EMPTYSTRING)))
+
+ if (_namespaceOfFunct != null &&
+ (_namespaceOfFunct.startsWith(JAVA_EXT_XSLTC) ||
+ _namespaceOfFunct.startsWith(JAVA_EXT_XALAN)))
{
- // the function is external, such as a java function
_isFunctionAvailable = hasMethods();
}
- // the case of internal function is handled in getResult.
}
- // case where _arg is not instanceof LiteralExpr can not be handled.
}
/**
@@ -113,13 +108,11 @@
* returns the type of function-available to be boolean.
*/
public Type typeCheck(SymbolTable stable) throws TypeCheckError {
- // may be already set
- if ( _type != null ) {
+ if (_type != null) {
return _type;
}
if (_arg instanceof LiteralExpr) {
- _type = Type.Boolean;
- return Type.Boolean;
+ return _type = Type.Boolean;
}
ErrorMsg err = new ErrorMsg(ErrorMsg.NEED_LITERAL_ERR,
"function-available", this);
@@ -127,6 +120,15 @@
}
/**
+ * Returns an object representing the compile-time evaluation
+ * of an expression. We are only using this for function-available
+ * and element-available at this time.
+ */
+ public Object evaluateAtCompileTime() {
+ return getResult() ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ /**
* (For ext. java functions only)
* Parses the argument to function-available to extract the package
* qualified class name, for example, given the argument
@@ -186,66 +188,68 @@
* the specified method is found in the specifed class.
*/
private boolean hasMethods() {
-
LiteralExpr arg = (LiteralExpr)_arg;
final String externalFunctName = getExternalFunctionName();
+
if (externalFunctName == null) {
return false;
}
+
final String className = getClassName(externalFunctName);
- if (_namespaceOfFunct.startsWith(JAVA_EXT_XSLTC) ||
- _namespaceOfFunct.startsWith(JAVA_EXT_XALAN)) {
- try {
- TransletLoader loader = new TransletLoader();
- final Class clazz = loader.loadClass(className);
+ try {
+ TransletLoader loader = new TransletLoader();
+ final Class clazz = loader.loadClass(className);
- if (clazz == null) {
- final ErrorMsg msg =
- new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, className);
- getParser().reportError(Constants.ERROR, msg);
- }
- else {
- final String methodName = getMethodName(externalFunctName);
- final Method[] methods = clazz.getDeclaredMethods();
+ if (clazz == null) {
+ final ErrorMsg msg =
+ new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, className);
+ getParser().reportError(Constants.ERROR, msg);
+ }
+ else {
+ final String methodName = getMethodName(externalFunctName);
+ final Method[] methods = clazz.getDeclaredMethods();
- for (int i = 0; i < methods.length; i++) {
- final int mods = methods[i].getModifiers();
+ for (int i = 0; i < methods.length; i++) {
+ final int mods = methods[i].getModifiers();
- if (Modifier.isPublic(mods)
- && Modifier.isStatic(mods)
- && methods[i].getName().equals(methodName))
- {
- return true;
- }
- }
- }
- }
- catch (ClassNotFoundException e) {
- final ErrorMsg msg =
- new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, className);
- getParser().reportError(Constants.ERROR, msg);
- }
- }
+ if (Modifier.isPublic(mods)
+ && Modifier.isStatic(mods)
+ && methods[i].getName().equals(methodName))
+ {
+ return true;
+ }
+ }
+ }
+ }
+ catch (ClassNotFoundException e) {
+ final ErrorMsg msg =
+ new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, className);
+ getParser().reportError(Constants.ERROR, msg);
+ }
return false;
}
/**
- * reports on whether the function specified in the argument to
+ * Reports on whether the function specified in the argument to
* xslt function 'function-available' was found.
*/
public boolean getResult() {
- if ((_namespaceOfFunct == null) ||
- (_namespaceOfFunct.equals(Constants.EMPTYSTRING)))
+ if (_nameOfFunct == null) {
+ return false;
+ }
+
+ if (_namespaceOfFunct == null ||
+ _namespaceOfFunct.equals(EMPTYSTRING) ||
+ _namespaceOfFunct.equals(TRANSLET_URI))
{
- // no namespace, so the function is an internal xslt function.
final Parser parser = getParser();
- _isFunctionAvailable = parser.functionSupported(_nameOfFunct);
+ _isFunctionAvailable =
+ parser.functionSupported(Util.getLocalName(_nameOfFunct));
}
return _isFunctionAvailable;
}
-
/**
* Calls to 'function-available' are resolved at compile time since
* the namespaces declared in the stylsheet are not available at run
diff --git a/src/org/apache/xalan/xsltc/compiler/FunctionCall.java b/src/org/apache/xalan/xsltc/compiler/FunctionCall.java
index d609cd8..50f341b 100644
--- a/src/org/apache/xalan/xsltc/compiler/FunctionCall.java
+++ b/src/org/apache/xalan/xsltc/compiler/FunctionCall.java
@@ -121,6 +121,7 @@
*/
static {
try {
+ final Class objectClass = Class.forName("java.lang.Object");
final Class stringClass = Class.forName("java.lang.String");
final Class nodeClass = Class.forName("org.w3c.dom.Node");
final Class nodeListClass = Class.forName("org.w3c.dom.NodeList");
@@ -156,6 +157,8 @@
_internal2Java.put(Type.ResultTree, nodeClass);
_internal2Java.put(Type.ResultTree, nodeListClass);
+ _internal2Java.put(Type.Reference, objectClass);
+
// Possible conversions between Java and internal types
_java2Internal.put(Boolean.TYPE, Type.Boolean);
@@ -169,6 +172,8 @@
_java2Internal.put(stringClass, Type.String);
+ _java2Internal.put(objectClass, Type.Reference);
+
// Conversions from org.w3c.dom.Node/NodeList are not supported
}
catch (ClassNotFoundException e) {
@@ -474,7 +479,7 @@
exp.translate(classGen, methodGen);
// Convert the argument to its Java type
exp.startResetIterator(classGen, methodGen);
- exp._type.translateTo(classGen, methodGen, paramTypes[i]);
+ exp.getType().translateTo(classGen, methodGen, paramTypes[i]);
}
final StringBuffer buffer = new StringBuffer();
diff --git a/src/org/apache/xalan/xsltc/compiler/If.java b/src/org/apache/xalan/xsltc/compiler/If.java
index cc115b0..b51d795 100644
--- a/src/org/apache/xalan/xsltc/compiler/If.java
+++ b/src/org/apache/xalan/xsltc/compiler/If.java
@@ -102,17 +102,11 @@
return;
}
- // We will ignore the contents of this <xsl:if> if we know that the
- // test will always return 'false'.
- if (_test instanceof ElementAvailableCall) {
- ElementAvailableCall call = (ElementAvailableCall)_test;
- _ignore = !call.getResult();
- return;
- }
- if (_test instanceof FunctionAvailableCall) {
- FunctionAvailableCall call = (FunctionAvailableCall)_test;
- _ignore = !call.getResult();
- return;
+ // Ignore xsl:if when test is false (function-available() and
+ // element-available())
+ Object result = _test.evaluateAtCompileTime();
+ if (result != null && result instanceof Boolean) {
+ _ignore = !((Boolean) result).booleanValue();
}
parseChildren(parser);
diff --git a/src/org/apache/xalan/xsltc/compiler/Include.java b/src/org/apache/xalan/xsltc/compiler/Include.java
index 1719cc8..e2f6728 100644
--- a/src/org/apache/xalan/xsltc/compiler/Include.java
+++ b/src/org/apache/xalan/xsltc/compiler/Include.java
@@ -90,7 +90,6 @@
public void parseContents(final Parser parser) {
final Stylesheet context = parser.getCurrentStylesheet();
String docToLoad = getAttribute("href");
-
try {
if (context.checkForLoop(docToLoad)) {
final int errno = ErrorMsg.CIRCULAR_INCLUDE_ERR;
@@ -141,6 +140,7 @@
_included.setSystemId(docToLoad);
_included.setParentStylesheet(context);
_included.setIncludingStylesheet(context);
+ _included.setTemplateInlining(context.getTemplateInlining());
// An included stylesheet gets the same import precedence
// as the stylesheet that included it.
diff --git a/src/org/apache/xalan/xsltc/compiler/Key.java b/src/org/apache/xalan/xsltc/compiler/Key.java
index e4e9d5e..adc8b66 100644
--- a/src/org/apache/xalan/xsltc/compiler/Key.java
+++ b/src/org/apache/xalan/xsltc/compiler/Key.java
@@ -87,7 +87,7 @@
public void parseContents(Parser parser) {
// Get the required attributes and parser XPath expressions
- _name = parser.getQName(getAttribute("name"));
+ _name = parser.getQNameIgnoreDefaultNs(getAttribute("name"));
_match = parser.parsePattern(this, "match", null);
_use = parser.parseExpression(this, "use", null);
@@ -111,12 +111,7 @@
* @return The key's name (from the <xsl:key> elements 'name' attribute).
*/
public String getName() {
- String name;
- if (_name.getPrefix() == null)
- name = _name.getLocalPart();
- else
- name = _name.getPrefix()+":"+_name.getLocalPart();
- return(name);
+ return _name.toString();
}
/**
@@ -191,7 +186,8 @@
// Prepare to call buildKeyIndex(String name, int node, String value);
il.append(classGen.loadTranslet());
- il.append(new PUSH(cpg, getName()));
+ // il.append(new PUSH(cpg, getName()));
+ il.append(new PUSH(cpg, _name.toString()));
il.append(new ILOAD(parentNode.getIndex()));
// Now get the node value and feck it on the parameter stack
diff --git a/src/org/apache/xalan/xsltc/compiler/KeyCall.java b/src/org/apache/xalan/xsltc/compiler/KeyCall.java
index a7f93c1..00e878f 100644
--- a/src/org/apache/xalan/xsltc/compiler/KeyCall.java
+++ b/src/org/apache/xalan/xsltc/compiler/KeyCall.java
@@ -73,6 +73,7 @@
private Expression _name; // The name of this key
private Expression _value; // The value to look up in the key/index
private Type _valueType; // The value's data type
+ private QName _resolvedQName = null;
/**
* Get the parameters passed to function:
@@ -117,7 +118,13 @@
// and if it is not it must be converted to one using string() rules.
if (_name != null) {
final Type nameType = _name.typeCheck(stable);
- if (!(nameType instanceof StringType)) {
+
+ if (_name instanceof LiteralExpr) {
+ final LiteralExpr literal = (LiteralExpr) _name;
+ _resolvedQName =
+ getParser().getQNameIgnoreDefaultNs(literal.getValue());
+ }
+ else if (nameType instanceof StringType == false) {
_name = new CastExpr(_name, Type.String);
}
}
@@ -241,10 +248,15 @@
// Initialise the index specified in the first parameter of key()
il.append(classGen.loadTranslet());
- if (_name == null)
+ if (_name == null) {
il.append(new PUSH(cpg,"##id"));
- else
+ }
+ else if (_resolvedQName != null) {
+ il.append(new PUSH(cpg, _resolvedQName.toString()));
+ }
+ else {
_name.translate(classGen, methodGen);
+ }
il.append(new INVOKEVIRTUAL(getKeyIndex));
il.append(new ASTORE(searchIndex.getIndex()));
@@ -265,10 +277,12 @@
il.append(methodGen.loadDOM());
il.append(methodGen.loadCurrentNode());
il.append(new INVOKEINTERFACE(getNodeValue, 2));
- if (_name == null)
+ if (_name == null) {
il.append(new INVOKEVIRTUAL(lookupId));
- else
+ }
+ else {
il.append(new INVOKEVIRTUAL(lookupKey));
+ }
// Call to returnIndex.merge(searchIndex);
il.append(new INVOKEVIRTUAL(merge));
@@ -295,10 +309,15 @@
// Call getKeyIndex in AbstractTranslet with the name of the key
// to get the index for this key (which is also a node iterator).
il.append(classGen.loadTranslet());
- if (_name == null)
+ if (_name == null) {
il.append(new PUSH(cpg,"##id"));
- else
+ }
+ else if (_resolvedQName != null) {
+ il.append(new PUSH(cpg, _resolvedQName.toString()));
+ }
+ else {
_name.translate(classGen, methodGen);
+ }
il.append(new INVOKEVIRTUAL(getKeyIndex));
// Now use the value in the second argument to determine what nodes
@@ -318,10 +337,12 @@
_value.translate(classGen, methodGen);
}
- if (_name == null)
+ if (_name == null) {
il.append(new INVOKEVIRTUAL(lookupId));
- else
+ }
+ else {
il.append(new INVOKEVIRTUAL(lookupKey));
+ }
}
}
}
diff --git a/src/org/apache/xalan/xsltc/compiler/LiteralElement.java b/src/org/apache/xalan/xsltc/compiler/LiteralElement.java
index 0308584..e04db84 100644
--- a/src/org/apache/xalan/xsltc/compiler/LiteralElement.java
+++ b/src/org/apache/xalan/xsltc/compiler/LiteralElement.java
@@ -64,13 +64,11 @@
package org.apache.xalan.xsltc.compiler;
-import java.util.Vector;
import java.util.Hashtable;
-import java.util.Properties;
import java.util.Enumeration;
+import java.util.Vector;
import javax.xml.parsers.*;
-import javax.xml.transform.OutputKeys;
import org.xml.sax.*;
@@ -272,18 +270,6 @@
_name = translateQName(_qname, stable);
- // Determine output type if first literal output is html
- if (_name.toString().equalsIgnoreCase("html")) {
- final SyntaxTreeNode parent = getParent();
- if (parent instanceof Template) {
- final Template tt = (Template) parent;
- if (tt.isRootTemplate()) {
- final Stylesheet stylesheet = parser.getCurrentStylesheet();
- stylesheet.setOutputProperty(OutputKeys.METHOD, "html");
- }
- }
- }
-
// Process all attributes and register all namespaces they use
final int count = _attributes.getLength();
for (int i = 0; i < count; i++) {
@@ -306,10 +292,12 @@
stable.excludeNamespaces(val);
}
else {
- // Ignore special attributes
+ // Ignore special attributes (e.g. xmlns:prefix and xmlns)
final String prefix = qname.getPrefix();
- if (uri != null && uri.equals(XSLT_URI) ||
- prefix != null && prefix.equals(XMLNS_STRING)) {
+ if (prefix != null && prefix.equals(XMLNS_PREFIX) ||
+ prefix == null && qname.getLocalPart().equals("xmlns") ||
+ uri != null && uri.equals(XSLT_URI))
+ {
continue;
}
diff --git a/src/org/apache/xalan/xsltc/compiler/LogicalExpr.java b/src/org/apache/xalan/xsltc/compiler/LogicalExpr.java
index ff727d0..a0d86a3 100644
--- a/src/org/apache/xalan/xsltc/compiler/LogicalExpr.java
+++ b/src/org/apache/xalan/xsltc/compiler/LogicalExpr.java
@@ -96,9 +96,31 @@
* needed for context changes in node steps containing multiple predicates.
*/
public boolean hasPositionCall() {
- if (_left.hasPositionCall()) return true;
- if (_right.hasPositionCall()) return true;
- return false;
+ return (_left.hasPositionCall() || _right.hasPositionCall());
+ }
+
+ /**
+ * Returns an object representing the compile-time evaluation
+ * of an expression. We are only using this for function-available
+ * and element-available at this time.
+ */
+ public Object evaluateAtCompileTime() {
+ final Object leftb = _left.evaluateAtCompileTime();
+ final Object rightb = _right.evaluateAtCompileTime();
+
+ // Return null if we can't evaluate at compile time
+ if (leftb == null || rightb == null) {
+ return null;
+ }
+
+ if (_op == AND) {
+ return (leftb == Boolean.TRUE && rightb == Boolean.TRUE) ?
+ Boolean.TRUE : Boolean.FALSE;
+ }
+ else {
+ return (leftb == Boolean.TRUE || rightb == Boolean.TRUE) ?
+ Boolean.TRUE : Boolean.FALSE;
+ }
}
/**
diff --git a/src/org/apache/xalan/xsltc/compiler/LongExpr.java b/src/org/apache/xalan/xsltc/compiler/LongExpr.java
deleted file mode 100644
index e650658..0000000
--- a/src/org/apache/xalan/xsltc/compiler/LongExpr.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * @(#)$Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2001 The Apache Software Foundation. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xalan" and "Apache Software Foundation" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- * nor may "Apache" appear in their name, without prior written
- * permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 2001, Sun
- * Microsystems., http://www.sun.com. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- * @author G. Todd Miller
- *
- */
-
-package org.apache.xalan.xsltc.compiler;
-
-import org.apache.xalan.xsltc.compiler.util.Type;
-import org.apache.bcel.generic.*;
-import org.apache.xalan.xsltc.compiler.util.*;
-
-final class LongExpr extends Expression {
- private final long _value;
-
- public LongExpr(long value) {
- _value = value;
- }
-
- public Type typeCheck(SymbolTable stable) throws TypeCheckError {
- return _type = Type.Lng;
- }
-
- public String toString() {
- return "long-expr(" + _value + ')';
- }
-
- public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
- ConstantPoolGen cpg = classGen.getConstantPool();
- InstructionList il = methodGen.getInstructionList();
- il.append(new PUSH(cpg, _value));
- }
-}
diff --git a/src/org/apache/xalan/xsltc/compiler/Mode.java b/src/org/apache/xalan/xsltc/compiler/Mode.java
index febab4f..c869a79 100644
--- a/src/org/apache/xalan/xsltc/compiler/Mode.java
+++ b/src/org/apache/xalan/xsltc/compiler/Mode.java
@@ -82,21 +82,54 @@
*/
final class Mode implements Constants {
- private final QName _name; // The QName of this mode
- private final Stylesheet _stylesheet; // The owning stylesheet
- private final String _methodName; // The method name for this mode
- private Vector _templates; // All templates in this mode
+ /**
+ * The name of this mode as defined in the stylesheet.
+ */
+ private final QName _name;
- // Pattern/test sequence for pattern with node()-type kernel
- private Vector _nodeGroup = null;
- private TestSeq _nodeTestSeq = null;
+ /**
+ * A reference to the stylesheet object that owns this mode.
+ */
+ private final Stylesheet _stylesheet;
- // Pattern/test sequence for pattern with id() or key()-type kernel
- private Vector _idxGroup = null;
- private TestSeq _idxTestSeq = null;
+ /**
+ * The name of the method in which this mode is compiled.
+ */
+ private final String _methodName;
- // Pattern/test sequence for patterns with any other kernel type
+ /**
+ * A vector of all the templates in this mode.
+ */
+ private Vector _templates;
+
+ /**
+ * Group for patterns with node()-type kernel.
+ */
+ private Vector _nodeGroup = null;
+
+ /**
+ * Test sequence for patterns with node()-type kernel.
+ */
+ private TestSeq _nodeTestSeq = null;
+
+ /**
+ * Group for patterns with id() or key()-type kernel.
+ */
+ private Vector _idxGroup = null;
+
+ /**
+ * Test sequence for patterns with id() or key()-type kernel.
+ */
+ private TestSeq _idxTestSeq = null;
+
+ /**
+ * Group for patterns with any other kernel type.
+ */
private Vector[] _patternGroups;
+
+ /**
+ * Test sequence for patterns with any other kernel type.
+ */
private TestSeq[] _testSeq;
private Hashtable _neededTemplates = new Hashtable();
@@ -114,7 +147,8 @@
/**
- * Creates a new Mode
+ * Creates a new Mode.
+ *
* @param name A textual representation of the mode's QName
* @param stylesheet The Stylesheet in which the mode occured
* @param suffix A suffix to append to the method name for this mode
@@ -161,30 +195,30 @@
_templates.addElement(template);
}
- /*
private Vector quicksort(Vector templates, int p, int r) {
- while (p < r) {
+ if (p < r) {
final int q = partition(templates, p, r);
quicksort(templates, p, q);
- p = q + 1;
+ quicksort(templates, q + 1, r);
}
return templates;
}
private int partition(Vector templates, int p, int r) {
- final Template x = (Template)templates.elementAt((p + r) >>> 1);
+ final Template x = (Template)templates.elementAt(p);
int i = p - 1;
int j = r + 1;
while (true) {
- while (x.compareTo((Template)templates.elementAt(--j)) < 0);
- while (x.compareTo((Template)templates.elementAt(++i)) > 0);
- if (i < j)
+ while (x.compareTo((Template)templates.elementAt(--j)) > 0);
+ while (x.compareTo((Template)templates.elementAt(++i)) < 0);
+ if (i < j) {
templates.set(j, templates.set(i, templates.elementAt(j)));
- else
- return(j);
+ }
+ else {
+ return j;
+ }
}
}
- */
/**
* Process all the test patterns in this mode
@@ -192,7 +226,27 @@
public void processPatterns(Hashtable keys) {
_keys = keys;
- //_templates = quicksort(_templates, 0, _templates.size() - 1);
+/*
+System.out.println("Before Sort " + _name);
+for (int i = 0; i < _templates.size(); i++) {
+ System.out.println("name = " + ((Template)_templates.elementAt(i)).getName());
+ System.out.println("pattern = " + ((Template)_templates.elementAt(i)).getPattern());
+ System.out.println("priority = " + ((Template)_templates.elementAt(i)).getPriority());
+ System.out.println("position = " + ((Template)_templates.elementAt(i)).getPosition());
+}
+*/
+
+ _templates = quicksort(_templates, 0, _templates.size() - 1);
+
+/*
+System.out.println("\n After Sort " + _name);
+for (int i = 0; i < _templates.size(); i++) {
+ System.out.println("name = " + ((Template)_templates.elementAt(i)).getName());
+ System.out.println("pattern = " + ((Template)_templates.elementAt(i)).getPattern());
+ System.out.println("priority = " + ((Template)_templates.elementAt(i)).getPriority());
+ System.out.println("position = " + ((Template)_templates.elementAt(i)).getPosition());
+}
+*/
// Traverse all templates
final Enumeration templates = _templates.elements();
@@ -200,15 +254,20 @@
// Get the next template
final Template template = (Template)templates.nextElement();
- // Add this template to a table of named templates if it has a name.
- // If there are multiple templates with the same name, all but one
- // (the one with highest priority) will be disabled.
- if (template.isNamed() && !template.disabled())
+ /*
+ * Add this template to a table of named templates if it has a name.
+ * If there are multiple templates with the same name, all but one
+ * (the one with highest priority) will be disabled.
+ */
+ if (template.isNamed() && !template.disabled()) {
_namedTemplates.put(template, this);
+ }
// Add this template to a test sequence if it has a pattern
final Pattern pattern = template.getPattern();
- if (pattern != null) flattenAlternative(pattern, template, keys);
+ if (pattern != null) {
+ flattenAlternative(pattern, template, keys);
+ }
}
prepareTestSequences();
}
@@ -261,10 +320,7 @@
Vector patterns;
// Use the vector for id()/key()/node() patterns if no kernel type
- if (kernelType == -1)
- patterns = _nodeGroup;
- else
- patterns = _patternGroups[kernelType];
+ patterns = (kernelType == -1) ? _nodeGroup : _patternGroups[kernelType];
// Create a new vector if needed and insert the very first pattern
if (patterns == null) {
@@ -389,7 +445,8 @@
private void compileTemplates(ClassGenerator classGen,
MethodGenerator methodGen,
- InstructionHandle next) {
+ InstructionHandle next)
+ {
Enumeration templates = _namedTemplates.keys();
while (templates.hasMoreElements()) {
final Template template = (Template)templates.nextElement();
@@ -563,22 +620,16 @@
}
/**
- * Auxillary method to determine if a qname describes an attribute/element
+ * Auxiliary method to determine if a qname describes an attribute/element
*/
private static boolean isAttributeName(String qname) {
final int col = qname.lastIndexOf(':') + 1;
- if (qname.charAt(col) == '@')
- return(true);
- else
- return(false);
+ return (qname.charAt(col) == '@');
}
private static boolean isNamespaceName(String qname) {
final int col = qname.lastIndexOf(':');
- if ((col > -1) && (qname.charAt(qname.length()-1) == '*'))
- return(true);
- else
- return(false);
+ return (col > -1 && qname.charAt(qname.length()-1) == '*');
}
/**
@@ -588,9 +639,9 @@
public void compileApplyTemplates(ClassGenerator classGen) {
final XSLTC xsltc = classGen.getParser().getXSLTC();
final ConstantPoolGen cpg = classGen.getConstantPool();
- final Vector names = xsltc.getNamesIndex();
+ final Vector names = xsltc.getNamesIndex();
- // (*) Create the applyTemplates() method
+ // Create the applyTemplates() method
final org.apache.bcel.generic.Type[] argTypes =
new org.apache.bcel.generic.Type[3];
argTypes[0] = Util.getJCRefType(DOM_INTF_SIG);
@@ -611,20 +662,20 @@
classGen.getConstantPool());
methodGen.addException("org.apache.xalan.xsltc.TransletException");
- // (*) Create the local variablea
+ // Create a local variable to hold the current node
final LocalVariableGen current;
current = methodGen.addLocalVariable2("current",
org.apache.bcel.generic.Type.INT,
mainIL.getEnd());
_currentIndex = current.getIndex();
- // (*) Create the "body" instruction list that will eventually hold the
- // code for the entire method (other ILs will be appended).
+ // Create the "body" instruction list that will eventually hold the
+ // code for the entire method (other ILs will be appended).
final InstructionList body = new InstructionList();
body.append(NOP);
- // (*) Create an instruction list that contains the default next-node
- // iteration
+ // Create an instruction list that contains the default next-node
+ // iteration
final InstructionList ilLoop = new InstructionList();
ilLoop.append(methodGen.loadIterator());
ilLoop.append(methodGen.nextNode());
@@ -635,41 +686,44 @@
// by a single IFNE(body.getStart()) instruction - need workaround:
final BranchHandle ifeq = ilLoop.append(new IFEQ(null));
final BranchHandle loop = ilLoop.append(new GOTO_W(null));
- ifeq.setTarget(ilLoop.append(RETURN)); // applyTemplates() ends here!
+ ifeq.setTarget(ilLoop.append(RETURN)); // applyTemplates() ends here!
final InstructionHandle ihLoop = ilLoop.getStart();
- // (*) Compile default handling of elements (traverse children)
+ // Compile default handling of elements (traverse children)
InstructionList ilRecurse =
compileDefaultRecursion(classGen, methodGen, ihLoop);
InstructionHandle ihRecurse = ilRecurse.getStart();
- // (*) Compile default handling of text/attribute nodes (output text)
+ // Compile default handling of text/attribute nodes (output text)
InstructionList ilText =
compileDefaultText(classGen, methodGen, ihLoop);
InstructionHandle ihText = ilText.getStart();
// Distinguish attribute/element/namespace tests for further processing
final int[] types = new int[DOM.NTYPES + names.size()];
- for (int i = 0; i < types.length; i++) types[i] = i;
+ for (int i = 0; i < types.length; i++) {
+ types[i] = i;
+ }
+ // Initialize isAttribute[] and isNamespace[] arrays
final boolean[] isAttribute = new boolean[types.length];
final boolean[] isNamespace = new boolean[types.length];
for (int i = 0; i < names.size(); i++) {
final String name = (String)names.elementAt(i);
- isAttribute[i+DOM.NTYPES] = isAttributeName(name);
- isNamespace[i+DOM.NTYPES] = isNamespaceName(name);
+ isAttribute[i + DOM.NTYPES] = isAttributeName(name);
+ isNamespace[i + DOM.NTYPES] = isNamespaceName(name);
}
- // (*) Compile all templates - regardless of pattern type
+ // Compile all templates - regardless of pattern type
compileTemplates(classGen, methodGen, ihLoop);
- // (*) Handle template with explicit "*" pattern
+ // Handle template with explicit "*" pattern
final TestSeq elemTest = _testSeq[DOM.ELEMENT];
InstructionHandle ihElem = ihRecurse;
if (elemTest != null)
ihElem = elemTest.compile(classGen, methodGen, ihRecurse);
- // (*) Handle template with explicit "@*" pattern
+ // Handle template with explicit "@*" pattern
final TestSeq attrTest = _testSeq[DOM.ATTRIBUTE];
InstructionHandle ihAttr = ihText;
if (attrTest != null)
@@ -685,39 +739,58 @@
loop.setTarget(body.getStart());
}
- // (*) If there is a match on node() we need to replace ihElem
- // and ihText (default behaviour for elements & text).
+ // If there is a match on node() we need to replace ihElem
+ // and ihText if the priority of node() is higher
if (_nodeTestSeq != null) {
- double nodePrio = -0.5; //_nodeTestSeq.getPriority();
+
+ // Compare priorities of node() and "*"
+ double nodePrio = _nodeTestSeq.getPriority();
int nodePos = _nodeTestSeq.getPosition();
double elemPrio = (0 - Double.MAX_VALUE);
int elemPos = Integer.MIN_VALUE;
+
if (elemTest != null) {
elemPrio = elemTest.getPriority();
elemPos = elemTest.getPosition();
}
- if ((elemPrio == Double.NaN) || (elemPrio < nodePrio) ||
- ((elemPrio == nodePrio) && (elemPos < nodePos))) {
+ if (elemPrio == Double.NaN || elemPrio < nodePrio ||
+ (elemPrio == nodePrio && elemPos < nodePos))
+ {
ihElem = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
- ihText = ihElem;
+ }
+
+ // Compare priorities of node() and text()
+ final TestSeq textTest = _testSeq[DOM.TEXT];
+ double textPrio = (0 - Double.MAX_VALUE);
+ int textPos = Integer.MIN_VALUE;
+
+ if (textTest != null) {
+ textPrio = textTest.getPriority();
+ textPos = textTest.getPosition();
+ }
+ if (textPrio == Double.NaN || textPrio < nodePrio ||
+ (textPrio == nodePrio && textPos < nodePos))
+ {
+ ihText = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
+ _testSeq[DOM.TEXT] = _nodeTestSeq;
}
}
- // (*) Handle templates with "ns:*" pattern
+ // Handle templates with "ns:*" pattern
InstructionHandle elemNamespaceHandle = ihElem;
InstructionList nsElem = compileNamespaces(classGen, methodGen,
isNamespace, isAttribute,
false, ihElem);
if (nsElem != null) elemNamespaceHandle = nsElem.getStart();
- // (*) Handle templates with "ns:@*" pattern
+ // Handle templates with "ns:@*" pattern
InstructionHandle attrNamespaceHandle = ihAttr;
InstructionList nsAttr = compileNamespaces(classGen, methodGen,
isNamespace, isAttribute,
true, ihAttr);
if (nsAttr != null) attrNamespaceHandle = nsAttr.getStart();
- // (*) Handle templates with "ns:elem" or "ns:@attr" pattern
+ // Handle templates with "ns:elem" or "ns:@attr" pattern
final InstructionHandle[] targets = new InstructionHandle[types.length];
for (int i = DOM.NTYPES; i < targets.length; i++) {
final TestSeq testSeq = _testSeq[i];
@@ -902,7 +975,7 @@
// Process all patterns from those templates
processPatterns(_keys);
- // (*) Create the applyTemplates() method
+ // Create the applyTemplates() method
final org.apache.bcel.generic.Type[] argTypes =
new org.apache.bcel.generic.Type[3];
argTypes[0] = Util.getJCRefType(DOM_INTF_SIG);
@@ -936,20 +1009,20 @@
return;
}
- // (*) Create the local variablea
+ // Create the local variablea
final LocalVariableGen current;
current = methodGen.addLocalVariable2("current",
org.apache.bcel.generic.Type.INT,
mainIL.getEnd());
_currentIndex = current.getIndex();
- // (*) Create the "body" instruction list that will eventually hold the
- // code for the entire method (other ILs will be appended).
+ // Create the "body" instruction list that will eventually hold the
+ // code for the entire method (other ILs will be appended).
final InstructionList body = new InstructionList();
body.append(NOP);
- // (*) Create an instruction list that contains the default next-node
- // iteration
+ // Create an instruction list that contains the default next-node
+ // iteration
final InstructionList ilLoop = new InstructionList();
ilLoop.append(methodGen.loadIterator());
ilLoop.append(methodGen.nextNode());
@@ -965,7 +1038,9 @@
// Distinguish attribute/element/namespace tests for further processing
final int[] types = new int[DOM.NTYPES + names.size()];
- for (int i = 0; i < types.length; i++) types[i] = i;
+ for (int i = 0; i < types.length; i++) {
+ types[i] = i;
+ }
final boolean[] isAttribute = new boolean[types.length];
final boolean[] isNamespace = new boolean[types.length];
@@ -975,20 +1050,22 @@
isNamespace[i+DOM.NTYPES] = isNamespaceName(name);
}
- // (*) Compile all templates - regardless of pattern type
+ // Compile all templates - regardless of pattern type
compileTemplateCalls(classGen, methodGen, ihLoop, min, max);
- // (*) Handle template with explicit "*" pattern
+ // Handle template with explicit "*" pattern
final TestSeq elemTest = _testSeq[DOM.ELEMENT];
InstructionHandle ihElem = ihLoop;
- if (elemTest != null)
+ if (elemTest != null) {
ihElem = elemTest.compile(classGen, methodGen, ihLoop);
+ }
- // (*) Handle template with explicit "@*" pattern
+ // Handle template with explicit "@*" pattern
final TestSeq attrTest = _testSeq[DOM.ATTRIBUTE];
InstructionHandle ihAttr = ihLoop;
- if (attrTest != null)
+ if (attrTest != null) {
ihAttr = attrTest.compile(classGen, methodGen, ihAttr);
+ }
// Do tests for id() and key() patterns first
InstructionList ilKey = null;
@@ -1000,40 +1077,61 @@
loop.setTarget(body.getStart());
}
- // (*) If there is a match on node() we need to replace ihElem
- // and ihText (default behaviour for elements & text).
+ // If there is a match on node() we need to replace ihElem
+ // and ihText if the priority of node() is higher
InstructionHandle ihText = ihLoop;
if (_nodeTestSeq != null) {
- double nodePrio = -0.5; //_nodeTestSeq.getPriority();
+
+ // Compare priorities of node() and "*"
+ double nodePrio = _nodeTestSeq.getPriority();
int nodePos = _nodeTestSeq.getPosition();
double elemPrio = (0 - Double.MAX_VALUE);
int elemPos = Integer.MIN_VALUE;
+
if (elemTest != null) {
elemPrio = elemTest.getPriority();
elemPos = elemTest.getPosition();
}
- if ((elemPrio == Double.NaN) || (elemPrio < nodePrio) ||
- ((elemPrio == nodePrio) && (elemPos < nodePos))) {
+
+ if (elemPrio == Double.NaN || elemPrio < nodePrio ||
+ (elemPrio == nodePrio && elemPos < nodePos))
+ {
ihElem = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
- ihText = ihElem;
+ }
+
+ // Compare priorities of node() and text()
+ final TestSeq textTest = _testSeq[DOM.TEXT];
+ double textPrio = (0 - Double.MAX_VALUE);
+ int textPos = Integer.MIN_VALUE;
+
+ if (textTest != null) {
+ textPrio = textTest.getPriority();
+ textPos = textTest.getPosition();
+ }
+
+ if (textPrio == Double.NaN || textPrio < nodePrio ||
+ (textPrio == nodePrio && textPos < nodePos))
+ {
+ ihText = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
+ _testSeq[DOM.TEXT] = _nodeTestSeq;
}
}
- // (*) Handle templates with "ns:*" pattern
+ // Handle templates with "ns:*" pattern
InstructionHandle elemNamespaceHandle = ihElem;
InstructionList nsElem = compileNamespaces(classGen, methodGen,
isNamespace, isAttribute,
false, ihElem);
if (nsElem != null) elemNamespaceHandle = nsElem.getStart();
- // (*) Handle templates with "ns:@*" pattern
+ // Handle templates with "ns:@*" pattern
InstructionList nsAttr = compileNamespaces(classGen, methodGen,
isNamespace, isAttribute,
true, ihAttr);
InstructionHandle attrNamespaceHandle = ihAttr;
if (nsAttr != null) attrNamespaceHandle = nsAttr.getStart();
- // (*) Handle templates with "ns:elem" or "ns:@attr" pattern
+ // Handle templates with "ns:elem" or "ns:@attr" pattern
final InstructionHandle[] targets = new InstructionHandle[types.length];
for (int i = DOM.NTYPES; i < targets.length; i++) {
final TestSeq testSeq = _testSeq[i];
@@ -1080,12 +1178,14 @@
// Match on processing instruction - default: loop
InstructionHandle ihPI = ihLoop;
if (_nodeTestSeq != null) ihPI = ihElem;
- if (_testSeq[DOM.PROCESSING_INSTRUCTION] != null)
+ if (_testSeq[DOM.PROCESSING_INSTRUCTION] != null) {
targets[DOM.PROCESSING_INSTRUCTION] =
_testSeq[DOM.PROCESSING_INSTRUCTION].
compile(classGen, methodGen, ihPI);
- else
+ }
+ else {
targets[DOM.PROCESSING_INSTRUCTION] = ihPI;
+ }
// Match on comments - default: process next node
InstructionHandle ihComment = ihLoop;
diff --git a/src/org/apache/xalan/xsltc/compiler/NameBase.java b/src/org/apache/xalan/xsltc/compiler/NameBase.java
index a15f49f..2b5c4d5 100644
--- a/src/org/apache/xalan/xsltc/compiler/NameBase.java
+++ b/src/org/apache/xalan/xsltc/compiler/NameBase.java
@@ -72,7 +72,7 @@
class NameBase extends FunctionCall {
private Expression _param = null;
- private Type _type = Type.Node;
+ private Type _paramType = Type.Node;
/**
* Handles calls with no parameter (current node is implicit parameter).
@@ -99,30 +99,29 @@
// Check the argument type (if any)
switch(argumentCount()) {
case 0:
- _type = Type.Node;
+ _paramType = Type.Node;
break;
case 1:
- _type = _param.typeCheck(stable);
+ _paramType = _param.typeCheck(stable);
break;
default:
throw new TypeCheckError(this);
}
// The argument has to be a node, a node-set or a node reference
- if ((_type != Type.NodeSet) &&
- (_type != Type.Node) &&
- (_type != Type.Reference)) {
+ if ((_paramType != Type.NodeSet) &&
+ (_paramType != Type.Node) &&
+ (_paramType != Type.Reference)) {
throw new TypeCheckError(this);
}
- return Type.String;
+ return (_type = Type.String);
}
public Type getType() {
- return Type.String;
+ return _type;
}
-
/**
* Translate the code required for getting the node for which the
* QName, local-name or namespace URI should be extracted.
@@ -139,10 +138,10 @@
il.append(methodGen.loadContextNode());
}
// Function was called with node parameter
- else if (_type == Type.Node) {
+ else if (_paramType == Type.Node) {
_param.translate(classGen, methodGen);
}
- else if (_type == Type.Reference) {
+ else if (_paramType == Type.Reference) {
_param.translate(classGen, methodGen);
il.append(new INVOKESTATIC(cpg.addMethodref
(BASIS_LIBRARY_CLASS,
diff --git a/src/org/apache/xalan/xsltc/compiler/Output.java b/src/org/apache/xalan/xsltc/compiler/Output.java
index 7127f28..0fa71df 100644
--- a/src/org/apache/xalan/xsltc/compiler/Output.java
+++ b/src/org/apache/xalan/xsltc/compiler/Output.java
@@ -75,7 +75,6 @@
import org.apache.bcel.classfile.JavaClass;
import org.apache.xalan.xsltc.compiler.util.*;
-import org.apache.xalan.xsltc.runtime.TextOutput;
final class Output extends TopLevelElement {
@@ -98,8 +97,8 @@
private boolean _disabled = false;
// Some global constants
- private final static String STRING_SIG = "Ljava/lang/String;";
- private final static String XML_VERSION = "1.0";
+ private final static String STRING_SIG = "Ljava/lang/String;";
+ private final static String XML_VERSION = "1.0";
private final static String HTML_VERSION = "4.0";
/**
@@ -216,6 +215,16 @@
_cdata = null;
}
else {
+ StringBuffer expandedNames = new StringBuffer();
+ StringTokenizer tokens = new StringTokenizer(_cdata);
+
+ // Make sure to store names in expanded form
+ while (tokens.hasMoreTokens()) {
+ expandedNames.append(parser.getQName(tokens.nextToken()).toString())
+ .append(' ');
+ }
+ _cdata = expandedNames.toString();
+
outputProperties.setProperty(OutputKeys.CDATA_SECTION_ELEMENTS, _cdata);
}
@@ -227,7 +236,6 @@
}
outputProperties.setProperty(OutputKeys.INDENT, attrib);
}
-
else if (_method != null && _method.equals("html")) {
_indent = true;
}
@@ -250,7 +258,6 @@
if (_mediaType == null) {
_mediaType = "text/html";
}
- _indent = true;
}
else if (_method.equals("text")) {
if (_mediaType == null) {
@@ -279,7 +286,7 @@
il.append(classGen.loadTranslet());
// Only update _version field if set and different from default
- if (_version != null && !_version.equals(XML_VERSION)) {
+ if ((_version != null) && (!_version.equals(XML_VERSION))) {
field = cpg.addFieldref(TRANSLET_CLASS, "_version", STRING_SIG);
il.append(DUP);
il.append(new PUSH(cpg, _version));
@@ -337,7 +344,7 @@
}
// Compile code to set output indentation on/off
- if (_indent ) {
+ if (_indent) {
field = cpg.addFieldref(TRANSLET_CLASS, "_indent", "Z");
il.append(DUP);
il.append(new PUSH(cpg, _indent));
@@ -349,6 +356,7 @@
int index = cpg.addMethodref(TRANSLET_CLASS,
"addCdataElement",
"(Ljava/lang/String;)V");
+
StringTokenizer tokens = new StringTokenizer(_cdata);
while (tokens.hasMoreTokens()) {
il.append(DUP);
diff --git a/src/org/apache/xalan/xsltc/compiler/ParentLocationPath.java b/src/org/apache/xalan/xsltc/compiler/ParentLocationPath.java
index 8ffd159..cb52df0 100644
--- a/src/org/apache/xalan/xsltc/compiler/ParentLocationPath.java
+++ b/src/org/apache/xalan/xsltc/compiler/ParentLocationPath.java
@@ -221,11 +221,10 @@
final int path = ((Step)_path).getAxis();
final int step = ((Step)stp).getAxis();
if ((path == Axis.DESCENDANTORSELF && step == Axis.CHILD) ||
- (path == Axis.DESCENDANTORSELF && step == Axis.ATTRIBUTE) ||
(path == Axis.PRECEDING && step == Axis.PARENT)) {
- final int incl = cpg.addMethodref(STEP_ITERATOR_CLASS,
+ final int incl = cpg.addMethodref(NODE_ITERATOR_BASE,
"includeSelf",
- "()"+NODE_ITERATOR_SIG);
+ "()" + NODE_ITERATOR_SIG);
il.append(new INVOKEVIRTUAL(incl));
}
}
diff --git a/src/org/apache/xalan/xsltc/compiler/ParentPattern.java b/src/org/apache/xalan/xsltc/compiler/ParentPattern.java
index 78f2053..4d92fbc 100644
--- a/src/org/apache/xalan/xsltc/compiler/ParentPattern.java
+++ b/src/org/apache/xalan/xsltc/compiler/ParentPattern.java
@@ -117,8 +117,6 @@
il.append(SWAP);
}
else if (_right instanceof StepPattern) {
- //!!! check this
-
il.append(DUP);
il.append(storeLocal);
@@ -129,6 +127,11 @@
}
else {
_right.translate(classGen, methodGen);
+
+ if (_right instanceof AncestorPattern) {
+ il.append(methodGen.loadDOM());
+ il.append(SWAP);
+ }
}
final int getParent = cpg.addInterfaceMethodref(DOM_INTF,
@@ -137,9 +140,9 @@
il.append(new INVOKEINTERFACE(getParent, 2));
final SyntaxTreeNode p = getParent();
- if ((p == null) ||
- (p instanceof Instruction) ||
- (p instanceof TopLevelElement)) {
+ if (p == null || p instanceof Instruction ||
+ p instanceof TopLevelElement)
+ {
_left.translate(classGen, methodGen);
}
else {
@@ -154,6 +157,15 @@
methodGen.removeLocalVariable(local);
+ /*
+ * If _right is an ancestor pattern, backpatch _left false
+ * list to the loop that searches for more ancestors.
+ */
+ if (_right instanceof AncestorPattern) {
+ final AncestorPattern ancestor = (AncestorPattern) _right;
+ _left.backPatchFalseList(ancestor.getLoopHandle()); // clears list
+ }
+
_trueList.append(_right._trueList.append(_left._trueList));
_falseList.append(_right._falseList.append(_left._falseList));
}
diff --git a/src/org/apache/xalan/xsltc/compiler/Parser.java b/src/org/apache/xalan/xsltc/compiler/Parser.java
index 6e71ffe..e6412d9 100644
--- a/src/org/apache/xalan/xsltc/compiler/Parser.java
+++ b/src/org/apache/xalan/xsltc/compiler/Parser.java
@@ -70,8 +70,8 @@
import java.net.URL;
import java.util.Vector;
import java.util.Hashtable;
-import java.util.Dictionary;
import java.util.Properties;
+import java.util.Dictionary;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.Stack;
@@ -260,23 +260,34 @@
String namespace = null;
// Get the namespace uri from the symbol table
- if (prefix.equals("xmlns") == false) {
+ if (prefix.equals(XMLNS_PREFIX) == false) {
namespace = _symbolTable.lookupNamespace(prefix);
if (namespace == null) namespace = EMPTYSTRING;
}
return getQName(namespace, prefix, localname);
}
else {
- final String uri = _symbolTable.lookupNamespace(EMPTYSTRING);
+ final String uri = stringRep.equals(XMLNS_PREFIX) ? null
+ : _symbolTable.lookupNamespace(EMPTYSTRING);
return getQName(uri, null, stringRep);
}
}
public QName getQName(final String stringRep) {
- return getQName(stringRep, true);
+ return getQName(stringRep, true, false);
+ }
+
+ public QName getQNameIgnoreDefaultNs(final String stringRep) {
+ return getQName(stringRep, true, true);
}
public QName getQName(final String stringRep, boolean reportError) {
+ return getQName(stringRep, reportError, false);
+ }
+
+ private QName getQName(final String stringRep, boolean reportError,
+ boolean ignoreDefaultNs)
+ {
// parse and retrieve namespace
final int colon = stringRep.lastIndexOf(':');
if (colon != -1) {
@@ -285,7 +296,7 @@
String namespace = null;
// Get the namespace uri from the symbol table
- if (prefix.equals("xmlns") == false) {
+ if (prefix.equals(XMLNS_PREFIX) == false) {
namespace = _symbolTable.lookupNamespace(prefix);
if (namespace == null && reportError) {
final int line = _locator.getLineNumber();
@@ -297,13 +308,17 @@
return getQName(namespace, prefix, localname);
}
else {
- final String defURI = _symbolTable.lookupNamespace(EMPTYSTRING);
+ if (stringRep.equals(XMLNS_PREFIX)) {
+ ignoreDefaultNs = true;
+ }
+ final String defURI = ignoreDefaultNs ? null
+ : _symbolTable.lookupNamespace(EMPTYSTRING);
return getQName(defURI, null, stringRep);
}
}
public QName getQName(String namespace, String prefix, String localname) {
- if (namespace == null) {
+ if (namespace == null || namespace.equals(EMPTYSTRING)) {
QName name = (QName)_qNames.get(localname);
if (name == null) {
name = new QName(null, prefix, localname);
@@ -368,7 +383,11 @@
stylesheet.setSimplified();
stylesheet.addElement(element);
stylesheet.setAttributes(element.getAttributes());
- element.addPrefixMapping(EMPTYSTRING, EMPTYSTRING);
+
+ // Map the default NS if not already defined
+ if (element.lookupNamespace(EMPTYSTRING) == null) {
+ element.addPrefixMapping(EMPTYSTRING, EMPTYSTRING);
+ }
}
stylesheet.setParser(this);
return stylesheet;
@@ -643,7 +662,6 @@
-
/**
* Initialize the _instructionClasses Hashtable, which maps XSL element
* names to Java classes in this package.
@@ -722,7 +740,6 @@
MethodType R_D = new MethodType(Type.Real, Type.NodeSet);
MethodType R_O = new MethodType(Type.Real, Type.Reference);
MethodType I_I = new MethodType(Type.Int, Type.Int);
- MethodType J_J = new MethodType(Type.Lng, Type.Lng); //GTM,bug 3592
MethodType D_O = new MethodType(Type.NodeSet, Type.Reference);
MethodType D_V = new MethodType(Type.NodeSet, Type.Void);
MethodType D_S = new MethodType(Type.NodeSet, Type.String);
@@ -863,7 +880,6 @@
// Unary minus.
_symbolTable.addPrimop("u-", R_R);
_symbolTable.addPrimop("u-", I_I);
- _symbolTable.addPrimop("u-", J_J); // GTM,bug 3592
}
public SymbolTable getSymbolTable() {
@@ -901,7 +917,6 @@
public SyntaxTreeNode makeInstance(String uri, String prefix,
String local, Attributes attributes)
{
- boolean isStylesheet = false;
SyntaxTreeNode node = null;
QName qname = getQName(uri, prefix, local);
String className = (String)_instructionClasses.get(qname);
@@ -912,42 +927,13 @@
node = (SyntaxTreeNode)clazz.newInstance();
node.setQName(qname);
node.setParser(this);
- if (_locator != null){
+ if (_locator != null) {
node.setLineNumber(_locator.getLineNumber());
}
if (node instanceof Stylesheet) {
- isStylesheet = true;
- _xsltc.setStylesheet((Stylesheet) node);
+ _xsltc.setStylesheet((Stylesheet)node);
}
-
- // Check for illegal attributes
- String[] legal = (String[]) _instructionAttrs.get(qname);
- if (versionIsOne && legal != null) {
- int j;
- final int n = attributes.getLength();
-
- for (int i = 0; i < n; i++) {
- final String attrQName = attributes.getQName(i);
-
- if (isStylesheet && attrQName.equals("version")) {
- versionIsOne = attributes.getValue(i).equals("1.0");
- }
-
- if (attrQName.startsWith("xml")) continue;
-
- for (j = 0; j < legal.length; j++) {
- if (attrQName.equalsIgnoreCase(legal[j])) {
- break;
- }
- }
- if (j == legal.length) {
- final ErrorMsg err =
- new ErrorMsg(ErrorMsg.ILLEGAL_ATTRIBUTE_ERR,
- attrQName, node);
- reportError(WARNING, err);
- }
- }
- }
+ checkForSuperfluousAttributes(node, attributes);
}
catch (ClassNotFoundException e) {
ErrorMsg err = new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, node);
@@ -1002,6 +988,46 @@
}
/**
+ * checks the list of attributes against a list of allowed attributes
+ * for a particular element node.
+ */
+ private void checkForSuperfluousAttributes(SyntaxTreeNode node,
+ Attributes attrs)
+ {
+ QName qname = node.getQName();
+ boolean isStylesheet = (node instanceof Stylesheet);
+ String[] legal = (String[]) _instructionAttrs.get(qname);
+ if (versionIsOne && legal != null) {
+ int j;
+ final int n = attrs.getLength();
+
+ for (int i = 0; i < n; i++) {
+ final String attrQName = attrs.getQName(i);
+
+ if (isStylesheet && attrQName.equals("version")) {
+ versionIsOne = attrs.getValue(i).equals("1.0");
+ }
+
+ if (attrQName.startsWith("xml") ||
+ attrQName.indexOf(':') > 0) continue;
+
+ for (j = 0; j < legal.length; j++) {
+ if (attrQName.equalsIgnoreCase(legal[j])) {
+ break;
+ }
+ }
+ if (j == legal.length) {
+ final ErrorMsg err =
+ new ErrorMsg(ErrorMsg.ILLEGAL_ATTRIBUTE_ERR,
+ attrQName, node);
+ reportError(WARNING, err);
+ }
+ }
+ }
+ }
+
+
+ /**
* Parse an XPath expression:
* @parent - XSL element where the expression occured
* @exp - textual representation of the expression
@@ -1062,7 +1088,7 @@
try {
_xpathParser.setScanner(new XPathLexer(new StringReader(text)));
- Symbol result = _xpathParser.parse(line);
+ Symbol result = _xpathParser.parse(expression, line);
if (result != null) {
final SyntaxTreeNode node = (SyntaxTreeNode)result.value;
if (node != null) {
@@ -1075,14 +1101,12 @@
reportError(ERROR, new ErrorMsg(ErrorMsg.XPATH_PARSER_ERR,
expression, parent));
}
- catch (ClassCastException e) {
+ catch (Exception e) {
+ if (_xsltc.debug()) e.printStackTrace();
reportError(ERROR, new ErrorMsg(ErrorMsg.XPATH_PARSER_ERR,
expression, parent));
}
- catch (Exception e) {
- if (_xsltc.debug()) e.printStackTrace();
- // Intentional fall through
- }
+
// Return a dummy pattern (which is an expression)
SyntaxTreeNode.Dummy.setParser(this);
return SyntaxTreeNode.Dummy;
@@ -1214,7 +1238,7 @@
final String prefix = (col == -1) ? null : qname.substring(0, col);
SyntaxTreeNode element = makeInstance(uri, prefix,
- localname, attributes);
+ localname, attributes);
if (element == null) {
ErrorMsg err = new ErrorMsg(ErrorMsg.ELEMENT_PARSE_ERR,
prefix+':'+localname);
diff --git a/src/org/apache/xalan/xsltc/compiler/Predicate.java b/src/org/apache/xalan/xsltc/compiler/Predicate.java
index 0d6c217..f57b23c 100644
--- a/src/org/apache/xalan/xsltc/compiler/Predicate.java
+++ b/src/org/apache/xalan/xsltc/compiler/Predicate.java
@@ -208,8 +208,8 @@
if (fexp instanceof KeyCall)
_canOptimize = false;
- //else if (fexp instanceof VariableRefBase)
- // _canOptimize = false;
+ else if (fexp instanceof VariableRefBase)
+ _canOptimize = false;
else if (fexp instanceof ParentLocationPath)
_canOptimize = false;
else if (fexp instanceof UnionPathExpr)
diff --git a/src/org/apache/xalan/xsltc/compiler/QName.java b/src/org/apache/xalan/xsltc/compiler/QName.java
index 6eace10..1c1b1b0 100644
--- a/src/org/apache/xalan/xsltc/compiler/QName.java
+++ b/src/org/apache/xalan/xsltc/compiler/QName.java
@@ -75,24 +75,14 @@
_namespace = namespace;
_prefix = prefix;
_localname = localname;
- if ((namespace != null) && (!namespace.equals(Constants.EMPTYSTRING))) {
- _stringRep = namespace+':'+localname;
- }
- else {
- _stringRep = localname;
- }
+
+ _stringRep =
+ (namespace != null && !namespace.equals(Constants.EMPTYSTRING)) ?
+ (namespace + ':' + localname) : localname;
_hashCode = _stringRep.hashCode() + 19; // cached for speed
}
- public void clearDefaultNamespace() {
- if ((_prefix == null) || (_prefix.equals(Constants.EMPTYSTRING))) {
- _namespace = null;
- _stringRep = _localname;
- _hashCode = _stringRep.hashCode() + 19; // cached for speed
- }
- }
-
public void clearNamespace() {
_namespace = Constants.EMPTYSTRING;
}
@@ -106,7 +96,7 @@
}
public boolean equals(Object other) {
- return this == other;
+ return (this == other);
}
public String getLocalPart() {
@@ -126,6 +116,7 @@
}
public String dump() {
- return(new String("QName: "+_namespace+"("+_prefix+"):"+_localname));
+ return new String("QName: " + _namespace + "(" + _prefix + "):"
+ + _localname);
}
}
diff --git a/src/org/apache/xalan/xsltc/compiler/Sort.java b/src/org/apache/xalan/xsltc/compiler/Sort.java
index 383b1df..4269f8a 100644
--- a/src/org/apache/xalan/xsltc/compiler/Sort.java
+++ b/src/org/apache/xalan/xsltc/compiler/Sort.java
@@ -349,7 +349,7 @@
// Class initializer - void NodeSortRecord.<clinit>();
final InstructionList il = new InstructionList();
final CompareGenerator classInit =
- new CompareGenerator(ACC_PUBLIC | ACC_FINAL,
+ new CompareGenerator(ACC_PUBLIC | ACC_STATIC,
org.apache.bcel.generic.Type.VOID,
new org.apache.bcel.generic.Type[] { },
new String[] { },
diff --git a/src/org/apache/xalan/xsltc/compiler/Step.java b/src/org/apache/xalan/xsltc/compiler/Step.java
index 9146616..265fe42 100644
--- a/src/org/apache/xalan/xsltc/compiler/Step.java
+++ b/src/org/apache/xalan/xsltc/compiler/Step.java
@@ -74,23 +74,28 @@
final class Step extends RelativeLocationPath {
- // This step's axis as defined in class Axis.
+ /**
+ * This step's axis as defined in class Axis.
+ */
private int _axis;
- // A vector of predicates (filters) defined on this step - may be null
+ /**
+ * A vector of predicates (filters) defined on this step - may be null
+ */
private Vector _predicates;
- // Some simple predicates can be handled by this class (and not by the
- // Predicate class) and will be removed from the above vector as they are
- // handled. We use this boolean to remember if we did have any predicates.
+ /**
+ * Some simple predicates can be handled by this class (and not by the
+ * Predicate class) and will be removed from the above vector as they are
+ * handled. We use this boolean to remember if we did have any predicates.
+ */
private boolean _hadPredicates = false;
- // Type of the node test.
+ /**
+ * Type of the node test.
+ */
private int _nodeType;
- /**
- * Constructor
- */
public Step(int axis, int nodeType, Vector predicates) {
_axis = axis;
_nodeType = nodeType;
@@ -156,16 +161,12 @@
* an element like <xsl:for-each> or <xsl:apply-templates>.
*/
private boolean hasParentPattern() {
- SyntaxTreeNode parent = getParent();
- if ((parent instanceof ParentPattern) ||
- (parent instanceof ParentLocationPath) ||
- (parent instanceof UnionPathExpr) ||
- (parent instanceof FilterParentPath))
- return(true);
- else
- return(false);
+ final SyntaxTreeNode parent = getParent();
+ return (parent instanceof ParentPattern ||
+ parent instanceof ParentLocationPath ||
+ parent instanceof UnionPathExpr ||
+ parent instanceof FilterParentPath);
}
-
/**
* Returns 'true' if this step has any predicates
@@ -214,24 +215,10 @@
// Special case for '.'
if (isAbbreviatedDot()) {
- if (hasParentPattern())
- _type = Type.NodeSet;
- else
- _type = Type.Node;
- }
- // Special case for '..'
- else if (isAbbreviatedDDot()) {
- _type = Type.NodeSet;
+ _type = (hasParentPattern()) ? Type.NodeSet : Type.Node;
}
else {
- // Special case for '@attr' with no parent or predicates
- if ((_axis == Axis.ATTRIBUTE) && (_nodeType!=NodeTest.ATTRIBUTE) &&
- (!hasParentPattern()) && (!_hadPredicates) && (!isPredicate())) {
- _type = Type.Node;
- }
- else {
- _type = Type.NodeSet;
- }
+ _type = Type.NodeSet;
}
// Type check all predicates (expressions applied to the step)
@@ -259,11 +246,8 @@
if ((_axis == Axis.ANCESTOR) || (_axis == Axis.ANCESTORORSELF) ||
(_axis == Axis.PRECEDING) || (_axis == Axis.PRECEDINGSIBLING)) {
- // Do not reverse nodes if we have a parent step that will reverse
- // the nodes for us.
- if (hasParentPattern()) return false;
- if (hasPredicates()) return false;
- if (_hadPredicates) return false;
+ // Do not reverse nodes if we had predicates
+ // if (_hadPredicates) return false;
// Check if this step occured under an <xsl:apply-templates> element
SyntaxTreeNode parent = this;
@@ -276,11 +260,11 @@
if (parent instanceof ApplyTemplates) return true;
if (parent instanceof ForEach) return true;
if (parent instanceof FilterParentPath) return true;
+ if (parent instanceof FilterExpr) return true;
+ if (parent instanceof WithParam) return true;
+ if (parent instanceof ValueOf) return true;
- // No not order node set if descendant of these elements:
- if (parent instanceof ValueOf) return false;
-
- } while (parent != null);
+ } while (parent != null && parent instanceof Instruction == false);
}
return false;
}
@@ -298,30 +282,23 @@
if (hasPredicates()) {
translatePredicates(classGen, methodGen);
+
+ // If needed, create a reverse iterator after compiling preds
+ if (_predicates.size() == 0) {
+ orderIterator(classGen, methodGen);
+ }
}
else {
// If it is an attribute but not '@*' or '@attr' with a parent
if ((_axis == Axis.ATTRIBUTE) &&
(_nodeType != NodeTest.ATTRIBUTE) && (!hasParentPattern())) {
- int node = cpg.addInterfaceMethodref(DOM_INTF,
- "getAttributeNode",
- "(II)I");
int iter = cpg.addInterfaceMethodref(DOM_INTF,
"getTypedAxisIterator",
"(II)"+NODE_ITERATOR_SIG);
- if (_type instanceof NodeType) {
- il.append(methodGen.loadDOM());
- il.append(new PUSH(cpg, _nodeType));
- il.append(methodGen.loadContextNode());
- il.append(new INVOKEINTERFACE(node, 3));
- }
- // If it is the case '@attr[P_1]...[P_k]'
- else if (_type instanceof NodeSetType) {
- il.append(methodGen.loadDOM());
- il.append(new PUSH(cpg, Axis.ATTRIBUTE));
- il.append(new PUSH(cpg, _nodeType));
- il.append(new INVOKEINTERFACE(iter, 3));
- }
+ il.append(methodGen.loadDOM());
+ il.append(new PUSH(cpg, Axis.ATTRIBUTE));
+ il.append(new PUSH(cpg, _nodeType));
+ il.append(new INVOKEINTERFACE(iter, 3));
return;
}
@@ -403,9 +380,14 @@
il.append(new PUSH(cpg, _axis));
il.append(new PUSH(cpg, _nodeType));
il.append(new INVOKEINTERFACE(ty, 3));
- orderIterator(classGen, methodGen);
+
break;
}
+
+ // If needed, create a reverse iterator
+ if (!_hadPredicates) {
+ orderIterator(classGen, methodGen);
+ }
}
}
diff --git a/src/org/apache/xalan/xsltc/compiler/StepPattern.java b/src/org/apache/xalan/xsltc/compiler/StepPattern.java
index c14b743..5078287 100644
--- a/src/org/apache/xalan/xsltc/compiler/StepPattern.java
+++ b/src/org/apache/xalan/xsltc/compiler/StepPattern.java
@@ -133,14 +133,11 @@
else {
switch(_nodeType) {
case -1:
- return(-0.25);
+ return -0.5; // node()
case 0:
- return(0.0);
+ return 0.0;
default:
- if (_nodeType >= NodeTest.GTYPE)
- return(0.0);
- else
- return(-0.5);
+ return (_nodeType >= NodeTest.GTYPE) ? 0.0 : -0.5;
}
}
}
diff --git a/src/org/apache/xalan/xsltc/compiler/Stylesheet.java b/src/org/apache/xalan/xsltc/compiler/Stylesheet.java
index 9b04d02..4d79fe4 100644
--- a/src/org/apache/xalan/xsltc/compiler/Stylesheet.java
+++ b/src/org/apache/xalan/xsltc/compiler/Stylesheet.java
@@ -129,7 +129,7 @@
private SourceLoader _loader = null;
- private boolean _compileTemplatesAsMethods;
+ private boolean _templateInlining = true;
private boolean _forwardReference = false;
@@ -139,8 +139,12 @@
_forwardReference = true;
}
- public void compileTemplatesAsMethods() {
- _compileTemplatesAsMethods = true;
+ public boolean getTemplateInlining() {
+ return _templateInlining;
+ }
+
+ public void setTemplateInlining(boolean flag) {
+ _templateInlining = flag;
}
public boolean isSimplified() {
@@ -222,8 +226,9 @@
public boolean checkForLoop(String systemId) {
// Return true if this stylesheet includes/imports itself
- if (_systemId.equals(systemId))
+ if (_systemId != null && _systemId.equals(systemId)) {
return true;
+ }
// Then check with any stylesheets that included/imported this one
if (_parentStylesheet != null)
return _parentStylesheet.checkForLoop(systemId);
@@ -428,9 +433,10 @@
parser.getSymbolTable().setCurrentNode(child);
child.parseContents(parser);
}
+
// All template code should be compiled as methods if the
// <xsl:apply-imports/> element was ever used in this stylesheet
- if (_compileTemplatesAsMethods && (child instanceof Template)) {
+ if (!_templateInlining && (child instanceof Template)) {
Template template = (Template)child;
String name = "template$dot$"+template.getPosition();
template.setName(parser.getQName(name));
@@ -722,9 +728,10 @@
}
/**
- * This method returns a vector with variables in the order in which
- * they are to be compiled. The order is determined by the dependencies
- * between them. The first step is to close the input vector under
+ * This method returns a vector with variables in the order in
+ * which they are to be compiled. The order is determined by the
+ * dependencies between them and the order in which they were defined
+ * in the stylesheet. The first step is to close the input vector under
* the dependence relation (this is usually needed when variables are
* defined inside other variables in a RTF).
*/
@@ -744,19 +751,21 @@
}
}
+ /* DEBUG CODE - INGORE
+ for (int i = 0; i < input.size(); i++) {
+ final VariableBase var = (VariableBase) input.elementAt(i);
+ System.out.println("var = " + var);
+ }
+ System.out.println("=================================");
+ */
+
Vector result = new Vector();
- int zeroDep = 0;
while (input.size() > 0) {
boolean changed = false;
for (int i = 0; i < input.size(); ) {
final VariableBase var = (VariableBase)input.elementAt(i);
final Vector dep = var.getDependencies();
- if (dep == null) {
- result.insertElementAt(var, zeroDep++);
- input.remove(i);
- changed = true;
- }
- else if (result.containsAll(dep)) {
+ if (dep == null || result.containsAll(dep)) {
result.addElement(var);
input.remove(i);
changed = true;
@@ -766,7 +775,6 @@
}
}
-
// If nothing was changed in this pass then we have a circular ref
if (!changed) {
ErrorMsg err = new ErrorMsg(ErrorMsg.CIRCULAR_VARIABLE_ERR,
@@ -775,7 +783,16 @@
return(result);
}
}
- return(result);
+
+ /* DEBUG CODE - INGORE
+ System.out.println("=================================");
+ for (int i = 0; i < result.size(); i++) {
+ final VariableBase var = (VariableBase) result.elementAt(i);
+ System.out.println("var = " + var);
+ }
+ */
+
+ return result;
}
/**
diff --git a/src/org/apache/xalan/xsltc/compiler/SymbolTable.java b/src/org/apache/xalan/xsltc/compiler/SymbolTable.java
index 4b190d1..4575744 100644
--- a/src/org/apache/xalan/xsltc/compiler/SymbolTable.java
+++ b/src/org/apache/xalan/xsltc/compiler/SymbolTable.java
@@ -85,12 +85,12 @@
private Hashtable _excludedURI = null;
private Hashtable _decimalFormats = null;
- public DecimalFormatting getDecimalFormatting(String name) {
+ public DecimalFormatting getDecimalFormatting(QName name) {
if (_decimalFormats == null) return null;
return((DecimalFormatting)_decimalFormats.get(name));
}
- public void addDecimalFormatting(String name, DecimalFormatting symbols) {
+ public void addDecimalFormatting(QName name, DecimalFormatting symbols) {
if (_decimalFormats == null) _decimalFormats = new Hashtable();
_decimalFormats.put(name, symbols);
}
@@ -105,14 +105,12 @@
public Template addTemplate(Template template) {
final QName name = template.getName();
- name.clearDefaultNamespace();
if (_templates == null) _templates = new Hashtable();
return (Template)_templates.put(name, template);
}
public Template lookupTemplate(QName name) {
if (_templates == null) return null;
- name.clearDefaultNamespace();
return (Template)_templates.get(name);
}
diff --git a/src/org/apache/xalan/xsltc/compiler/Template.java b/src/org/apache/xalan/xsltc/compiler/Template.java
index a02faac..07b6186 100644
--- a/src/org/apache/xalan/xsltc/compiler/Template.java
+++ b/src/org/apache/xalan/xsltc/compiler/Template.java
@@ -132,11 +132,6 @@
return _name != null;
}
- public boolean isRootTemplate() {
- final String match = getAttribute("match");
- return (match != null && match.equals("/"));
- }
-
public Pattern getPattern() {
return _pattern;
}
@@ -250,11 +245,11 @@
_stylesheet = super.getStylesheet();
if (name.length() > 0) {
- _name = parser.getQName(name);
+ _name = parser.getQNameIgnoreDefaultNs(name);
}
if (mode.length() > 0) {
- _mode = parser.getQName(mode);
+ _mode = parser.getQNameIgnoreDefaultNs(mode);
}
if (match.length() > 0) {
diff --git a/src/org/apache/xalan/xsltc/compiler/TestSeq.java b/src/org/apache/xalan/xsltc/compiler/TestSeq.java
index 2f4b644..0ea54cb 100644
--- a/src/org/apache/xalan/xsltc/compiler/TestSeq.java
+++ b/src/org/apache/xalan/xsltc/compiler/TestSeq.java
@@ -73,18 +73,18 @@
import org.apache.bcel.generic.*;
import org.apache.xalan.xsltc.compiler.util.*;
+/**
+ * A test sequence is a sequence of patterns that
+ *
+ * (1) occured in templates in the same mode
+ * (2) share the same kernel node type (such as A/B and C/C/B).
+ *
+ * A test sequence may have a default template, which will be run if
+ * none of the patterns do not match. This template is always a template
+ * that matches solely on the shared kernel node type.
+ */
final class TestSeq {
- /*
- * A test sequence is a sequence of patterns that
- *
- * (1) occured in templates in the same mode
- * (2) share the same kernel node type (such as A/B and C/C/B).
- *
- * A test sequence may have a default template, which will be run if
- * none of the patterns do not match. This template is always a template
- * that matches solely on the shared kernel node type.
- */
private Vector _patterns = null; // all patterns
private Mode _mode = null; // the shared mode
private Template _default = null; // the default template
@@ -107,6 +107,7 @@
public double getPriority() {
double prio = (0 - Double.MAX_VALUE);
final int count = _patterns.size();
+
for (int i = 0; i < count; i++) {
final Pattern pattern = (Pattern)_patterns.elementAt(i);
final Template template = pattern.getTemplate();
@@ -127,6 +128,7 @@
public int getPosition() {
int pos = Integer.MIN_VALUE;
final int count = _patterns.size();
+
for (int i = 0; i < count; i++) {
final Pattern pattern = (Pattern)_patterns.elementAt(i);
final Template template = pattern.getTemplate();
@@ -144,7 +146,7 @@
* Reduce the patterns in this test sequence to exclude the shared
* kernel node type. After the switch() in the translet's applyTemplates()
* we already know that we have a hit for the kernel node type, we only
- * have the check the rest of the pattens.
+ * have the check the rest of the pattern.
*/
public void reduce() {
final Vector newPatterns = new Vector();
diff --git a/src/org/apache/xalan/xsltc/compiler/Text.java b/src/org/apache/xalan/xsltc/compiler/Text.java
index aa07fe9..93b1689 100644
--- a/src/org/apache/xalan/xsltc/compiler/Text.java
+++ b/src/org/apache/xalan/xsltc/compiler/Text.java
@@ -126,7 +126,12 @@
parseChildren(parser);
if (_text == null) {
- _ignore = true;
+ if (_textElement) {
+ _text = EMPTYSTRING;
+ }
+ else {
+ _ignore = true;
+ }
}
else if (_textElement) {
if (_text.length() == 0) _ignore = true;
@@ -162,35 +167,27 @@
// Turn off character escaping if so is wanted.
final int esc = cpg.addInterfaceMethodref(OUTPUT_HANDLER,
"setEscaping", "(Z)Z");
- // set escaping value in output handler
- if (_escaping) {
- il.append(methodGen.loadHandler());
- il.append(new PUSH(cpg,true));
- il.append(new INVOKEINTERFACE(esc, 2));
- } else {
+ if (!_escaping) {
il.append(methodGen.loadHandler());
il.append(new PUSH(cpg, false));
il.append(new INVOKEINTERFACE(esc, 2));
}
- final int toCharArr = cpg.addMethodref("java/lang/String",
- "toCharArray", "()[C");
final int characters = cpg.addInterfaceMethodref(OUTPUT_HANDLER,
"characters",
- "([CII)V");
+ "(" + STRING_SIG + ")V");
il.append(methodGen.loadHandler());
il.append(new PUSH(cpg, _text));
- il.append(new INVOKEVIRTUAL(toCharArr));
- il.append(new ICONST(0));
- il.append(new PUSH(cpg, _text.length()));
- il.append(new INVOKEINTERFACE(characters, 4));
+ il.append(new INVOKEINTERFACE(characters, 2));
// Restore character escaping setting to whatever it was.
// Note: setEscaping(bool) returns the original (old) value
- il.append(methodGen.loadHandler());
- il.append(SWAP);
- il.append(new INVOKEINTERFACE(esc, 2));
- il.append(POP);
+ if (!_escaping) {
+ il.append(methodGen.loadHandler());
+ il.append(SWAP);
+ il.append(new INVOKEINTERFACE(esc, 2));
+ il.append(POP);
+ }
}
translateContents(classGen, methodGen);
}
diff --git a/src/org/apache/xalan/xsltc/compiler/UnresolvedRef.java b/src/org/apache/xalan/xsltc/compiler/UnresolvedRef.java
index 276a87b..baa8cc6 100644
--- a/src/org/apache/xalan/xsltc/compiler/UnresolvedRef.java
+++ b/src/org/apache/xalan/xsltc/compiler/UnresolvedRef.java
@@ -119,10 +119,10 @@
ErrorMsg err = new ErrorMsg(ErrorMsg.CIRCULAR_VARIABLE_ERR,
name, this);
}
- if ((_ref = resolve(getParser(), stable)) != null)
- return(_ref.typeCheck(stable));
- else
- throw new TypeCheckError(reportError());
+ if ((_ref = resolve(getParser(), stable)) != null) {
+ return (_type = _ref.typeCheck(stable));
+ }
+ throw new TypeCheckError(reportError());
}
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
@@ -131,4 +131,9 @@
else
reportError();
}
+
+ public String toString() {
+ return "unresolved-ref()";
+ }
+
}
diff --git a/src/org/apache/xalan/xsltc/compiler/UseAttributeSets.java b/src/org/apache/xalan/xsltc/compiler/UseAttributeSets.java
index abe1e59..42c1a64 100644
--- a/src/org/apache/xalan/xsltc/compiler/UseAttributeSets.java
+++ b/src/org/apache/xalan/xsltc/compiler/UseAttributeSets.java
@@ -99,7 +99,8 @@
if ((setNames != null) && (!setNames.equals(Constants.EMPTYSTRING))) {
final StringTokenizer tokens = new StringTokenizer(setNames);
while (tokens.hasMoreTokens()) {
- final QName qname = getParser().getQName(tokens.nextToken());
+ final QName qname =
+ getParser().getQNameIgnoreDefaultNs(tokens.nextToken());
_sets.add(qname);
}
}
diff --git a/src/org/apache/xalan/xsltc/compiler/VariableBase.java b/src/org/apache/xalan/xsltc/compiler/VariableBase.java
index 5a8bd04..e10c511 100644
--- a/src/org/apache/xalan/xsltc/compiler/VariableBase.java
+++ b/src/org/apache/xalan/xsltc/compiler/VariableBase.java
@@ -125,8 +125,12 @@
*
*/
public void addDependency(VariableBase other) {
- if (_dependencies == null) _dependencies = new Vector();
- _dependencies.addElement(other);
+ if (_dependencies == null) {
+ _dependencies = new Vector();
+ }
+ if (!_dependencies.contains(other)) {
+ _dependencies.addElement(other);
+ }
}
/**
@@ -227,7 +231,6 @@
*/
public void setName(QName name) {
_name = name;
- _name.clearDefaultNamespace();
_variable = Util.escape(name.getLocalPart());
}
@@ -247,7 +250,7 @@
if (name == null) name = EMPTYSTRING;
if (name.length() > 0)
- setName(parser.getQName(name));
+ setName(parser.getQNameIgnoreDefaultNs(name));
else
reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "name");
@@ -260,6 +263,10 @@
select = getAttribute("select");
if (select.length() > 0) {
_select = getParser().parseExpression(this, "select", null);
+ if (_select.isDummy()) {
+ reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "select");
+ return;
+ }
}
// Children must be parsed first -> static scoping
diff --git a/src/org/apache/xalan/xsltc/compiler/When.java b/src/org/apache/xalan/xsltc/compiler/When.java
index 825a1e3..d2e4250 100644
--- a/src/org/apache/xalan/xsltc/compiler/When.java
+++ b/src/org/apache/xalan/xsltc/compiler/When.java
@@ -90,13 +90,12 @@
public void parseContents(Parser parser) {
_test = parser.parseExpression(this, "test", null);
- if (_test instanceof ElementAvailableCall) {
- ElementAvailableCall call = (ElementAvailableCall)_test;
- _ignore = !call.getResult();
- }
- if (_test instanceof FunctionAvailableCall) {
- FunctionAvailableCall call = (FunctionAvailableCall)_test;
- _ignore = !call.getResult();
+
+ // Ignore xsl:if when test is false (function-available() and
+ // element-available())
+ Object result = _test.evaluateAtCompileTime();
+ if (result != null && result instanceof Boolean) {
+ _ignore = !((Boolean) result).booleanValue();
}
parseChildren(parser);
diff --git a/src/org/apache/xalan/xsltc/compiler/XSLTC.java b/src/org/apache/xalan/xsltc/compiler/XSLTC.java
index a5676d5..988f6c7 100644
--- a/src/org/apache/xalan/xsltc/compiler/XSLTC.java
+++ b/src/org/apache/xalan/xsltc/compiler/XSLTC.java
@@ -67,12 +67,12 @@
package org.apache.xalan.xsltc.compiler;
import java.io.*;
+import java.util.Set;
import java.util.Vector;
import java.util.Hashtable;
-import java.util.Set;
+import java.util.Properties;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.Properties;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.Date;
@@ -142,6 +142,7 @@
private Vector _classes;
private boolean _callsNodeset = false;
private boolean _multiDocument = false;
+ private boolean _templateInlining = true;
/**
* XSLTC compiler constructor
@@ -216,6 +217,16 @@
}
/**
+ * Set a flag indicating if templates are to be inlined or not. The
+ * default is to do inlining, but this causes problems when the
+ * stylesheets have a large number of templates (e.g. branch targets
+ * exceeding 64K or a length of a method exceeding 64K).
+ */
+ public void setTemplateInlining(boolean templateInlining) {
+ _templateInlining = templateInlining;
+ }
+
+ /**
* Set the parameters to use to locate the correct <?xml-stylesheet ...?>
* processing instruction in the case where the input document to the
* compiler (and parser) is an XML document.
@@ -320,7 +331,9 @@
_stylesheet.setSourceLoader(_loader);
_stylesheet.setSystemId(systemId);
_stylesheet.setParentStylesheet(null);
+ _stylesheet.setTemplateInlining(_templateInlining);
_parser.setCurrentStylesheet(_stylesheet);
+
// Create AST under the Stylesheet element (parse & type-check)
_parser.createAST(_stylesheet);
}
@@ -675,7 +688,10 @@
try {
switch (_outputType) {
case FILE_OUTPUT:
- clazz.dump(getOutputFile(clazz.getClassName()));
+ clazz.dump(
+ new BufferedOutputStream(
+ new FileOutputStream(
+ getOutputFile(clazz.getClassName()))));
break;
case JAR_OUTPUT:
_classes.addElement(clazz);
@@ -707,7 +723,7 @@
// create the manifest
final Manifest manifest = new Manifest();
final java.util.jar.Attributes atrs = manifest.getMainAttributes();
- atrs.put(java.util.jar.Attributes.Name.MANIFEST_VERSION,"1.0");
+ atrs.put(java.util.jar.Attributes.Name.MANIFEST_VERSION,"1.1");
final Map map = manifest.getEntries();
// create manifest
diff --git a/src/org/apache/xalan/xsltc/compiler/util/ErrorMessages.java b/src/org/apache/xalan/xsltc/compiler/util/ErrorMessages.java
index 1ff59cd..455349d 100644
--- a/src/org/apache/xalan/xsltc/compiler/util/ErrorMessages.java
+++ b/src/org/apache/xalan/xsltc/compiler/util/ErrorMessages.java
@@ -218,38 +218,54 @@
// COMPILE_STDIN_ERR
"The -i option must be used with the -o option.",
+
// COMPILE_USAGE_STR
- "Usage:\n" +
- " java org.apache.xalan.xsltc.cmdline.Compile [-o <output>] [-d <directory>] [-j <jarfile>]\n"+
- " [-p <package name>] [-x] [-s] [-u] { <stylesheet> | -i }\n\n"+
- " Where <output> is the name to give the the generated translet.\n"+
- " <stylesheet> is one or more stylesheet file names, or if\n"+
- " the -u options is specified, one or more stylesheet URLs.\n"+
- " <directory> is the output directory.\n"+
- " <jarfile> is the name of a JAR-file to put all classes in.\n"+
- " <package-name> is used to prefix all class names.\n\n"+
- " Notes:\n"+
- " The -i options forces the compiler to read from stdin\n"+
- " The -o option is ignored if compiling multiple stylesheets\n"+
- " The -x option switches on debug messages.\n"+
- " The -s option disables calling System.exit.",
+ "SYNOPSIS\n" +
+ " java org.apache.xalan.xsltc.cmdline.Compile [-o <output>]\n" +
+ " [-d <directory>] [-j <jarfile>] [-p <package>]\n" +
+ " [-n] [-x] [-s] [-u] [-v] [-h] { <stylesheet> | -i }\n\n" +
+ "OPTIONS\n" +
+ " -o <output> assigns the name <output> to the generated\n" +
+ " translet. By default the translet name\n" +
+ " is taken from the <stylesheet> name. This option\n"+
+ " is ignored if compiling multiple stylesheets.\n" +
+ " -d <directory> specifies a destination directory for translet\n" +
+ " -j <jarfile> packages translet classes into a jar file of the\n"+
+ " name specified as <jarfile>\n"+
+ " -p <package> specifies a package name prefix for all generated\n"+
+ " translet classes.\n" +
+ " -n disables template inlining to reduce method\n" +
+ " length.\n"+
+ " -x turns on additional debugging message output\n" +
+ " -s disables calling System.exit\n" +
+ " -u interprets <stylesheet> arguments as URLs\n" +
+ " -i forces compiler to read stylesheet from stdin\n" +
+ " -v prints the version of the compiler\n" +
+ " -h prints this usage statement\n",
+
// TRANSFORM_USAGE_STR
- "Usage: \n" +
- " java org.apache.xalan.xsltc.cmdline.Transform [-j <jarfile>] [-x] [-s]\n" +
- " {-u <document_url> | <document>} <class> [<param1>=<value1> ...]\n" +
- " Where <document> is the xml document to be transformed, or\n" +
- " <document_url> is a url for the xml document,\n" +
- " <class> is the translet class which is either in\n" +
- " user's CLASSPATH or in the <jarfile> specified \n" +
- " with the -j option.\n" +
- " Notes:\n"+
- " The -x option switches on debug messages.\n"+
- " The -s option disables calling System.exit.",
+ "SYNOPSIS \n" +
+ " java org.apache.xalan.xsltc.cmdline.Transform [-j <jarfile>]\n"+
+ " [-x] [-s] [-n <iterations>] {-u <document_url> | <document>}\n" +
+ " <class> [<param1>=<value1> ...]\n\n" +
+ " uses the translet <class> to transform an XML document \n"+
+ " specified as <document>. The translet <class> is either in\n"+
+ " the user's CLASSPATH or in the optionally specified <jarfile>.\n"+
+ "OPTIONS\n" +
+ " -j <jarfile> specifies a jarfile from which to load translet\n"+
+ " -x turns on additional debugging message output\n" +
+ " -s disables calling System.exit\n" +
+ " -n <iterations> runs the transformation <iterations> times and\n" +
+ " displays profiling information\n" +
+ " -u <document_url> specifies XML input document as a URL\n",
+
// STRAY_SORT_ERR
"<xsl:sort> can only be used within <xsl:for-each> or <xsl:apply-templates>.",
// UNSUPPORTED_ENCODING
- "Output encoding ''{0}'' is not supported on this JVM."
+ "Output encoding ''{0}'' is not supported on this JVM.",
+ // SYNTAX_ERR
+ "Syntax error in ''{0}''."
};
private static Vector _keys;
diff --git a/src/org/apache/xalan/xsltc/compiler/util/ErrorMessages_no.java b/src/org/apache/xalan/xsltc/compiler/util/ErrorMessages_no.java
index 648cd7c..2a481a6 100644
--- a/src/org/apache/xalan/xsltc/compiler/util/ErrorMessages_no.java
+++ b/src/org/apache/xalan/xsltc/compiler/util/ErrorMessages_no.java
@@ -249,7 +249,9 @@
// STRAY_SORT_ERR
"<xsl:sort> kan bare brukes under <xsl:for-each> eller <xsl:apply-templates>.",
// UNSUPPORTED_ENCODING
- "Karaktersett ''{0}'' er ikke st\u00f8ttet av denne JVM."
+ "Karaktersett ''{0}'' er ikke st\u00f8ttet av denne JVM.",
+ // SYNTAX_ERR
+ "Syntax error in ''{0}''." // TODO: How do you say "syntax error" in norwegian?
};
public Object handleGetObject(String key) {
diff --git a/src/org/apache/xalan/xsltc/compiler/util/ErrorMsg.java b/src/org/apache/xalan/xsltc/compiler/util/ErrorMsg.java
index 4351a64..4a97c42 100644
--- a/src/org/apache/xalan/xsltc/compiler/util/ErrorMsg.java
+++ b/src/org/apache/xalan/xsltc/compiler/util/ErrorMsg.java
@@ -165,6 +165,7 @@
// Recently added error messages
public static final int STRAY_SORT_ERR = 74;
public static final int UNSUPPORTED_ENCODING = 75;
+ public static final int SYNTAX_ERR = 76;
// All error messages are localized and are stored in resource bundles.
// This array and the following 4 strings are read from that bundle.
diff --git a/src/org/apache/xalan/xsltc/compiler/util/LongType.java b/src/org/apache/xalan/xsltc/compiler/util/LongType.java
deleted file mode 100644
index cb9435a..0000000
--- a/src/org/apache/xalan/xsltc/compiler/util/LongType.java
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * @(#)$Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2001 The Apache Software Foundation. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xalan" and "Apache Software Foundation" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- * nor may "Apache" appear in their name, without prior written
- * permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 2001, Sun
- * Microsystems., http://www.sun.com. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- * @author G. Todd Miller
- *
- */
-
-package org.apache.xalan.xsltc.compiler.util;
-
-import org.apache.xalan.xsltc.compiler.util.Type;
-import org.apache.bcel.generic.*;
-import org.apache.xalan.xsltc.compiler.Parser;
-import org.apache.xalan.xsltc.compiler.FlowList;
-import org.apache.xalan.xsltc.compiler.Constants;
-
-public final class LongType extends NumberType {
- protected LongType() {}
-
- public String toString() {
- return "long";
- }
-
- public boolean identicalTo(Type other) {
- return this == other;
- }
-
- public String toSignature() {
- return "J";
- }
-
- public org.apache.bcel.generic.Type toJCType() {
- return org.apache.bcel.generic.Type.LONG;
- }
-
- /**
- * @see org.apache.xalan.xsltc.compiler.util.Type#distanceTo
- */
- public int distanceTo(Type type) {
- if (type == this) {
- return 0;
- }
- else if (type == Type.Int) {
- return 1;
- }
- else
- return Integer.MAX_VALUE;
- }
-
- /**
- * Translates an long into an object of internal type <code>type</code>.
- *
- * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo
- */
- public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
- final Type type) {
- if (type == Type.Real) {
- translateTo(classGen, methodGen, (RealType) type);
- }
- else if (type == Type.Int) {
- translateTo(classGen, methodGen, (IntType) type);
- }
- else if (type == Type.String) {
- translateTo(classGen, methodGen, (StringType) type);
- }
- else if (type == Type.Boolean) {
- translateTo(classGen, methodGen, (BooleanType) type);
- }
- else if (type == Type.Reference) {
- translateTo(classGen, methodGen, (ReferenceType) type);
- }
- else {
- ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
- toString(), type.toString());
- classGen.getParser().reportError(Constants.FATAL, err);
- }
- }
-
-
- /**
- * Expects an long on the stack and pushes a real.
- *
- * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo
- */
- public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
- RealType type) {
- methodGen.getInstructionList().append(L2D);
- }
-
- /**
- * Expects an long on the stack and pushes its string value by calling
- * <code>Long.toString(int i)</code>.
- *
- * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo
- */
- public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
- StringType type) {
- final ConstantPoolGen cpg = classGen.getConstantPool();
- final InstructionList il = methodGen.getInstructionList();
- il.append(new INVOKESTATIC(cpg.addMethodref(LONG_CLASS,
- "toString",
- "(J)" + STRING_SIG)));
- }
-
- /**
- * Expects an long on the stack and pushes a 0 if its value is 0 and
- * a 1 otherwise.
- *
- * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo
- */
- public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
- BooleanType type) {
- final InstructionList il = methodGen.getInstructionList();
- final BranchHandle falsec = il.append(new IFEQ(null));
- il.append(LCONST_1);
- final BranchHandle truec = il.append(new GOTO(null));
- falsec.setTarget(il.append(LCONST_0));
- truec.setTarget(il.append(NOP));
- }
-
- /**
- * Expects an long on the stack and translates it to a non-synthesized
- * boolean. It does not push a 0 or a 1 but instead returns branchhandle
- * list to be appended to the false list.
- *
- * @see org.apache.xalan.xsltc.compiler.util.Type#translateToDesynthesized
- */
- public FlowList translateToDesynthesized(ClassGenerator classGen,
- MethodGenerator methodGen,
- BooleanType type) {
- final InstructionList il = methodGen.getInstructionList();
- return new FlowList(il.append(new IFEQ(null)));
- }
-
- /**
- * Expects an long on the stack and pushes a boxed integer.
- * Boxed integers are represented by an instance of
- * <code>java.lang.Integer</code>.
- *
- * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo
- */
- public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
- ReferenceType type) {
- final ConstantPoolGen cpg = classGen.getConstantPool();
- final InstructionList il = methodGen.getInstructionList();
- il.append(new NEW(cpg.addClass(LONG_CLASS)));
- il.append(DUP_X1);
- il.append(SWAP);
- il.append(new INVOKESPECIAL(cpg.addMethodref(LONG_CLASS,
- "<init>", "(J)V")));
- }
-
- /**
- * Translates an long into the Java type denoted by <code>clazz</code>.
- * Expects an long on the stack and pushes a number of the appropriate
- * type after coercion.
- */
- public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
- Class clazz) {
- final InstructionList il = methodGen.getInstructionList();
- if (clazz == Character.TYPE) {
- il.append(L2I);
- il.append(I2C);
- }
- else if (clazz == Byte.TYPE) {
- il.append(L2I);
- il.append(I2B);
- }
- else if (clazz == Short.TYPE) {
- il.append(L2I);
- il.append(I2S);
- }
- else if (clazz == Integer.TYPE) {
- il.append(L2I);
- }
- else if (clazz == Long.TYPE) {
- il.append(NOP);
- }
- else if (clazz == Float.TYPE) {
- il.append(L2F);
- }
- else if (clazz == Double.TYPE) {
- il.append(L2D);
- }
- else {
- ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
- toString(), clazz.getName());
- classGen.getParser().reportError(Constants.FATAL, err);
- }
- }
-
- /**
- * Translates an object of this type to its boxed representation.
- */
- public void translateBox(ClassGenerator classGen,
- MethodGenerator methodGen) {
- translateTo(classGen, methodGen, Type.Reference);
- }
-
- /**
- * Translates an object of this type to its unboxed representation.
- */
- public void translateUnBox(ClassGenerator classGen,
- MethodGenerator methodGen) {
- final ConstantPoolGen cpg = classGen.getConstantPool();
- final InstructionList il = methodGen.getInstructionList();
- il.append(new CHECKCAST(cpg.addClass(LONG_CLASS)));
- final int index = cpg.addMethodref(LONG_CLASS,
- LONG_VALUE,
- LONG_VALUE_SIG);
- il.append(new INVOKEVIRTUAL(index));
- }
-
- public Instruction ADD() {
- return InstructionConstants.LADD;
- }
-
- public Instruction SUB() {
- return InstructionConstants.LSUB;
- }
-
- public Instruction MUL() {
- return InstructionConstants.LMUL;
- }
-
- public Instruction DIV() {
- return InstructionConstants.LDIV;
- }
-
- public Instruction REM() {
- return InstructionConstants.LREM;
- }
-
- public Instruction NEG() {
- return InstructionConstants.LNEG;
- }
-
- public Instruction LOAD(int slot) {
- return new LLOAD(slot);
- }
-
- public Instruction STORE(int slot) {
- return new LSTORE(slot);
- }
-
- public BranchInstruction GT(boolean tozero) {
- // GTM:TBD
- return tozero ? (BranchInstruction) new IFGT(null) :
- (BranchInstruction) new IF_ICMPGT(null);
- }
-
- public BranchInstruction GE(boolean tozero) {
- // GTM:TBD
- return tozero ? (BranchInstruction) new IFGE(null) :
- (BranchInstruction) new IF_ICMPGE(null);
- }
-
- public BranchInstruction LT(boolean tozero) {
- // GTM:TBD
- return tozero ? (BranchInstruction) new IFLT(null) :
- (BranchInstruction) new IF_ICMPLT(null);
- }
-
- public BranchInstruction LE(boolean tozero) {
- // GTM:TBD
- return tozero ? (BranchInstruction) new IFLE(null) :
- (BranchInstruction) new IF_ICMPLE(null);
- }
-}
diff --git a/src/org/apache/xalan/xsltc/compiler/util/ReferenceType.java b/src/org/apache/xalan/xsltc/compiler/util/ReferenceType.java
index b04a7f8..c7ac287 100644
--- a/src/org/apache/xalan/xsltc/compiler/util/ReferenceType.java
+++ b/src/org/apache/xalan/xsltc/compiler/util/ReferenceType.java
@@ -228,6 +228,38 @@
}
/**
+ * Translates a reference into the Java type denoted by <code>clazz</code>.
+ * Only conversion allowed is to java.lang.Object.
+ */
+ public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
+ Class clazz) {
+ if (clazz.getName().equals("java.lang.Object")) {
+ methodGen.getInstructionList().append(NOP);
+ }
+ else {
+ ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
+ toString(), clazz.getName());
+ classGen.getParser().reportError(Constants.FATAL, err);
+ }
+ }
+
+ /**
+ * Translates an external Java type into a reference. Only conversion
+ * allowed is from java.lang.Object.
+ */
+ public void translateFrom(ClassGenerator classGen, MethodGenerator methodGen,
+ Class clazz) {
+ if (clazz.getName().equals("java.lang.Object")) {
+ methodGen.getInstructionList().append(NOP);
+ }
+ else {
+ ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
+ toString(), clazz.getName());
+ classGen.getParser().reportError(Constants.FATAL, err);
+ }
+ }
+
+ /**
* Expects a reference on the stack and translates it to a non-synthesized
* boolean. It does not push a 0 or a 1 but instead returns branchhandle
* list to be appended to the false list.
diff --git a/src/org/apache/xalan/xsltc/compiler/util/Type.java b/src/org/apache/xalan/xsltc/compiler/util/Type.java
index 5413d96..689b65f 100644
--- a/src/org/apache/xalan/xsltc/compiler/util/Type.java
+++ b/src/org/apache/xalan/xsltc/compiler/util/Type.java
@@ -72,7 +72,6 @@
public abstract class Type implements Constants {
public static final Type Int = new IntType();
- public static final Type Lng = new LongType(); //GTM,bug 3592
public static final Type Real = new RealType();
public static final Type Boolean = new BooleanType();
public static final Type NodeSet = new NodeSetType();
diff --git a/src/org/apache/xalan/xsltc/compiler/util/Util.java b/src/org/apache/xalan/xsltc/compiler/util/Util.java
index 0fc872b..022bac5 100644
--- a/src/org/apache/xalan/xsltc/compiler/util/Util.java
+++ b/src/org/apache/xalan/xsltc/compiler/util/Util.java
@@ -66,6 +66,7 @@
import org.apache.bcel.generic.Type;
import org.apache.bcel.generic.*;
import org.apache.xalan.xsltc.compiler.Parser;
+import org.apache.xalan.xsltc.compiler.Constants;
public final class Util {
static public char filesep;
@@ -155,35 +156,46 @@
/**
* Replace a certain character in a string with a new substring.
*/
- public static String replace(String base, char c, String str) {
- final int len = base.length() - 1;
- int pos;
- while ((pos = base.indexOf(c)) > -1) {
- if (pos == 0) {
- final String after = base.substring(1);
- base = str + after;
- }
- else if (pos == len) {
- final String before = base.substring(0, pos);
- base = before + str;
+ public static String replace(String base, char ch, String str) {
+ return (base.indexOf(ch) < 0) ? base :
+ replace(base, String.valueOf(ch), new String[] { str });
+ }
+
+ public static String replace(String base, String delim, String[] str) {
+ final int len = base.length();
+ final StringBuffer result = new StringBuffer();
+
+ for (int i = 0; i < len; i++) {
+ final char ch = base.charAt(i);
+ final int k = delim.indexOf(ch);
+
+ if (k >= 0) {
+ result.append(str[k]);
}
else {
- final String before = base.substring(0, pos);
- final String after = base.substring(pos+1);
- base = before + str + after;
+ result.append(ch);
}
}
- return base;
+ return result.toString();
}
/**
- * Replace occurances of '.' with '$dot$' and '-' with '$dash$'
+ * Replace occurances of '.', '-', '/' and ':'
*/
public static String escape(String input) {
- input = replace(input, '.', "$dot$");
- input = replace(input, '-', "$dash$");
- return input;
+ return replace(input, ".-/:",
+ new String[] { "$dot$", "$dash$", "$slash$", "$colon$" });
}
+ public static String getLocalName(String qname) {
+ final int index = qname.lastIndexOf(":");
+ return (index > 0) ? qname.substring(index + 1) : qname;
+ }
+
+ public static String getPrefix(String qname) {
+ final int index = qname.lastIndexOf(":");
+ return (index > 0) ? qname.substring(0, index) :
+ Constants.EMPTYSTRING;
+ }
}
diff --git a/src/org/apache/xalan/xsltc/compiler/xpath.cup b/src/org/apache/xalan/xsltc/compiler/xpath.cup
index a4f1e85..adce4e3 100644
--- a/src/org/apache/xalan/xsltc/compiler/xpath.cup
+++ b/src/org/apache/xalan/xsltc/compiler/xpath.cup
@@ -92,6 +92,11 @@
private XSLTC _xsltc;
/**
+ * String representation of the expression being parsed.
+ */
+ private String _expression;
+
+ /**
* Line number where this expression/pattern was declared.
*/
private int _lineNumber = 0;
@@ -115,6 +120,10 @@
return _parser.getQName(name);
}
+ public QName getQNameIgnoreDefaultNs(String name) {
+ return _parser.getQNameIgnoreDefaultNs(name);
+ }
+
public void setMultiDocument(boolean flag) {
_xsltc.setMultiDocument(flag);
}
@@ -178,8 +187,9 @@
* compiled in a separate module.
*
*/
- public Symbol parse(int lineNumber) throws Exception {
+ public Symbol parse(String expression, int lineNumber) throws Exception {
try {
+ _expression = expression;
_lineNumber = lineNumber;
return super.parse();
}
@@ -210,12 +220,29 @@
}
public void report_error(String message, Object info) {
- // empty
+ final ErrorMsg err = new ErrorMsg(ErrorMsg.SYNTAX_ERR, _lineNumber,
+ _expression);
+ _parser.reportError(Constants.FATAL, err);
}
public void report_fatal_error(String message, Object info) {
// empty
}
+
+ public RelativeLocationPath insertStep(Step step, RelativeLocationPath rlp) {
+ if (rlp instanceof Step) {
+ return new ParentLocationPath(step, (Step) rlp);
+ }
+ else if (rlp instanceof ParentLocationPath) {
+ final ParentLocationPath plp = (ParentLocationPath) rlp;
+ final RelativeLocationPath newrlp = insertStep(step, plp.getPath());
+ return new ParentLocationPath(newrlp, plp.getStep());
+ }
+ else {
+ addError(new ErrorMsg(ErrorMsg.INTERNAL_ERR, "XPathParser.insertStep"));
+ return rlp;
+ }
+ }
:}
terminal SLASH, DOT, LBRACK, RBRACK, VBAR, LPAREN, RPAREN, STAR, COMMA;
@@ -294,12 +321,6 @@
| SLASH RelativePathPattern:rpp
{: RESULT = new AbsolutePathPattern(rpp); :}
- | ProcessingInstructionPattern:pip
- {: RESULT = pip; :}
-
- | ProcessingInstructionPattern:pip Predicates:pp
- {: RESULT = (ProcessingInstructionPattern)pip.setPredicates(pp); :}
-
| IdKeyPattern:ikp
{: RESULT = ikp; :}
@@ -345,6 +366,12 @@
pp);
:}
+ | ProcessingInstructionPattern:pip
+ {: RESULT = pip; :}
+
+ | ProcessingInstructionPattern:pip Predicates:pp
+ {: RESULT = (ProcessingInstructionPattern)pip.setPredicates(pp); :}
+
| ChildOrAttributeAxisSpecifier:axis NodeTestPattern:nt
{: RESULT=new StepPattern(axis.intValue(),
parser.findNodeType(axis.intValue(), nt),
@@ -356,7 +383,19 @@
{: RESULT = new StepPattern(axis.intValue(),
parser.findNodeType(axis.intValue(),nt),
pp);
- :};
+ :}
+
+ | ChildOrAttributeAxisSpecifier:axis ProcessingInstructionPattern:pip
+ {:
+ RESULT = pip; // TODO: report error if axis is attribute
+ :}
+
+ | ChildOrAttributeAxisSpecifier:axis ProcessingInstructionPattern:pip
+ Predicates:pp
+ {:
+ // TODO: report error if axis is attribute
+ RESULT = (ProcessingInstructionPattern)pip.setPredicates(pp);
+ :};
NodeTestPattern ::= NameTestPattern:nt
{: RESULT = nt; :}
@@ -586,30 +625,13 @@
AbbreviatedAbsoluteLocationPath ::= DSLASH RelativeLocationPath:rlp
{:
+ final Step step = new Step(Axis.DESCENDANTORSELF, -1, null);
- AbsoluteLocationPath alp = null;
-
- Step left = new Step(Axis.DESCENDANTORSELF, -1, null);
-
- if (rlp instanceof ParentLocationPath) {
- ParentLocationPath plp = new ParentLocationPath(left, rlp);
- alp = new AbsoluteLocationPath(plp);
- }
- else if (rlp instanceof Step) {
- Step right = (Step)rlp;
- alp = new AbsoluteLocationPath(new ParentLocationPath(left, right));
- }
- else {
- // Don't think we'll ever get here...
- Step right = new Step(Axis.CHILD, NodeTest.ELEMENT, null);
- alp = new AbsoluteLocationPath(new ParentLocationPath(left, right));
- }
-
- RESULT = new FilteredAbsoluteLocationPath(alp);
+ RESULT = new FilteredAbsoluteLocationPath(
+ new AbsoluteLocationPath(parser.insertStep(step,
+ (RelativeLocationPath) rlp)));
:};
-
-
Step ::= NodeTest:ntest
{:
if (ntest instanceof Step) {
@@ -718,25 +740,25 @@
/*
* If the string appears to have the syntax of a QName, store
* namespace info in the literal expression. This is used for
- * element-available and function-available functions.
+ * element-available and function-available functions, among
+ * others. Also, the default namespace must be ignored.
*/
+ String namespace = null;
final int index = string.lastIndexOf(':');
- final String prefix = index >= 0
- ? string.substring(0, index)
- : Constants.EMPTYSTRING;
- String namespace = parser._symbolTable.lookupNamespace(prefix);
- RESULT = namespace == null
- ? new LiteralExpr(string)
- : new LiteralExpr(string, namespace);
+
+ if (index > 0) {
+ final String prefix = string.substring(0, index);
+ namespace = parser._symbolTable.lookupNamespace(prefix);
+ }
+ RESULT = (namespace == null) ? new LiteralExpr(string)
+ : new LiteralExpr(string, namespace);
:}
| INT:num
{:
- // bug fix 3592, num comes in as a Long rather than an Integer
- // see xpath.lex, {Digit}+ rule.
long value = num.longValue();
- if ((value < Integer.MIN_VALUE) || (value > Integer.MAX_VALUE)) {
- RESULT = new LongExpr(num.longValue());
+ if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
+ RESULT = new RealExpr(value);
}
else {
if (num.doubleValue() == -0)
@@ -745,7 +767,7 @@
RESULT = new IntExpr(num.intValue());
else if (num.doubleValue() == 0.0)
RESULT = new RealExpr(num.doubleValue());
- else
+ else
RESULT = new IntExpr(num.intValue());
}
:}
@@ -777,49 +799,48 @@
if (node == null) {
RESULT = new UnresolvedRef(varName);
}
-
:};
FunctionCall ::= FunctionName:fname LPAREN RPAREN
{:
- if (fname == parser.getQName("current")) {
+ if (fname == parser.getQNameIgnoreDefaultNs("current")) {
RESULT = new CurrentCall(fname);
}
- else if (fname == parser.getQName("number")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("number")) {
RESULT = new NumberCall(fname, parser.EmptyArgs);
}
- else if (fname == parser.getQName("string")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("string")) {
RESULT = new StringCall(fname, parser.EmptyArgs);
}
- else if (fname == parser.getQName("concat")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("concat")) {
RESULT = new ConcatCall(fname, parser.EmptyArgs);
}
- else if (fname == parser.getQName("true")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("true")) {
RESULT = new BooleanExpr(true);
}
- else if (fname == parser.getQName("false")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("false")) {
RESULT = new BooleanExpr(false);
}
- else if (fname == parser.getQName("name")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("name")) {
RESULT = new NameCall(fname);
}
- else if (fname == parser.getQName("generate-id")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("generate-id")) {
RESULT = new GenerateIdCall(fname, parser.EmptyArgs);
}
- else if (fname == parser.getQName("string-length")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("string-length")) {
RESULT = new StringLengthCall(fname, parser.EmptyArgs);
}
- else if (fname == parser.getQName("position")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("position")) {
RESULT = new PositionCall(fname);
}
- else if (fname == parser.getQName("last")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("last")) {
RESULT = new LastCall(fname);
}
- else if (fname == parser.getQName("local-name")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("local-name")) {
RESULT = new LocalNameCall(fname);
}
- else if (fname == parser.getQName("namespace-uri")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("namespace-uri")) {
RESULT = new NamespaceUriCall(fname);
}
else {
@@ -829,74 +850,74 @@
| FunctionName:fname LPAREN NonemptyArgumentList:argl RPAREN
{:
- if (fname == parser.getQName("concat")) {
+ if (fname == parser.getQNameIgnoreDefaultNs("concat")) {
RESULT = new ConcatCall(fname, argl);
}
- else if (fname == parser.getQName("number")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("number")) {
RESULT = new NumberCall(fname, argl);
}
- else if (fname == parser.getQName("document")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("document")) {
parser.setMultiDocument(true);
RESULT = new DocumentCall(fname, argl);
}
- else if (fname == parser.getQName("string")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("string")) {
RESULT = new StringCall(fname, argl);
}
- else if (fname == parser.getQName("boolean")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("boolean")) {
RESULT = new BooleanCall(fname, argl);
}
- else if (fname == parser.getQName("name")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("name")) {
RESULT = new NameCall(fname, argl);
}
- else if (fname == parser.getQName("generate-id")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("generate-id")) {
RESULT = new GenerateIdCall(fname, argl);
}
- else if (fname == parser.getQName("not")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("not")) {
RESULT = new NotCall(fname, argl);
}
- else if (fname == parser.getQName("format-number")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("format-number")) {
RESULT = new FormatNumberCall(fname, argl);
}
- else if (fname == parser.getQName("unparsed-entity-uri")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("unparsed-entity-uri")) {
RESULT = new UnparsedEntityUriCall(fname, argl);
}
- else if (fname == parser.getQName("key")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("key")) {
RESULT = new KeyCall(fname, argl);
}
- else if (fname == parser.getQName("id")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("id")) {
RESULT = new KeyCall(fname, argl);
}
- else if (fname == parser.getQName("ceiling")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("ceiling")) {
RESULT = new CeilingCall(fname, argl);
}
- else if (fname == parser.getQName("round")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("round")) {
RESULT = new RoundCall(fname, argl);
}
- else if (fname == parser.getQName("floor")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("floor")) {
RESULT = new FloorCall(fname, argl);
}
- else if (fname == parser.getQName("contains")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("contains")) {
RESULT = new ContainsCall(fname, argl);
}
- else if (fname == parser.getQName("string-length")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("string-length")) {
RESULT = new StringLengthCall(fname, argl);
}
- else if (fname == parser.getQName("starts-with")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("starts-with")) {
RESULT = new StartsWithCall(fname, argl);
}
- else if (fname == parser.getQName("function-available")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("function-available")) {
RESULT = new FunctionAvailableCall(fname, argl);
}
- else if (fname == parser.getQName("element-available")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("element-available")) {
RESULT = new ElementAvailableCall(fname, argl);
}
- else if (fname == parser.getQName("local-name")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("local-name")) {
RESULT = new LocalNameCall(fname, argl);
}
- else if (fname == parser.getQName("lang")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("lang")) {
RESULT = new LangCall(fname, argl);
}
- else if (fname == parser.getQName("namespace-uri")) {
+ else if (fname == parser.getQNameIgnoreDefaultNs("namespace-uri")) {
RESULT = new NamespaceUriCall(fname, argl);
}
// Special case for extension function nodeset()
@@ -920,18 +941,24 @@
{: argl.insertElementAt(arg, 0); RESULT = argl; :};
FunctionName ::= QName:fname
- {:
- fname.clearDefaultNamespace();
- RESULT = fname;
- :};
+ {:
+ final String prefix = fname.getPrefix();
+ if (prefix == null || prefix.equals(Constants.EMPTYSTRING)) {
+ fname = parser.getQNameIgnoreDefaultNs(fname.getLocalPart());
+ }
+ RESULT = fname;
+ :};
VariableName ::= QName:vname
- {:
- vname.clearDefaultNamespace();
- RESULT = vname;
- :};
+ {:
+ final String prefix = vname.getPrefix();
+ if (prefix == null || prefix.equals(Constants.EMPTYSTRING)) {
+ vname = parser.getQNameIgnoreDefaultNs(vname.getLocalPart());
+ }
+ RESULT = vname;
+ :};
-Argument ::= Expr:ex
+Argument ::= Expr:ex
{: RESULT = ex; :};
NodeTest ::= NameTest:nt
@@ -948,14 +975,13 @@
| PIPARAM LPAREN Literal:l RPAREN
{:
- QName name = parser.getQName("name");
+ QName name = parser.getQNameIgnoreDefaultNs("name");
Expression exp = new EqualityExpr(Operators.EQ,
new NameCall(name),
new LiteralExpr(l));
Vector predicates = new Vector();
predicates.addElement(new Predicate(exp));
RESULT = new Step(Axis.CHILD, NodeTest.PI, predicates);
- //RESULT = new Integer(NodeTest.PI);
:}
| PI
@@ -970,54 +996,54 @@
QName ::= QNAME:qname
{: RESULT = parser.getQName(qname); :}
- | DIV
- {: RESULT = parser.getQName("div"); :}
+ | DIV
+ {: RESULT = parser.getQNameIgnoreDefaultNs("div"); :}
| MOD
- {: RESULT = parser.getQName("mod"); :}
+ {: RESULT = parser.getQNameIgnoreDefaultNs("mod"); :}
| KEY
- {: RESULT = parser.getQName("key"); :}
+ {: RESULT = parser.getQNameIgnoreDefaultNs("key"); :}
| ANCESTOR
- {: RESULT = parser.getQName("child"); :}
+ {: RESULT = parser.getQNameIgnoreDefaultNs("child"); :}
| ANCESTORORSELF
- {: RESULT = parser.getQName("ancestor-or-self"); :}
+ {: RESULT = parser.getQNameIgnoreDefaultNs("ancestor-or-self"); :}
| ATTRIBUTE
- {: RESULT = parser.getQName("attribute"); :}
+ {: RESULT = parser.getQNameIgnoreDefaultNs("attribute"); :}
| CHILD
- {: RESULT = parser.getQName("child"); :}
+ {: RESULT = parser.getQNameIgnoreDefaultNs("child"); :}
| DESCENDANT
- {: RESULT = parser.getQName("decendant"); :}
+ {: RESULT = parser.getQNameIgnoreDefaultNs("decendant"); :}
| DESCENDANTORSELF
- {: RESULT = parser.getQName("decendant-or-self"); :}
+ {: RESULT = parser.getQNameIgnoreDefaultNs("decendant-or-self"); :}
| FOLLOWING
- {: RESULT = parser.getQName("following"); :}
+ {: RESULT = parser.getQNameIgnoreDefaultNs("following"); :}
| FOLLOWINGSIBLING
- {: RESULT = parser.getQName("following-sibling"); :}
+ {: RESULT = parser.getQNameIgnoreDefaultNs("following-sibling"); :}
| NAMESPACE
- {: RESULT = parser.getQName("namespace"); :}
+ {: RESULT = parser.getQNameIgnoreDefaultNs("namespace"); :}
| PARENT
- {: RESULT = parser.getQName("parent"); :}
+ {: RESULT = parser.getQNameIgnoreDefaultNs("parent"); :}
| PRECEDING
- {: RESULT = parser.getQName("preceding"); :}
+ {: RESULT = parser.getQNameIgnoreDefaultNs("preceding"); :}
| PRECEDINGSIBLING
- {: RESULT = parser.getQName("preceding-sibling"); :}
+ {: RESULT = parser.getQNameIgnoreDefaultNs("preceding-sibling"); :}
| SELF
- {: RESULT = parser.getQName("self"); :}
+ {: RESULT = parser.getQNameIgnoreDefaultNs("self"); :}
| ID
- {: RESULT = parser.getQName("id"); :};
+ {: RESULT = parser.getQNameIgnoreDefaultNs("id"); :};
diff --git a/src/org/apache/xalan/xsltc/compiler/xpath.lex b/src/org/apache/xalan/xsltc/compiler/xpath.lex
index a82c95a..2f361a8 100644
--- a/src/org/apache/xalan/xsltc/compiler/xpath.lex
+++ b/src/org/apache/xalan/xsltc/compiler/xpath.lex
@@ -79,10 +79,22 @@
Exception
%yylexthrow}
-Digit=[0-9]
-Letter=[A-Za-z]
-NCNameChar=({Letter}|{Digit}|"."|"-"|"_")
+Letter={BaseChar}|{Ideographic}
+
+BaseChar=[\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u0131\u0134-\u013E\u0141-\u0148\u014A-\u017E\u0180-\u01C3\u01CD-\u01F0\u01F4-\u01F5\u01FA-\u0217\u0250-\u02A8\u02BB-\u02C1\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03D6\u03DA\u03DC\u03DE\u03E0\u03E2-\u03F3\u0401-\u040C\u040E-\u044F\u0451-\u045C\u045E-\u0481\u0490-\u04C4\u04C7-\u04C8\u04CB-\u04CC\u04D0-\u04EB\u04EE-\u04F5\u04F8-\u04F9\u0531-\u0556\u0559\u0561-\u0586\u05D0-\u05EA\u05F0-\u05F2\u0621-\u063A\u0641-\u064A\u0671-\u06B7\u06BA-\u06BE\u06C0-\u06CE\u06D0-\u06D3\u06D5\u06E5-\u06E6\u0905-\u0939\u093D\u0958-\u0961\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09DC-\u09DD\u09DF-\u09E1\u09F0-\u09F1\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8B\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD\u0AE0\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B36-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB5\u0BB7-\u0BB9\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C60-\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CDE\u0CE0-\u0CE1\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39\u0D60-\u0D61\u0E01-\u0E2E\u0E30\u0E32-\u0E33\u0E40-\u0E45\u0E81-\u0E82\u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EAE\u0EB0\u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0F40-\u0F47\u0F49-\u0F69\u10A0-\u10C5\u10D0-\u10F6\u1100\u1102-\u1103\u1105-\u1107\u1109\u110B-\u110C\u110E-\u1112\u113C\u113E\u1140\u114C\u114E\u1150\u1154-\u1155\u1159\u115F-\u1161\u1163\u1165\u1167\u1169\u116D-\u116E\u1172-\u1173\u1175\u119E\u11A8\u11AB\u11AE-\u11AF\u11B7-\u11B8\u11BA\u11BC-\u11C2\u11EB\u11F0\u11F9\u1E00-\u1E9B\u1EA0-\u1EF9\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2126\u212A-\u212B\u212E\u2180-\u2182\u3041-\u3094\u30A1-\u30FA\u3105-\u312C\uAC00-\uD7A3]
+
+Ideographic=[\u4E00-\u9FA5\u3007\u3021-\u3029]
+
+CombiningChar=[\u0300-\u0345\u0360-\u0361\u0483-\u0486\u0591-\u05A1\u05A3-\u05B9\u05BB-\u05BD\u05BF\u05C1-\u05C2\u05C4\u064B-\u0652\u0670\u06D6-\u06DC\u06DD-\u06DF\u06E0-\u06E4\u06E7-\u06E8\u06EA-\u06ED\u0901-\u0903\u093C\u093E-\u094C\u094D\u0951-\u0954\u0962-\u0963\u0981-\u0983\u09BC\u09BE\u09BF\u09C0-\u09C4\u09C7-\u09C8\u09CB-\u09CD\u09D7\u09E2-\u09E3\u0A02\u0A3C\u0A3E\u0A3F\u0A40-\u0A42\u0A47-\u0A48\u0A4B-\u0A4D\u0A70-\u0A71\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0B01-\u0B03\u0B3C\u0B3E-\u0B43\u0B47-\u0B48\u0B4B-\u0B4D\u0B56-\u0B57\u0B82-\u0B83\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C01-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55-\u0C56\u0C82-\u0C83\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5-\u0CD6\u0D02-\u0D03\u0D3E-\u0D43\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EC8-\u0ECD\u0F18-\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86-\u0F8B\u0F90-\u0F95\u0F97\u0F99-\u0FAD\u0FB1-\u0FB7\u0FB9\u20D0-\u20DC\u20E1\u302A-\u302F\u3099\u309A]
+
+Digit=[\u0030-\u0039\u0660-\u0669\u06F0-\u06F9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE7-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29]
+
+Extender=[\u00B7\u02D0\u02D1\u0387\u0640\u0E46\u0EC6\u3005\u3031-\u3035\u309D-\u309E\u30FC-\u30FE]
+
NCName=({Letter}|"_")({NCNameChar})*
+
+NCNameChar={Letter}|{Digit}|"."|"-"|"_"|{CombiningChar}|{Extender}
+
%%
"*" { return new Symbol(sym.STAR); }
diff --git a/src/org/apache/xalan/xsltc/dom/BitArray.java b/src/org/apache/xalan/xsltc/dom/BitArray.java
index 9e33047..16894a4 100644
--- a/src/org/apache/xalan/xsltc/dom/BitArray.java
+++ b/src/org/apache/xalan/xsltc/dom/BitArray.java
@@ -93,6 +93,10 @@
/**
* Constructor. Defines the initial size of the bit array (in bits).
*/
+ public BitArray() {
+ this(32);
+ }
+
public BitArray(int size) {
if (size < 32) size = 32;
_bitSize = size;
diff --git a/src/org/apache/xalan/xsltc/dom/CurrentNodeListIterator.java b/src/org/apache/xalan/xsltc/dom/CurrentNodeListIterator.java
index 79df194..5e26eec 100644
--- a/src/org/apache/xalan/xsltc/dom/CurrentNodeListIterator.java
+++ b/src/org/apache/xalan/xsltc/dom/CurrentNodeListIterator.java
@@ -70,28 +70,31 @@
import org.apache.xalan.xsltc.runtime.BasisLibrary;
public final class CurrentNodeListIterator extends NodeIteratorBase {
- private NodeIterator _source;
+
private boolean _docOrder;
+ private NodeIterator _source;
private final CurrentNodeListFilter _filter;
private IntegerArray _nodes = new IntegerArray();
private int _current; // index in _nodes of the next node to try
+ private int _last = -1;
- private AbstractTranslet _translet;
private final int _currentNode;
- private int _last;
+ private AbstractTranslet _translet;
public CurrentNodeListIterator(NodeIterator source,
CurrentNodeListFilter filter,
int currentNode,
- AbstractTranslet translet) {
+ AbstractTranslet translet)
+ {
this(source, !source.isReverse(), filter, currentNode, translet);
}
public CurrentNodeListIterator(NodeIterator source, boolean docOrder,
CurrentNodeListFilter filter,
int currentNode,
- AbstractTranslet translet) {
+ AbstractTranslet translet)
+ {
_source = source;
_filter = filter;
_translet = translet;
@@ -129,13 +132,13 @@
}
public int next() {
- final boolean docOrder = _docOrder;
final int last = _nodes.cardinality();
final int currentNode = _currentNode;
+ final AbstractTranslet translet = _translet;
for (int index = _current; index < last; ) {
final int node = _nodes.at(index++); // note increment
- if (_filter.test(node, index, last, currentNode, _translet, this)) {
+ if (_filter.test(node, index, last, currentNode, translet, this)) {
_current = index;
return returnNode(node);
}
@@ -143,28 +146,12 @@
return END;
}
- private int computePositionOfLast() {
- int lastPosition = 0;
- final boolean docOrder = _docOrder;
- final int last = _nodes.cardinality();
- final int currNode = _currentNode;
-
- for (int index = _current; index < last; ) {
- int nodeIndex = _nodes.at(index++); // note increment
- if (_filter.test(nodeIndex, index, last, currNode, _translet, this)) {
- lastPosition++;
- }
- }
- return lastPosition;
- }
-
public NodeIterator setStartNode(int node) {
NodeIterator retval = this;
if (_isRestartable) {
- // iterator is not a clone
_source.setStartNode(_startNode = node);
- // including ROOT
+
_nodes.clear();
while ((node = _source.next()) != END) {
_nodes.add(node);
@@ -172,13 +159,14 @@
_current = 0;
retval = resetPosition();
}
- // compute position of _last
- _last = computePositionOfLast();
return retval;
}
public int getLast() {
- return (_last == -1) ? computePositionOfLast() : _last;
+ if (_last == -1) {
+ _last = computePositionOfLast();
+ }
+ return _last;
}
public void setMark() {
@@ -190,4 +178,20 @@
_source.gotoMark();
_current = _markedNode;
}
+
+ private int computePositionOfLast() {
+ final int last = _nodes.cardinality();
+ final int currNode = _currentNode;
+ final AbstractTranslet translet = _translet;
+
+ int lastPosition = 0;
+ for (int index = _current; index < last; ) {
+ int nodeIndex = _nodes.at(index++); // note increment
+ if (_filter.test(nodeIndex, index, last, currNode, translet, this)) {
+ lastPosition++;
+ }
+ }
+ return lastPosition;
+ }
}
+
diff --git a/src/org/apache/xalan/xsltc/dom/DOMAdapter.java b/src/org/apache/xalan/xsltc/dom/DOMAdapter.java
index e0cc9bf..450f844 100644
--- a/src/org/apache/xalan/xsltc/dom/DOMAdapter.java
+++ b/src/org/apache/xalan/xsltc/dom/DOMAdapter.java
@@ -73,6 +73,7 @@
import org.apache.xalan.xsltc.TransletException;
public final class DOMAdapter implements DOM {
+
private final DOMImpl _domImpl;
private short[] _mapping;
private short[] _reverse;
@@ -85,7 +86,8 @@
public DOMAdapter(DOMImpl dom,
String[] namesArray,
- String[] namespaceArray) {
+ String[] namespaceArray)
+ {
_domImpl = dom;
_mapping = dom.getMapping(namesArray);
_reverse = dom.getReverseMapping(namesArray);
@@ -100,7 +102,9 @@
_NSreverse = _domImpl.getReverseNamespaceMapping(namespaces);
}
- /** returns singleton iterator containg the document root */
+ /**
+ * Returns singleton iterator containg the document root
+ */
public NodeIterator getIterator() {
return _domImpl.getIterator();
}
@@ -124,11 +128,11 @@
public NodeIterator getChildren(final int node) {
NodeIterator iterator = _domImpl.getChildren(node);
if (_filter == null) {
- return(iterator.setStartNode(node));
+ return iterator.setStartNode(node);
}
else {
- iterator = _domImpl.strippingIterator(iterator,_mapping,_filter);
- return(iterator.setStartNode(node));
+ iterator = _domImpl.strippingIterator(iterator, _mapping, _filter);
+ return iterator.setStartNode(node);
}
}
@@ -138,9 +142,10 @@
public NodeIterator getTypedChildren(final int type) {
NodeIterator iterator = _domImpl.getTypedChildren(_reverse[type]);
- if ((_reverse[type] == DOM.TEXT) && (_filter != null))
- iterator = _domImpl.strippingIterator(iterator,_mapping,_filter);
- return(iterator);
+ if (_reverse[type] == DOM.TEXT && _filter != null) {
+ return _domImpl.strippingIterator(iterator,_mapping,_filter);
+ }
+ return iterator;
}
public NodeIterator getNamespaceAxisIterator(final int axis, final int ns) {
@@ -150,26 +155,27 @@
public NodeIterator getAxisIterator(final int axis) {
NodeIterator iterator = _domImpl.getAxisIterator(axis);
if (_filter != null) {
- iterator = _domImpl.strippingIterator(iterator,_mapping,_filter);
+ return _domImpl.strippingIterator(iterator, _mapping, _filter);
}
- return(iterator);
+ return iterator;
}
public NodeIterator getTypedAxisIterator(final int axis, final int type) {
NodeIterator iterator;
if (axis == Axis.NAMESPACE) {
- if ((type == NO_TYPE) || (type > _NSreverse.length))
- iterator = _domImpl.getAxisIterator(axis);
- else
- iterator = _domImpl.getTypedAxisIterator(axis,_NSreverse[type]);
+ iterator = (type == NO_TYPE || type > _NSreverse.length) ?
+ _domImpl.getAxisIterator(axis) :
+ _domImpl.getTypedAxisIterator(axis,_NSreverse[type]);
}
- else
+ else {
iterator = _domImpl.getTypedAxisIterator(axis, _reverse[type]);
+ }
- if ((_reverse[type] == DOM.TEXT) && (_filter != null))
- iterator = _domImpl.strippingIterator(iterator,_mapping,_filter);
- return(iterator);
+ if (_reverse[type] == DOM.TEXT && _filter != null) {
+ iterator = _domImpl.strippingIterator(iterator, _mapping, _filter);
+ }
+ return iterator;
}
public NodeIterator getNthDescendant(int type, int n, boolean includeself) {
@@ -177,7 +183,8 @@
}
public NodeIterator getNodeValueIterator(NodeIterator iterator, int type,
- String value, boolean op) {
+ String value, boolean op)
+ {
return _domImpl.getNodeValueIterator(iterator, type, value, op);
}
diff --git a/src/org/apache/xalan/xsltc/dom/DOMImpl.java b/src/org/apache/xalan/xsltc/dom/DOMImpl.java
index 8721aab..f82c8df 100644
--- a/src/org/apache/xalan/xsltc/dom/DOMImpl.java
+++ b/src/org/apache/xalan/xsltc/dom/DOMImpl.java
@@ -242,11 +242,7 @@
// Hack for ordering attribute nodes
if (node1 >= _firstAttributeNode) node1 = _parent[node1];
if (node2 >= _firstAttributeNode) node2 = _parent[node2];
-
- if ((node2 < _treeNodeLimit) && (node1 < node2))
- return(true);
- else
- return(false);
+ return (node2 < _treeNodeLimit && node1 < node2);
}
/**
@@ -256,9 +252,8 @@
if (_nodes == null) {
_nodes = new Node[_type.length];
}
- return _nodes[index] != null
- ? _nodes[index]
- : (_nodes[index] = new NodeImpl(index));
+ return _nodes[index] != null ? _nodes[index]
+ : (_nodes[index] = new NodeImpl(index));
}
/**
@@ -276,9 +271,8 @@
if (_nodeLists == null) {
_nodeLists = new NodeList[_type.length];
}
- return _nodeLists[index] != null
- ? _nodeLists[index]
- : (_nodeLists[index] = new NodeListImpl(index));
+ return _nodeLists[index] != null ? _nodeLists[index]
+ : (_nodeLists[index] = new NodeListImpl(index));
}
/**
@@ -293,8 +287,7 @@
* Create an empty org.w3c.dom.NodeList
*/
private NodeList getEmptyNodeList() {
- return EmptyNodeList != null
- ? EmptyNodeList
+ return EmptyNodeList != null ? EmptyNodeList
: (EmptyNodeList = new NodeListImpl(new int[0]));
}
@@ -302,8 +295,7 @@
* Create an empty org.w3c.dom.NamedNodeMap
*/
private NamedNodeMap getEmptyNamedNodeMap() {
- return EmptyNamedNodeMap != null
- ? EmptyNamedNodeMap
+ return EmptyNamedNodeMap != null ? EmptyNamedNodeMap
: (EmptyNamedNodeMap = new NamedNodeMapImpl(new int[0]));
}
@@ -791,18 +783,19 @@
}
public NodeIterator reset() {
- if (hasChildren(_startNode))
- _currentChild = _offsetOrChild[_startNode];
- else
- _currentChild = END;
+ _currentChild = hasChildren(_startNode) ?
+ _offsetOrChild[_startNode] : END;
return resetPosition();
}
public int next() {
- for (int node = _currentChild; node != END;
- node = _nextSibling[node]) {
- if (_type[node] == _nodeType) {
- _currentChild = _nextSibling[node];
+ final short[] type = _type;
+ final int nodeType = _nodeType;
+ final int[] nextSibling = _nextSibling;
+
+ for (int node = _currentChild; node != END; node = nextSibling[node]) {
+ if (type[node] == nodeType) {
+ _currentChild = nextSibling[node];
return returnNode(node);
}
}
@@ -1018,9 +1011,14 @@
_nodeType = nodeType;
}
- // assumes caller will pass element nodes
public NodeIterator setStartNode(int node) {
if (_isRestartable) {
+ // If not an element node, then set iterator at END
+ if (!isElement(node)) {
+ _attribute = END;
+ return resetPosition();
+ }
+
for (node = _lengthOrAttr[_startNode = node];
node != NULL && _type[node] != _nodeType;
node = _nextSibling[node]);
@@ -1413,12 +1411,15 @@
public NodeIterator setStartNode(int node) {
if (_isRestartable) {
_last = -1;
- if (node >= _firstAttributeNode)
- _startNode = node = _parent[node];
- else if (_includeSelf)
+ if (_includeSelf) {
_startNode = node;
- else
+ }
+ else if (node >= _firstAttributeNode) {
+ _startNode = node = _parent[node];
+ }
+ else {
_startNode = _parent[node];
+ }
_index = _startNode;
return resetPosition();
}
@@ -1432,12 +1433,9 @@
public int next() {
if (_index >= 0) {
- int bob = _index;
- if (_index == 0)
- _index = -1;
- else
- _index = _parent[_index];
- return returnNode(bob);
+ final int node = _index;
+ _index = (_index == 0) ? -1 : _parent[_index];
+ return returnNode(node);
}
return(NULL);
}
@@ -1985,10 +1983,7 @@
* Returns the type of a specific node
*/
public int getType(final int node) {
- if (node >= _type.length)
- return(0);
- else
- return _type[node];
+ return (node >= _type.length) ? 0 : _type[node];
}
/**
@@ -1996,10 +1991,8 @@
*/
public int getNamespaceType(final int node) {
final int type = _type[node];
- if (type >= NTYPES)
- return(_namespace[type-NTYPES]);
- else
- return(0); // default namespace
+ return (type >= NTYPES) ? _namespace[type-NTYPES]
+ : 0; // default namespace
}
/**
@@ -2025,15 +2018,10 @@
case PROCESSING_INSTRUCTION:
final String pistr = makeStringValue(node);
final int col = pistr.indexOf(' ');
- if (col > 0)
- return pistr.substring(col+1);
- else
- return pistr;
+ return (col > 0) ? pistr.substring(col+1) : pistr;
default:
- if (node < _firstAttributeNode)
- return getElementValue(node); // element string value
- else
- return makeStringValue(node); // attribute value
+ return (node < _firstAttributeNode) ? getElementValue(node) :
+ makeStringValue(node);
}
}
@@ -2101,20 +2089,16 @@
len = uri.length();
if (len > 0) len++;
}
-
- if ((name.length() > 0) && (name.charAt(len) == '@'))
- result[i] = (short)ATTRIBUTE;
- else
- result[i] = (short)ELEMENT;
+ result[i] = (short) ((name.length() > 0 && name.charAt(len) == '@') ?
+ ATTRIBUTE : ELEMENT);
}
// actual mapping of caller requested names
for (i = 0; i < namesLength; i++) {
result[getGeneralizedType(names[i])] = (short)(i + NTYPES);
}
-
- return(result);
+ return result;
}
/**
@@ -2133,7 +2117,7 @@
if (result[i + NTYPES] == ELEMENT)
result[i + NTYPES] = NO_TYPE;
}
- return(result);
+ return result;
}
/**
@@ -2167,15 +2151,11 @@
final int length = namespaces.length;
final short[] result = new short[length];
- for (i=0; i<length; i++) {
+ for (i = 0; i < length; i++) {
Integer type = (Integer)_nsIndex.get(namespaces[i]);
- if (type == null)
- result[i] = -1;
- else
- result[i] = type.shortValue();
+ result[i] = (type == null) ? -1 : type.shortValue();
}
-
- return(result);
+ return result;
}
/**
@@ -2313,17 +2293,12 @@
return EMPTYSTRING;
case DOM.NAMESPACE:
final int index = _prefix[node];
- if (index < _prefixArray.length)
- return _prefixArray[index];
- else
- return EMPTYSTRING;
+ return (index < _prefixArray.length) ? _prefixArray[index]
+ : EMPTYSTRING;
case DOM.PROCESSING_INSTRUCTION:
final String pistr = makeStringValue(node);
final int col = pistr.indexOf(' ');
- if (col > -1)
- return(pistr.substring(0,col));
- else
- return pistr;
+ return (col > -1) ? pistr.substring(0,col) : pistr;
default:
// Construct the local part (omit '@' for attributes)
String name = getLocalName(node);
@@ -2333,8 +2308,9 @@
final int pi = _prefix[node];
if (pi > 0) {
final String prefix = _prefixArray[pi];
- if (prefix != EMPTYSTRING)
- name = prefix+':'+name;
+ if (prefix != EMPTYSTRING) {
+ name = prefix + ':' + name;
+ }
}
return name;
}
@@ -2350,10 +2326,7 @@
else {
final int type = getNamespaceType(node);
final String name = _uriArray[type];
- if (name == null)
- return(EMPTYSTRING);
- else
- return(name);
+ return (name == null) ? EMPTYSTRING : name;
}
}
@@ -2382,20 +2355,14 @@
*/
public String getAttributeValue(final int type, final int element) {
final int attr = getAttributeNode(type, element);
- if (attr != NULL)
- return makeStringValue(attr);
- else
- return EMPTYSTRING;
+ return (attr != NULL) ? makeStringValue(attr) : EMPTYSTRING;
}
/**
* Returns true if a given element has an attribute of a given type
*/
public boolean hasAttribute(final int type, final int node) {
- if (getAttributeNode(type, node) != NULL)
- return true;
- else
- return false;
+ return (getAttributeNode(type, node) != NULL);
}
/**
@@ -2421,10 +2388,8 @@
* Returns an iterator with all the children of a given node
*/
public NodeIterator getChildren(final int node) {
- if (hasChildren(node))
- return(new ChildrenIterator());
- else
- return(EMPTYITERATOR);
+ return hasChildren(node) ? new ChildrenIterator()
+ : EMPTYITERATOR;
}
/**
@@ -2492,66 +2457,58 @@
* containing nodes of a typed axis (ex.: child::foo)
*/
public NodeIterator getTypedAxisIterator(int axis, int type) {
- NodeIterator iterator = null;
-
/* This causes an error when using patterns for elements that
do not exist in the DOM (translet types which do not correspond
to a DOM type are mapped to the DOM.ELEMENT type).
*/
- if (type == NO_TYPE) {
- return(EMPTYITERATOR);
+ // Most common case handled first
+ if (axis == Axis.CHILD && type != ELEMENT) {
+ return new TypedChildrenIterator(type);
}
- else if ((type == ELEMENT) && (axis != Axis.NAMESPACE)) {
- iterator = new FilterIterator(getAxisIterator(axis),
- getElementFilter());
+
+ if (type == NO_TYPE) {
+ return EMPTYITERATOR;
+ }
+
+ if (type == ELEMENT && axis != Axis.NAMESPACE) {
+ return new FilterIterator(getAxisIterator(axis),
+ getElementFilter());
}
else {
switch (axis) {
case Axis.SELF:
- iterator = new TypedSingletonIterator(type);
- break;
- case Axis.CHILD:
- iterator = new TypedChildrenIterator(type);
- break;
+ return new TypedSingletonIterator(type);
case Axis.PARENT:
- return(new ParentIterator().setNodeType(type));
+ return new ParentIterator().setNodeType(type);
case Axis.ANCESTOR:
- return(new TypedAncestorIterator(type));
+ return new TypedAncestorIterator(type);
case Axis.ANCESTORORSELF:
- return((new TypedAncestorIterator(type)).includeSelf());
+ return (new TypedAncestorIterator(type)).includeSelf();
case Axis.ATTRIBUTE:
- return(new TypedAttributeIterator(type));
+ return new TypedAttributeIterator(type);
case Axis.DESCENDANT:
- iterator = new TypedDescendantIterator(type);
- break;
+ return new TypedDescendantIterator(type);
case Axis.DESCENDANTORSELF:
- iterator = (new TypedDescendantIterator(type)).includeSelf();
- break;
+ return (new TypedDescendantIterator(type)).includeSelf();
case Axis.FOLLOWING:
- iterator = new TypedFollowingIterator(type);
- break;
+ return new TypedFollowingIterator(type);
case Axis.PRECEDING:
- iterator = new TypedPrecedingIterator(type);
- break;
+ return new TypedPrecedingIterator(type);
case Axis.FOLLOWINGSIBLING:
- iterator = new TypedFollowingSiblingIterator(type);
- break;
+ return new TypedFollowingSiblingIterator(type);
case Axis.PRECEDINGSIBLING:
- iterator = new TypedPrecedingSiblingIterator(type);
- break;
+ return new TypedPrecedingSiblingIterator(type);
case Axis.NAMESPACE:
- if (type == ELEMENT)
- iterator = new NamespaceIterator();
- else
- iterator = new TypedNamespaceIterator(type);
- break;
+ return (type == ELEMENT) ?
+ (NodeIterator) new NamespaceIterator() :
+ (NodeIterator) new TypedNamespaceIterator(type);
default:
BasisLibrary.runTimeError(BasisLibrary.TYPED_AXIS_SUPPORT_ERR,
Axis.names[axis]);
}
}
- return(iterator);
+ return null;
}
/**
@@ -2562,26 +2519,21 @@
* nodes are taken, while 'ns' specifies the namespace URI type.
*/
public NodeIterator getNamespaceAxisIterator(int axis, int ns) {
-
- NodeIterator iterator = null;
-
if (ns == NO_TYPE) {
- return(EMPTYITERATOR);
+ return EMPTYITERATOR;
}
else {
switch (axis) {
case Axis.CHILD:
- iterator = new NamespaceChildrenIterator(ns);
- break;
+ return new NamespaceChildrenIterator(ns);
case Axis.ATTRIBUTE:
- iterator = new NamespaceAttributeIterator(ns);
- break;
+ return new NamespaceAttributeIterator(ns);
default:
BasisLibrary.runTimeError(BasisLibrary.TYPED_AXIS_SUPPORT_ERR,
Axis.names[axis]);
}
}
- return(iterator);
+ return null;
}
/**
@@ -2589,27 +2541,23 @@
* a given type.
*/
public NodeIterator getTypedDescendantIterator(int type) {
- NodeIterator iterator;
- if (type == ELEMENT)
- iterator = new FilterIterator(new DescendantIterator(),
- getElementFilter());
- else
- iterator = new TypedDescendantIterator(type);
- return(iterator);
+ return (type == ELEMENT) ? (NodeIterator)
+ new FilterIterator(new DescendantIterator(), getElementFilter())
+ : (NodeIterator) new TypedDescendantIterator(type);
}
/**
* Returns the nth descendant of a node
*/
public NodeIterator getNthDescendant(int type, int n, boolean includeself) {
- NodeIterator source;
- if (type == ELEMENT)
- source = new FilterIterator(new DescendantIterator(),
- getElementFilter());
- else
- source = new TypedDescendantIterator(type);
- if (includeself) ((NodeIteratorBase)source).includeSelf();
- return(new NthDescendantIterator(source, n, type));
+ NodeIterator source = (type == ELEMENT) ? (NodeIterator)
+ new FilterIterator(new DescendantIterator(), getElementFilter())
+ : (NodeIterator) new TypedDescendantIterator(type);
+
+ if (includeself) {
+ ((NodeIteratorBase)source).includeSelf();
+ }
+ return new NthDescendantIterator(source, n, type);
}
/**
@@ -2753,8 +2701,8 @@
* Performs a shallow copy (ref. XSLs copy())
*/
public String shallowCopy(final int node, TransletOutputHandler handler)
- throws TransletException {
-
+ throws TransletException
+ {
final int type = _type[node];
switch(type) {
@@ -2798,40 +2746,53 @@
private String copyElement(int node, int type,
TransletOutputHandler handler)
- throws TransletException {
-
+ throws TransletException
+ {
type = type - NTYPES;
String name = _namesArray[type];
final int pi = _prefix[node];
final int ui = _namespace[type];
+
if (pi > 0) {
final String prefix = _prefixArray[pi];
final String uri = _uriArray[ui];
final String local = getLocalName(node);
- if (prefix.equals(EMPTYSTRING))
- name = local;
- else
- name = prefix+':'+local;
+
+ name = prefix.equals(EMPTYSTRING) ? local : (prefix + ':' + local);
handler.startElement(name);
handler.namespace(prefix, uri);
}
else {
if (ui > 0) {
- handler.startElement(getLocalName(node));
+ handler.startElement(name = getLocalName(node));
handler.namespace(EMPTYSTRING, _uriArray[ui]);
}
else {
handler.startElement(name);
}
}
+
+ // Copy element namespaces
+ for (int a = _lengthOrAttr[node]; a != NULL; a = _nextSibling[a]) {
+ if (_type[a] == NAMESPACE) {
+ handler.namespace(_prefixArray[_prefix[a]],
+ makeStringValue(a));
+ }
+ }
+
return name;
}
/**
* Returns the string value of the entire tree
*/
+ private String _cachedStringValue = null;
+
public String getStringValue() {
- return getElementValue(ROOTNODE);
+ if (_cachedStringValue == null) {
+ _cachedStringValue = getElementValue(ROOTNODE);
+ }
+ return _cachedStringValue;
}
/**
@@ -2888,6 +2849,18 @@
if ((name = getNodeName(element)) != null) {
buffer.append('<');
buffer.append(name);
+
+ int attribute = _lengthOrAttr[element];
+ while (attribute != NULL) {
+ // Skip namespace nodes
+ if (_type[attribute] != NAMESPACE) {
+ buffer.append(' ').append(getNodeName(attribute))
+ .append("=\"").append(getNodeValue(attribute))
+ .append('"');
+ }
+ attribute = _nextSibling[attribute];
+ }
+
if (_offsetOrChild[element] == NULL) {
buffer.append("/>");
return buffer;
@@ -3046,11 +3019,8 @@
private String getNamespaceURI(String prefix) {
// Get the stack associated with this namespace prefix
final Stack stack = (Stack)_nsPrefixes.get(prefix);
- if ((stack != null) && (!stack.empty())) {
- return((String)stack.peek());
- }
- else
- return(EMPTYSTRING);
+ return (stack != null && !stack.empty()) ? (String) stack.peek()
+ : EMPTYSTRING;
}
/**
@@ -3355,8 +3325,6 @@
*/
public void characters(char[] ch, int start, int length) {
if (_currentOffset + length > _text.length) {
- // GTM resizeTextArray(_text.length * 2);
- // bug fix 6189, contributed by Mirko Seifert
resizeTextArray(
Math.max(_text.length * 2, _currentOffset + length));
}
@@ -3497,23 +3465,14 @@
}
}
// Did we append namespace nodes only?
- if (!attrsAdded && last != -1) {
- _nextSibling2[last] = DOM.NULL;
- }
- else {
- _nextSibling2[attr] = DOM.NULL;
- }
+ _nextSibling2[(!attrsAdded && last != -1) ? last : attr] = DOM.NULL;
}
final int col = qname.lastIndexOf(':');
// Assign an internal type to this element (may exist)
- if (uri != null && localName.length() > 0) {
- _type[node] = makeElementNode(uri, localName);
- }
- else {
- _type[node] = makeElementNode(qname, col);
- }
+ _type[node] = (uri != null && localName.length() > 0) ?
+ makeElementNode(uri, localName) : makeElementNode(qname, col);
// Assign an internal type to the element's prefix (may exist)
if (col > -1) {
@@ -3556,7 +3515,8 @@
*/
public void ignorableWhitespace(char[] ch, int start, int length) {
if (_currentOffset + length > _text.length) {
- resizeTextArray(_text.length * 2);
+ resizeTextArray(
+ Math.max(_text.length * 2, _currentOffset + length));
}
System.arraycopy(ch, start, _text, _currentOffset, length);
_currentOffset += length;
@@ -3627,7 +3587,8 @@
public void comment(char[] ch, int start, int length) {
makeTextNode(false);
if (_currentOffset + length > _text.length) {
- resizeTextArray(_text.length * 2);
+ resizeTextArray(
+ Math.max(_text.length * 2, _currentOffset + length));
}
System.arraycopy(ch, start, _text, _currentOffset, length);
_currentOffset += length;
@@ -3652,8 +3613,6 @@
private void characters(final String string) {
final int length = string.length();
if (_currentOffset + length > _text.length) {
- // GTM: resizeTextArray(_text.length * 2);
- // bug fix 6189, contributed by Mirko Seifert
resizeTextArray(
Math.max(_text.length * 2, _currentOffset + length));
}
diff --git a/src/org/apache/xalan/xsltc/dom/MultiDOM.java b/src/org/apache/xalan/xsltc/dom/MultiDOM.java
index 42f9f19..95bfa77 100644
--- a/src/org/apache/xalan/xsltc/dom/MultiDOM.java
+++ b/src/org/apache/xalan/xsltc/dom/MultiDOM.java
@@ -76,6 +76,7 @@
import org.apache.xalan.xsltc.runtime.BasisLibrary;
public final class MultiDOM implements DOM {
+
private static final int NO_TYPE = DOM.FIRST_TYPE - 2;
private static final int INITIAL_SIZE = 4;
private static final int CLR = 0x00FFFFFF;
@@ -88,12 +89,11 @@
private Hashtable _documents = new Hashtable();
private final class AxisIterator implements NodeIterator {
- // constitutive data
private final int _axis;
private final int _type;
- // implementation mechanism
- private NodeIterator _source;
+
private int _mask;
+ private NodeIterator _source = null;
public AxisIterator(final int axis, final int type) {
_axis = axis;
@@ -112,19 +112,23 @@
}
public NodeIterator setStartNode(final int node) {
- _mask = node & SET;
- int dom = node >>> 24;
+ final int dom = node >>> 24;
+ final int mask = node & SET;
- // consider caching these
- if ((_type == NO_TYPE) || (_type == DOM.ELEMENT)) {
- _source = _adapters[dom].getAxisIterator(_axis);
+ // Get a new source first time and when mask changes
+ if (_source == null || _mask != mask) {
+ if (_type == NO_TYPE) {
+ _source = _adapters[dom].getAxisIterator(_axis);
+ }
+ else if (_axis == Axis.CHILD && _type != ELEMENT) {
+ _source = _adapters[dom].getTypedChildren(_type);
+ }
+ else {
+ _source = _adapters[dom].getTypedAxisIterator(_axis, _type);
+ }
}
- else if (_axis == Axis.CHILD) {
- _source = _adapters[dom].getTypedChildren(_type);
- }
- else {
- _source = _adapters[dom].getTypedAxisIterator(_axis,_type);
- }
+
+ _mask = mask;
_source.setStartNode(node & CLR);
return this;
}
@@ -143,10 +147,7 @@
}
public boolean isReverse() {
- if (_source == null)
- return(false);
- else
- return _source.isReverse();
+ return (_source == null) ? false : _source.isReverse();
}
public void setMark() {
@@ -290,7 +291,9 @@
return((domIdx.intValue() << 24));
}
- /** returns singleton iterator containg the document root */
+ /**
+ * Returns singleton iterator containg the document root
+ */
public NodeIterator getIterator() {
// main source document @ 0
return _adapters[0].getIterator();
diff --git a/src/org/apache/xalan/xsltc/dom/NodeIteratorBase.java b/src/org/apache/xalan/xsltc/dom/NodeIteratorBase.java
index 310ae5e..78d56a4 100644
--- a/src/org/apache/xalan/xsltc/dom/NodeIteratorBase.java
+++ b/src/org/apache/xalan/xsltc/dom/NodeIteratorBase.java
@@ -83,7 +83,8 @@
public NodeIterator reset() {
final boolean temp = _isRestartable;
_isRestartable = true;
- setStartNode(_startNode);
+ // Must adjust _startNode if self is included
+ setStartNode(_includeSelf ? _startNode + 1 : _startNode);
_isRestartable = temp;
return this;
}
diff --git a/src/org/apache/xalan/xsltc/dom/StepIterator.java b/src/org/apache/xalan/xsltc/dom/StepIterator.java
index fe4cdbe..8edb6b3 100644
--- a/src/org/apache/xalan/xsltc/dom/StepIterator.java
+++ b/src/org/apache/xalan/xsltc/dom/StepIterator.java
@@ -104,12 +104,10 @@
if (_isRestartable) {
// Set start node for left-hand iterator...
_source.setStartNode(_startNode = node);
+
// ... and get start node for right-hand iterator from left-hand,
// with special case for //* path - see ParentLocationPath
- if (_includeSelf)
- _iterator.setStartNode(_startNode);
- else
- _iterator.setStartNode(_source.next());
+ _iterator.setStartNode(_includeSelf ? _startNode : _source.next());
return resetPosition();
}
return this;
@@ -118,10 +116,7 @@
public NodeIterator reset() {
_source.reset();
// Special case for //* path - see ParentLocationPath
- if (_includeSelf)
- _iterator.setStartNode(_startNode);
- else
- _iterator.setStartNode(_source.next());
+ _iterator.setStartNode(_includeSelf ? _startNode : _source.next());
return resetPosition();
}
diff --git a/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java b/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java
index 9b4c431..8bffb59 100644
--- a/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java
+++ b/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java
@@ -65,8 +65,8 @@
package org.apache.xalan.xsltc.runtime;
-import java.io.File;
-import java.util.Vector;
+import java.io.FileWriter;
+import java.util.ArrayList;
import java.util.Enumeration;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
@@ -77,6 +77,7 @@
import org.apache.xalan.xsltc.dom.KeyIndex;
import org.apache.xalan.xsltc.dom.DTDMonitor;
import org.apache.xalan.xsltc.util.IntegerArray;
+import org.apache.xalan.xsltc.runtime.output.*;
public abstract class AbstractTranslet implements Translet {
@@ -103,6 +104,25 @@
// Use one empty string instead of constantly instanciating String("");
private final static String EMPTYSTRING = "";
+
+ /************************************************************************
+ * Debugging
+ ************************************************************************/
+ public void printInternalState() {
+ System.out.println("-------------------------------------");
+ System.out.println("AbstractTranslet this = " + this);
+ System.out.println("vbase = " + vbase);
+ System.out.println("vframe = " + vframe);
+ System.out.println("varsStack.size() = " + varsStack.size());
+ System.out.println("pbase = " + pbase);
+ System.out.println("vframe = " + pframe);
+ System.out.println("paramsStack.size() = " + paramsStack.size());
+ System.out.println("namesArray.size = " + namesArray.length);
+ System.out.println("namespaceArray.size = " + namespaceArray.length);
+ System.out.println("");
+ System.out.println("Total memory = " + Runtime.getRuntime().totalMemory());
+ }
+
/**
* Wrap the initial input DOM in a dom adapter. This adapter is wrapped in
* a DOM multiplexer if the document() function is used (handled by compiled
@@ -123,18 +143,18 @@
// Variable's stack: <tt>vbase</tt> and <tt>vframe</tt> are used
// to denote the current variable frame.
protected int vbase = 0, vframe = 0;
- protected Vector varsStack = new Vector();
+ protected ArrayList varsStack = new ArrayList();
// Parameter's stack: <tt>pbase</tt> and <tt>pframe</tt> are used
// to denote the current parameter frame.
protected int pbase = 0, pframe = 0;
- protected Vector paramsStack = new Vector();
+ protected ArrayList paramsStack = new ArrayList();
/**
* Push a new parameter frame.
*/
public final void pushParamFrame() {
- paramsStack.insertElementAt(new Integer(pbase), pframe);
+ paramsStack.add(pframe, new Integer(pbase));
pbase = ++pframe;
}
@@ -143,9 +163,9 @@
*/
public final void popParamFrame() {
if (pbase > 0) {
- final int oldpbase = ((Integer)paramsStack.elementAt(--pbase)).intValue();
- for (int i = pbase; i < pframe; i++) {
- paramsStack.setElementAt(null, i); // for the GC
+ final int oldpbase = ((Integer)paramsStack.get(--pbase)).intValue();
+ for (int i = pframe - 1; i >= pbase; i--) {
+ paramsStack.remove(i);
}
pframe = pbase; pbase = oldpbase;
}
@@ -155,10 +175,9 @@
* Add a new global parameter if not already in the current frame.
*/
public final Object addParameter(String name, Object value) {
- String parName = new String(name);
- parName = replace(parName, '.', "$dot$");
- parName = replace(parName, '-', "$dash$");
- return addParameter(parName, value, false);
+ name = BasisLibrary.replace(name, ".-",
+ new String[] { "$dot$", "$dash$" });
+ return addParameter(name, value, false);
}
/**
@@ -167,16 +186,17 @@
* default value from the <xsl:parameter> element's select attribute or
* element body.
*/
- public final Object addParameter(String name, Object value,
- boolean isDefault) {
-
+ public final Object addParameter(String name, Object value,
+ boolean isDefault)
+ {
// Local parameters need to be re-evaluated for each iteration
for (int i = pframe - 1; i >= pbase; i--) {
- final Parameter param = (Parameter) paramsStack.elementAt(i);
+ final Parameter param = (Parameter) paramsStack.get(i);
+
if (param._name.equals(name)) {
// Only overwrite if current value is the default value and
// the new value is _NOT_ the default value.
- if ((param._isDefault == true) || (!isDefault)) {
+ if (param._isDefault || !isDefault) {
param._value = value;
param._isDefault = isDefault;
return value;
@@ -186,8 +206,7 @@
}
// Add new parameter to parameter stack
- final Parameter param = new Parameter(name, value, isDefault);
- paramsStack.insertElementAt(param, pframe++);
+ paramsStack.add(pframe++, new Parameter(name, value, isDefault));
return value;
}
@@ -205,7 +224,7 @@
*/
public final Object getParameter(String name) {
for (int i = pframe - 1; i >= pbase; i--) {
- final Parameter param = (Parameter)paramsStack.elementAt(i);
+ final Parameter param = (Parameter)paramsStack.get(i);
if (param._name.equals(name)) return param._value;
}
return null;
@@ -215,10 +234,14 @@
* Push a new variable frame.
*/
public final void pushVarFrame(int frameSize) {
- varsStack.insertElementAt(new Integer(vbase), vframe);
+ varsStack.add(vframe, new Integer(vbase));
vbase = ++vframe;
vframe += frameSize;
- varsStack.setSize(vframe + 1); // clear stack frame
+
+ // Clear stack frame
+ for (int i = vbase; i <= vframe + 1; i++) {
+ varsStack.add(i, null);
+ }
}
/**
@@ -226,9 +249,9 @@
*/
public final void popVarFrame() {
if (vbase > 0) {
- final int oldvbase = ((Integer)varsStack.elementAt(--vbase)).intValue();
+ final int oldvbase = ((Integer)varsStack.get(--vbase)).intValue();
for (int i = vbase; i < vframe; i++) {
- varsStack.setElementAt(null, i); // for the GC
+ varsStack.set(i, null); // for the GC
}
vframe = vbase; vbase = oldvbase;
}
@@ -238,38 +261,14 @@
* Get the value of a variable given its index.
*/
public final Object getVariable(int vindex) {
- return varsStack.elementAt(vbase + vindex);
+ return varsStack.get(vbase + vindex);
}
/**
* Set the value of a variable in the current frame.
*/
public final void addVariable(int vindex, Object value) {
- varsStack.setElementAt(value, vbase + vindex);
- }
-
- /**
- * Replace a certain character in a string with a new substring.
- */
- private static String replace(String base, char c, String str) {
- final int len = base.length() - 1;
- int pos;
- while ((pos = base.indexOf(c)) > -1) {
- if (pos == 0) {
- final String after = base.substring(1);
- base = str + after;
- }
- else if (pos == len) {
- final String before = base.substring(0, pos);
- base = before + str;
- }
- else {
- final String before = base.substring(0, pos);
- final String after = base.substring(pos+1);
- base = before + str + after;
- }
- }
- return base;
+ varsStack.set(vbase + vindex, value);
}
/************************************************************************
@@ -489,17 +488,23 @@
************************************************************************/
public TransletOutputHandler openOutputHandler(String filename)
- throws TransletException {
+ throws TransletException
+ {
try {
- // Use the default SAX handler to send the output to the file
- DefaultSAXOutputHandler handler =
- new DefaultSAXOutputHandler(filename, _encoding);
+ final TransletOutputHandlerFactory factory
+ = TransletOutputHandlerFactory.newInstance();
- // Create a translet output handler and plug in the SAX handler
- TextOutput text = new TextOutput(handler, handler, _encoding);
- transferOutputSettings(text);
- text.startDocument();
- return(text);
+ factory.setEncoding(_encoding);
+ factory.setOutputMethod(_method);
+ factory.setWriter(new FileWriter(filename));
+ factory.setOutputType(TransletOutputHandlerFactory.STREAM);
+
+ final TransletOutputHandler handler
+ = factory.getTransletOutputHandler();
+
+ transferOutputSettings(handler);
+ handler.startDocument();
+ return handler;
}
catch (Exception e) {
throw new TransletException(e);
@@ -557,46 +562,43 @@
/**
* Transfer the output settings to the output post-processor
*/
- protected void transferOutputSettings(TransletOutputHandler output) {
-
- // It is an error if this method is called with anything else than
- // the translet post-processor (TextOutput)
- if (!(output instanceof TextOutput)) return;
-
- TextOutput handler = (TextOutput)output;
-
- // Transfer the output method setting
+ protected void transferOutputSettings(TransletOutputHandler handler) {
if (_method != null) {
- // Transfer all settings relevant to XML output
if (_method.equals("xml")) {
- if (_standalone != null) handler.setStandalone(_standalone);
- if (_omitHeader) handler.omitHeader(true);
- handler.setType(TextOutput.XML);
+ if (_standalone != null) {
+ handler.setStandalone(_standalone);
+ }
+ if (_omitHeader) {
+ handler.omitHeader(true);
+ }
handler.setCdataElements(_cdata);
- if (_version != null) handler.setVersion(_version);
+ if (_version != null) {
+ handler.setVersion(_version);
+ }
handler.setIndent(_indent);
- if (_doctypeSystem != null)
+ if (_doctypeSystem != null) {
handler.setDoctype(_doctypeSystem, _doctypePublic);
+ }
}
- // Transfer all output settings relevant to HTML output
else if (_method.equals("html")) {
- handler.setType(TextOutput.HTML);
handler.setIndent(_indent);
handler.setDoctype(_doctypeSystem, _doctypePublic);
- if (_mediaType != null) handler.setMediaType(_mediaType);
- }
- else if (_method.equals("text")) {
- handler.setType(TextOutput.TEXT);
- }
- else {
- handler.setType(TextOutput.QNAME);
+ if (_mediaType != null) {
+ handler.setMediaType(_mediaType);
+ }
}
}
else {
handler.setCdataElements(_cdata);
- if (_version != null) handler.setVersion(_version);
- if (_standalone != null) handler.setStandalone(_standalone);
- if (_omitHeader) handler.omitHeader(true);
+ if (_version != null) {
+ handler.setVersion(_version);
+ }
+ if (_standalone != null) {
+ handler.setStandalone(_standalone);
+ }
+ if (_omitHeader) {
+ handler.omitHeader(true);
+ }
handler.setIndent(_indent);
handler.setDoctype(_doctypeSystem, _doctypePublic);
}
diff --git a/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java b/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java
index a623187..93f8f0c 100644
--- a/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java
+++ b/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java
@@ -431,7 +431,7 @@
if (name.equals("xsl:version"))
return("1.0");
if (name.equals("xsl:vendor"))
- return("Apache Software Foundation");
+ return("Apache Software Foundation (Xalan XSLTC)");
if (name.equals("xsl:vendor-url"))
return("http://xml.apache.org/xalan-j");
@@ -890,6 +890,31 @@
try {
StringBuffer result = new StringBuffer();
formatter.applyLocalizedPattern(pattern);
+
+ //------------------------------------------------------
+ // bug fix # 9179 - make sure localized pattern contains
+ // a leading zero before decimal, handle cases where
+ // decimal is in position zero, and >= to 1.
+ // localized pattern is ###.### convert to ##0.###
+ // localized pattern is .### convert to 0.###
+ //------------------------------------------------------
+ String localizedPattern = formatter.toPattern();
+ int index = localizedPattern.indexOf('.');
+ if ( index >= 1 && localizedPattern.charAt(index-1) == '#' ) {
+ //insert a zero before the decimal point in the pattern
+ StringBuffer newpattern = new StringBuffer();
+ newpattern.append(localizedPattern.substring(0, index-1));
+ newpattern.append("0");
+ newpattern.append(localizedPattern.substring(index));
+ formatter.applyLocalizedPattern(newpattern.toString());
+ } else if (index == 0) {
+ // insert a zero before decimal point in pattern
+ StringBuffer newpattern = new StringBuffer();
+ newpattern.append("0");
+ newpattern.append(localizedPattern);
+ formatter.applyLocalizedPattern(newpattern.toString());
+ }
+
formatter.format(number, result, _fieldPosition);
return(result.toString());
}
@@ -1050,5 +1075,31 @@
System.out.println(msg);
}
+ /**
+ * Replace a certain character in a string with a new substring.
+ */
+ public static String replace(String base, char ch, String str) {
+ return (base.indexOf(ch) < 0) ? base :
+ replace(base, String.valueOf(ch), new String[] { str });
+ }
+
+ public static String replace(String base, String delim, String[] str) {
+ final int len = base.length();
+ final StringBuffer result = new StringBuffer();
+
+ for (int i = 0; i < len; i++) {
+ final char ch = base.charAt(i);
+ final int k = delim.indexOf(ch);
+
+ if (k >= 0) {
+ result.append(str[k]);
+ }
+ else {
+ result.append(ch);
+ }
+ }
+ return result.toString();
+ }
+
//-- End utility functions
}
diff --git a/src/org/apache/xalan/xsltc/runtime/DefaultRun.java b/src/org/apache/xalan/xsltc/runtime/DefaultRun.java
deleted file mode 100644
index 6b66121..0000000
--- a/src/org/apache/xalan/xsltc/runtime/DefaultRun.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * @(#)$Id$
- *
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2001 The Apache Software Foundation. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xalan" and "Apache Software Foundation" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- * nor may "Apache" appear in their name, without prior written
- * permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 2001, Sun
- * Microsystems., http://www.sun.com. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- * @author Jacek Ambroziak
- * @author Santiago Pericas-Geertsen
- * @author G. Todd Miller
- * @author Morten Jorgensen
- *
- */
-
-package org.apache.xalan.xsltc.runtime;
-
-import java.io.*;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.UnknownHostException;
-import java.util.Vector;
-
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.xml.sax.XMLReader;
-import org.xml.sax.SAXException;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.ext.LexicalHandler;
-
-import org.apache.xalan.xsltc.*;
-import org.apache.xalan.xsltc.dom.DOMImpl;
-import org.apache.xalan.xsltc.dom.Axis;
-import org.apache.xalan.xsltc.dom.DTDMonitor;
-import org.apache.xalan.xsltc.runtime.Constants;
-
-final public class DefaultRun {
-
- private TransletOutputHandler _handler;
-
- private String _fileName;
- private String _className;
- private String _jarFileSrc;
- private boolean _isJarFileSpecified = false;
- private Vector _params = null;
- private boolean _uri, _debug;
-
- AbstractTranslet _translet;
-
- public DefaultRun(String className, String fileName,
- boolean uri, boolean debug) {
- _fileName = fileName;
- _className = className;
- _uri = uri;
- _debug = debug;
- }
-
- public void setParameters(Vector params) {
- _params = params;
- }
-
- private void setJarFileInputSrc(boolean flag, String jarFile) {
- // TODO: at this time we do not do anything with this
- // information, attempts to add the jarfile to the CLASSPATH
- // were successful via System.setProperty, but the effects
- // were not visible to the running JVM. For now we add jarfile
- // to CLASSPATH in the wrapper script that calls this program.
- _isJarFileSpecified = flag;
- // TODO verify jarFile exists...
- _jarFileSrc = jarFile;
- }
-
- private void doTransform() {
- try {
- final Class clazz = Class.forName(_className);
- final Translet translet = (Translet)clazz.newInstance();
-
- // Create a SAX parser and get the XMLReader object it uses
- final SAXParserFactory factory = SAXParserFactory.newInstance();
- try {
- factory.setFeature(Constants.NAMESPACE_FEATURE, true);
- }
- catch (Exception e) {
- factory.setNamespaceAware(true);
- }
- final SAXParser parser = factory.newSAXParser();
- final XMLReader reader = parser.getXMLReader();
-
- // Set the DOM's DOM builder as the XMLReader's SAX2 content handler
- final DOMImpl dom = new DOMImpl();
- reader.setContentHandler(dom.getBuilder());
- // Create a DTD monitor and pass it to the XMLReader object
- final DTDMonitor dtdMonitor = new DTDMonitor();
- dtdMonitor.handleDTD(reader);
-
- _translet = (AbstractTranslet)translet;
- dom.setDocumentURI(_fileName);
- if (_uri)
- reader.parse(_fileName);
- else {
- reader.parse(new File(_fileName).toURL().toExternalForm());
- }
-
- // Set size of key/id indices
- _translet.setIndexSize(dom.getSize());
- // If there are any elements with ID attributes, build an index
- dtdMonitor.buildIdIndex(dom, 0, _translet);
-
- _translet.setDTDMonitor(dtdMonitor);
-
- // Pass global parameters
- int n = _params.size();
- for (int i = 0; i < n; i++) {
- Parameter param = (Parameter) _params.elementAt(i);
- translet.addParameter(param._name, param._value);
- }
-
- // Transform the document
- String encoding = _translet._encoding;
-
- DefaultSAXOutputHandler saxHandler =
- new DefaultSAXOutputHandler(System.out, encoding);
- TextOutput textOutput =
- new TextOutput((ContentHandler)saxHandler,
- (LexicalHandler)saxHandler, encoding);
- translet.transform(dom, textOutput);
-
- if (_debug) {
- TransletOutputBase handler = new TransletOutputBase();
- long start = System.currentTimeMillis();
- final int nTimes = 100;
- for (int i = 0; i < nTimes; i++)
- translet.transform(dom, dom.getIterator(), handler);
- long end = System.currentTimeMillis();
- System.out.println("total " + (end - start) + " msec for "
- + nTimes + " transformations");
- System.out.println(((double)end - start)/nTimes + " msec avg");
- }
- }
- catch (TransletException e) {
- System.err.println("\nTranslet Error: " + e.getMessage());
- if (_debug) {
- System.err.println(e.toString());
- e.printStackTrace();
- }
- doSystemExit(1);
- }
- catch (RuntimeException e) {
- System.err.println("\nRuntime Error: " + e.getMessage());
- if (_debug) {
- System.err.println(e.toString());
- e.printStackTrace();
- }
- doSystemExit(1);
- }
- catch (FileNotFoundException e) {
- System.err.println("Error: File or URI '"+_fileName+"' not found.");
- doSystemExit(1);
- }
- catch (MalformedURLException e) {
- System.err.println("Error: Invalid URI '"+_fileName+"'.");
- doSystemExit(1);
- }
- catch (ClassNotFoundException e) {
- System.err.println("Error: Cannot find class '"+_className+"'.");
- doSystemExit(1);
- }
- catch (UnknownHostException e) {
- System.err.println("Error: Can't resolve URI specification '"+
- _fileName+"'.");
- doSystemExit(1);
- }
- catch (Exception e) {
- e.printStackTrace();
- System.err.println("Error: internal error.");
- doSystemExit(1);
- }
- }
-
- /** If we should call System.exit or not */
- protected static boolean allowSystemExit = true;
-
- /** Worker method to call System.exit or not */
- protected static void doSystemExit(int retVal) {
- if (allowSystemExit)
- System.exit(retVal);
- }
-
- private final static String USAGE_STRING =
- "Usage: \n" +
- " xslt [-j <jarfile>] {-u <document_url> | <document>} <class>\n"+
- " [<name1>=<value1> ...]\n\n" +
- " <document> is the xml document to be transformed, or\n" +
- " <document_url> is a url for the xml document,\n" +
- " <class> is the translet class which is either in\n" +
- " user's CLASSPATH or in the <jarfile> specified \n" +
- " with the -j option.\n" +
- " also: [-x] (debug), [-s] (don't allow System.exit)";
-
- public static void printUsage() {
- System.err.println(USAGE_STRING);
- System.exit(1);
- }
-
- public static void main(String[] args) {
- try {
- if (args.length > 0) {
- int i;
- boolean uri = false, debug = false;
- boolean isJarFileSpecified = false;
- String jarFile = null;
-
- // Parse options starting with '-'
- for (i = 0; i < args.length && args[i].charAt(0) == '-'; i++) {
- if (args[i].equals("-u")) {
- uri = true;
- }
- else if (args[i].equals("-s")){
- allowSystemExit = false;
- }
- else if (args[i].equals("-x")) {
- debug = true;
- }
- else if (args[i].equals("-j")) {
- isJarFileSpecified = true;
- jarFile = args[++i];
- }
- else {
- printUsage();
- }
- }
-
- // Enough arguments left ?
- if (args.length - i < 2) {
- printUsage();
- }
-
- // Get document file and class name
- DefaultRun handler = new DefaultRun(args[i+1], args[i],
- uri, debug);
- handler.setJarFileInputSrc(isJarFileSpecified, jarFile);
-
- // Parse stylesheet parameters
- Vector params = new Vector();
- for (i += 2; i < args.length; i++) {
- int equal = args[i].indexOf('=');
- if (equal > 0) {
- final Parameter param =
- new Parameter(args[i].substring(0, equal),
- args[i].substring(equal + 1,
- args[i].length()));
- params.addElement(param);
- }
- else {
- printUsage();
- }
- }
-
- if (i == args.length) {
- handler.setParameters(params);
- handler.doTransform();
- doSystemExit(0);
- }
- }else{
- printUsage();
- }
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- }
-}
diff --git a/src/org/apache/xalan/xsltc/runtime/DefaultSAXOutputHandler.java b/src/org/apache/xalan/xsltc/runtime/DefaultSAXOutputHandler.java
index b3d356f..f808a3c 100644
--- a/src/org/apache/xalan/xsltc/runtime/DefaultSAXOutputHandler.java
+++ b/src/org/apache/xalan/xsltc/runtime/DefaultSAXOutputHandler.java
@@ -215,11 +215,11 @@
buffer.append(_version);
buffer.append("\" encoding=\"");
buffer.append(_encoding);
- if (_standalone != null) {
+ if ( _standalone != null ) {
buffer.append("\" standalone=\"");
buffer.append(_standalone);
}
- buffer.append("\" ?>\n");
+ buffer.append("\"?>\n");
characters(buffer.toString());
}
diff --git a/src/org/apache/xalan/xsltc/runtime/SAXAdapter.java b/src/org/apache/xalan/xsltc/runtime/SAXAdapter.java
index 8642def..f77f890 100644
--- a/src/org/apache/xalan/xsltc/runtime/SAXAdapter.java
+++ b/src/org/apache/xalan/xsltc/runtime/SAXAdapter.java
@@ -106,6 +106,10 @@
}
}
+ public void characters(String characters) throws TransletException {
+ characters(characters.toCharArray(), 0, characters.length());
+ }
+
public void characters(char[] characters, int offset, int length)
throws TransletException {
try {
@@ -186,7 +190,11 @@
public void setHeader(String header) {}
public void setIndent(boolean indent) {}
public void omitHeader(boolean value) {}
- public void setCdataElements(Hashtable elements) { }
+ public void setCdataElements(Hashtable elements) {}
+ public void setDoctype(String system, String pub) {}
+ public void setMediaType(String mediaType) {}
+ public void setStandalone(String standalone) {}
+ public void setVersion(String version) {}
public void close() {}
public String getPrefix(String uri) { return(""); }
}
diff --git a/src/org/apache/xalan/xsltc/runtime/StringValueHandler.java b/src/org/apache/xalan/xsltc/runtime/StringValueHandler.java
index cd0f76e..dec46b5 100644
--- a/src/org/apache/xalan/xsltc/runtime/StringValueHandler.java
+++ b/src/org/apache/xalan/xsltc/runtime/StringValueHandler.java
@@ -71,7 +71,9 @@
private char[] _buffer = new char[32];
private int _free = 0;
- public void characters(char[] ch, int off, int len) {
+ public void characters(char[] ch, int off, int len)
+ throws TransletException
+ {
if (_free + len >= _buffer.length) {
char[] newBuffer = new char[_free + len + 32];
System.arraycopy(_buffer, 0, newBuffer, 0, _free);
@@ -87,6 +89,10 @@
return new String(_buffer, 0, length);
}
+ public void characters(String characters) throws TransletException {
+ characters(characters.toCharArray(), 0, characters.length());
+ }
+
/**
* The value of a PI must not contain the substring "?>". Should
* that substring be present, replace it by "? >".
diff --git a/src/org/apache/xalan/xsltc/runtime/TextOutput.java b/src/org/apache/xalan/xsltc/runtime/TextOutput.java
index 22eb12c..73068e0 100644
--- a/src/org/apache/xalan/xsltc/runtime/TextOutput.java
+++ b/src/org/apache/xalan/xsltc/runtime/TextOutput.java
@@ -335,12 +335,13 @@
}
}
- /**
- * Utility method - pass a string to the SAX handler's characters() method
- */
- private void characters(String str) throws SAXException {
- final char[] ch = str.toCharArray();
- characters(ch, 0, ch.length);
+ public void characters(String str) throws TransletException {
+ try {
+ characters(str.toCharArray(), 0, str.length());
+ }
+ catch (SAXException e) {
+ throw new TransletException(e);
+ }
}
/**
@@ -833,14 +834,6 @@
BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR, patchedName);
}
-/*
-System.err.println("TextOutput.attribute() uri = " + uri
- + " localname = " + localName
- + " qname = " + name
- + "\n value = " + value
- + " escapeString(value) = " + escapeString(value));
-*/
-
// Output as namespace declaration
if (name.startsWith(XMLNS_PREFIX)) {
namespace(name.length() > 6 ? name.substring(6) : EMPTYSTRING, value);
diff --git a/src/org/apache/xalan/xsltc/runtime/TransletOutputBase.java b/src/org/apache/xalan/xsltc/runtime/TransletOutputBase.java
index 79bc81a..61d69ea 100644
--- a/src/org/apache/xalan/xsltc/runtime/TransletOutputBase.java
+++ b/src/org/apache/xalan/xsltc/runtime/TransletOutputBase.java
@@ -71,6 +71,7 @@
public class TransletOutputBase implements TransletOutputHandler {
public void startDocument() throws TransletException {}
public void endDocument() throws TransletException {}
+ public void characters(String characters) throws TransletException {}
public void characters(char[] characters, int offset, int length)
throws TransletException {}
public void startElement(String elementName) throws TransletException {}
@@ -89,5 +90,9 @@
public void setIndent(boolean indent) {}
public void omitHeader(boolean value) {}
public void setCdataElements(Hashtable elements) {}
+ public void setDoctype(String system, String pub) {}
+ public void setMediaType(String mediaType) {}
+ public void setStandalone(String standalone) {}
+ public void setVersion(String version) {}
public void close() {}
}
diff --git a/src/org/apache/xalan/xsltc/trax/DOM2SAX.java b/src/org/apache/xalan/xsltc/trax/DOM2SAX.java
index 4f3af59..48ee609 100644
--- a/src/org/apache/xalan/xsltc/trax/DOM2SAX.java
+++ b/src/org/apache/xalan/xsltc/trax/DOM2SAX.java
@@ -69,6 +69,7 @@
import org.xml.sax.XMLReader;
import org.xml.sax.ContentHandler;
+import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.Locator;
import org.xml.sax.ErrorHandler;
@@ -88,8 +89,6 @@
import org.w3c.dom.Entity;
import org.w3c.dom.Notation;
-// import org.apache.xalan.xsltc.runtime.AttributeList;
-
class DOM2SAX implements XMLReader, Locator {
private final static String EMPTYSTRING = "";
@@ -97,6 +96,7 @@
private Node _dom = null;
private ContentHandler _sax = null;
+ private LexicalHandler _lex = null;
private Hashtable _nsPrefixes = new Hashtable();
public DOM2SAX(Node root) {
@@ -110,8 +110,10 @@
public void setContentHandler(ContentHandler handler) throws
NullPointerException
{
- if (handler == null) throw new NullPointerException();
_sax = handler;
+ if (handler instanceof LexicalHandler) {
+ _lex = (LexicalHandler) handler;
+ }
}
/**
@@ -195,8 +197,6 @@
switch (node.getNodeType()) {
case Node.ATTRIBUTE_NODE: // handled by ELEMENT_NODE
- case Node.COMMENT_NODE: // should be handled!!!
- case Node.CDATA_SECTION_NODE:
case Node.DOCUMENT_FRAGMENT_NODE:
case Node.DOCUMENT_TYPE_NODE :
case Node.ENTITY_NODE :
@@ -204,7 +204,26 @@
case Node.NOTATION_NODE :
// These node types are ignored!!!
break;
+ case Node.CDATA_SECTION_NODE:
+ final String cdata = node.getNodeValue();
+ if (_lex != null) {
+ _lex.startCDATA();
+ _sax.characters(cdata.toCharArray(), 0, cdata.length());
+ _lex.endCDATA();
+ }
+ else {
+ // in the case where there is no lex handler, we still
+ // want the text of the cdate to make its way through.
+ _sax.characters(cdata.toCharArray(), 0, cdata.length());
+ }
+ break;
+ case Node.COMMENT_NODE: // should be handled!!!
+ if (_lex != null) {
+ final String value = node.getNodeValue();
+ _lex.comment(value.toCharArray(), 0, value.length());
+ }
+ break;
case Node.DOCUMENT_NODE:
_sax.setDocumentLocator(this);
diff --git a/src/org/apache/xalan/xsltc/trax/SAX2DOM.java b/src/org/apache/xalan/xsltc/trax/SAX2DOM.java
index de6da38..20b8d71 100644
--- a/src/org/apache/xalan/xsltc/trax/SAX2DOM.java
+++ b/src/org/apache/xalan/xsltc/trax/SAX2DOM.java
@@ -73,21 +73,26 @@
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Comment;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import org.w3c.dom.Attr;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.SAXException;
import org.apache.xalan.xsltc.runtime.Constants;
-class SAX2DOM implements ContentHandler, Constants {
+public class SAX2DOM implements ContentHandler, LexicalHandler, Constants {
private Document _root = null;
private Stack _nodeStk = new Stack();
private Vector _namespaceDecls = null;
public SAX2DOM() throws ParserConfigurationException {
- final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ final DocumentBuilderFactory factory =
+ DocumentBuilderFactory.newInstance();
_root = factory.newDocumentBuilder().newDocument();
}
@@ -96,7 +101,8 @@
_root = (Document) root; // TODO: add support for frags and elems
}
else {
- final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ final DocumentBuilderFactory factory =
+ DocumentBuilderFactory.newInstance();
_root = factory.newDocumentBuilder().newDocument();
}
}
@@ -189,10 +195,13 @@
}
/**
- * This class is only used internally so this method should never
- * be called.
+ * adds processing instruction node to DOM.
*/
public void processingInstruction(String target, String data) {
+ final Node last = (Node)_nodeStk.peek();
+ ProcessingInstruction pi = _root.createProcessingInstruction(
+ target, data);
+ if (pi != null) last.appendChild(pi);
}
/**
@@ -208,4 +217,24 @@
*/
public void skippedEntity(String name) {
}
+
+
+ /**
+ * Lexical Handler method to create comment node in DOM tree.
+ */
+ public void comment(char[] ch, int start, int length) {
+ final Node last = (Node)_nodeStk.peek();
+ Comment comment = _root.createComment(new String(ch,start,length));
+ if (comment != null) last.appendChild(comment);
+ }
+
+ // Lexical Handler methods- not implemented
+ public void startCDATA() { }
+ public void endCDATA() { }
+ public void startEntity(java.lang.String name) { }
+ public void endDTD() { }
+ public void endEntity(String name) { }
+ public void startDTD(String name, String publicId, String systemId)
+ throws SAXException { }
+
}
diff --git a/src/org/apache/xalan/xsltc/trax/TemplatesHandlerImpl.java b/src/org/apache/xalan/xsltc/trax/TemplatesHandlerImpl.java
index 0fcddbb..0af479d 100644
--- a/src/org/apache/xalan/xsltc/trax/TemplatesHandlerImpl.java
+++ b/src/org/apache/xalan/xsltc/trax/TemplatesHandlerImpl.java
@@ -65,6 +65,7 @@
import javax.xml.transform.*;
import javax.xml.transform.sax.*;
+import org.xml.sax.Locator;
import org.apache.xalan.xsltc.Translet;
import org.apache.xalan.xsltc.runtime.AbstractTranslet;
import org.apache.xalan.xsltc.compiler.*;
@@ -76,12 +77,18 @@
public class TemplatesHandlerImpl extends Parser implements TemplatesHandler {
private String _systemId;
+ private int _indentNumber;
+
+ // Temporary
+ private boolean _oldOutputSystem;
/**
* Default constructor
*/
- protected TemplatesHandlerImpl() {
+ protected TemplatesHandlerImpl(int indentNumber, boolean oldOutputSystem) {
super(null);
+ _indentNumber = indentNumber;
+ _oldOutputSystem = oldOutputSystem;
}
/**
@@ -128,50 +135,60 @@
*/
public Templates getTemplates() {
try {
-
final XSLTC xsltc = getXSLTC();
// Set the translet class name if not already set
String transletName = TransformerFactoryImpl._defaultTransletName;
- if (_systemId != null) transletName = Util.baseName(_systemId);
+ if (_systemId != null) {
+ transletName = Util.baseName(_systemId);
+ }
xsltc.setClassName(transletName);
- // get java-legal class name from XSLTC module
+
+ // Get java-legal class name from XSLTC module
transletName = xsltc.getClassName();
Stylesheet stylesheet = null;
SyntaxTreeNode root = getDocumentRoot();
// Compile the translet - this is where the work is done!
- if ((!errorsFound()) && (root != null)) {
+ if (!errorsFound() && root != null) {
// Create a Stylesheet element from the root node
stylesheet = makeStylesheet(root);
stylesheet.setSystemId(_systemId);
stylesheet.setParentStylesheet(null);
setCurrentStylesheet(stylesheet);
- // Create AST under the Stylesheet element (parse & type-check)
+ // Create AST under the Stylesheet element
createAST(stylesheet);
}
// Generate the bytecodes and output the translet class(es)
- if ((!errorsFound()) && (stylesheet != null)) {
+ if (!errorsFound() && stylesheet != null) {
stylesheet.setMultiDocument(xsltc.isMultiDocument());
stylesheet.translate();
}
- xsltc.printWarnings();
-
- // Check that the transformation went well before returning
- final byte[][] bytecodes = xsltc.getBytecodes();
- if (bytecodes == null) {
- xsltc.printErrors();
- return null;
+ if (!errorsFound()) {
+ // Check that the transformation went well before returning
+ final byte[][] bytecodes = xsltc.getBytecodes();
+ if (bytecodes != null) {
+ return new TemplatesImpl(xsltc.getBytecodes(), transletName,
+ getOutputProperties(), _indentNumber, _oldOutputSystem);
+ }
}
-
- return new TemplatesImpl(bytecodes, transletName, getOutputProperties());
}
catch (CompilerException e) {
- return null;
+ // falls through
}
+ return null;
+ }
+
+ /**
+ * recieve an object for locating the origin of SAX document events.
+ * Most SAX parsers will use this method to inform content handler
+ * of the location of the parsed document.
+ */
+ public void setDocumentLocator(Locator locator) {
+ setSystemId(locator.getSystemId());
}
}
diff --git a/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java b/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java
index 0686969..d0a2a95 100644
--- a/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java
+++ b/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java
@@ -97,7 +97,12 @@
// and _bytecodes arrays (above).
private int _transletIndex = -1;
- private Properties _outputProperties;
+ private Properties _outputProperties;
+
+ private int _indentNumber;
+
+ // Temporary
+ private boolean _oldOutputSystem;
// Our own private class loader - builds Class definitions from bytecodes
private class TransletClassLoader extends ClassLoader {
@@ -130,11 +135,14 @@
* the main translet class, must be supplied
*/
protected TemplatesImpl(byte[][] bytecodes, String transletName,
- Properties outputProperties)
+ Properties outputProperties, int indentNumber,
+ boolean oldOutputSystem)
{
_bytecodes = bytecodes;
_name = transletName;
_outputProperties = outputProperties;
+ _indentNumber = indentNumber;
+ _oldOutputSystem = oldOutputSystem;
}
/**
@@ -261,7 +269,8 @@
*/
public Transformer newTransformer()
throws TransformerConfigurationException {
- return new TransformerImpl(getTransletInstance(), _outputProperties);
+ return new TransformerImpl(getTransletInstance(), _outputProperties,
+ _indentNumber, _oldOutputSystem);
}
/**
diff --git a/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java b/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java
index 6ebfe90..29dbaa4 100644
--- a/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java
+++ b/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java
@@ -140,8 +140,11 @@
}
}
- // This flag is passed to the compiler - will produce stack traces etc.
+ // This flags are passed to the compiler
private boolean _debug = false;
+ private boolean _disableInlining = false;
+ private boolean _oldOutputSystem = false;
+ private int _indentNumber = -1;
/**
* javax.xml.transform.sax.TransformerFactory implementation.
@@ -206,20 +209,64 @@
* @throws IllegalArgumentException
*/
public void setAttribute(String name, Object value)
- throws IllegalArgumentException {
+ throws IllegalArgumentException
+ {
// Set the default translet name (ie. class name), which will be used
// for translets that cannot be given a name from their system-id.
- if ((name.equals("translet-name")) && (value instanceof String)) {
- _defaultTransletName = (String)value;
+ if (name.equals("translet-name") && value instanceof String) {
+ _defaultTransletName = (String) value;
+ return;
}
else if (name.equals("debug")) {
- _debug = true;
+ if (value instanceof Boolean) {
+ _debug = ((Boolean) value).booleanValue();
+ return;
+ }
+ else if (value instanceof String) {
+ _debug = ((String) value).equalsIgnoreCase("true");
+ return;
+ }
}
- else {
- // Throw an exception for all other attributes
- ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_INVALID_ATTR_ERR, name);
- throw new IllegalArgumentException(err.toString());
+ else if (name.equals("disable-inlining")) {
+ if (value instanceof Boolean) {
+ _disableInlining = ((Boolean) value).booleanValue();
+ return;
+ }
+ else if (value instanceof String) {
+ _disableInlining = ((String) value).equalsIgnoreCase("true");
+ return;
+ }
}
+ else if (name.equals("old-output")) {
+ if (value instanceof Boolean) {
+ _oldOutputSystem = ((Boolean) value).booleanValue();
+ return;
+ }
+ else if (value instanceof String) {
+ _oldOutputSystem = ((String) value).equalsIgnoreCase("true");
+ return;
+ }
+ }
+ else if (name.equals("indent-number")) {
+ if (value instanceof String) {
+ try {
+ _indentNumber = Integer.parseInt((String) value);
+ return;
+ }
+ catch (NumberFormatException e) {
+ // Falls through
+ }
+ }
+ else if (value instanceof Integer) {
+ _indentNumber = ((Integer) value).intValue();
+ return;
+ }
+ }
+
+ // Throw an exception for all other attributes
+ final ErrorMsg err
+ = new ErrorMsg(ErrorMsg.JAXP_INVALID_ATTR_ERR, name);
+ throw new IllegalArgumentException(err.toString());
}
/**
@@ -320,6 +367,7 @@
XSLTC xsltc = new XSLTC();
if (_debug) xsltc.setDebug(true);
+ if (_disableInlining) xsltc.setTemplateInlining(false);
xsltc.init();
// Compile the default copy-stylesheet
@@ -336,11 +384,14 @@
}
// Create a Transformer object and store for other calls
- Templates templates = new TemplatesImpl(bytecodes,
- _defaultTransletName, xsltc.getOutputProperties());
+ Templates templates = new TemplatesImpl(bytecodes, _defaultTransletName,
+ xsltc.getOutputProperties(), _indentNumber, _oldOutputSystem);
+
_copyTransformer = templates.newTransformer();
- if (_uriResolver != null) _copyTransformer.setURIResolver(_uriResolver);
- return(_copyTransformer);
+ if (_uriResolver != null) {
+ _copyTransformer.setURIResolver(_uriResolver);
+ }
+ return _copyTransformer;
}
/**
@@ -364,8 +415,8 @@
/**
* Pass warning messages from the compiler to the error listener
*/
- private void passWarningsToListener(Vector messages)
- throws TransformerException
+ private void passWarningsToListener(Vector messages)
+ throws TransformerException
{
if (_errorListener == null || messages == null ) {
return;
@@ -377,7 +428,6 @@
_errorListener.error(
new TransformerConfigurationException(message));
}
-
}
/**
@@ -428,6 +478,9 @@
xsltc.setXMLReader(dom2sax);
// try to get SAX InputSource from DOM Source.
input = SAXSource.sourceToInputSource(source);
+ if (input == null){
+ input = new InputSource(domsrc.getSystemId());
+ }
}
// Try to get InputStream or Reader from StreamSource
else if (source instanceof StreamSource) {
@@ -476,6 +529,7 @@
// Create and initialize a stylesheet compiler
final XSLTC xsltc = new XSLTC();
if (_debug) xsltc.setDebug(true);
+ if (_disableInlining) xsltc.setTemplateInlining(false);
xsltc.init();
// Set a document loader (for xsl:include/import) if defined
@@ -497,15 +551,14 @@
final String transletName = xsltc.getClassName();
// Pass compiler warnings to the error listener
- if (_errorListener != this){
- //passWarningsToListener(xsltc.getWarnings());
- try {
+ if (_errorListener != this) {
+ try {
passWarningsToListener(xsltc.getWarnings());
}
catch (TransformerException e) {
throw new TransformerConfigurationException(e);
}
- }
+ }
else {
xsltc.printWarnings();
}
@@ -521,7 +574,7 @@
throw new TransformerConfigurationException(err.toString());
}
return new TemplatesImpl(bytecodes, transletName,
- xsltc.getOutputProperties());
+ xsltc.getOutputProperties(), _indentNumber, _oldOutputSystem);
}
/**
@@ -534,7 +587,8 @@
*/
public TemplatesHandler newTemplatesHandler()
throws TransformerConfigurationException {
- final TemplatesHandlerImpl handler = new TemplatesHandlerImpl();
+ final TemplatesHandlerImpl handler =
+ new TemplatesHandlerImpl(_indentNumber, _oldOutputSystem);
handler.init();
return handler;
}
diff --git a/src/org/apache/xalan/xsltc/trax/TransformerHandlerImpl.java b/src/org/apache/xalan/xsltc/trax/TransformerHandlerImpl.java
index b1a87b7..6000457 100644
--- a/src/org/apache/xalan/xsltc/trax/TransformerHandlerImpl.java
+++ b/src/org/apache/xalan/xsltc/trax/TransformerHandlerImpl.java
@@ -63,12 +63,14 @@
package org.apache.xalan.xsltc.trax;
import org.xml.sax.*;
+import org.xml.sax.ext.DeclHandler;
import javax.xml.transform.*;
import javax.xml.transform.sax.*;
import org.apache.xalan.xsltc.Translet;
import org.apache.xalan.xsltc.dom.DOMImpl;
+import org.apache.xalan.xsltc.dom.DOMBuilder;
import org.apache.xalan.xsltc.dom.DTDMonitor;
import org.apache.xalan.xsltc.runtime.AbstractTranslet;
import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
@@ -76,13 +78,13 @@
/**
* Implementation of a JAXP1.1 TransformerHandler
*/
-public class TransformerHandlerImpl implements TransformerHandler {
+public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
private TransformerImpl _transformer;
private AbstractTranslet _translet = null;
private String _systemId;
private DOMImpl _dom = null;
- private ContentHandler _handler = null;
+ private DOMBuilder _handler = null;
private DTDMonitor _dtd = null;
private Result _result = null;
@@ -97,6 +99,13 @@
// Get a reference to the translet wrapped inside the transformer
_translet = _transformer.getTranslet();
+
+ // Create a DOMBuilder object and get the handler
+ _dom = new DOMImpl();
+ _handler = _dom.getBuilder();
+
+ // Create a new DTD monitor
+ _dtd = new DTDMonitor();
}
/**
@@ -126,7 +135,7 @@
* @return The Transformer object
*/
public Transformer getTransformer() {
- return(_transformer);
+ return _transformer;
}
/**
@@ -157,7 +166,8 @@
* Receive notification of character data.
*/
public void characters(char[] ch, int start, int length)
- throws SAXException {
+ throws SAXException
+ {
_handler.characters(ch, start, length);
}
@@ -172,9 +182,8 @@
throw new SAXException(err.toString());
}
- // Create an internal DOM (not W3C) and get SAX2 input handler
- _dom = new DOMImpl();
- _handler = _dom.getBuilder();
+ // Set document URI
+ _dom.setDocumentURI(_systemId);
// Proxy call
_handler.startDocument();
@@ -187,12 +196,12 @@
public void endDocument() throws SAXException {
// Signal to the DOMBuilder that the document is complete
_handler.endDocument();
- // Pass unparsed entity declarations (if any) to the translet
- if (_dtd != null) _translet.setDTDMonitor(_dtd);
+
// Run the transformation now if we have a reference to a Result object
if (_result != null) {
try {
_transformer.setDOM(_dom);
+ _transformer.setDTDMonitor(_dtd); // for id/key
_transformer.transform(null, _result);
}
catch (TransformerException e) {
@@ -235,31 +244,54 @@
}
/**
+ * Implements org.xml.sax.ext.LexicalHandler.startCDATA()
+ */
+ public void startCDATA() throws SAXException {
+ _handler.startCDATA();
+ }
+
+ /**
+ * Implements org.xml.sax.ext.LexicalHandler.endCDATA()
+ */
+ public void endCDATA() throws SAXException {
+ _handler.endCDATA();
+ }
+
+ /**
+ * Implements org.xml.sax.ext.LexicalHandler.comment()
+ * Receieve notification of a comment
+ */
+ public void comment(char[] ch, int start, int length)
+ throws SAXException
+ {
+ _handler.comment(ch, start, length);
+ }
+
+ /**
* Implements org.xml.sax.ContentHandler.ignorableWhitespace()
* Receive notification of ignorable whitespace in element
* content. Similar to characters(char[], int, int).
*/
public void ignorableWhitespace(char[] ch, int start, int length)
- throws SAXException {
+ throws SAXException
+ {
_handler.ignorableWhitespace(ch, start, length);
}
/**
* Implements org.xml.sax.ContentHandler.setDocumentLocator()
* Receive an object for locating the origin of SAX document events.
- * We do not handle this method, and the input is quietly ignored
*/
public void setDocumentLocator(Locator locator) {
- // Not handled by DOMBuilder - ignored
+ _handler.setDocumentLocator(locator);
}
/**
* Implements org.xml.sax.ContentHandler.skippedEntity()
* Receive notification of a skipped entity.
- * We do not handle this method, and the input is quietly ignored
*/
- public void skippedEntity(String name) {
- // Not handled by DOMBuilder - ignored
+ public void skippedEntity(String name) throws SAXException {
+ _handler.skippedEntity(name);
}
/**
@@ -280,66 +312,86 @@
}
/**
- * Implements org.xml.sax.DTDHandler.notationDecl()
- * End the scope of a prefix-URI Namespace mapping.
- * We do not handle this method, and the input is quietly ignored.
+ * Implements org.xml.sax.ext.LexicalHandler.startDTD()
*/
- public void notationDecl(String name, String publicId, String systemId) {
- // Not handled by DTDMonitor - ignored
+ public void startDTD(String name, String publicId, String systemId)
+ throws SAXException
+ {
+ _handler.startDTD(name, publicId, systemId);
+ }
+
+ /**
+ * Implements org.xml.sax.ext.LexicalHandler.endDTD()
+ */
+ public void endDTD() throws SAXException {
+ _handler.endDTD();
+ }
+
+ /**
+ * Implements org.xml.sax.ext.LexicalHandler.startEntity()
+ */
+ public void startEntity(String name) throws SAXException {
+ _handler.startEntity(name);
+ }
+
+ /**
+ * Implements org.xml.sax.ext.LexicalHandler.endEntity()
+ */
+ public void endEntity(String name) throws SAXException {
+ _handler.endEntity(name);
}
/**
* Implements org.xml.sax.DTDHandler.unparsedEntityDecl()
- * End the scope of a prefix-URI Namespace mapping.
*/
- public void unparsedEntityDecl(String name, String publicId,
- String systemId, String notationName)
- throws SAXException {
- // Create new contained for unparsed entities
- if (_dtd == null) _dtd = new DTDMonitor();
+ public void unparsedEntityDecl(String name, String publicId,
+ String systemId, String notationName) throws SAXException
+ {
_dtd.unparsedEntityDecl(name, publicId, systemId, notationName);
}
/**
- * Implements org.xml.sax.ext.LexicalHandler.startDTD()
- * We do not handle this method, and the input is quietly ignored
+ * Implements org.xml.sax.DTDHandler.notationDecl()
*/
- public void startDTD(String name, String publicId, String systemId) { }
+ public void notationDecl(String name, String publicId, String systemId)
+ throws SAXException
+ {
+ _dtd.notationDecl(name, publicId, systemId);
+ }
/**
- * Implements org.xml.sax.ext.LexicalHandler.endDTD()
- * We do not handle this method, and the input is quietly ignored
+ * Implements org.xml.sax.ext.DeclHandler.attributeDecl()
*/
- public void endDTD() { }
+ public void attributeDecl(String eName, String aName, String type,
+ String valueDefault, String value) throws SAXException
+ {
+ _dtd.attributeDecl(eName, aName, type, valueDefault, value);
+ }
/**
- * Implements org.xml.sax.ext.LexicalHandler.startEntity()
- * We do not handle this method, and the input is quietly ignored
+ * Implements org.xml.sax.ext.DeclHandler.elementDecl()
*/
- public void startEntity(String name) { }
+ public void elementDecl(String name, String model)
+ throws SAXException
+ {
+ _dtd.elementDecl(name, model);
+ }
/**
- * Implements org.xml.sax.ext.LexicalHandler.endEntity()
- * We do not handle this method, and the input is quietly ignored
+ * Implements org.xml.sax.ext.DeclHandler.externalEntityDecl()
*/
- public void endEntity(String name) { }
+ public void externalEntityDecl(String name, String publicId, String systemId)
+ throws SAXException
+ {
+ _dtd.externalEntityDecl(name, publicId, systemId);
+ }
/**
- * Implements org.xml.sax.ext.LexicalHandler.startCDATA()
- * We do not handle this method, and the input is quietly ignored
+ * Implements org.xml.sax.ext.DeclHandler.externalEntityDecl()
*/
- public void startCDATA() { }
-
- /**
- * Implements org.xml.sax.ext.LexicalHandler.endCDATA()
- * We do not handle this method, and the input is quietly ignored
- */
- public void endCDATA() { }
-
- /**
- * Implements org.xml.sax.ext.LexicalHandler.comment()
- * We do not handle this method, and the input is quietly ignored
- */
- public void comment(char[] ch, int start, int length) { }
-
+ public void internalEntityDecl(String name, String value)
+ throws SAXException
+ {
+ _dtd.internalEntityDecl(name, value);
+ }
}
diff --git a/src/org/apache/xalan/xsltc/trax/TransformerImpl.java b/src/org/apache/xalan/xsltc/trax/TransformerImpl.java
index 9ff16cd..9e4e531 100644
--- a/src/org/apache/xalan/xsltc/trax/TransformerImpl.java
+++ b/src/org/apache/xalan/xsltc/trax/TransformerImpl.java
@@ -101,9 +101,12 @@
import org.apache.xalan.xsltc.Translet;
import org.apache.xalan.xsltc.TransletException;
+import org.apache.xalan.xsltc.TransletOutputHandler;
import org.apache.xalan.xsltc.DOMCache;
import org.apache.xalan.xsltc.dom.*;
+import org.apache.xalan.xsltc.compiler.Constants;
import org.apache.xalan.xsltc.runtime.*;
+import org.apache.xalan.xsltc.runtime.output.*;
import org.apache.xalan.xsltc.compiler.*;
import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
@@ -113,8 +116,9 @@
implements DOMCache, ErrorListener {
private AbstractTranslet _translet = null;
+ private String _method = null;
private String _encoding = null;
- private ContentHandler _handler = null;
+ private ContentHandler _handler = null;
private ErrorListener _errorListener = this;
private URIResolver _uriResolver = null;
@@ -129,26 +133,39 @@
// Pre-set DOMImpl to use as input (used only with TransformerHandlerImpl)
private DOMImpl _dom = null;
+ private DTDMonitor _dtdMonitor = null;
+
private final static String LEXICAL_HANDLER_PROPERTY =
"http://xml.org/sax/properties/lexical-handler";
private static final String NAMESPACE_FEATURE =
"http://xml.org/sax/features/namespaces";
+ private TransletOutputHandlerFactory _tohFactory = null;
+
+ private int _indentNumber;
+
+ // Temporary
+ private boolean _oldOutputSystem;
+
/**
* Implements JAXP's Transformer constructor
* Our Transformer objects always need a translet to do the actual work
*/
- protected TransformerImpl(Translet translet, Properties outputProperties) {
- _translet = (AbstractTranslet)translet;
+ protected TransformerImpl(Translet translet, Properties outputProperties,
+ int indentNumber, boolean oldOutputSystem)
+ {
+ _translet = (AbstractTranslet) translet;
_properties = createOutputProperties(outputProperties);
+ _oldOutputSystem = oldOutputSystem;
_propertiesClone = (Properties) _properties.clone();
+ _indentNumber = indentNumber;
}
/**
* Returns the translet wrapped inside this Transformer
*/
protected AbstractTranslet getTranslet() {
- return(_translet);
+ return _translet;
}
/**
@@ -159,31 +176,168 @@
* @throws TransformerException
*/
public void transform(Source source, Result result)
- throws TransformerException {
-
+ throws TransformerException
+ {
if (_translet == null) {
ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_TRANSLET_ERR);
throw new TransformerException(err.toString());
}
- _handler = getOutputHandler(result);
- if (_handler == null) {
- ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_HANDLER_ERR);
- throw new TransformerException(err.toString());
+ // Pass output properties to the translet
+ setOutputProperties(_translet, _properties);
+
+ if (!_oldOutputSystem) {
+ final TransletOutputHandler toHandler = getOutputHandler(result);
+
+ if (toHandler == null) {
+ ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_HANDLER_ERR);
+ throw new TransformerException(err.toString());
+ }
+
+ if (_uriResolver != null) {
+ _translet.setDOMCache(this);
+ }
+
+ transform(source, toHandler, _encoding);
+
+ if (result instanceof DOMResult) {
+ ((DOMResult)result).setNode(_tohFactory.getNode());
+ }
+ }
+ else {
+ _handler = getOldOutputHandler(result);
+ if (_handler == null) {
+ ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_HANDLER_ERR);
+ throw new TransformerException(err.toString());
+ }
+
+ if (_uriResolver != null) {
+ _translet.setDOMCache(this);
+ }
+
+ // Run the transformation
+ transform(source, (ContentHandler)_handler, _encoding);
+
+ // If a DOMResult, then we must set the DOM Tree so it can
+ // be retrieved later
+ if (result instanceof DOMResult) {
+ ((DOMResult)result).setNode(((SAX2DOM)_handler).getDOM());
+ }
+ }
+ }
+
+ /**
+ * Create an output handler for the transformation output based on
+ * the type and contents of the TrAX Result object passed to the
+ * transform() method.
+ */
+ private TransletOutputHandler getOutputHandler(Result result)
+ throws TransformerException
+ {
+ // Get output method using get() to ignore defaults
+ _method = (String) _properties.get(OutputKeys.METHOD);
+
+ // Get encoding using getProperty() to use defaults
+ _encoding = (String) _properties.getProperty(OutputKeys.ENCODING);
+
+ _tohFactory = TransletOutputHandlerFactory.newInstance();
+ _tohFactory.setEncoding(_encoding);
+ if (_method != null) {
+ _tohFactory.setOutputMethod(_method);
}
- if (_uriResolver != null) {
- _translet.setDOMCache(this);
+ // Set indentation number in the factory
+ if (_indentNumber >= 0) {
+ _tohFactory.setIndentNumber(_indentNumber);
}
- // Run the transformation
- transform(source, (ContentHandler)_handler, _encoding);
+ // Return the content handler for this Result object
+ try {
+ // Result object could be SAXResult, DOMResult, or StreamResult
+ if (result instanceof SAXResult) {
+ final SAXResult target = (SAXResult)result;
+ final ContentHandler handler = target.getHandler();
- // If a DOMResult, then we must set the DOM Tree so it can
- // be retrieved later
- if (result instanceof DOMResult) {
- ((DOMResult)result).setNode(((SAX2DOM)_handler).getDOM());
+ _tohFactory.setHandler(handler);
+ if (handler instanceof LexicalHandler) {
+ _tohFactory.setLexicalHandler((LexicalHandler) handler);
+ }
+ _tohFactory.setOutputType(TransletOutputHandlerFactory.SAX);
+ return _tohFactory.getTransletOutputHandler();
+ }
+ else if (result instanceof DOMResult) {
+ _tohFactory.setNode(((DOMResult) result).getNode());
+ _tohFactory.setOutputType(TransletOutputHandlerFactory.DOM);
+ return _tohFactory.getTransletOutputHandler();
+ }
+ else if (result instanceof StreamResult) {
+ // Get StreamResult
+ final StreamResult target = (StreamResult) result;
+
+ // StreamResult may have been created with a java.io.File,
+ // java.io.Writer, java.io.OutputStream or just a String
+ // systemId.
+
+ _tohFactory.setOutputType(TransletOutputHandlerFactory.STREAM);
+
+ // try to get a Writer from Result object
+ final Writer writer = target.getWriter();
+ if (writer != null) {
+ _tohFactory.setWriter(writer);
+ return _tohFactory.getTransletOutputHandler();
+ }
+
+ // or try to get an OutputStream from Result object
+ final OutputStream ostream = target.getOutputStream();
+ if (ostream != null) {
+ _tohFactory.setOutputStream(ostream);
+ return _tohFactory.getTransletOutputHandler();
+ }
+
+ // or try to get just a systemId string from Result object
+ String systemId = result.getSystemId();
+ if (systemId == null) {
+ ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_RESULT_ERR);
+ throw new TransformerException(err.toString());
+ }
+
+ // System Id may be in one of several forms, (1) a uri
+ // that starts with 'file:', (2) uri that starts with 'http:'
+ // or (3) just a filename on the local system.
+ URL url = null;
+ if (systemId.startsWith("file:")) {
+ url = new URL(systemId);
+ _tohFactory.setOutputStream(
+ new FileOutputStream(url.getFile()));
+ return _tohFactory.getTransletOutputHandler();
+ }
+ else if (systemId.startsWith("http:")) {
+ url = new URL(systemId);
+ final URLConnection connection = url.openConnection();
+ _tohFactory.setOutputStream(connection.getOutputStream());
+ return _tohFactory.getTransletOutputHandler();
+ }
+ else {
+ // system id is just a filename
+ url = new File(systemId).toURL();
+ _tohFactory.setOutputStream(
+ new FileOutputStream(url.getFile()));
+ return _tohFactory.getTransletOutputHandler();
+ }
+ }
}
+ // If we cannot write to the location specified by the SystemId
+ catch (UnknownServiceException e) {
+ throw new TransformerException(e);
+ }
+ catch (ParserConfigurationException e) {
+ throw new TransformerException(e);
+ }
+ // If we cannot create the file specified by the SystemId
+ catch (IOException e) {
+ throw new TransformerException(e);
+ }
+ return null;
}
/**
@@ -191,7 +345,7 @@
* based on the type and contents of the TrAX Result object passed to
* the transform() method.
*/
- private ContentHandler getOutputHandler(Result result) throws
+ private ContentHandler getOldOutputHandler(Result result) throws
TransformerException
{
// Try to get the encoding from the translet (may not be set)
@@ -282,80 +436,6 @@
return null;
}
-
-/*************
- private ContentHandler getOutputHandler(Result result)
- throws TransformerException {
- // Try to get the encoding from Translet (may not be set)
- if (_translet._encoding != null) {
- _encoding = _translet._encoding;
- }
- else {
- _encoding = "UTF-8"; // default output encoding
- }
-
- try {
- String systemId = result.getSystemId();
-
- // Handle SAXResult output handler
- if (result instanceof SAXResult) {
- final SAXResult target = (SAXResult)result;
- final ContentHandler handler = target.getHandler();
- // Simple as feck, just pass the SAX handler back...
- if (handler != null) return handler;
- }
- // Handle StreamResult output handler
- else if (result instanceof StreamResult) {
- final StreamResult target = (StreamResult)result;
- final OutputStream ostream = target.getOutputStream();
- final Writer writer = target.getWriter();
-
- if (ostream != null)
- return (new DefaultSAXOutputHandler(ostream, _encoding));
- else if (writer != null)
- return (new DefaultSAXOutputHandler(writer, _encoding));
- else if ((systemId != null) && systemId.startsWith("file:")) {
- final URL url = new URL(systemId);
- final OutputStream os = new FileOutputStream(url.getFile());
- return (new DefaultSAXOutputHandler(os, _encoding));
- }
- }
- // Handle DOMResult output handler
- else if (result instanceof DOMResult) {
- return (new SAX2DOM());
- }
-
- // Common, final handling of all input sources, only used if the
- // other contents of the Result object could not be used
- if (systemId != null) {
- if ((new File(systemId)).exists()) systemId = "file:"+systemId;
- final URL url = new URL(systemId);
- final URLConnection connection = url.openConnection();
- final OutputStream ostream = connection.getOutputStream();
- return(new DefaultSAXOutputHandler(ostream, _encoding));
- }
- else {
- ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_RESULT_ERR);
- throw new TransformerException(err.toString());
- }
- }
- // If we cannot write to the location specified by the SystemId
- catch (UnknownServiceException e) {
- throw new TransformerException(e);
- }
- // If we cannot create a SAX2DOM adapter
- catch (ParserConfigurationException e) {
- ErrorMsg err = new ErrorMsg(ErrorMsg.SAX2DOM_ADAPTER_ERR);
- throw new TransformerException(err.toString());
- }
- // If we cannot create the file specified by the SystemId
- catch (IOException e) {
- throw new TransformerException(e);
- }
- }
-
-**********************/
-
/**
* Set the internal DOMImpl that will be used for the next transformation
*/
@@ -364,18 +444,19 @@
}
/**
+ * Set the internal DOMImpl that will be used for the next transformation
+ */
+ protected void setDTDMonitor(DTDMonitor dtdMonitor) {
+ _dtdMonitor = dtdMonitor;
+ }
+
+ /**
* Builds an internal DOM from a TrAX Source object
*/
private DOMImpl getDOM(Source source, int mask)
- throws TransformerException {
+ throws TransformerException
+ {
try {
- // Use the pre-defined DOM if present
- if (_dom != null) {
- DOMImpl dom = _dom;
- _dom = null; // use only once, so reset to 'null'
- return(dom);
- }
-
DOMImpl dom = null;
DTDMonitor dtd = null;
@@ -383,10 +464,18 @@
if (source instanceof SAXSource) {
// Get all info from the input SAXSource object
final SAXSource sax = (SAXSource)source;
- final XMLReader reader = sax.getXMLReader();
+ XMLReader reader = sax.getXMLReader();
final InputSource input = sax.getInputSource();
final String systemId = sax.getSystemId();
+ // if reader was not set with setXMLReader by user,
+ // then we must create one ourselves.
+ if (reader == null) {
+ SAXParserFactory pfactory= SAXParserFactory.newInstance();
+ pfactory.setNamespaceAware(true);
+ reader = pfactory.newSAXParser().getXMLReader();
+ }
+
// Create a DTD monitor to trap all DTD/declarative events
dtd = new DTDMonitor();
dtd.handleDTD(reader);
@@ -478,13 +567,15 @@
reader.setContentHandler(builder);
InputSource input;
- if (streamInput != null)
+ if (streamInput != null) {
input = new InputSource(streamInput);
- else if (streamReader != null)
+ input.setSystemId(systemId);
+ } else if (streamReader != null) {
input = new InputSource(streamReader);
- else if (systemId != null)
+ input.setSystemId(systemId);
+ } else if (systemId != null) {
input = new InputSource(systemId);
- else {
+ } else {
ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_SOURCE_ERR);
throw new TransformerException(err.toString());
}
@@ -499,6 +590,11 @@
dtd = xsltcsrc.getDTD();
dom = xsltcsrc.getDOM();
}
+ // DOM already set via a call to setDOM()
+ else if (_dom != null) {
+ dtd = _dtdMonitor; // must be set via setDTDMonitor()
+ dom = _dom; _dom = null; // use only once, so reset to 'null'
+ }
else {
return null;
}
@@ -532,23 +628,45 @@
/**
* Internal transformation method - uses the internal APIs of XSLTC
*/
+ private void transform(Source src, TransletOutputHandler handler,
+ String encoding) throws TransformerException
+ {
+ try {
+ _translet.transform(getDOM(src, 0), handler);
+ }
+ catch (TransletException e) {
+ if (_errorListener != null) postErrorToListener(e.getMessage());
+ throw new TransformerException(e);
+ }
+ catch (RuntimeException e) {
+ if (_errorListener != null) postErrorToListener(e.getMessage());
+ throw new TransformerException(e);
+ }
+ catch (Exception e) {
+ if (_errorListener != null) postErrorToListener(e.getMessage());
+ throw new TransformerException(e);
+ }
+ }
+
+ /**
+ * Internal transformation method - uses the internal APIs of XSLTC
+ */
private void transform(Source src, ContentHandler sax, String encoding)
throws TransformerException {
try {
// Build an iternal DOMImpl from the TrAX Source
DOMImpl dom = getDOM(src, 0);
- // Pass output properties to the translet
- setOutputProperties(_translet, _properties);
-
// This handler will post-process the translet output
TextOutput handler;
// Check if the ContentHandler also implements LexicalHandler
- if (sax instanceof LexicalHandler)
+ if (sax instanceof LexicalHandler) {
handler = new TextOutput(sax, (LexicalHandler)sax, encoding);
- else
+ }
+ else {
handler = new TextOutput(sax, encoding);
+ }
_translet.transform(dom, handler);
}
catch (TransletException e) {
@@ -643,7 +761,12 @@
/**
* Implements JAXP's Transformer.getOutputProperties().
- * Returns a copy of the output properties for the transformation.
+ * Returns a copy of the output properties for the transformation. This is
+ * a set of layered properties. The first layer contains properties set by
+ * calls to setOutputProperty() and setOutputProperties() on this class,
+ * and the output settings defined in the stylesheet's <xsl:output>
+ * element makes up the second level, while the default XSLT output
+ * settings are returned on the third level.
*
* @return Properties in effect for this Transformer
*/
@@ -661,7 +784,8 @@
* @throws IllegalArgumentException if the property name is not known
*/
public String getOutputProperty(String name)
- throws IllegalArgumentException {
+ throws IllegalArgumentException
+ {
if (!validOutputProperty(name)) {
ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_PROP_ERR, name);
throw new IllegalArgumentException(err.toString());
@@ -686,6 +810,10 @@
while (names.hasMoreElements()) {
final String name = (String) names.nextElement();
+
+ // Ignore lower layer properties
+ if (isDefaultProperty(name, properties)) continue;
+
if (validOutputProperty(name)) {
_properties.setProperty(name, properties.getProperty(name));
}
@@ -711,7 +839,8 @@
* @throws IllegalArgumentException Never, errors are ignored
*/
public void setOutputProperty(String name, String value)
- throws IllegalArgumentException {
+ throws IllegalArgumentException
+ {
if (!validOutputProperty(name)) {
ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_PROP_ERR, name);
throw new IllegalArgumentException(err.toString());
@@ -724,44 +853,50 @@
* initiating the transformation
*/
private void setOutputProperties(AbstractTranslet translet,
- Properties properties) {
+ Properties properties)
+ {
// Return right now if no properties are set
if (properties == null) return;
// Get a list of all the defined properties
Enumeration names = properties.propertyNames();
while (names.hasMoreElements()) {
- // Get the next property name and value
- String name = (String)names.nextElement();
- // bug fix # 6636- contributed by Tim Elcott
- String value = (String)properties.getProperty(name);
+ // Note the use of get() instead of getProperty()
+ String name = (String) names.nextElement();
+ String value = (String) properties.get(name);
+
+ // Ignore default properties
+ if (value == null) continue;
// Pass property value to translet - override previous setting
- if (name.equals(OutputKeys.ENCODING))
+ if (name.equals(OutputKeys.ENCODING)) {
translet._encoding = value;
- else if (name.equals(OutputKeys.METHOD))
+ }
+ else if (name.equals(OutputKeys.METHOD)) {
translet._method = value;
- else if (name.equals(OutputKeys.DOCTYPE_PUBLIC))
+ }
+ else if (name.equals(OutputKeys.DOCTYPE_PUBLIC)) {
translet._doctypePublic = value;
- else if (name.equals(OutputKeys.DOCTYPE_SYSTEM))
+ }
+ else if (name.equals(OutputKeys.DOCTYPE_SYSTEM)) {
translet._doctypeSystem = value;
- else if (name.equals(OutputKeys.MEDIA_TYPE))
+ }
+ else if (name.equals(OutputKeys.MEDIA_TYPE)) {
translet._mediaType = value;
- else if (name.equals(OutputKeys.STANDALONE))
+ }
+ else if (name.equals(OutputKeys.STANDALONE)) {
translet._standalone = value;
- else if (name.equals(OutputKeys.VERSION))
+ }
+ else if (name.equals(OutputKeys.VERSION)) {
translet._version = value;
+ }
else if (name.equals(OutputKeys.OMIT_XML_DECLARATION)) {
- if ((value != null) && (value.toLowerCase().equals("yes")))
- translet._omitHeader = true;
- else
- translet._omitHeader = false;
+ translet._omitHeader =
+ (value != null && value.toLowerCase().equals("yes"));
}
else if (name.equals(OutputKeys.INDENT)) {
- if ((value != null) && (value.toLowerCase().equals("yes")))
- translet._indent = true;
- else
- translet._indent = false;
+ translet._indent =
+ (value != null && value.toLowerCase().equals("yes"));
}
else if (name.equals(OutputKeys.CDATA_SECTION_ELEMENTS)) {
if (value != null) {
@@ -776,8 +911,10 @@
}
/**
- * Internal method to pass any properties to the translet prior to
- * initiating the transformation
+ * Internal method to create the initial set of properties. There
+ * are two layers of properties: the default layer and the base layer.
+ * The latter contains properties defined in the stylesheet or by
+ * the user using this API.
*/
private Properties createOutputProperties(Properties outputProperties) {
final Properties defaults = new Properties();
@@ -820,18 +957,24 @@
* the JAXP 1.1 / TrAX spec
*/
private boolean validOutputProperty(String name) {
- if (name.equals(OutputKeys.ENCODING)) return true;
- if (name.equals(OutputKeys.METHOD)) return true;
- if (name.equals(OutputKeys.INDENT)) return true;
- if (name.equals(OutputKeys.DOCTYPE_PUBLIC)) return true;
- if (name.equals(OutputKeys.DOCTYPE_SYSTEM)) return true;
- if (name.equals(OutputKeys.CDATA_SECTION_ELEMENTS)) return true;
- if (name.equals(OutputKeys.MEDIA_TYPE)) return true;
- if (name.equals(OutputKeys.OMIT_XML_DECLARATION)) return true;
- if (name.equals(OutputKeys.STANDALONE)) return true;
- if (name.equals(OutputKeys.VERSION)) return true;
- if (name.charAt(0) == '{') return true;
- return false;
+ return (name.equals(OutputKeys.ENCODING) ||
+ name.equals(OutputKeys.METHOD) ||
+ name.equals(OutputKeys.INDENT) ||
+ name.equals(OutputKeys.DOCTYPE_PUBLIC) ||
+ name.equals(OutputKeys.DOCTYPE_SYSTEM) ||
+ name.equals(OutputKeys.CDATA_SECTION_ELEMENTS) ||
+ name.equals(OutputKeys.MEDIA_TYPE) ||
+ name.equals(OutputKeys.OMIT_XML_DECLARATION) ||
+ name.equals(OutputKeys.STANDALONE) ||
+ name.equals(OutputKeys.VERSION) ||
+ name.charAt(0) == '{');
+ }
+
+ /**
+ * Checks if a given output property is default (2nd layer only)
+ */
+ private boolean isDefaultProperty(String name, Properties properties) {
+ return (properties.get(name) == null);
}
/**
@@ -925,8 +1068,9 @@
* the transformation (always does in our case).
*/
public void error(TransformerException e)
- throws TransformerException {
- System.err.println("ERROR: "+e.getMessageAndLocation());
+ throws TransformerException
+ {
+ System.err.println("ERROR: " + e.getMessageAndLocation());
throw(e);
}
@@ -944,11 +1088,13 @@
* the transformation (always does in our case).
*/
public void fatalError(TransformerException e)
- throws TransformerException {
- System.err.println("FATAL: "+e.getMessageAndLocation());
+ throws TransformerException
+ {
+ System.err.println("FATAL: " + e.getMessageAndLocation());
Throwable wrapped = e.getException();
- if (wrapped != null)
+ if (wrapped != null) {
System.err.println(" : "+wrapped.getMessage());
+ }
throw(e);
}
@@ -966,11 +1112,13 @@
* the transformation (never does in our case).
*/
public void warning(TransformerException e)
- throws TransformerException {
- System.err.println("WARNING: "+e.getMessageAndLocation());
+ throws TransformerException
+ {
+ System.err.println("WARNING: " + e.getMessageAndLocation());
Throwable wrapped = e.getException();
- if (wrapped != null)
+ if (wrapped != null) {
System.err.println(" : "+wrapped.getMessage());
+ }
}
}
diff --git a/src/org/apache/xalan/xsltc/util/IntegerArray.java b/src/org/apache/xalan/xsltc/util/IntegerArray.java
index c3a2297..f416018 100644
--- a/src/org/apache/xalan/xsltc/util/IntegerArray.java
+++ b/src/org/apache/xalan/xsltc/util/IntegerArray.java
@@ -87,7 +87,9 @@
}
public Object clone() {
- return new IntegerArray(_array);
+ final IntegerArray clone = new IntegerArray(_array);
+ clone._free = _free;
+ return clone;
}
public int[] toIntArray() {
@@ -105,23 +107,24 @@
}
public int indexOf(int n) {
- for (int i = 0; i < _free; i++)
- if (n == _array[i])
- return i;
+ for (int i = 0; i < _free; i++) {
+ if (n == _array[i]) return i;
+ }
return -1;
}
public final void add(int value) {
- if (_free == _size)
+ if (_free == _size) {
growArray(_size * 2);
+ }
_array[_free++] = value;
}
/** adds new int at the end if not already present */
public void addNew(int value) {
- for (int i = 0; i < _free; i++)
- if (_array[i] == value) // already in array
- return;
+ for (int i = 0; i < _free; i++) {
+ if (_array[i] == value) return; // already in array
+ }
add(value);
}
@@ -163,7 +166,8 @@
}
out.println(_array[_free - 1]);
}
- else
+ else {
out.println("IntegerArray: empty");
+ }
}
}