santiagopg 2002/12/02 07:51:29
Modified: java/src/org/apache/xalan/xsltc Tag: xslt20 DOM.java
Translet.java TransletOutputHandler.java
java/src/org/apache/xalan/xsltc/cmdline Tag: xslt20
Compile.java Transform.java
java/src/org/apache/xalan/xsltc/cmdline/getopt Tag: xslt20
GetOpt.java
java/src/org/apache/xalan/xsltc/compiler Tag: xslt20
ApplyTemplates.java AttributeSet.java CastExpr.java
Constants.java ElementAvailableCall.java
EqualityExpr.java Expression.java FlowList.java
ForEach.java FunctionAvailableCall.java
FunctionCall.java If.java Import.java Include.java
Key.java KeyCall.java LastCall.java
LocationPathPattern.java LogicalExpr.java Mode.java
Number.java Output.java Param.java
ParameterRef.java ParentLocationPath.java
Parser.java PositionCall.java
PositionCall.java.inuse Predicate.java
RelationalExpr.java Sort.java Step.java
StepPattern.java Stylesheet.java
SyntaxTreeNode.java Template.java TestSeq.java
TransletOutput.java Variable.java VariableRef.java
VariableRefBase.java When.java XSLTC.java
XslElement.java xpath.cup xpath.lex
java/src/org/apache/xalan/xsltc/compiler/util Tag: xslt20
BooleanType.java ErrorMessages.java ErrorMsg.java
IntType.java MultiHashtable.java NodeSetType.java
NodeType.java ObjectType.java RealType.java
ReferenceType.java ResultTreeType.java
StringType.java Type.java TypeCheckError.java
Util.java
java/src/org/apache/xalan/xsltc/dom Tag: xslt20
AbsoluteIterator.java CurrentNodeListIterator.java
DOM.java.Palm DOMAdapter.java DOMImpl.java
DTDMonitor.java DocumentCache.java
DupFilterIterator.java FilterIterator.java
FilteredStepIterator.java KeyIndex.java
LoadDocument.java MatchingIterator.java
MultiDOM.java NodeCounter.java
NodeIteratorBase.java NthIterator.java
StepIterator.java UnionIterator.java
java/src/org/apache/xalan/xsltc/runtime Tag: xslt20
AbstractTranslet.java BasisLibrary.java
ErrorMessages.java SAXAdapter.java TextOutput.java
TransletOutputBase.java
java/src/org/apache/xalan/xsltc/runtime/output Tag: xslt20
OutputBase.java SAXHTMLOutput.java
SAXXMLOutput.java StreamHTMLOutput.java
StreamOutput.java StreamTextOutput.java
StreamUnknownOutput.java StreamXMLOutput.java
TransletOutputHandlerFactory.java
java/src/org/apache/xalan/xsltc/trax Tag: xslt20
DOM2SAX.java DOM2TO.java SAX2DOM.java
TemplatesHandlerImpl.java TemplatesImpl.java
TrAXFilter.java TransformerFactoryImpl.java
TransformerHandlerImpl.java TransformerImpl.java
Util.java
java/src/org/apache/xalan/xsltc/util Tag: xslt20
IntegerArray.java
Added: java/src/org/apache/xalan/xsltc/compiler Tag: xslt20
Closure.java ForwardPositionExpr.java
java/src/org/apache/xalan/xsltc/compiler/util Tag: xslt20
NodeSortRecordFactGenerator.java
java/src/org/apache/xalan/xsltc/dom Tag: xslt20
ForwardPositionIterator.java
java/src/org/apache/xalan/xsltc/runtime/output Tag: xslt20
OutputBuffer.java StringOutputBuffer.java
WriterOutputBuffer.java
Removed: java/src/org/apache/xalan/xsltc/dom Tag: xslt20
ReverseIterator.java
Log:
Updating changes to XSLTC from MAIN branch into xslt20 branch.
Revision Changes Path
No revision
No revision
1.10.2.1.2.1 +1 -3 xml-xalan/java/src/org/apache/xalan/xsltc/DOM.java
Index: DOM.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/DOM.java,v
retrieving revision 1.10.2.1
retrieving revision 1.10.2.1.2.1
diff -u -r1.10.2.1 -r1.10.2.1.2.1
--- DOM.java 14 Aug 2002 19:21:31 -0000 1.10.2.1
+++ DOM.java 2 Dec 2002 15:51:15 -0000 1.10.2.1.2.1
@@ -126,8 +126,6 @@
public String getLanguage(int node);
public int getSize();
public String getDocumentURI(int node);
- public int getTypedPosition(int type, int node);
- public int getTypedLast(int type, int node);
public void setFilter(StripFilter filter);
public void setupMapping(String[] names, String[] namespaces);
public boolean isElement(final int node);
1.4.2.1.2.1 +3 -1 xml-xalan/java/src/org/apache/xalan/xsltc/Translet.java
Index: Translet.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/Translet.java,v
retrieving revision 1.4.2.1
retrieving revision 1.4.2.1.2.1
diff -u -r1.4.2.1 -r1.4.2.1.2.1
--- Translet.java 14 Aug 2002 19:21:31 -0000 1.4.2.1
+++ Translet.java 2 Dec 2002 15:51:15 -0000 1.4.2.1.2.1
@@ -80,4 +80,6 @@
throws TransletException;
public void addAuxiliaryClass(Class auxClass);
public Class getAuxiliaryClass(String className);
+ public String[] getNamesArray();
+ public String[] getNamespaceArray();
}
1.10.2.1.2.1 +3 -1
xml-xalan/java/src/org/apache/xalan/xsltc/TransletOutputHandler.java
Index: TransletOutputHandler.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/TransletOutputHandler.java,v
retrieving revision 1.10.2.1
retrieving revision 1.10.2.1.2.1
diff -u -r1.10.2.1 -r1.10.2.1.2.1
--- TransletOutputHandler.java 14 Aug 2002 19:21:31 -0000 1.10.2.1
+++ TransletOutputHandler.java 2 Dec 2002 15:51:15 -0000
1.10.2.1.2.1
@@ -82,6 +82,8 @@
public void comment(String comment) throws TransletException;
public void processingInstruction(String target, String data)
throws TransletException;
+ public void startCDATA() throws TransletException;
+ public void endCDATA() throws TransletException;
public void setType(int type);
public void setIndent(boolean indent);
public void omitHeader(boolean value);
No revision
No revision
1.11.2.1.2.1 +4 -4
xml-xalan/java/src/org/apache/xalan/xsltc/cmdline/Compile.java
Index: Compile.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/cmdline/Compile.java,v
retrieving revision 1.11.2.1
retrieving revision 1.11.2.1.2.1
diff -u -r1.11.2.1 -r1.11.2.1.2.1
--- Compile.java 14 Aug 2002 19:21:32 -0000 1.11.2.1
+++ Compile.java 2 Dec 2002 15:51:15 -0000 1.11.2.1.2.1
@@ -82,8 +82,8 @@
// Versioning numbers for the compiler -v option output
private static int VERSION_MAJOR = 1;
- private static int VERSION_MINOR = 0;
- private static int VERSION_DELTA = 0;
+ private static int VERSION_MINOR = 2;
+ private static int VERSION_DELTA = 1;
// This variable should be set to false to prevent any methods in this
@@ -148,7 +148,7 @@
_allowExit = false;
break;
case 'n':
- xsltc.setTemplateInlining(false);
+ xsltc.setTemplateInlining(true); // used to be 'false'
break;
case 'v':
// fall through to case h
1.20.2.1.2.1 +12 -4
xml-xalan/java/src/org/apache/xalan/xsltc/cmdline/Transform.java
Index: Transform.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/cmdline/Transform.java,v
retrieving revision 1.20.2.1
retrieving revision 1.20.2.1.2.1
diff -u -r1.20.2.1 -r1.20.2.1.2.1
--- Transform.java 14 Aug 2002 19:21:32 -0000 1.20.2.1
+++ Transform.java 2 Dec 2002 15:51:15 -0000 1.20.2.1.2.1
@@ -118,7 +118,10 @@
_uri = uri;
_debug = debug;
_iterations = iterations;
- }
+ }
+
+ public String getFileName(){return _fileName;}
+ public String getClassName(){return _className;}
public void setParameters(Vector params) {
_params = params;
@@ -224,8 +227,13 @@
mm = System.currentTimeMillis() - mm;
System.err.println("\n<!--");
- System.err.println(" transform = " + (mm / _iterations) + "
ms");
- System.err.println(" throughput = " + (1000.0 / (mm /
_iterations)) + " tps");
+ System.err.println(" transform = "
+ + (((double) mm) / ((double) _iterations))
+ + " ms");
+ System.err.println(" throughput = "
+ + (1000.0 / (((double) mm)
+ / ((double) _iterations)))
+ + " tps");
System.err.println("-->");
}
}
No revision
No revision
1.1.12.1.2.1 +10 -7
xml-xalan/java/src/org/apache/xalan/xsltc/cmdline/getopt/GetOpt.java
Index: GetOpt.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/cmdline/getopt/GetOpt.java,v
retrieving revision 1.1.12.1
retrieving revision 1.1.12.1.2.1
diff -u -r1.1.12.1 -r1.1.12.1.2.1
--- GetOpt.java 14 Aug 2002 19:21:32 -0000 1.1.12.1
+++ GetOpt.java 2 Dec 2002 15:51:15 -0000 1.1.12.1.2.1
@@ -68,6 +68,7 @@
import org.apache.xalan.xsltc.cmdline.getopt.IllegalArgumentException;
import org.apache.xalan.xsltc.cmdline.getopt.MissingOptArgException;
+import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
/**
@@ -189,13 +190,15 @@
char c = theCurrentOption.getArgLetter();
boolean shouldHaveArg = theOptionMatcher.hasArg(c);
String arg = theCurrentOption.getArgument();
- if(!theOptionMatcher.match(c)){
- throw (new IllegalArgumentException("Option " +
- c + " is not valid."));
+ if(!theOptionMatcher.match(c)) {
+ ErrorMsg msg = new
ErrorMsg(ErrorMsg.ILLEGAL_CMDLINE_OPTION_ERR,
+ new Character(c));
+ throw (new IllegalArgumentException(msg.toString()));
}
- else if(shouldHaveArg && (arg == null)){
- throw (new MissingOptArgException("Option " +
- c + " is missing its argument."));
+ else if(shouldHaveArg && (arg == null)) {
+ ErrorMsg msg = new
ErrorMsg(ErrorMsg.CMDLINE_OPT_MISSING_ARG_ERR,
+ new Character(c));
+ throw (new MissingOptArgException(msg.toString()));
}
retval = c;
}
No revision
No revision
1.14.2.1.2.1 +7 -1
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ApplyTemplates.java
Index: ApplyTemplates.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ApplyTemplates.java,v
retrieving revision 1.14.2.1
retrieving revision 1.14.2.1.2.1
diff -u -r1.14.2.1 -r1.14.2.1.2.1
--- ApplyTemplates.java 14 Aug 2002 19:21:32 -0000 1.14.2.1
+++ ApplyTemplates.java 2 Dec 2002 15:51:16 -0000 1.14.2.1.2.1
@@ -103,6 +103,12 @@
if (select.length() > 0) {
_select = parser.parseExpression(this, "select", null);
+
+ // Wrap _select in a ForwardPositionExpr
+ final Expression fpe = new ForwardPositionExpr(_select);
+ _select.setParent(fpe);
+ fpe.setParser(_select.getParser());
+ _select = fpe;
}
if (mode.length() > 0) {
1.12.2.1.2.1 +21 -30
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/AttributeSet.java
Index: AttributeSet.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/AttributeSet.java,v
retrieving revision 1.12.2.1
retrieving revision 1.12.2.1.2.1
diff -u -r1.12.2.1 -r1.12.2.1.2.1
--- AttributeSet.java 14 Aug 2002 19:21:32 -0000 1.12.2.1
+++ AttributeSet.java 2 Dec 2002 15:51:16 -0000 1.12.2.1.2.1
@@ -84,6 +84,7 @@
// Element contents
private QName _name;
private UseAttributeSets _useSets;
+ private AttributeSet _mergeSet;
private String _method;
private boolean _ignore = false;
@@ -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) {
@@ -205,6 +181,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)
1.14.2.1.2.1 +12 -11
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/CastExpr.java
Index: CastExpr.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/CastExpr.java,v
retrieving revision 1.14.2.1
retrieving revision 1.14.2.1.2.1
diff -u -r1.14.2.1 -r1.14.2.1.2.1
--- CastExpr.java 14 Aug 2002 19:21:32 -0000 1.14.2.1
+++ CastExpr.java 2 Dec 2002 15:51:16 -0000 1.14.2.1.2.1
@@ -85,32 +85,27 @@
InternalTypeMap.put(Type.Boolean, Type.Real);
InternalTypeMap.put(Type.Boolean, Type.String);
InternalTypeMap.put(Type.Boolean, Type.Reference);
+ InternalTypeMap.put(Type.Boolean, Type.Object);
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.Real, Type.Object);
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.Int, Type.Object);
InternalTypeMap.put(Type.String, Type.String);
InternalTypeMap.put(Type.String, Type.Boolean);
InternalTypeMap.put(Type.String, Type.Real);
InternalTypeMap.put(Type.String, Type.Reference);
+ InternalTypeMap.put(Type.String, Type.Object);
InternalTypeMap.put(Type.NodeSet, Type.NodeSet);
InternalTypeMap.put(Type.NodeSet, Type.Boolean);
@@ -118,6 +113,7 @@
InternalTypeMap.put(Type.NodeSet, Type.String);
InternalTypeMap.put(Type.NodeSet, Type.Node);
InternalTypeMap.put(Type.NodeSet, Type.Reference);
+ InternalTypeMap.put(Type.NodeSet, Type.Object);
InternalTypeMap.put(Type.Node, Type.Node);
InternalTypeMap.put(Type.Node, Type.Boolean);
@@ -125,6 +121,7 @@
InternalTypeMap.put(Type.Node, Type.String);
InternalTypeMap.put(Type.Node, Type.NodeSet);
InternalTypeMap.put(Type.Node, Type.Reference);
+ InternalTypeMap.put(Type.Node, Type.Object);
InternalTypeMap.put(Type.ResultTree, Type.ResultTree);
InternalTypeMap.put(Type.ResultTree, Type.Boolean);
@@ -132,6 +129,7 @@
InternalTypeMap.put(Type.ResultTree, Type.String);
InternalTypeMap.put(Type.ResultTree, Type.NodeSet);
InternalTypeMap.put(Type.ResultTree, Type.Reference);
+ InternalTypeMap.put(Type.ResultTree, Type.Object);
InternalTypeMap.put(Type.Reference, Type.Reference);
InternalTypeMap.put(Type.Reference, Type.Boolean);
@@ -141,6 +139,9 @@
InternalTypeMap.put(Type.Reference, Type.Node);
InternalTypeMap.put(Type.Reference, Type.NodeSet);
InternalTypeMap.put(Type.Reference, Type.ResultTree);
+ InternalTypeMap.put(Type.Reference, Type.Object);
+
+ InternalTypeMap.put(Type.Object, Type.String);
InternalTypeMap.put(Type.Void, Type.String);
}
@@ -205,7 +206,7 @@
else if (tleft instanceof ResultTreeType) {
tleft = Type.ResultTree; // multiple instances
}
- if (InternalTypeMap.maps(tleft, _type)) {
+ if (InternalTypeMap.maps(tleft, _type) != null) {
return _type;
}
throw new TypeCheckError(this);
1.24.2.1.2.1 +11 -25
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Constants.java
Index: Constants.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Constants.java,v
retrieving revision 1.24.2.1
retrieving revision 1.24.2.1.2.1
diff -u -r1.24.2.1 -r1.24.2.1.2.1
--- Constants.java 14 Aug 2002 19:21:32 -0000 1.24.2.1
+++ Constants.java 2 Dec 2002 15:51:16 -0000 1.24.2.1.2.1
@@ -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;";
@@ -153,8 +155,8 @@
= "org.apache.xalan.xsltc.dom.SortingIterator";
public static final String SORT_ITERATOR_SIG
= "Lorg.apache.xalan.xsltc.dom.SortingIterator;";
- public static final String REVERSE_ITERATOR
- = "org.apache.xalan.xsltc.dom.ReverseIterator";
+ public static final String FORWARD_POSITION_ITERATOR
+ = "org.apache.xalan.xsltc.dom.ForwardPositionIterator";
public static final String NODE_SORT_RECORD
= "org.apache.xalan.xsltc.dom.NodeSortRecord";
public static final String NODE_SORT_FACTORY
@@ -284,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
@@ -299,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
@@ -316,6 +312,8 @@
= "iterator";
public static final String DOCUMENT_PNAME
= "document";
+ public static final String TRANSLET_PNAME
+ = "translet";
public static final String GET_NODE_NAME
= "getNodeName";
@@ -450,22 +448,6 @@
= "(" + STRING_SIG + ")" + OBJECT_SIG;
public static final String ADD_PARAMETER_SIG
= "(" + STRING_SIG + OBJECT_SIG + "Z)" + OBJECT_SIG;
- public static final String PUSH_VAR_FRAME
- = "pushVarFrame";
- public static final String PUSH_VAR_FRAME_SIG
- = "(I)V";
- public static final String POP_VAR_FRAME
- = "popVarFrame";
- public static final String POP_VAR_FRAME_SIG
- = "()V";
- public static final String ADD_VARIABLE
- = "addVariable";
- public static final String ADD_VARIABLE_SIG
- = "(I" + OBJECT_SIG + ")V";
- public static final String GET_VARIABLE
- = "getVariable";
- public static final String GET_VARIABLE_SIG
- = "(I)" + OBJECT_SIG;
public static final String STRIP_SPACE
= "stripSpace";
@@ -494,6 +476,10 @@
= "http://www.w3.org/1999/xhtml";
public static final String TRANSLET_URI
= "http://xml.apache.org/xalan/xsltc";
+ public static final String REDIRECT_URI
+ = "http://xml.apache.org/xalan/redirect";
public static final String FALLBACK_CLASS
= "org.apache.xalan.xsltc.compiler.Fallback";
+
+ public static final int RTF_INITIAL_SIZE = 64;
}
1.7.2.1.2.1 +22 -6
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ElementAvailableCall.java
Index: ElementAvailableCall.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ElementAvailableCall.java,v
retrieving revision 1.7.2.1
retrieving revision 1.7.2.1.2.1
diff -u -r1.7.2.1 -r1.7.2.1.2.1
--- ElementAvailableCall.java 14 Aug 2002 19:21:32 -0000 1.7.2.1
+++ ElementAvailableCall.java 2 Dec 2002 15:51:16 -0000 1.7.2.1.2.1
@@ -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;
+ }
}
/**
1.9.2.1.2.1 +1 -3
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/EqualityExpr.java
Index: EqualityExpr.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/EqualityExpr.java,v
retrieving revision 1.9.2.1
retrieving revision 1.9.2.1.2.1
diff -u -r1.9.2.1 -r1.9.2.1.2.1
--- EqualityExpr.java 14 Aug 2002 19:21:32 -0000 1.9.2.1
+++ EqualityExpr.java 2 Dec 2002 15:51:16 -0000 1.9.2.1.2.1
@@ -360,7 +360,6 @@
// Call the appropriate compare() from the BasisLibrary
il.append(new PUSH(cpg, _op));
- il.append(methodGen.loadContextNode());
il.append(methodGen.loadDOM());
final int compare = cpg.addMethodref(BASIS_LIBRARY_CLASS,
@@ -369,7 +368,6 @@
+ tleft.toSignature()
+ tright.toSignature()
+ "I"
- + NODE_SIG
+ DOM_INTF_SIG
+ ")Z");
il.append(new INVOKESTATIC(compare));
1.15.2.1.2.1 +19 -10
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Expression.java
Index: Expression.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Expression.java,v
retrieving revision 1.15.2.1
retrieving revision 1.15.2.1.2.1
diff -u -r1.15.2.1 -r1.15.2.1.2.1
--- Expression.java 14 Aug 2002 19:21:32 -0000 1.15.2.1
+++ Expression.java 2 Dec 2002 15:51:16 -0000 1.15.2.1.2.1
@@ -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 {
@@ -171,15 +180,7 @@
return; // nothing to do
}
- if (this instanceof VariableRefBase) {
- // The method cloneIterator() also does resetting
- final int clone =
- cpg.addInterfaceMethodref(NODE_ITERATOR,
- "cloneIterator",
- "()" + NODE_ITERATOR_SIG);
- il.append(new INVOKEINTERFACE(clone, 1));
- }
- else {
+ if ( (this instanceof VariableRefBase) == false ) {
il.append(methodGen.loadContextNode());
il.append(methodGen.setStartNode());
}
@@ -203,6 +204,14 @@
MethodGenerator methodGen) {
final InstructionList il = methodGen.getInstructionList();
_falseList.add(il.append(new IFEQ(null)));
+ }
+
+ public FlowList getFalseList() {
+ return _falseList;
+ }
+
+ public FlowList getTrueList() {
+ return _trueList;
}
public void backPatchFalseList(InstructionHandle ih) {
1.3.2.1.2.1 +31 -1
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/FlowList.java
Index: FlowList.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/FlowList.java,v
retrieving revision 1.3.2.1
retrieving revision 1.3.2.1.2.1
diff -u -r1.3.2.1 -r1.3.2.1.2.1
--- FlowList.java 14 Aug 2002 19:21:32 -0000 1.3.2.1
+++ FlowList.java 2 Dec 2002 15:51:16 -0000 1.3.2.1.2.1
@@ -64,6 +64,7 @@
package org.apache.xalan.xsltc.compiler;
import java.util.Vector;
+import java.util.Iterator;
import org.apache.bcel.generic.*;
public final class FlowList {
@@ -118,5 +119,34 @@
}
_elements.clear(); // avoid backpatching more than once
}
+ }
+
+ /**
+ * Redirect the handles from oldList to newList. "This" flow list
+ * is assumed to be relative to oldList.
+ */
+ public FlowList copyAndRedirect(InstructionList oldList,
+ InstructionList newList)
+ {
+ final FlowList result = new FlowList();
+ if (_elements == null) {
+ return result;
+ }
+
+ final int n = _elements.size();
+ final Iterator oldIter = oldList.iterator();
+ final Iterator newIter = newList.iterator();
+
+ while (oldIter.hasNext()) {
+ final InstructionHandle oldIh = (InstructionHandle) oldIter.next();
+ final InstructionHandle newIh = (InstructionHandle) newIter.next();
+
+ for (int i = 0; i < n; i++) {
+ if (_elements.elementAt(i) == oldIh) {
+ result.add(newIh);
+ }
+ }
+ }
+ return result;
}
}
1.12.8.1.2.1 +10 -3
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ForEach.java
Index: ForEach.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ForEach.java,v
retrieving revision 1.12.8.1
retrieving revision 1.12.8.1.2.1
diff -u -r1.12.8.1 -r1.12.8.1.2.1
--- ForEach.java 14 Aug 2002 19:21:32 -0000 1.12.8.1
+++ ForEach.java 2 Dec 2002 15:51:16 -0000 1.12.8.1.2.1
@@ -97,8 +97,14 @@
// make sure required attribute(s) have been set
if (_select.isDummy()) {
reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "select");
- return;
}
+ else {
+ // Wrap _select in a ForwardPositionExpr
+ final Expression fpe = new ForwardPositionExpr(_select);
+ _select.setParent(fpe);
+ fpe.setParser(_select.getParser());
+ _select = fpe;
+ }
}
public Type typeCheck(SymbolTable stable) throws TypeCheckError {
@@ -161,7 +167,8 @@
else {
_select.translate(classGen, methodGen);
}
- if (!(_type instanceof ReferenceType)) {
+
+ if (_type instanceof ReferenceType == false) {
_select.startResetIterator(classGen, methodGen);
}
}
1.11.2.1.2.1 +90 -120
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/FunctionAvailableCall.java
Index: FunctionAvailableCall.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/FunctionAvailableCall.java,v
retrieving revision 1.11.2.1
retrieving revision 1.11.2.1.2.1
diff -u -r1.11.2.1 -r1.11.2.1.2.1
--- FunctionAvailableCall.java 14 Aug 2002 19:21:32 -0000 1.11.2.1
+++ FunctionAvailableCall.java 2 Dec 2002 15:51:16 -0000
1.11.2.1.2.1
@@ -73,39 +73,31 @@
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)))
- {
- // the function is external, such as a java function
- _isFunctionAvailable = hasMethods();
+
+ if (!isInternalNamespace()) {
+ _isFunctionAvailable = hasMethods();
}
- // the case of internal function is handled in getResult.
}
- // case where _arg is not instanceof LiteralExpr can not be handled.
}
/**
@@ -113,13 +105,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,58 +117,12 @@
}
/**
- * (For ext. java functions only)
- * Parses the argument to function-available to extract the package
- * qualified class name, for example, given the argument
- * 'java:java.lang.Math.sin', getClassName would return
- * 'java.lang.Math'. See also 'getMethodName'.
- */
- private String getClassName(String argValue){
- int colonSep = argValue.indexOf(":");
- if (colonSep != -1) {
- argValue = argValue.substring(colonSep+1);
- }
- int lastDot = argValue.lastIndexOf(".");
- if (lastDot != -1) {
- argValue = argValue.substring(0, lastDot);
- }
- return argValue;
- }
-
- /**
- * (For ext. java functions only)
- * Parses the argument to function-available
- * to extract the method name, for example, given the argument
- * 'java.lang.Math.sin', getMethodName would return 'sin'.
- */
- private String getMethodName(String argValue){
- int lastDot = argValue.lastIndexOf(".");
- if (lastDot != -1) {
- argValue = argValue.substring(lastDot+1);
- }
- return argValue;
- }
-
- /**
- * (For java external functions only)
- * Creates a full package qualified
- * function name taking into account the namespace and the
- * function name derived from the argument passed to function-available.
- * For example, given a name of 'java:java.lang.Math.sin' and a
- * namespace of 'http://xml.apache.org/xalan/xsltc/java' this routine
- * constructs a uri and then derives the class name
- * 'java.lang.Math.sin' from the uri. The uri in this example would
- * be 'http://xml.apache.org/xalan/xsltc/java.java.lang.Math.sin'
+ * 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.
*/
- private String getExternalFunctionName() {
- int colonIndex = _nameOfFunct.indexOf(":");
- String uri = _namespaceOfFunct +
- "." + _nameOfFunct.substring(colonIndex+1);
- try{
- return getClassNameFromUri(uri);
- } catch (TypeCheckError e) {
- return null;
- }
+ public Object evaluateAtCompileTime() {
+ return getResult() ? Boolean.TRUE : Boolean.FALSE;
}
/**
@@ -186,65 +130,91 @@
* the specified method is found in the specifed class.
*/
private boolean hasMethods() {
-
LiteralExpr arg = (LiteralExpr)_arg;
- final String externalFunctName = getExternalFunctionName();
- if (externalFunctName == null) {
+
+ // Get the class name from the namespace uri
+ String className = getClassNameFromUri(_namespaceOfFunct);
+
+ // Get the method name from the argument to function-available
+ String methodName = null;
+ int colonIndex = _nameOfFunct.indexOf(":");
+ if (colonIndex > 0) {
+ String functionName = _nameOfFunct.substring(colonIndex+1);
+ int lastDotIndex = functionName.lastIndexOf('.');
+ if (lastDotIndex > 0) {
+ methodName = functionName.substring(lastDotIndex+1);
+ if (className != null && !className.equals(""))
+ className = className + "." + functionName.substring(0,
lastDotIndex);
+ else
+ className = functionName.substring(0, lastDotIndex);
+ }
+ else
+ methodName = functionName;
+ }
+ else
+ methodName = _nameOfFunct;
+
+ if (className == null || methodName == 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);
-
- 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();
-
- 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);
- }
- }
+
+ // Replace the '-' characters in the method name
+ if (methodName.indexOf('-') > 0)
+ methodName = replaceDash(methodName);
+
+ try {
+ TransletLoader loader = new TransletLoader();
+ final Class clazz = loader.loadClass(className);
+
+ if (clazz == null) {
+ return false;
+ }
+ else {
+ final Method[] methods = clazz.getMethods();
+
+ 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) {
+ return false;
+ }
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)))
- {
- // no namespace, so the function is an internal xslt function.
+ if (_nameOfFunct == null) {
+ return false;
+ }
+
+ if (isInternalNamespace()) {
final Parser parser = getParser();
- _isFunctionAvailable = parser.functionSupported(_nameOfFunct);
+ _isFunctionAvailable =
+ parser.functionSupported(Util.getLocalName(_nameOfFunct));
}
return _isFunctionAvailable;
}
-
+
+ /**
+ * Return true if the namespace uri is null or it is the XSLTC translet
uri.
+ */
+ private boolean isInternalNamespace() {
+ return (_namespaceOfFunct == null ||
+ _namespaceOfFunct.equals(EMPTYSTRING) ||
+ _namespaceOfFunct.equals(TRANSLET_URI));
+ }
/**
* Calls to 'function-available' are resolved at compile time since
1.22.2.1.2.1 +549 -139
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/FunctionCall.java
Index: FunctionCall.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/FunctionCall.java,v
retrieving revision 1.22.2.1
retrieving revision 1.22.2.1.2.1
diff -u -r1.22.2.1 -r1.22.2.1.2.1
--- FunctionCall.java 14 Aug 2002 19:21:32 -0000 1.22.2.1
+++ FunctionCall.java 2 Dec 2002 15:51:16 -0000 1.22.2.1.2.1
@@ -60,6 +60,7 @@
* @author Santiago Pericas-Geertsen
* @author Morten Jorgensen
* @author Erwin Bolwidt <[EMAIL PROTECTED]>
+ * @author Todd Miller
*
*/
@@ -71,8 +72,18 @@
import java.lang.reflect.*;
+import org.apache.bcel.generic.NEW;
+import org.apache.bcel.generic.IFEQ;
+import org.apache.bcel.generic.PUSH;
+import org.apache.bcel.generic.INVOKESTATIC;
+import org.apache.bcel.generic.INVOKEVIRTUAL;
+import org.apache.bcel.generic.INVOKESPECIAL;
+import org.apache.bcel.generic.ConstantPoolGen;
+import org.apache.bcel.generic.InstructionList;
+import org.apache.bcel.generic.InstructionConstants;
+import org.apache.bcel.generic.InvokeInstruction;
+
import org.apache.xalan.xsltc.compiler.util.Type;
-import org.apache.bcel.generic.*;
import org.apache.xalan.xsltc.compiler.util.*;
import org.apache.xalan.xsltc.runtime.TransletLoader;
@@ -96,22 +107,84 @@
"http://xml.apache.org/xalan";
protected final static String JAVA_EXT_XALAN =
+ "http://xml.apache.org/xalan/java";
+
+ protected final static String JAVA_EXT_XALAN_OLD =
"http://xml.apache.org/xslt/java";
+
+ protected final static String EXSLT_COMMON =
+ "http://exslt.org/common";
+
+ protected final static String EXSLT_MATH =
+ "http://exslt.org/math";
+
+ protected final static String EXSLT_SETS =
+ "http://exslt.org/sets";
+ protected final static String EXSLT_DATETIME =
+ "http://exslt.org/dates-and-times";
+
+ protected final static String EXSLT_STRINGS =
+ "http://exslt.org/strings";
+
+ // Namespace format constants
+ protected final static int NAMESPACE_FORMAT_JAVA = 0;
+ protected final static int NAMESPACE_FORMAT_CLASS = 1;
+ protected final static int NAMESPACE_FORMAT_PACKAGE = 2;
+ protected final static int NAMESPACE_FORMAT_CLASS_OR_PACKAGE = 3;
+
+ // Namespace format
+ private int _namespace_format = NAMESPACE_FORMAT_JAVA;
+
+ /**
+ * Stores reference to object for non-static Java calls
+ */
+ Expression _thisArgument = null;
// External Java function's class/method/signature
- private String _className;
- private Method _chosenMethod;
- private MethodType _chosenMethodType;
+ private String _className;
+ private Class _clazz;
+ private Method _chosenMethod;
+ private Constructor _chosenConstructor;
+ private MethodType _chosenMethodType;
// Encapsulates all unsupported external function calls
private boolean unresolvedExternal;
+ // If FunctionCall is a external java constructor
+ private boolean _isExtConstructor = false;
+
+ // If the java method is static
+ private boolean _isStatic = false;
+
// Legal conversions between internal and Java types.
private static final MultiHashtable _internal2Java = new
MultiHashtable();
// Legal conversions between Java and internal types.
private static final Hashtable _java2Internal = new Hashtable();
+
+ // The mappings between EXSLT extension namespaces and implementation
classes
+ private static final Hashtable _extensionNamespaceTable = new
Hashtable();
+
+ // Extension functions that are implemented in BasisLibrary
+ private static final Hashtable _extensionFunctionTable = new Hashtable();
+ /**
+ * inner class to used in internal2Java mappings, contains
+ * the Java type and the distance between the internal type and
+ * the Java type.
+ */
+ static class JavaType {
+ public Class type;
+ public int distance;
+
+ public JavaType(Class type, int distance){
+ this.type = type;
+ this.distance = distance;
+ }
+ public boolean equals(Object query){
+ return query.equals(type);
+ }
+ }
/**
* Defines 2 conversion tables:
@@ -120,6 +193,7 @@
* These two tables are used when calling external (Java) functions.
*/
static {
+
try {
final Class objectClass = Class.forName("java.lang.Object");
final Class stringClass = Class.forName("java.lang.String");
@@ -127,42 +201,56 @@
final Class nodeListClass = Class.forName("org.w3c.dom.NodeList");
// Possible conversions between internal and Java types
- _internal2Java.put(Type.Boolean, Boolean.TYPE);
-
- _internal2Java.put(Type.Int, Character.TYPE);
- _internal2Java.put(Type.Int, Byte.TYPE);
- _internal2Java.put(Type.Int, Short.TYPE);
- _internal2Java.put(Type.Int, Integer.TYPE);
- _internal2Java.put(Type.Int, Long.TYPE);
- _internal2Java.put(Type.Int, Float.TYPE);
- _internal2Java.put(Type.Int, Double.TYPE);
-
- _internal2Java.put(Type.Real, Character.TYPE);
- _internal2Java.put(Type.Real, Byte.TYPE);
- _internal2Java.put(Type.Real, Short.TYPE);
- _internal2Java.put(Type.Real, Integer.TYPE);
- _internal2Java.put(Type.Real, Long.TYPE);
- _internal2Java.put(Type.Real, Float.TYPE);
- _internal2Java.put(Type.Real, Double.TYPE);
-
- _internal2Java.put(Type.String, stringClass);
-
- _internal2Java.put(Type.Node, nodeClass);
- _internal2Java.put(Type.Node, nodeListClass);
-
- _internal2Java.put(Type.NodeSet, Integer.TYPE);
- _internal2Java.put(Type.NodeSet, nodeClass);
- _internal2Java.put(Type.NodeSet, nodeListClass);
-
- _internal2Java.put(Type.ResultTree, nodeClass);
- _internal2Java.put(Type.ResultTree, nodeListClass);
+ _internal2Java.put(Type.Boolean, new JavaType(objectClass,2));
+ _internal2Java.put(Type.Boolean, new
JavaType(java.lang.Boolean.class,1));
+ _internal2Java.put(Type.Boolean, new JavaType(Boolean.TYPE,0));
+
+ _internal2Java.put(Type.Int, new JavaType(objectClass, 8));
+ _internal2Java.put(Type.Int, new JavaType(Character.TYPE, 7));
+ _internal2Java.put(Type.Int, new JavaType(Byte.TYPE, 6));
+ _internal2Java.put(Type.Int, new JavaType(Short.TYPE, 5));
+ _internal2Java.put(Type.Int, new JavaType(Integer.TYPE, 0));
+ _internal2Java.put(Type.Int, new JavaType(java.lang.Integer.class,
1));
+ _internal2Java.put(Type.Int, new JavaType(Long.TYPE, 2));
+ _internal2Java.put(Type.Int, new JavaType(Float.TYPE, 3));
+ _internal2Java.put(Type.Int, new JavaType(Double.TYPE, 4));
+
+ _internal2Java.put(Type.Real, new JavaType(objectClass, 8));
+ _internal2Java.put(Type.Real, new JavaType(Character.TYPE, 7));
+ _internal2Java.put(Type.Real, new JavaType(Byte.TYPE, 6));
+ _internal2Java.put(Type.Real, new JavaType(Short.TYPE, 5));
+ _internal2Java.put(Type.Real, new JavaType(Integer.TYPE, 4));
+ _internal2Java.put(Type.Real, new JavaType(Long.TYPE, 3));
+ _internal2Java.put(Type.Real, new JavaType(Float.TYPE, 2));
+ _internal2Java.put(Type.Real, new JavaType(java.lang.Double.class,
1));
+ _internal2Java.put(Type.Real, new JavaType(Double.TYPE, 0));
+
+ _internal2Java.put(Type.String, new JavaType(objectClass, 1));
+ _internal2Java.put(Type.String, new JavaType(stringClass, 0));
+
+ _internal2Java.put(Type.Node, new JavaType(nodeClass, 0));
+ _internal2Java.put(Type.Node, new JavaType(nodeListClass, 1));
+ _internal2Java.put(Type.Node, new JavaType(objectClass, 2));
+ _internal2Java.put(Type.Node, new JavaType(stringClass, 3));
+
+ _internal2Java.put(Type.NodeSet, new JavaType(Integer.TYPE, 10));
+ _internal2Java.put(Type.NodeSet, new JavaType(stringClass, 3));
+ _internal2Java.put(Type.NodeSet, new JavaType(objectClass, 2));
+ _internal2Java.put(Type.NodeSet, new JavaType(nodeClass, 1));
+ _internal2Java.put(Type.NodeSet, new JavaType(nodeListClass,0));
+
+ _internal2Java.put(Type.ResultTree, new JavaType(nodeClass, 1));
+ _internal2Java.put(Type.ResultTree, new JavaType(nodeListClass, 0));
+ _internal2Java.put(Type.ResultTree, new JavaType(objectClass, 2));
+ _internal2Java.put(Type.ResultTree, new JavaType(stringClass, 3));
+ _internal2Java.put(Type.ResultTree, new JavaType(Double.TYPE, 4));
- _internal2Java.put(Type.Reference, objectClass);
+ _internal2Java.put(Type.Reference, new JavaType(objectClass,0));
// Possible conversions between Java and internal types
- _java2Internal.put(Boolean.TYPE, Type.Boolean);
-
- _java2Internal.put(Character.TYPE, Type.Real);
+ _java2Internal.put(Boolean.TYPE, Type.Boolean);
+ _java2Internal.put(Void.TYPE, Type.Void);
+ _java2Internal.put(Character.TYPE, Type.Real);
_java2Internal.put(Byte.TYPE, Type.Real);
_java2Internal.put(Short.TYPE, Type.Real);
_java2Internal.put(Integer.TYPE, Type.Real);
@@ -174,7 +262,22 @@
_java2Internal.put(objectClass, Type.Reference);
- // Conversions from org.w3c.dom.Node/NodeList are not supported
+ // Conversions from org.w3c.dom.Node/NodeList to internal NodeSet
+ _java2Internal.put(nodeListClass, Type.NodeSet);
+ _java2Internal.put(nodeClass, Type.NodeSet);
+
+ // Initialize the extension namespace table
+ _extensionNamespaceTable.put(EXT_XALAN,
"org.apache.xalan.lib.Extensions");
+ _extensionNamespaceTable.put(EXSLT_COMMON,
"org.apache.xalan.lib.ExsltCommon");
+ _extensionNamespaceTable.put(EXSLT_MATH,
"org.apache.xalan.lib.ExsltMath");
+ _extensionNamespaceTable.put(EXSLT_SETS,
"org.apache.xalan.lib.ExsltSets");
+ _extensionNamespaceTable.put(EXSLT_DATETIME,
"org.apache.xalan.lib.ExsltDatetime");
+ _extensionNamespaceTable.put(EXSLT_STRINGS,
"org.apache.xalan.lib.ExsltStrings");
+
+ // Initialize the extension function table
+ _extensionFunctionTable.put(EXSLT_COMMON + ":nodeSet", "nodeset");
+ _extensionFunctionTable.put(EXSLT_COMMON + ":objectType",
"objectType");
+ _extensionFunctionTable.put(EXT_XALAN + ":nodeset", "nodeset");
}
catch (ClassNotFoundException e) {
System.err.println(e);
@@ -208,16 +311,29 @@
}
public String getClassNameFromUri(String uri)
- throws TypeCheckError
- {
- final int length =
- uri.startsWith(JAVA_EXT_XSLTC) ? JAVA_EXT_XSLTC.length() + 1 :
- uri.startsWith(JAVA_EXT_XALAN) ? JAVA_EXT_XALAN.length() + 1 : 0;
-
- if (length == 0) {
- throw new TypeCheckError(this);
- }
- return (uri.length() > length) ? uri.substring(length) : EMPTYSTRING;
+ {
+ String className = (String)_extensionNamespaceTable.get(uri);
+
+ if (className != null)
+ return className;
+ else {
+ if (uri.startsWith(JAVA_EXT_XSLTC)) {
+ int length = JAVA_EXT_XSLTC.length() + 1;
+ return (uri.length() > length) ? uri.substring(length) :
EMPTYSTRING;
+ }
+ else if (uri.startsWith(JAVA_EXT_XALAN)) {
+ int length = JAVA_EXT_XALAN.length() + 1;
+ return (uri.length() > length) ? uri.substring(length) :
EMPTYSTRING;
+ }
+ else if (uri.startsWith(JAVA_EXT_XALAN_OLD)) {
+ int length = JAVA_EXT_XALAN_OLD.length() + 1;
+ return (uri.length() > length) ? uri.substring(length) :
EMPTYSTRING;
+ }
+ else {
+ int index = uri.lastIndexOf('/');
+ return (index > 0) ? uri.substring(index+1) : uri;
+ }
+ }
}
/**
@@ -227,10 +343,10 @@
public Type typeCheck(SymbolTable stable)
throws TypeCheckError
{
- if (_type != null) return _type;
+ if (_type != null) return _type;
final String namespace = _fname.getNamespace();
- final String local = _fname.getLocalPart();
+ String local = _fname.getLocalPart();
if (isExtension()) {
_fname = new QName(null, null, local);
@@ -242,37 +358,61 @@
// Handle extension functions (they all have a namespace)
else {
try {
- _className = getClassNameFromUri(namespace);
-
- final int pos = local.lastIndexOf('.');
+ _className = getClassNameFromUri(namespace);
+
+ final int pos = local.lastIndexOf('.');
if (pos > 0) {
- _className = _className + local.substring(0, pos);
+ _isStatic = true;
+ if (_className != null && _className.length() > 0) {
+ _namespace_format = NAMESPACE_FORMAT_PACKAGE;
+ _className = _className + "." + local.substring(0, pos);
+ }
+ else {
+ _namespace_format = NAMESPACE_FORMAT_JAVA;
+ _className = local.substring(0, pos);
+ }
+
_fname = new QName(namespace, null, local.substring(pos +
1));
}
else {
- _fname = new QName(namespace, null, local);
+ if (_className != null && _className.length() > 0) {
+ try {
+ TransletLoader loader = new TransletLoader();
+ _clazz = loader.loadClass(_className);
+ _namespace_format = NAMESPACE_FORMAT_CLASS;
+ }
+ catch (ClassNotFoundException e) {
+ _namespace_format = NAMESPACE_FORMAT_PACKAGE;
+ }
+ }
+ else
+ _namespace_format = NAMESPACE_FORMAT_JAVA;
+
+ if (local.indexOf('-') > 0) {
+ local = replaceDash(local);
+ }
+
+ String extFunction =
(String)_extensionFunctionTable.get(namespace + ":" + local);
+ if (extFunction != null) {
+ _fname = new QName(null, null, extFunction);
+ return typeCheckStandard(stable);
+ }
+ else
+ _fname = new QName(namespace, null, local);
}
- if (_className.length() > 0) {
- return typeCheckExternal(stable);
+
+ return typeCheckExternal(stable);
+ }
+ catch (TypeCheckError e) {
+ ErrorMsg errorMsg = e.getErrorMsg();
+ if (errorMsg == null) {
+ final String name = _fname.getLocalPart();
+ errorMsg = new ErrorMsg(ErrorMsg.METHOD_NOT_FOUND_ERR,
name);
}
- } catch (TypeCheckError e) {
- // Falls through
+ getParser().reportError(ERROR, errorMsg);
+ return _type = Type.Void;
}
-
- /*
- * Warn user if external function could not be resolved.
- * Warning will _NOT_ be issued is the call is properly
- * wrapped in an <xsl:if> or <xsl:when> element. For details
- * see If.parserContents() and When.parserContents()
- */
- final Parser parser = getParser();
- if (parser != null) {
- reportWarning(this, parser, ErrorMsg.FUNCTION_RESOLVE_ERR,
- _fname.toString());
- }
- unresolvedExternal = true;
- return _type = Type.Void;
- }
+ }
}
/**
@@ -308,6 +448,67 @@
throw new TypeCheckError(this);
}
+
+
+ public Type typeCheckConstructor(SymbolTable stable) throws
TypeCheckError{
+ final Vector constructors = findConstructors();
+ if (constructors == null) {
+ // Constructor not found in this class
+ throw new TypeCheckError(ErrorMsg.CONSTRUCTOR_NOT_FOUND,
+ _className);
+
+ }
+
+ final int nConstructors = constructors.size();
+ final int nArgs = _arguments.size();
+ final Vector argsType = typeCheckArgs(stable);
+
+ // Try all constructors
+ int bestConstrDistance = Integer.MAX_VALUE;
+ _type = null; // reset
+ for (int j, i = 0; i < nConstructors; i++) {
+ // Check if all parameters to this constructor can be converted
+ final Constructor constructor =
+ (Constructor)constructors.elementAt(i);
+ final Class[] paramTypes = constructor.getParameterTypes();
+
+ Class extType = null;
+ int currConstrDistance = 0;
+ for (j = 0; j < nArgs; j++) {
+ // Convert from internal (translet) type to external (Java) type
+ extType = paramTypes[j];
+ final Type intType = (Type)argsType.elementAt(j);
+ Object match = _internal2Java.maps(intType, extType);
+ if (match != null) {
+ currConstrDistance += ((JavaType)match).distance;
+ }
+ else {
+ // no mapping available
+ currConstrDistance = Integer.MAX_VALUE;
+ break;
+ }
+ }
+
+ if (j == nArgs && currConstrDistance < bestConstrDistance ) {
+ _chosenConstructor = constructor;
+ _isExtConstructor = true;
+ bestConstrDistance = currConstrDistance;
+
+ if (_clazz != null)
+ _type = new ObjectType(_clazz);
+ else
+ _type = new ObjectType(_className);
+ }
+ }
+
+ if (_type != null) {
+ return _type;
+ }
+
+ throw new TypeCheckError(ErrorMsg.ARGUMENT_CONVERSION_ERR,
getMethodSignature(argsType));
+ }
+
+
/**
* Type check a call to an external (Java) method.
* The method must be static an public, and a legal type conversion
@@ -316,58 +517,148 @@
* as a possible candidate.
*/
public Type typeCheckExternal(SymbolTable stable) throws TypeCheckError {
+ int nArgs = _arguments.size();
+ final String name = _fname.getLocalPart();
+
+ // check if function is a contructor 'new'
+ if (_fname.getLocalPart().equals("new")) {
+ return typeCheckConstructor(stable);
+ }
+ // check if we are calling an instance method
+ else {
+ boolean hasThisArgument = false;
+
+ if (nArgs == 0)
+ _isStatic = true;
+
+ if (!_isStatic) {
+ if (_namespace_format == NAMESPACE_FORMAT_JAVA
+ || _namespace_format == NAMESPACE_FORMAT_PACKAGE)
+ hasThisArgument = true;
+
+ Expression firstArg = (Expression)_arguments.elementAt(0);
+ Type firstArgType = (Type)firstArg.typeCheck(stable);
+
+ if (_namespace_format == NAMESPACE_FORMAT_CLASS
+ && firstArgType instanceof ObjectType
+ && _clazz != null
+ &&
_clazz.isAssignableFrom(((ObjectType)firstArgType).getJavaClass()))
+ hasThisArgument = true;
+
+ if (hasThisArgument) {
+ _thisArgument = (Expression) _arguments.elementAt(0);
+ _arguments.remove(0); nArgs--;
+ if (firstArgType instanceof ObjectType) {
+ _className = ((ObjectType)
firstArgType).getJavaClassName();
+ }
+ else
+ throw new
TypeCheckError(ErrorMsg.NO_JAVA_FUNCT_THIS_REF, name);
+ }
+ }
+ else if (_className.length() == 0) {
+ /*
+ * Warn user if external function could not be resolved.
+ * Warning will _NOT_ be issued is the call is properly
+ * wrapped in an <xsl:if> or <xsl:when> element. For details
+ * see If.parserContents() and When.parserContents()
+ */
+ final Parser parser = getParser();
+ if (parser != null) {
+ reportWarning(this, parser, ErrorMsg.FUNCTION_RESOLVE_ERR,
+ _fname.toString());
+ }
+ unresolvedExternal = true;
+ return _type = Type.Int; // use "Int" as "unknown"
+ }
+ }
+
final Vector methods = findMethods();
if (methods == null) {
// Method not found in this class
- final String name = _fname.getLocalPart();
- throw new TypeCheckError(ErrorMsg.METHOD_NOT_FOUND_ERR, name);
+ throw new TypeCheckError(ErrorMsg.METHOD_NOT_FOUND_ERR, _className
+ "." + name);
}
+ Class extType = null;
final int nMethods = methods.size();
- final int nArgs = _arguments.size();
final Vector argsType = typeCheckArgs(stable);
- // Try all methods with the same name as this function
+ // Try all methods to identify the best fit
+ int bestMethodDistance = Integer.MAX_VALUE;
+ _type = null; // reset internal type
for (int j, i = 0; i < nMethods; i++) {
// Check if all paramteters to this method can be converted
final Method method = (Method)methods.elementAt(i);
final Class[] paramTypes = method.getParameterTypes();
+
+ int currMethodDistance = 0;
for (j = 0; j < nArgs; j++) {
// Convert from internal (translet) type to external (Java) type
+ extType = paramTypes[j];
final Type intType = (Type)argsType.elementAt(j);
- final Class extType = paramTypes[j];
- if (!_internal2Java.maps(intType, extType)) break;
+ Object match = _internal2Java.maps(intType, extType);
+ if (match != null) {
+ currMethodDistance += ((JavaType)match).distance;
+ }
+ else {
+ // no mapping available
+ //
+ // Allow a Reference type to match any external (Java) type
at
+ // the moment. The real type checking is performed at
runtime.
+ if (intType instanceof ReferenceType) {
+ currMethodDistance += 1;
+ }
+ else if (intType instanceof ObjectType) {
+ ObjectType object = (ObjectType)intType;
+ if (extType.getName().equals(object.getJavaClassName()))
+ currMethodDistance += 0;
+ else if
(extType.isAssignableFrom(object.getJavaClass()))
+ currMethodDistance += 1;
+ else {
+ currMethodDistance = Integer.MAX_VALUE;
+ break;
+ }
+ }
+ else {
+ currMethodDistance = Integer.MAX_VALUE;
+ break;
+ }
+ }
}
if (j == nArgs) {
- // Check if the return type can be converted
- final Class extType = method.getReturnType();
- if (extType.getName().equals("void"))
- _type = Type.Void;
- else
- _type = (Type)_java2Internal.get(extType);
- // Use this method if all parameters & return type match
- if (_type != null) {
- _chosenMethod = method;
- return _type;
- }
+ // Check if the return type can be converted
+ extType = method.getReturnType();
+
+ _type = (Type) _java2Internal.get(extType);
+ if (_type == null) {
+ _type = new ObjectType(extType);
+ }
+
+ // Use this method if all parameters & return type match
+ if (_type != null && currMethodDistance < bestMethodDistance)
{
+ _chosenMethod = method;
+ bestMethodDistance = currMethodDistance;
+ }
}
}
+
+ // It is an error if the chosen method is an instance menthod but we
don't
+ // have a this argument.
+ if (_chosenMethod != null && _thisArgument == null &&
+ !Modifier.isStatic(_chosenMethod.getModifiers())) {
+ throw new TypeCheckError(ErrorMsg.NO_JAVA_FUNCT_THIS_REF,
getMethodSignature(argsType));
+ }
- final StringBuffer buf = new StringBuffer(_className);
- buf.append('.');
- buf.append(_fname.getLocalPart());
- buf.append('(');
- for (int a=0; a<nArgs; a++) {
- final Type intType = (Type)argsType.elementAt(a);
- buf.append(intType.toString());
- if (a < (nArgs-1)) buf.append(", ");
+ if (_type != null) {
+ if (_type == Type.NodeSet) {
+ getXSLTC().setMultiDocument(true);
+ }
+ return _type;
}
- buf.append(");");
- final String args = buf.toString();
- throw new TypeCheckError(ErrorMsg.ARGUMENT_CONVERSION_ERR, args);
+
+ throw new TypeCheckError(ErrorMsg.ARGUMENT_CONVERSION_ERR,
getMethodSignature(argsType));
}
/**
@@ -469,11 +760,50 @@
il.append(new PUSH(cpg, _fname.toString()));
il.append(new INVOKESTATIC(index));
}
+ else if (_isExtConstructor) {
+ final String clazz =
+ _chosenConstructor.getDeclaringClass().getName();
+ Class[] paramTypes = _chosenConstructor.getParameterTypes();
+
+ il.append(new NEW(cpg.addClass(_className)));
+ il.append(InstructionConstants.DUP);
+
+ for (int i = 0; i < n; i++) {
+ final Expression exp = argument(i);
+ exp.translate(classGen, methodGen);
+ // Convert the argument to its Java type
+ exp.startResetIterator(classGen, methodGen);
+ exp.getType().translateTo(classGen, methodGen, paramTypes[i]);
+ }
+
+ final StringBuffer buffer = new StringBuffer();
+ buffer.append('(');
+ for (int i = 0; i < paramTypes.length; i++) {
+ buffer.append(getSignature(paramTypes[i]));
+ }
+ buffer.append(')');
+ buffer.append("V");
+
+ index = cpg.addMethodref(clazz,
+ "<init>",
+ buffer.toString());
+ il.append(new INVOKESPECIAL(index));
+
+ // Convert the return type back to our internal type
+ (Type.Object).translateFrom(classGen, methodGen,
+ _chosenConstructor.getDeclaringClass());
+
+ }
// Invoke function calls that are handled in separate classes
else {
final String clazz = _chosenMethod.getDeclaringClass().getName();
Class[] paramTypes = _chosenMethod.getParameterTypes();
+ // Push "this" if it is an instance method
+ if (_thisArgument != null) {
+ _thisArgument.translate(classGen, methodGen);
+ }
+
for (int i = 0; i < n; i++) {
final Expression exp = argument(i);
exp.translate(classGen, methodGen);
@@ -493,8 +823,9 @@
index = cpg.addMethodref(clazz,
_fname.getLocalPart(),
buffer.toString());
- il.append(new INVOKESTATIC(index));
-
+ il.append(_thisArgument != null ? (InvokeInstruction) new
INVOKEVIRTUAL(index) :
+ (InvokeInstruction) new INVOKESTATIC(index));
+
// Convert the return type back to our internal type
_type.translateFrom(classGen, methodGen,
_chosenMethod.getReturnType());
@@ -512,8 +843,7 @@
public boolean isExtension() {
final String namespace = _fname.getNamespace();
- return (namespace != null) && (namespace.equals(EXT_XSLTC)
- || namespace.equals(EXT_XALAN));
+ return (namespace != null) && (namespace.equals(EXT_XSLTC));
}
/**
@@ -522,51 +852,94 @@
* if no such methods exist.
*/
private Vector findMethods() {
- Vector result = null;
- final String namespace = _fname.getNamespace();
+
+ Vector result = null;
+ final String namespace = _fname.getNamespace();
- if (namespace.startsWith(JAVA_EXT_XSLTC) ||
- namespace.startsWith(JAVA_EXT_XALAN)) {
+ if (_className != null && _className.length() > 0) {
final int nArgs = _arguments.size();
try {
+ if (_clazz == null) {
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);
+ _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 = _fname.getLocalPart();
- final Method[] methods = clazz.getDeclaredMethods();
+ }
- for (int i = 0; i < methods.length; i++) {
- final int mods = methods[i].getModifiers();
+ final String methodName = _fname.getLocalPart();
+ final Method[] methods = _clazz.getMethods();
- // Is it public, static and same number of args ?
- if (Modifier.isPublic(mods)
- && Modifier.isStatic(mods)
- && methods[i].getName().equals(methodName)
- && methods[i].getParameterTypes().length == nArgs)
- {
- if (result == null) {
- result = new Vector();
- }
- result.addElement(methods[i]);
- }
- }
+ for (int i = 0; i < methods.length; i++) {
+ final int mods = methods[i].getModifiers();
+ // Is it public and same number of args ?
+ if (Modifier.isPublic(mods)
+ && methods[i].getName().equals(methodName)
+ && methods[i].getParameterTypes().length == nArgs)
+ {
+ if (result == null) {
+ result = new Vector();
+ }
+ result.addElement(methods[i]);
}
+ }
}
catch (ClassNotFoundException e) {
- final ErrorMsg msg =
- new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, _className);
- getParser().reportError(Constants.ERROR, msg);
+ final ErrorMsg msg = new
ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, _className);
+ getParser().reportError(Constants.ERROR, msg);
}
- }
- return result;
+ }
+ return result;
+ }
+
+ /**
+ * Returns a vector with all constructors named <code>_fname</code>
+ * after stripping its namespace or <code>null</code>
+ * if no such methods exist.
+ */
+ private Vector findConstructors() {
+ Vector result = null;
+ final String namespace = _fname.getNamespace();
+
+ final int nArgs = _arguments.size();
+ try {
+ if (_clazz == null) {
+ TransletLoader loader = new TransletLoader();
+ _clazz = loader.loadClass(_className);
+
+ if (_clazz == null) {
+ final ErrorMsg msg = new
ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, _className);
+ getParser().reportError(Constants.ERROR, msg);
+ }
+ }
+
+ final Constructor[] constructors = _clazz.getConstructors();
+
+ for (int i = 0; i < constructors.length; i++) {
+ final int mods = constructors[i].getModifiers();
+ // Is it public, static and same number of args ?
+ if (Modifier.isPublic(mods) &&
+ constructors[i].getParameterTypes().length == nArgs)
+ {
+ if (result == null) {
+ result = new Vector();
+ }
+ result.addElement(constructors[i]);
+ }
+ }
+ }
+ catch (ClassNotFoundException e) {
+ final ErrorMsg msg = new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR,
_className);
+ getParser().reportError(Constants.ERROR, msg);
+ }
+
+ return result;
}
+
/**
* Compute the JVM signature for the class.
*/
@@ -646,4 +1019,41 @@
}
return sb.append(")V").toString();
}
+
+ /**
+ * Return the signature of the current method
+ */
+ private String getMethodSignature(Vector argsType) {
+ final StringBuffer buf = new StringBuffer(_className);
+ buf.append('.').append(_fname.getLocalPart()).append('(');
+
+ int nArgs = argsType.size();
+ for (int i = 0; i < nArgs; i++) {
+ final Type intType = (Type)argsType.elementAt(i);
+ buf.append(intType.toString());
+ if (i < nArgs - 1) buf.append(", ");
+ }
+
+ buf.append(')');
+ return buf.toString();
+ }
+
+ /**
+ * To support EXSLT extensions, convert names with dash to allowable
Java names:
+ * e.g., convert abc-xyz to abcXyz.
+ * Note: dashes only appear in middle of an EXSLT function or element
name.
+ */
+ protected static String replaceDash(String name)
+ {
+ char dash = '-';
+ StringBuffer buff = new StringBuffer("");
+ for (int i = 0; i < name.length(); i++) {
+ if (i > 0 && name.charAt(i-1) == dash)
+ buff.append(Character.toUpperCase(name.charAt(i)));
+ else if (name.charAt(i) != dash)
+ buff.append(name.charAt(i));
+ }
+ return buff.toString();
+ }
+
}
1.10.2.1.2.1 +6 -12
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/If.java
Index: If.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/If.java,v
retrieving revision 1.10.2.1
retrieving revision 1.10.2.1.2.1
diff -u -r1.10.2.1 -r1.10.2.1.2.1
--- If.java 14 Aug 2002 19:21:32 -0000 1.10.2.1
+++ If.java 2 Dec 2002 15:51:16 -0000 1.10.2.1.2.1
@@ -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);
1.16.2.1.2.1 +21 -10
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Import.java
Index: Import.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Import.java,v
retrieving revision 1.16.2.1
retrieving revision 1.16.2.1.2.1
diff -u -r1.16.2.1 -r1.16.2.1.2.1
--- Import.java 14 Aug 2002 19:21:32 -0000 1.16.2.1
+++ Import.java 2 Dec 2002 15:51:16 -0000 1.16.2.1.2.1
@@ -84,11 +84,12 @@
private Stylesheet _imported = null;
public Stylesheet getImportedStylesheet() {
- return(_imported);
+ return _imported;
}
public void parseContents(final Parser parser) {
final Stylesheet context = parser.getCurrentStylesheet();
+
try {
String docToLoad = getAttribute("href");
if (context.checkForLoop(docToLoad)) {
@@ -114,10 +115,18 @@
input = new InputSource(docToLoad);
}
+ // Return if we could not resolve the URL
+ if (input == null) {
+ final ErrorMsg msg =
+ new ErrorMsg(ErrorMsg.FILE_NOT_FOUND_ERR, docToLoad, this);
+ parser.reportError(Constants.FATAL, msg);
+ return;
+ }
+
SyntaxTreeNode root = parser.parse(input);
if (root == null) return;
- final Stylesheet _imported = parser.makeStylesheet(root);
+ _imported = parser.makeStylesheet(root);
if (_imported == null) return;
_imported.setSourceLoader(loader);
@@ -138,14 +147,16 @@
while (elements.hasMoreElements()) {
final Object element = elements.nextElement();
if (element instanceof TopLevelElement) {
- if (element instanceof Variable)
- topStylesheet.addVariable((Variable)element);
- else if (element instanceof Param)
- topStylesheet.addParam((Param)element);
- else
- topStylesheet.addElement((TopLevelElement)element);
+ if (element instanceof Variable) {
+ topStylesheet.addVariable((Variable) element);
+ }
+ else if (element instanceof Param) {
+ topStylesheet.addParam((Param) element);
+ }
+ else {
+ topStylesheet.addElement((TopLevelElement) element);
+ }
}
-
}
}
catch (Exception e) {
1.19.2.1.2.1 +26 -12
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Include.java
Index: Include.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Include.java,v
retrieving revision 1.19.2.1
retrieving revision 1.19.2.1.2.1
diff -u -r1.19.2.1 -r1.19.2.1.2.1
--- Include.java 14 Aug 2002 19:21:32 -0000 1.19.2.1
+++ Include.java 2 Dec 2002 15:51:16 -0000 1.19.2.1.2.1
@@ -84,11 +84,12 @@
private Stylesheet _included = null;
public Stylesheet getIncludedStylesheet() {
- return(_included);
+ return _included;
}
public void parseContents(final Parser parser) {
final Stylesheet context = parser.getCurrentStylesheet();
+
String docToLoad = getAttribute("href");
try {
if (context.checkForLoop(docToLoad)) {
@@ -124,16 +125,27 @@
docToLoad = "file:" + file.getCanonicalPath();
}
else {
- throw new FileNotFoundException(
- "Could not load file " + docToLoad);
+ final ErrorMsg msg =
+ new ErrorMsg(ErrorMsg.FILE_ACCESS_ERR,
+ docToLoad);
+ parser.reportError(Constants.FATAL, msg);
+ return;
}
input = new InputSource(docToLoad);
}
}
+ // Return if we could not resolve the URL
+ if (input == null) {
+ final ErrorMsg msg =
+ new ErrorMsg(ErrorMsg.FILE_NOT_FOUND_ERR, docToLoad, this);
+ parser.reportError(Constants.FATAL, msg);
+ return;
+ }
+
final SyntaxTreeNode root = parser.parse(input);
if (root == null) return;
- final Stylesheet _included = parser.makeStylesheet(root);
+ _included = parser.makeStylesheet(root);
if (_included == null) return;
_included.setSourceLoader(loader);
@@ -146,7 +158,6 @@
// as the stylesheet that included it.
final int precedence = context.getImportPrecedence();
_included.setImportPrecedence(precedence);
-
parser.setCurrentStylesheet(_included);
_included.parseContents(parser);
@@ -155,12 +166,15 @@
while (elements.hasMoreElements()) {
final Object element = elements.nextElement();
if (element instanceof TopLevelElement) {
- if (element instanceof Variable)
- topStylesheet.addVariable((Variable)element);
- else if (element instanceof Param)
- topStylesheet.addParam((Param)element);
- else
- topStylesheet.addElement((TopLevelElement)element);
+ if (element instanceof Variable) {
+ topStylesheet.addVariable((Variable) element);
+ }
+ else if (element instanceof Param) {
+ topStylesheet.addParam((Param) element);
+ }
+ else {
+ topStylesheet.addElement((TopLevelElement) element);
+ }
}
}
}
1.11.2.1.2.1 +33 -52
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Key.java
Index: Key.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Key.java,v
retrieving revision 1.11.2.1
retrieving revision 1.11.2.1.2.1
diff -u -r1.11.2.1 -r1.11.2.1.2.1
--- Key.java 14 Aug 2002 19:21:32 -0000 1.11.2.1
+++ Key.java 2 Dec 2002 15:51:16 -0000 1.11.2.1.2.1
@@ -57,6 +57,7 @@
* <http://www.apache.org/>.
*
* @author Morten Jorgensen
+ * @author Santiago Pericas-Geertsen
*
*/
@@ -75,10 +76,25 @@
final class Key extends TopLevelElement {
- private QName _name; // The name of this key (ie. index)
- private Pattern _match; // The nodes to generate index keys from
- private Expression _use; // The nodes to include in the key
- private Type _useType; // The data type of the key's contents
+ /**
+ * The name of this key as defined in xsl:key.
+ */
+ private QName _name;
+
+ /**
+ * The pattern to match starting at the root node.
+ */
+ private Pattern _match;
+
+ /**
+ * The expression that generates the values for this key.
+ */
+ private Expression _use;
+
+ /**
+ * The type of the _use expression.
+ */
+ private Type _useType;
/**
* Parse the <xsl:key> element and attributes
@@ -114,30 +130,16 @@
return _name.toString();
}
- /**
- * Run type check on the "use" attribute and make sure it is something
- * we can use to extract some value from nodes.
- * @param stable The stylesheet parser's symbol table
- * @return The data-type of this key (always void)
- * @throws TypeCheckError If the use attribute does not represent a
string,
- * a node-set or a number
- */
public Type typeCheck(SymbolTable stable) throws TypeCheckError {
+ // Type check match pattern
_match.typeCheck(stable);
- _useType = _use.typeCheck(stable);
- // Cast node values to string values
- if (_useType instanceof NodeType) {
+ // Cast node values to string values (except for nodesets)
+ _useType = _use.typeCheck(stable);
+ if (_useType instanceof StringType == false &&
+ _useType instanceof NodeSetType == false)
+ {
_use = new CastExpr(_use, Type.String);
- _useType = Type.String;
- }
-
- // If the 'use' attribute is not a string, node-set or number
- if (!(_useType instanceof StringType) &&
- !(_useType instanceof NodeSetType) &&
- !(_useType instanceof RealType)) {
- ErrorMsg err = new ErrorMsg(ErrorMsg.KEY_USE_ATTR_ERR, this);
- throw new TypeCheckError(err);
}
return Type.Void;
@@ -147,8 +149,6 @@
* This method is called if the "use" attribute of the key contains a
* node set. In this case we must traverse all nodes in the set and
* create one entry in this key's index for each node in the set.
- * @param classGen The Java class generator
- * @param methodGen The method generator
*/
public void traverseNodeSet(ClassGenerator classGen,
MethodGenerator methodGen,
@@ -186,7 +186,6 @@
// 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, _name.toString()));
il.append(new ILOAD(parentNode.getIndex()));
@@ -213,8 +212,6 @@
/**
* Gather all nodes that match the expression in the attribute "match"
* and add one (or more) entries in this key's index.
- * @param classGen The Java class generator
- * @param methodGen The method generator
*/
public void translate(ClassGenerator classGen, MethodGenerator
methodGen) {
@@ -255,34 +252,18 @@
_match.synthesize(classGen, methodGen); // Leaves 0 or 1 on stack
final BranchHandle skipNode = il.append(new IFEQ(null));
- // If this is just a single node we should convert that to a string
- // and use that string as the value in the index for this key.
- if (_useType instanceof RealType) {
- final int dbl = cpg.addMethodref(DOUBLE_CLASS,"<init>", "(D)V");
-
- il.append(classGen.loadTranslet());
- il.append(new PUSH(cpg, _name.toString()));
+ // If this is a node-set we must go through each node in the set
+ if (_useType instanceof NodeSetType) {
+ // Pass current node as parameter (we're indexing on that node)
il.append(methodGen.loadCurrentNode());
- il.append(new NEW(cpg.addClass(DOUBLE_CLASS)));
- il.append(DUP);
- _use.translate(classGen,methodGen);
- il.append(new INVOKESPECIAL(dbl));
- il.append(new INVOKEVIRTUAL(key));
-
+ traverseNodeSet(classGen, methodGen, key);
}
- else if (_useType instanceof StringType) {
+ else {
il.append(classGen.loadTranslet());
il.append(new PUSH(cpg, _name.toString()));
il.append(methodGen.loadCurrentNode());
- _use.translate(classGen,methodGen);
+ _use.translate(classGen, methodGen);
il.append(new INVOKEVIRTUAL(key));
- }
- // If this is a node-set we must go through each node in the set
- // and create one entry in the key index for each node in the set.
- else {
- // Pass current node as parameter (we're indexing on that node)
- il.append(methodGen.loadCurrentNode());
- traverseNodeSet(classGen,methodGen,key);
}
// Get the next node from the iterator and do loop again...
1.8.2.1.2.1 +25 -22
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/KeyCall.java
Index: KeyCall.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/KeyCall.java,v
retrieving revision 1.8.2.1
retrieving revision 1.8.2.1.2.1
diff -u -r1.8.2.1 -r1.8.2.1.2.1
--- KeyCall.java 14 Aug 2002 19:21:32 -0000 1.8.2.1
+++ KeyCall.java 2 Dec 2002 15:51:16 -0000 1.8.2.1.2.1
@@ -57,6 +57,7 @@
* <http://www.apache.org/>.
*
* @author Morten Jorgensen
+ * @author Santiago Pericas-Geertsen
*
*/
@@ -70,10 +71,25 @@
final class KeyCall extends FunctionCall {
- 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;
+ /**
+ * The name of the key.
+ */
+ private Expression _name;
+
+ /**
+ * The value to look up in the key/index.
+ */
+ private Expression _value;
+
+ /**
+ * The value's data type.
+ */
+ private Type _valueType; // The value's data type
+
+ /**
+ * Expanded qname when name is literal.
+ */
+ private QName _resolvedQName = null;
/**
* Get the parameters passed to function:
@@ -138,11 +154,9 @@
// be added to the resulting node-set.
_valueType = _value.typeCheck(stable);
- if ((_valueType != Type.NodeSet) &&
- (_valueType != Type.ResultTree) &&
- (_valueType != Type.String) &&
- (_valueType != Type.Real) &&
- (_valueType != Type.Int)) {
+ if (_valueType != Type.NodeSet && _valueType != Type.ResultTree
+ && _valueType != Type.String)
+ {
_value = new CastExpr(_value, Type.String);
}
@@ -324,18 +338,7 @@
// the iterator should return.
il.append(DUP);
- if (_valueType == Type.Int || _valueType == Type.Real) {
- final int dbl = cpg.addMethodref(DOUBLE_CLASS,"<init>", "(D)V");
- il.append(new NEW(cpg.addClass(DOUBLE_CLASS)));
- il.append(DUP);
- _value.translate(classGen, methodGen);
- if (_valueType == Type.Int)
- il.append(new I2D());
- il.append(new INVOKESPECIAL(dbl));
- }
- else {
- _value.translate(classGen, methodGen);
- }
+ _value.translate(classGen, methodGen);
if (_name == null) {
il.append(new INVOKEVIRTUAL(lookupId));
1.7.8.1.2.1 +8 -66
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/LastCall.java
Index: LastCall.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/LastCall.java,v
retrieving revision 1.7.8.1
retrieving revision 1.7.8.1.2.1
diff -u -r1.7.8.1 -r1.7.8.1.2.1
--- LastCall.java 14 Aug 2002 19:21:32 -0000 1.7.8.1
+++ LastCall.java 2 Dec 2002 15:51:16 -0000 1.7.8.1.2.1
@@ -71,17 +71,10 @@
final class LastCall extends FunctionCall {
- private int _type = -1;
-
public LastCall(QName fname) {
super(fname);
}
- public LastCall(QName fname, int type) {
- this(fname);
- _type = type;
- }
-
public boolean hasPositionCall() {
return true;
}
@@ -91,72 +84,21 @@
}
public void translate(ClassGenerator classGen, MethodGenerator
methodGen) {
-
final InstructionList il = methodGen.getInstructionList();
- final ConstantPoolGen cpg = classGen.getConstantPool();
-
- boolean lastChild = false;
-
- // If we're a part of an pattern's predicate we want to know what
- // type of node we want to be looking for (not just any).
- if (getParent() instanceof Expression) {
- if (getParent().getParent() instanceof Predicate) {
- Predicate pred = (Predicate)getParent().getParent();
- _type = pred.getPosType();
- if ((_type==DOM.ELEMENT) || (_type==DOM.ATTRIBUTE)) _type = -1;
- }
- }
-
- // If we're a part of a step-type expression we want the last of the
- // current node's children and not the last in the current iterator.
- if (getParent() instanceof Predicate) {
- _type = ((Predicate)getParent()).getPosType();
- if ((_type==DOM.ELEMENT) || (_type==DOM.ATTRIBUTE)) _type = -1;
- if (getParent().getParent() instanceof Step) {
- lastChild = true;
- }
- }
if (methodGen instanceof CompareGenerator) {
il.append(((CompareGenerator)methodGen).loadLastNode());
}
- else if (classGen.isExternal()) {
+ else if (methodGen instanceof TestGenerator) {
il.append(new ILOAD(LAST_INDEX));
}
- else if (_type == -1) {
- final int last = cpg.addInterfaceMethodref(NODE_ITERATOR,
- "getLast",
- "()I");
- final int git = cpg.addInterfaceMethodref(DOM_INTF,
- "getTypedAxisIterator",
- "(II)"+NODE_ITERATOR_SIG);
- final int start = cpg.addInterfaceMethodref(NODE_ITERATOR,
- "setStartNode",
- "(I)"+
- NODE_ITERATOR_SIG);
- if (lastChild) {
- il.append(methodGen.loadDOM());
- il.append(new PUSH(cpg, Axis.CHILD));
- il.append(new PUSH(cpg, DOM.ELEMENT));
- il.append(new INVOKEINTERFACE(git, 3));
- il.append(methodGen.loadCurrentNode());
- il.append(new INVOKEINTERFACE(start, 2));
- }
- else {
- il.append(methodGen.loadIterator());
- }
- il.append(new INVOKEINTERFACE(last, 1));
- }
else {
- // public int getTypedLast(int type, int node) {
- final int last = cpg.addInterfaceMethodref(DOM_INTF,
- "getTypedLast",
- "(II)I");
- il.append(methodGen.loadDOM());
- il.append(new PUSH(cpg, _type));
- il.append(methodGen.loadContextNode());
- il.append(new INVOKEINTERFACE(last, 3));
-
+ final ConstantPoolGen cpg = classGen.getConstantPool();
+ final int getLast = cpg.addInterfaceMethodref(NODE_ITERATOR,
+ "getLast",
+ "()I");
+ il.append(methodGen.loadIterator());
+ il.append(new INVOKEINTERFACE(getLast, 1));
}
}
}
1.2.16.1.2.1 +7 -2
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/LocationPathPattern.java
Index: LocationPathPattern.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/LocationPathPattern.java,v
retrieving revision 1.2.16.1
retrieving revision 1.2.16.1.2.1
diff -u -r1.2.16.1 -r1.2.16.1.2.1
--- LocationPathPattern.java 14 Aug 2002 19:21:33 -0000 1.2.16.1
+++ LocationPathPattern.java 2 Dec 2002 15:51:16 -0000 1.2.16.1.2.1
@@ -64,6 +64,7 @@
package org.apache.xalan.xsltc.compiler;
+import org.apache.xalan.xsltc.dom.Axis;
import org.apache.xalan.xsltc.compiler.util.Type;
import org.apache.xalan.xsltc.compiler.util.*;
@@ -125,12 +126,16 @@
return false;
}
- /** return last pattern (matching the current node) */
public abstract StepPattern getKernelPattern();
public abstract void reduceKernelPattern();
public abstract boolean isWildcard();
+
+ public int getAxis() {
+ final StepPattern sp = getKernelPattern();
+ return (sp != null) ? sp.getAxis() : Axis.CHILD;
+ }
public String toString() {
return "root()";
1.10.2.1.2.1 +26 -4
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/LogicalExpr.java
Index: LogicalExpr.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/LogicalExpr.java,v
retrieving revision 1.10.2.1
retrieving revision 1.10.2.1.2.1
diff -u -r1.10.2.1 -r1.10.2.1.2.1
--- LogicalExpr.java 14 Aug 2002 19:21:33 -0000 1.10.2.1
+++ LogicalExpr.java 2 Dec 2002 15:51:16 -0000 1.10.2.1.2.1
@@ -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;
+ }
}
/**
1.24.2.1.2.1 +260 -108
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Mode.java
Index: Mode.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Mode.java,v
retrieving revision 1.24.2.1
retrieving revision 1.24.2.1.2.1
diff -u -r1.24.2.1 -r1.24.2.1.2.1
--- Mode.java 14 Aug 2002 19:21:33 -0000 1.24.2.1
+++ Mode.java 2 Dec 2002 15:51:17 -0000 1.24.2.1.2.1
@@ -70,15 +70,18 @@
import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
-import org.apache.xalan.xsltc.compiler.util.Type;
-import org.apache.bcel.generic.*;
+
import org.apache.bcel.util.*;
-import org.apache.xalan.xsltc.compiler.util.*;
+import org.apache.bcel.generic.*;
import org.apache.xalan.xsltc.DOM;
+import org.apache.xalan.xsltc.dom.Axis;
+import org.apache.xalan.xsltc.compiler.util.*;
+import org.apache.xalan.xsltc.compiler.util.Type;
/**
- * Mode gathers all the templates belonging to a given mode; it is
responsible
- * for generating an appropriate applyTemplates + (mode name) function
+ * Mode gathers all the templates belonging to a given mode;
+ * it is responsible for generating an appropriate
+ * applyTemplates + (mode name) method in the translet.
*/
final class Mode implements Constants {
@@ -103,16 +106,26 @@
private Vector _templates;
/**
- * Group for patterns with node()-type kernel.
+ * Group for patterns with node()-type kernel and child axis.
*/
- private Vector _nodeGroup = null;
+ private Vector _childNodeGroup = null;
/**
- * Test sequence for patterns with node()-type kernel.
+ * Test sequence for patterns with node()-type kernel and child axis.
*/
- private TestSeq _nodeTestSeq = null;
+ private TestSeq _childNodeTestSeq = null;
/**
+ * Group for patterns with node()-type kernel and attribute axis.
+ */
+ private Vector _attribNodeGroup = null;
+
+ /**
+ * Test sequence for patterns with node()-type kernel and attribute axis.
+ */
+ private TestSeq _attribNodeTestSeq = null;
+
+ /**
* Group for patterns with id() or key()-type kernel.
*/
private Vector _idxGroup = null;
@@ -120,32 +133,67 @@
/**
* Test sequence for patterns with id() or key()-type kernel.
*/
- private TestSeq _idxTestSeq = null;
+ private TestSeq _idxTestSeq = null;
/**
* Group for patterns with any other kernel type.
*/
- private Vector[] _patternGroups;
+ private Vector[] _patternGroups;
/**
* Test sequence for patterns with any other kernel type.
*/
private TestSeq[] _testSeq;
+ /**
+ * A mapping between patterns and instruction lists used by
+ * test sequences to avoid compiling the same pattern multiple
+ * times. Note that patterns whose kernels are "*", "node()"
+ * and "@*" can between shared by test sequences.
+ */
+ private Hashtable _preCompiled = new Hashtable();
+
+ /**
+ * A mapping between templates and test sequences.
+ */
private Hashtable _neededTemplates = new Hashtable();
+
+ /**
+ * A mapping between named templates and Mode objects.
+ */
private Hashtable _namedTemplates = new Hashtable();
+
+ /**
+ * A mapping between templates and instruction handles.
+ */
private Hashtable _templateIHs = new Hashtable();
+
+ /**
+ * A mapping between templates and instruction lists.
+ */
private Hashtable _templateILs = new Hashtable();
+
+ /**
+ * A reference to the pattern matching the root node.
+ */
private LocationPathPattern _rootPattern = null;
+ /**
+ * Stores ranges of template precendences for the compilation
+ * of apply-imports (a Hashtable for historical reasons).
+ */
private Hashtable _importLevels = null;
+ /**
+ * A mapping between key names and keys.
+ */
private Hashtable _keys = null;
- // Variable index for the current node - used in code generation
+ /**
+ * Variable index for the current node used in code generation.
+ */
private int _currentIndex;
-
/**
* Creates a new Mode.
*
@@ -155,19 +203,18 @@
* (normally a sequence number - still in a String).
*/
public Mode(QName name, Stylesheet stylesheet, String suffix) {
- // Save global info
_name = name;
_stylesheet = stylesheet;
_methodName = APPLY_TEMPLATES + suffix;
- // Initialise some data structures
_templates = new Vector();
_patternGroups = new Vector[32];
}
/**
- * Returns the name of the method (_not_ function) that will be compiled
- * for this mode. Normally takes the form 'applyTemplates()' or
- * 'applyTemplates2()'.
+ * Returns the name of the method (_not_ function) that will be
+ * compiled for this mode. Normally takes the form 'applyTemplates()'
+ * or * 'applyTemplates2()'.
+ *
* @return Method name for this mode
*/
public String functionName() {
@@ -175,9 +222,28 @@
}
public String functionName(int min, int max) {
- if (_importLevels == null) _importLevels = new Hashtable();
+ if (_importLevels == null) {
+ _importLevels = new Hashtable();
+ }
_importLevels.put(new Integer(max), new Integer(min));
- return _methodName+'_'+max;
+ return _methodName + '_' + max;
+ }
+
+ /**
+ * Add a pre-compiled pattern to this mode.
+ */
+ public void addInstructionList(Pattern pattern,
+ InstructionList ilist)
+ {
+ _preCompiled.put(pattern, ilist);
+ }
+
+ /**
+ * Get the instruction list for a pre-compiled pattern. Used by
+ * test sequences to avoid compiling patterns more than once.
+ */
+ public InstructionList getInstructionList(Pattern pattern) {
+ return (InstructionList) _preCompiled.get(pattern);
}
/**
@@ -187,10 +253,10 @@
return _stylesheet.getClassName();
}
- /**
- * Add a template to this mode
- * @param template The template to add
- */
+ public Stylesheet getStylesheet() {
+ return _stylesheet;
+ }
+
public void addTemplate(Template template) {
_templates.addElement(template);
}
@@ -304,10 +370,32 @@
}
/**
+ * Group patterns by NodeTests of their last Step
+ * Keep them sorted by priority within group
+ */
+ private void addPatternToGroup(final LocationPathPattern lpp) {
+ // id() and key()-type patterns do not have a kernel type
+ if (lpp instanceof IdKeyPattern) {
+ addPattern(-1, lpp);
+ }
+ // Otherwise get the kernel pattern from the LPP
+ else {
+ // kernel pattern is the last (maybe only) Step
+ final StepPattern kernel = lpp.getKernelPattern();
+ if (kernel != null) {
+ addPattern(kernel.getNodeType(), lpp);
+ }
+ else if (_rootPattern == null ||
+ lpp.noSmallerThan(_rootPattern)) {
+ _rootPattern = lpp;
+ }
+ }
+ }
+
+ /**
* Adds a pattern to a pattern group
*/
private void addPattern(int kernelType, LocationPathPattern pattern) {
-
// Make sure the array of pattern groups is long enough
final int oldLength = _patternGroups.length;
if (kernelType >= oldLength) {
@@ -319,24 +407,31 @@
// Find the vector to put this pattern into
Vector patterns;
- // Use the vector for id()/key()/node() patterns if no kernel type
- patterns = (kernelType == -1) ? _nodeGroup : _patternGroups[kernelType];
+ if (kernelType == DOM.NO_TYPE) {
+ if (pattern.getAxis() == Axis.ATTRIBUTE) {
+ patterns = (_attribNodeGroup == null) ?
+ (_attribNodeGroup = new Vector(2)) : _attribNodeGroup;
+ }
+ else {
+ patterns = (_childNodeGroup == null) ?
+ (_childNodeGroup = new Vector(2)) : _childNodeGroup;
+ }
+ }
+ else {
+ patterns = (_patternGroups[kernelType] == null) ?
+ (_patternGroups[kernelType] = new Vector(2)) :
+ _patternGroups[kernelType];
+ }
- // Create a new vector if needed and insert the very first pattern
if (patterns == null) {
- patterns = new Vector(2);
patterns.addElement(pattern);
- if (kernelType == -1)
- _nodeGroup = patterns;
- else
- _patternGroups[kernelType] = patterns;
}
- // Otherwise make sure patterns are ordered by precedence/priorities
else {
boolean inserted = false;
for (int i = 0; i < patterns.size(); i++) {
final LocationPathPattern lppToCompare =
(LocationPathPattern)patterns.elementAt(i);
+
if (pattern.noSmallerThan(lppToCompare)) {
inserted = true;
patterns.insertElementAt(pattern, i);
@@ -350,53 +445,106 @@
}
/**
- * Group patterns by NodeTests of their last Step
- * Keep them sorted by priority within group
+ * Complete test sequences of a given type by adding all patterns
+ * from a given group.
*/
- private void addPatternToGroup(final LocationPathPattern lpp) {
- // id() and key()-type patterns do not have a kernel type
- if (lpp instanceof IdKeyPattern) {
- addPattern(-1, lpp);
- }
- // Otherwise get the kernel pattern from the LPP
- else {
- // kernel pattern is the last (maybe only) Step
- final StepPattern kernel = lpp.getKernelPattern();
- if (kernel != null) {
- addPattern(kernel.getNodeType(), lpp);
+ private void completeTestSequences(int nodeType, Vector patterns) {
+ if (patterns != null) {
+ if (_patternGroups[nodeType] == null) {
+ _patternGroups[nodeType] = patterns;
}
- else if (_rootPattern == null ||
- lpp.noSmallerThan(_rootPattern)) {
- _rootPattern = lpp;
+ else {
+ final int m = patterns.size();
+ for (int j = 0; j < m; j++) {
+ addPattern(nodeType,
+ (LocationPathPattern) patterns.elementAt(j));
+ }
}
}
}
/**
- * Build test sequences
+ * Build test sequences. The first step is to complete the test
sequences
+ * by including patterns of "*" and "node()" kernel to all element test
+ * sequences, and of "@*" to all attribute test sequences.
*/
private void prepareTestSequences() {
+ final Vector starGroup = _patternGroups[DOM.ELEMENT];
+ final Vector atStarGroup = _patternGroups[DOM.ATTRIBUTE];
+
+ // Complete test sequence for "text()" with "child::node()"
+ completeTestSequences(DOM.TEXT, _childNodeGroup);
+
+ // Complete test sequence for "*" with "child::node()"
+ completeTestSequences(DOM.ELEMENT, _childNodeGroup);
+
+ // Complete test sequence for "pi()" with "child::node()"
+ completeTestSequences(DOM.PROCESSING_INSTRUCTION, _childNodeGroup);
+
+ // Complete test sequence for "comment()" with "child::node()"
+ completeTestSequences(DOM.COMMENT, _childNodeGroup);
+
+ // Complete test sequence for "@*" with "attribute::node()"
+ completeTestSequences(DOM.ATTRIBUTE, _attribNodeGroup);
+
final Vector names = _stylesheet.getXSLTC().getNamesIndex();
+ if (starGroup != null || atStarGroup != null ||
+ _childNodeGroup != null || _attribNodeGroup != null)
+ {
+ final int n = _patternGroups.length;
+
+ // Complete test sequence for user-defined types
+ for (int i = DOM.NTYPES; i < n; i++) {
+ if (_patternGroups[i] == null) continue;
+
+ final String name = (String) names.elementAt(i - DOM.NTYPES);
+
+ if (isAttributeName(name)) {
+ // If an attribute then copy "@*" to its test sequence
+ completeTestSequences(i, atStarGroup);
+
+ // And also copy "attribute::node()" to its test sequence
+ completeTestSequences(i, _attribNodeGroup);
+ }
+ else {
+ // If an element then copy "*" to its test sequence
+ completeTestSequences(i, starGroup);
+
+ // And also copy "child::node()" to its test sequence
+ completeTestSequences(i, _childNodeGroup);
+ }
+ }
+ }
+
_testSeq = new TestSeq[DOM.NTYPES + names.size()];
final int n = _patternGroups.length;
for (int i = 0; i < n; i++) {
final Vector patterns = _patternGroups[i];
if (patterns != null) {
- final TestSeq testSeq = new TestSeq(patterns, this);
+ final TestSeq testSeq = new TestSeq(patterns, i, this);
+// System.out.println("testSeq[" + i + "] = " + testSeq);
testSeq.reduce();
_testSeq[i] = testSeq;
testSeq.findTemplates(_neededTemplates);
}
}
- if ((_nodeGroup != null) && (_nodeGroup.size() > 0)) {
- _nodeTestSeq = new TestSeq(_nodeGroup, this);
- _nodeTestSeq.reduce();
- _nodeTestSeq.findTemplates(_neededTemplates);
+ if (_childNodeGroup != null && _childNodeGroup.size() > 0) {
+ _childNodeTestSeq = new TestSeq(_childNodeGroup, -1, this);
+ _childNodeTestSeq.reduce();
+ _childNodeTestSeq.findTemplates(_neededTemplates);
}
- if ((_idxGroup != null) && (_idxGroup.size() > 0)) {
+/*
+ if (_attribNodeGroup != null && _attribNodeGroup.size() > 0) {
+ _attribNodeTestSeq = new TestSeq(_attribNodeGroup, -1, this);
+ _attribNodeTestSeq.reduce();
+ _attribNodeTestSeq.findTemplates(_neededTemplates);
+ }
+*/
+
+ if (_idxGroup != null && _idxGroup.size() > 0) {
_idxTestSeq = new TestSeq(_idxGroup, this);
_idxTestSeq.reduce();
_idxTestSeq.findTemplates(_neededTemplates);
@@ -619,20 +767,7 @@
}
}
- /**
- * Auxiliary method to determine if a qname describes an
attribute/element
- */
- private static boolean isAttributeName(String qname) {
- final int col = qname.lastIndexOf(':') + 1;
- return (qname.charAt(col) == '@');
- }
-
- private static boolean isNamespaceName(String qname) {
- final int col = qname.lastIndexOf(':');
- return (col > -1 && qname.charAt(qname.length()-1) == '*');
- }
-
- /**
+ /**
* Compiles the applyTemplates() method and adds it to the translet.
* This is the main dispatch method.
*/
@@ -741,11 +876,10 @@
// If there is a match on node() we need to replace ihElem
// and ihText if the priority of node() is higher
- if (_nodeTestSeq != null) {
-
+ if (_childNodeTestSeq != null) {
// Compare priorities of node() and "*"
- double nodePrio = _nodeTestSeq.getPriority();
- int nodePos = _nodeTestSeq.getPosition();
+ double nodePrio = _childNodeTestSeq.getPriority();
+ int nodePos = _childNodeTestSeq.getPosition();
double elemPrio = (0 - Double.MAX_VALUE);
int elemPos = Integer.MIN_VALUE;
@@ -756,7 +890,7 @@
if (elemPrio == Double.NaN || elemPrio < nodePrio ||
(elemPrio == nodePrio && elemPos < nodePos))
{
- ihElem = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
+ ihElem = _childNodeTestSeq.compile(classGen, methodGen, ihLoop);
}
// Compare priorities of node() and text()
@@ -771,8 +905,8 @@
if (textPrio == Double.NaN || textPrio < nodePrio ||
(textPrio == nodePrio && textPos < nodePos))
{
- ihText = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
- _testSeq[DOM.TEXT] = _nodeTestSeq;
+ ihText = _childNodeTestSeq.compile(classGen, methodGen, ihLoop);
+ _testSeq[DOM.TEXT] = _childNodeTestSeq;
}
}
@@ -815,6 +949,7 @@
}
}
+
// Handle pattern with match on root node - default: traverse children
targets[DOM.ROOT] = _rootPattern != null
? getTemplateInstructionHandle(_rootPattern.getTemplate())
@@ -836,7 +971,7 @@
// Match on processing instruction - default: process next node
InstructionHandle ihPI = ihLoop;
- if (_nodeTestSeq != null) ihPI = ihElem;
+ if (_childNodeTestSeq != null) ihPI = ihElem;
if (_testSeq[DOM.PROCESSING_INSTRUCTION] != null)
targets[DOM.PROCESSING_INSTRUCTION] =
_testSeq[DOM.PROCESSING_INSTRUCTION].
@@ -846,7 +981,7 @@
// Match on comments - default: process next node
InstructionHandle ihComment = ihLoop;
- if (_nodeTestSeq != null) ihComment = ihElem;
+ if (_childNodeTestSeq != null) ihComment = ihElem;
targets[DOM.COMMENT] = _testSeq[DOM.COMMENT] != null
? _testSeq[DOM.COMMENT].compile(classGen, methodGen, ihComment)
: ihComment;
@@ -996,20 +1131,7 @@
classGen.getConstantPool());
methodGen.addException("org.apache.xalan.xsltc.TransletException");
- // No templates? Then just stuff in a single 'return' instruction
- if (_neededTemplates.size() == 0) {
- mainIL.append(new RETURN());
- methodGen.stripAttributes(true);
- methodGen.setMaxLocals();
- methodGen.setMaxStack();
- methodGen.removeNOPs();
- classGen.addMethod(methodGen.getMethod());
- // Restore original/complete set of templates for the transformation
- _templates = oldTemplates;
- return;
- }
-
- // Create the local variablea
+ // Create the local variable to hold the current node
final LocalVariableGen current;
current = methodGen.addLocalVariable2("current",
org.apache.bcel.generic.Type.INT,
@@ -1036,6 +1158,16 @@
ifeq.setTarget(ilLoop.append(RETURN)); // applyTemplates() ends here!
final InstructionHandle ihLoop = ilLoop.getStart();
+ // 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)
+ 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++) {
@@ -1055,7 +1187,7 @@
// Handle template with explicit "*" pattern
final TestSeq elemTest = _testSeq[DOM.ELEMENT];
- InstructionHandle ihElem = ihLoop;
+ InstructionHandle ihElem = ihRecurse;
if (elemTest != null) {
ihElem = elemTest.compile(classGen, methodGen, ihLoop);
}
@@ -1079,12 +1211,10 @@
// 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) {
-
+ if (_childNodeTestSeq != null) {
// Compare priorities of node() and "*"
- double nodePrio = _nodeTestSeq.getPriority();
- int nodePos = _nodeTestSeq.getPosition();
+ double nodePrio = _childNodeTestSeq.getPriority();
+ int nodePos = _childNodeTestSeq.getPosition();
double elemPrio = (0 - Double.MAX_VALUE);
int elemPos = Integer.MIN_VALUE;
@@ -1096,7 +1226,7 @@
if (elemPrio == Double.NaN || elemPrio < nodePrio ||
(elemPrio == nodePrio && elemPos < nodePos))
{
- ihElem = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
+ ihElem = _childNodeTestSeq.compile(classGen, methodGen, ihLoop);
}
// Compare priorities of node() and text()
@@ -1112,8 +1242,8 @@
if (textPrio == Double.NaN || textPrio < nodePrio ||
(textPrio == nodePrio && textPos < nodePos))
{
- ihText = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
- _testSeq[DOM.TEXT] = _nodeTestSeq;
+ ihText = _childNodeTestSeq.compile(classGen, methodGen, ihLoop);
+ _testSeq[DOM.TEXT] = _childNodeTestSeq;
}
}
@@ -1156,10 +1286,10 @@
}
}
- // Handle pattern with match on root node - default: loop
+ // Handle pattern with match on root node - default: traverse children
targets[DOM.ROOT] = _rootPattern != null
? getTemplateInstructionHandle(_rootPattern.getTemplate())
- : ihLoop;
+ : ihRecurse;
// Handle any pattern with match on text nodes - default: loop
targets[DOM.TEXT] = _testSeq[DOM.TEXT] != null
@@ -1177,7 +1307,7 @@
// Match on processing instruction - default: loop
InstructionHandle ihPI = ihLoop;
- if (_nodeTestSeq != null) ihPI = ihElem;
+ if (_childNodeTestSeq != null) ihPI = ihElem;
if (_testSeq[DOM.PROCESSING_INSTRUCTION] != null) {
targets[DOM.PROCESSING_INSTRUCTION] =
_testSeq[DOM.PROCESSING_INSTRUCTION].
@@ -1189,7 +1319,7 @@
// Match on comments - default: process next node
InstructionHandle ihComment = ihLoop;
- if (_nodeTestSeq != null) ihComment = ihElem;
+ if (_childNodeTestSeq != null) ihComment = ihElem;
targets[DOM.COMMENT] = _testSeq[DOM.COMMENT] != null
? _testSeq[DOM.COMMENT].compile(classGen, methodGen, ihComment)
: ihComment;
@@ -1237,6 +1367,11 @@
// Append NS:@* node tests (if any)
if (nsAttr != null) body.append(nsAttr);
+ // Append default action for element and root nodes
+ body.append(ilRecurse);
+ // Append default action for text and attribute nodes
+ body.append(ilText);
+
// putting together constituent instruction lists
mainIL.append(new GOTO_W(ihLoop));
mainIL.append(body);
@@ -1320,5 +1455,22 @@
public InstructionHandle getTemplateInstructionHandle(Template template)
{
return (InstructionHandle)_templateIHs.get(template);
+ }
+
+ /**
+ * Auxiliary method to determine if a qname is an attribute.
+ */
+ private static boolean isAttributeName(String qname) {
+ final int col = qname.lastIndexOf(':') + 1;
+ return (qname.charAt(col) == '@');
+ }
+
+ /**
+ * Auxiliary method to determine if a qname is a namespace
+ * qualified "*".
+ */
+ private static boolean isNamespaceName(String qname) {
+ final int col = qname.lastIndexOf(':');
+ return (col > -1 && qname.charAt(qname.length()-1) == '*');
}
}
1.9.2.1.2.1 +104 -33
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Number.java
Index: Number.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Number.java,v
retrieving revision 1.9.2.1
retrieving revision 1.9.2.1.2.1
diff -u -r1.9.2.1 -r1.9.2.1.2.1
--- Number.java 14 Aug 2002 19:21:33 -0000 1.9.2.1
+++ Number.java 2 Dec 2002 15:51:17 -0000 1.9.2.1.2.1
@@ -63,6 +63,8 @@
package org.apache.xalan.xsltc.compiler;
+import java.util.ArrayList;
+
import org.apache.xalan.xsltc.compiler.util.Type;
import org.apache.xalan.xsltc.compiler.util.ReferenceType;
import org.apache.bcel.classfile.JavaClass;
@@ -71,11 +73,23 @@
import org.apache.xalan.xsltc.compiler.util.*;
-final class Number extends Instruction {
+final class Number extends Instruction implements Closure {
private static final int LEVEL_SINGLE = 0;
private static final int LEVEL_MULTIPLE = 1;
private static final int LEVEL_ANY = 2;
+ static final private String[] ClassNames = {
+ "org.apache.xalan.xsltc.dom.SingleNodeCounter", // LEVEL_SINGLE
+ "org.apache.xalan.xsltc.dom.MultipleNodeCounter", // LEVEL_MULTIPLE
+ "org.apache.xalan.xsltc.dom.AnyNodeCounter" // LEVEL_ANY
+ };
+
+ static final private String[] FieldNames = {
+ "___single_node_counter", // LEVEL_SINGLE
+ "___multiple_node_counter", // LEVEL_MULTIPLE
+ "___any_node_counter" // LEVEL_ANY
+ };
+
private Pattern _from = null;
private Pattern _count = null;
private Expression _value = null;
@@ -89,19 +103,51 @@
private int _level = LEVEL_SINGLE;
private boolean _formatNeeded = false;
- static final private String[] ClassNames = {
- "org.apache.xalan.xsltc.dom.SingleNodeCounter", // LEVEL_SINGLE
- "org.apache.xalan.xsltc.dom.MultipleNodeCounter", // LEVEL_MULTIPLE
- "org.apache.xalan.xsltc.dom.AnyNodeCounter" // LEVEL_ANY
- };
+ private String _className = null;
+ private ArrayList _closureVars = null;
- static final private String[] FieldNames = {
- "___single_node_counter", // LEVEL_SINGLE
- "___multiple_node_counter", // LEVEL_MULTIPLE
- "___any_node_counter" // LEVEL_ANY
- };
+ // -- Begin Closure interface --------------------
+
+ /**
+ * Returns true if this closure is compiled in an inner class (i.e.
+ * if this is a real closure).
+ */
+ public boolean inInnerClass() {
+ return (_className != null);
+ }
- public void parseContents(Parser parser) {
+ /**
+ * Returns a reference to its parent closure or null if outermost.
+ */
+ public Closure getParentClosure() {
+ return null;
+ }
+
+ /**
+ * Returns the name of the auxiliary class or null if this predicate
+ * is compiled inside the Translet.
+ */
+ public String getInnerClassName() {
+ return _className;
+ }
+
+ /**
+ * Add new variable to the closure.
+ */
+ public void addVariable(VariableRefBase variableRef) {
+ if (_closureVars == null) {
+ _closureVars = new ArrayList();
+ }
+
+ // Only one reference per variable
+ if (!_closureVars.contains(variableRef)) {
+ _closureVars.add(variableRef);
+ }
+ }
+
+ // -- End Closure interface ----------------------
+
+ public void parseContents(Parser parser) {
final int count = _attributes.getLength();
for (int i = 0; i < count; i++) {
@@ -253,12 +299,11 @@
}
/**
- * Compiles a constructor for the class <tt>className</tt> that
+ * Compiles a constructor for the class <tt>_className</tt> that
* inherits from {Any,Single,Multiple}NodeCounter. This constructor
* simply calls the same constructor in the super class.
*/
- private void compileConstructor(ClassGenerator classGen,
- String className) {
+ private void compileConstructor(ClassGenerator classGen) {
MethodGenerator cons;
final InstructionList il = new InstructionList();
final ConstantPoolGen cpg = classGen.getConstantPool();
@@ -275,7 +320,7 @@
"translet",
"iterator"
},
- "<init>", className, il, cpg);
+ "<init>", _className, il, cpg);
il.append(ALOAD_0); // this
il.append(ALOAD_1); // translet
@@ -303,13 +348,11 @@
*/
private void compileLocals(NodeCounterGenerator nodeCounterGen,
MatchGenerator matchGen,
- InstructionList il) {
-
- ConstantPoolGen cpg = nodeCounterGen.getConstantPool();
- final String className = matchGen.getClassName();
-
- LocalVariableGen local;
+ InstructionList il)
+ {
int field;
+ LocalVariableGen local;
+ ConstantPoolGen cpg = nodeCounterGen.getConstantPool();
// Get NodeCounter._iterator and store locally
local = matchGen.addLocalVariable("iterator",
@@ -338,7 +381,7 @@
local = matchGen.addLocalVariable("document",
Util.getJCRefType(DOM_INTF_SIG),
null, null);
- field = cpg.addFieldref(className, "_document", DOM_INTF_SIG);
+ field = cpg.addFieldref(_className, "_document", DOM_INTF_SIG);
il.append(ALOAD_0); // 'this' pointer on stack
il.append(new GETFIELD(field));
// Make sure we have the correct DOM type on the stack!!!
@@ -347,16 +390,16 @@
}
private void compilePatterns(ClassGenerator classGen,
- MethodGenerator methodGen) {
- //!!! local variables?
+ MethodGenerator methodGen)
+ {
int current;
int field;
LocalVariableGen local;
MatchGenerator matchGen;
NodeCounterGenerator nodeCounterGen;
- final String className = getXSLTC().getHelperClassName();
- nodeCounterGen = new NodeCounterGenerator(className,
+ _className = getXSLTC().getHelperClassName();
+ nodeCounterGen = new NodeCounterGenerator(_className,
ClassNames[_level],
toString(),
ACC_PUBLIC | ACC_SUPER,
@@ -365,8 +408,22 @@
InstructionList il = null;
ConstantPoolGen cpg = nodeCounterGen.getConstantPool();
+ // Add a new instance variable for each var in closure
+ final int closureLen = (_closureVars == null) ? 0 :
+ _closureVars.size();
+
+ for (int i = 0; i < closureLen; i++) {
+ VariableBase var =
+ ((VariableRefBase) _closureVars.get(i)).getVariable();
+
+ nodeCounterGen.addField(new Field(ACC_PUBLIC,
+ cpg.addUtf8(var.getVariable()),
+
cpg.addUtf8(var.getType().toSignature()),
+ null, cpg.getConstantPool()));
+ }
+
// Add a single constructor to the class
- compileConstructor(nodeCounterGen, className);
+ compileConstructor(nodeCounterGen);
/*
* Compile method matchesFrom()
@@ -382,7 +439,7 @@
new String[] {
"node",
},
- "matchesFrom", className, il, cpg);
+ "matchesFrom", _className, il, cpg);
compileLocals(nodeCounterGen,matchGen,il);
@@ -412,7 +469,7 @@
new String[] {
"node",
},
- "matchesCount", className, il, cpg);
+ "matchesCount", _className, il, cpg);
compileLocals(nodeCounterGen,matchGen,il);
@@ -436,17 +493,31 @@
cpg = classGen.getConstantPool();
il = methodGen.getInstructionList();
- final int index = cpg.addMethodref(className, "<init>",
+ final int index = cpg.addMethodref(_className, "<init>",
"(" + TRANSLET_INTF_SIG
+ DOM_INTF_SIG
+ NODE_ITERATOR_SIG
+ ")V");
- il.append(new NEW(cpg.addClass(className)));
+ il.append(new NEW(cpg.addClass(_className)));
il.append(DUP);
il.append(classGen.loadTranslet());
il.append(methodGen.loadDOM());
il.append(methodGen.loadIterator());
il.append(new INVOKESPECIAL(index));
+
+ // Initialize closure variables
+ for (int i = 0; i < closureLen; i++) {
+ final VariableRefBase varRef = (VariableRefBase)
_closureVars.get(i);
+ final VariableBase var = varRef.getVariable();
+ final Type varType = var.getType();
+
+ // Store variable in new closure
+ il.append(DUP);
+ il.append(var.loadInstruction());
+ il.append(new PUTFIELD(
+ cpg.addFieldref(_className, var.getVariable(),
+ varType.toSignature())));
+ }
}
public void translate(ClassGenerator classGen, MethodGenerator
methodGen) {
1.16.2.1.2.1 +21 -6
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Output.java
Index: Output.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Output.java,v
retrieving revision 1.16.2.1
retrieving revision 1.16.2.1.2.1
diff -u -r1.16.2.1 -r1.16.2.1.2.1
--- Output.java 14 Aug 2002 19:21:33 -0000 1.16.2.1
+++ Output.java 2 Dec 2002 15:51:17 -0000 1.16.2.1.2.1
@@ -75,6 +75,7 @@
import org.apache.bcel.classfile.JavaClass;
import org.apache.xalan.xsltc.compiler.util.*;
+import org.apache.xalan.xsltc.runtime.output.StreamOutput;
final class Output extends TopLevelElement {
@@ -92,6 +93,7 @@
private String _cdata;
private boolean _indent = false;
private String _mediaType;
+ private String _cdataToMerge;
// Disables this output element (when other element has higher
precedence)
private boolean _disabled = false;
@@ -122,6 +124,14 @@
return !_disabled;
}
+ public String getCdata() {
+ return _cdata;
+ }
+
+ public void mergeCdata(String cdata) {
+ _cdataToMerge = cdata;
+ }
+
/**
* Scans the attribute list for the xsl:output instruction
*/
@@ -162,8 +172,10 @@
}
else {
try {
+ // Create a write to verify encoding support
OutputStreamWriter writer =
- new OutputStreamWriter(System.out, _encoding);
+ new OutputStreamWriter(System.out,
+ StreamOutput.getCanonicalEncoding(_encoding));
}
catch (java.io.UnsupportedEncodingException e) {
ErrorMsg msg = new ErrorMsg(ErrorMsg.UNSUPPORTED_ENCODING,
@@ -220,12 +232,15 @@
// Make sure to store names in expanded form
while (tokens.hasMoreTokens()) {
-
expandedNames.append(parser.getQName(tokens.nextToken()).toString())
- .append(' ');
+ expandedNames.append(
+ parser.getQName(tokens.nextToken()).toString()).append(' ');
}
_cdata = expandedNames.toString();
-
- outputProperties.setProperty(OutputKeys.CDATA_SECTION_ELEMENTS,
_cdata);
+ if (_cdataToMerge != null) {
+ _cdata = _cdata + _cdataToMerge;
+ }
+ outputProperties.setProperty(OutputKeys.CDATA_SECTION_ELEMENTS,
+ _cdata);
}
// Get the indent setting - only has effect for xml and html output
1.19.8.1.2.1 +1 -4
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Param.java
Index: Param.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Param.java,v
retrieving revision 1.19.8.1
retrieving revision 1.19.8.1.2.1
diff -u -r1.19.8.1 -r1.19.8.1.2.1
--- Param.java 14 Aug 2002 19:21:33 -0000 1.19.8.1
+++ Param.java 2 Dec 2002 15:51:17 -0000 1.19.8.1.2.1
@@ -149,15 +149,12 @@
* element has a body and no 'select' expression.
*/
public Type typeCheck(SymbolTable stable) throws TypeCheckError {
-
- // Get the type from the select exrepssion...
if (_select != null) {
_type = _select.typeCheck(stable);
if (_type instanceof ReferenceType == false) {
_select = new CastExpr(_select, Type.Reference);
}
}
- // ...or set the type to result tree
else if (hasContents()) {
typeCheckContents(stable);
}
1.11.2.1.2.1 +25 -16
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ParameterRef.java
Index: ParameterRef.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ParameterRef.java,v
retrieving revision 1.11.2.1
retrieving revision 1.11.2.1.2.1
diff -u -r1.11.2.1 -r1.11.2.1.2.1
--- ParameterRef.java 14 Aug 2002 19:21:33 -0000 1.11.2.1
+++ ParameterRef.java 2 Dec 2002 15:51:17 -0000 1.11.2.1.2.1
@@ -79,21 +79,31 @@
return "parameter-ref("+_variable.getName()+'/'+_variable.getType()+')';
}
- public void translate(ClassGenerator classGen, MethodGenerator
methodGen) {
+ public void translate(ClassGenerator classGen, MethodGenerator methodGen)
{
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
final String name = _variable.getVariable();
+ final String signature = _type.toSignature();
if (_variable.isLocal()) {
if (classGen.isExternal()) {
- il.append(classGen.loadTranslet());
- il.append(new PUSH(cpg, name));
- final int index = cpg.addMethodref(TRANSLET_CLASS,
- GET_PARAMETER,
- GET_PARAMETER_SIG);
- il.append(new INVOKEVIRTUAL(index));
- _type.translateUnBox(classGen, methodGen);
+ Closure variableClosure = _closure;
+ while (variableClosure != null) {
+ if (variableClosure.inInnerClass()) break;
+ variableClosure = variableClosure.getParentClosure();
+ }
+
+ if (variableClosure != null) {
+ il.append(ALOAD_0);
+ il.append(new GETFIELD(
+ cpg.addFieldref(variableClosure.getInnerClassName(),
+ name, signature)));
+ }
+ else {
+ il.append(_variable.loadInstruction());
+ _variable.removeReference(this);
+ }
}
else {
il.append(_variable.loadInstruction());
@@ -101,10 +111,8 @@
}
}
else {
- final String signature = _type.toSignature();
final String className = classGen.getClassName();
il.append(classGen.loadTranslet());
- // If inside a predicate we must cast this ref down
if (classGen.isExternal()) {
il.append(new CHECKCAST(cpg.addClass(className)));
}
@@ -112,11 +120,12 @@
}
if (_variable.getType() instanceof NodeSetType) {
- final int reset = cpg.addInterfaceMethodref(NODE_ITERATOR,
- "reset",
- "()"+NODE_ITERATOR_SIG);
- il.append(new INVOKEINTERFACE(reset,1));
+ // The method cloneIterator() also does resetting
+ final int clone = cpg.addInterfaceMethodref(NODE_ITERATOR,
+ "cloneIterator",
+ "()" +
+ NODE_ITERATOR_SIG);
+ il.append(new INVOKEINTERFACE(clone, 1));
}
-
}
}
1.19.2.1.2.1 +1 -2
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ParentLocationPath.java
Index: ParentLocationPath.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ParentLocationPath.java,v
retrieving revision 1.19.2.1
retrieving revision 1.19.2.1.2.1
diff -u -r1.19.2.1 -r1.19.2.1.2.1
--- ParentLocationPath.java 14 Aug 2002 19:21:33 -0000 1.19.2.1
+++ ParentLocationPath.java 2 Dec 2002 15:51:17 -0000 1.19.2.1.2.1
@@ -221,7 +221,6 @@
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(NODE_ITERATOR_BASE,
"includeSelf",
1.51.2.1.2.1 +17 -6
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Parser.java
Index: Parser.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Parser.java,v
retrieving revision 1.51.2.1
retrieving revision 1.51.2.1.2.1
diff -u -r1.51.2.1 -r1.51.2.1.2.1
--- Parser.java 14 Aug 2002 19:21:33 -0000 1.51.2.1
+++ Parser.java 2 Dec 2002 15:51:17 -0000 1.51.2.1.2.1
@@ -154,6 +154,8 @@
public void setOutput(Output output) {
if (_output != null) {
if (_output.getImportPrecedence() <= output.getImportPrecedence()) {
+ String cdata = _output.getCdata();
+ output.mergeCdata(cdata);
_output.disable();
_output = output;
}
@@ -719,6 +721,7 @@
private void initExtClasses() {
initExtClass("output", "TransletOutput");
+ initExtClass(REDIRECT_URI, "write", "TransletOutput");
}
private void initExtClass(String elementName, String className) {
@@ -726,6 +729,11 @@
COMPILER_PACKAGE + '.' + className);
}
+ private void initExtClass(String namespace, String elementName, String
className) {
+ _instructionClasses.put(getQName(namespace, TRANSLET, elementName),
+ COMPILER_PACKAGE + '.' + className);
+ }
+
/**
* Add primops and base functions to the symbol table.
*/
@@ -740,7 +748,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);
@@ -755,7 +762,7 @@
MethodType B_V = new MethodType(Type.Boolean, Type.Void);
MethodType B_B = new MethodType(Type.Boolean, Type.Boolean);
MethodType B_S = new MethodType(Type.Boolean, Type.String);
- MethodType D_T = new MethodType(Type.NodeSet, Type.ResultTree);
+ MethodType D_X = new MethodType(Type.NodeSet, Type.Object);
MethodType R_RR = new MethodType(Type.Real, Type.Real, Type.Real);
MethodType I_II = new MethodType(Type.Int, Type.Int, Type.Int);
MethodType B_RR = new MethodType(Type.Boolean, Type.Real, Type.Real);
@@ -841,7 +848,8 @@
_symbolTable.addPrimop("system-property", S_S);
// Extensions
- _symbolTable.addPrimop("nodeset", D_T);
+ _symbolTable.addPrimop("nodeset", D_O);
+ _symbolTable.addPrimop("objectType", S_O);
// Operators +, -, *, /, % defined on real types.
_symbolTable.addPrimop("+", R_RR);
@@ -881,7 +889,6 @@
// Unary minus.
_symbolTable.addPrimop("u-", R_R);
_symbolTable.addPrimop("u-", I_I);
- _symbolTable.addPrimop("u-", J_J); // GTM,bug 3592
}
public SymbolTable getSymbolTable() {
@@ -1010,7 +1017,10 @@
versionIsOne = attrs.getValue(i).equals("1.0");
}
- if (attrQName.startsWith("xml")) continue;
+ // Ignore if special or if it has a prefix
+ if (attrQName.startsWith("xml") ||
+ attrQName.indexOf(':') > 0) continue;
+
for (j = 0; j < legal.length; j++) {
if (attrQName.equalsIgnoreCase(legal[j])) {
break;
@@ -1095,6 +1105,7 @@
node.setParser(this);
node.setParent(parent);
node.setLineNumber(line);
+// System.out.println("e = " + text + " " + node);
return node;
}
}
1.8.8.1.2.1 +7 -44
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/PositionCall.java
Index: PositionCall.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/PositionCall.java,v
retrieving revision 1.8.8.1
retrieving revision 1.8.8.1.2.1
diff -u -r1.8.8.1 -r1.8.8.1.2.1
--- PositionCall.java 14 Aug 2002 19:21:33 -0000 1.8.8.1
+++ PositionCall.java 2 Dec 2002 15:51:17 -0000 1.8.8.1.2.1
@@ -71,68 +71,31 @@
final class PositionCall extends FunctionCall {
- private int _type = -1;
-
public PositionCall(QName fname) {
super(fname);
}
- public PositionCall(QName fname, int type) {
- this(fname);
- _type = type;
- }
-
public boolean hasPositionCall() {
return true;
}
public void translate(ClassGenerator classGen, MethodGenerator
methodGen) {
-
final InstructionList il = methodGen.getInstructionList();
- SyntaxTreeNode parent = getParent();
- SyntaxTreeNode granny = parent.getParent();
-
- // If we're a part of an expression's predicate we want to know what
- // type of node we want to be looking for
- if ((parent instanceof Expression) && (granny instanceof Predicate)) {
- _type = ((Predicate)granny).getPosType();
- }
- else {
- while ((granny != null) && !(granny instanceof StepPattern)) {
- parent = granny;
- granny = granny.getParent();
- }
- if ((parent instanceof Predicate) &&
- (granny instanceof StepPattern)){
- _type = ((StepPattern)granny).getNodeType();
- }
- }
-
if (methodGen instanceof CompareGenerator) {
il.append(((CompareGenerator)methodGen).loadCurrentNode());
}
else if (methodGen instanceof TestGenerator) {
il.append(new ILOAD(POSITION_INDEX));
}
- else if (_type == -1) {
- final ConstantPoolGen cpg = classGen.getConstantPool();
- final int getPosition = cpg.addInterfaceMethodref(NODE_ITERATOR,
- "getPosition",
- "()I");
- il.append(methodGen.loadIterator());
- il.append(new INVOKEINTERFACE(getPosition, 1));
- }
else {
final ConstantPoolGen cpg = classGen.getConstantPool();
- // public int getTypedPosition(int type, int node)
- final int pos = cpg.addInterfaceMethodref(DOM_INTF,
- "getTypedPosition",
- "(II)I");
- il.append(methodGen.loadDOM());
- il.append(new PUSH(cpg, _type));
- il.append(methodGen.loadContextNode());
- il.append(new INVOKEINTERFACE(pos, 3));
+ final int index =
+ cpg.addMethodref(BASIS_LIBRARY_CLASS, "positionF",
+ "("+NODE_ITERATOR_SIG+")I");
+
+ il.append(methodGen.loadIterator());
+ il.append(new INVOKESTATIC(index));
}
}
}
1.1.16.1.2.1 +1 -1
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/PositionCall.java.inuse
Index: PositionCall.java.inuse
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/PositionCall.java.inuse,v
retrieving revision 1.1.16.1
retrieving revision 1.1.16.1.2.1
diff -u -r1.1.16.1 -r1.1.16.1.2.1
1.24.2.1.2.1 +123 -16
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Predicate.java
Index: Predicate.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Predicate.java,v
retrieving revision 1.24.2.1
retrieving revision 1.24.2.1.2.1
diff -u -r1.24.2.1 -r1.24.2.1.2.1
--- Predicate.java 14 Aug 2002 19:21:33 -0000 1.24.2.1
+++ Predicate.java 2 Dec 2002 15:51:17 -0000 1.24.2.1.2.1
@@ -65,22 +65,27 @@
package org.apache.xalan.xsltc.compiler;
import java.util.Vector;
+import java.util.ArrayList;
import org.apache.bcel.classfile.JavaClass;
import org.apache.xalan.xsltc.compiler.util.Type;
import org.apache.xalan.xsltc.compiler.util.ReferenceType;
import org.apache.bcel.generic.*;
import org.apache.xalan.xsltc.compiler.util.*;
+import org.apache.bcel.classfile.Field;
-final class Predicate extends Expression {
+final class Predicate extends Expression implements Closure {
private Expression _exp = null; // Expression to be compiled inside pred.
- private String _className; // Name of filter to generate
private boolean _nthPositionFilter = false;
private boolean _nthDescendant = false;
private boolean _canOptimize = true;
private int _ptype = -1;
+ private String _className = null;
+ private ArrayList _closureVars = null;
+ private Closure _parentClosure = null;
+
public Predicate(Expression exp) {
(_exp = exp).setParent(this);
}
@@ -102,10 +107,66 @@
_canOptimize = false;
}
- protected final boolean isClosureBoundary() {
- return true;
+ // -- Begin Closure interface --------------------
+
+ /**
+ * Returns true if this closure is compiled in an inner class (i.e.
+ * if this is a real closure).
+ */
+ public boolean inInnerClass() {
+ return (_className != null);
+ }
+
+ /**
+ * Returns a reference to its parent closure or null if outermost.
+ */
+ public Closure getParentClosure() {
+ if (_parentClosure == null) {
+ SyntaxTreeNode node = getParent();
+ do {
+ if (node instanceof Closure) {
+ _parentClosure = (Closure) node;
+ break;
+ }
+ if (node instanceof TopLevelElement) {
+ break; // way up in the tree
+ }
+ node = node.getParent();
+ } while (node != null);
+ }
+ return _parentClosure;
}
-
+
+ /**
+ * Returns the name of the auxiliary class or null if this predicate
+ * is compiled inside the Translet.
+ */
+ public String getInnerClassName() {
+ return _className;
+ }
+
+ /**
+ * Add new variable to the closure.
+ */
+ public void addVariable(VariableRefBase variableRef) {
+ if (_closureVars == null) {
+ _closureVars = new ArrayList();
+ }
+
+ // Only one reference per variable
+ if (!_closureVars.contains(variableRef)) {
+ _closureVars.add(variableRef);
+
+ // Add variable to parent closure as well
+ Closure parentClosure = getParentClosure();
+ if (parentClosure != null) {
+ parentClosure.addVariable(variableRef);
+ }
+ }
+ }
+
+ // -- End Closure interface ----------------------
+
public int getPosType() {
if (_ptype == -1) {
SyntaxTreeNode parent = getParent();
@@ -189,7 +250,7 @@
(parent instanceof Pattern) ||
(parent instanceof FilterExpr)) {
- final QName position = getParser().getQName("position");
+ final QName position =
getParser().getQNameIgnoreDefaultNs("position");
final PositionCall positionCall = new PositionCall(position);
positionCall.setParser(getParser());
positionCall.setParent(this);
@@ -208,8 +269,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)
@@ -273,9 +334,20 @@
},
classGen.getStylesheet());
- final InstructionList il = new InstructionList();
final ConstantPoolGen cpg = filterGen.getConstantPool();
+ final int length = (_closureVars == null) ? 0 : _closureVars.size();
+ // Add a new instance variable for each var in closure
+ for (int i = 0; i < length; i++) {
+ VariableBase var = ((VariableRefBase)
_closureVars.get(i)).getVariable();
+
+ filterGen.addField(new Field(ACC_PUBLIC,
+ cpg.addUtf8(var.getVariable()),
+
cpg.addUtf8(var.getType().toSignature()),
+ null, cpg.getConstantPool()));
+ }
+
+ final InstructionList il = new InstructionList();
testGen = new TestGenerator(ACC_PUBLIC | ACC_FINAL,
org.apache.bcel.generic.Type.BOOLEAN,
new org.apache.bcel.generic.Type[] {
@@ -339,10 +411,7 @@
*/
public boolean isNodeValueTest() {
if (!_canOptimize) return false;
- if ((getStep() != null) && (getCompareValue() != null))
- return true;
- else
- return false;
+ return (getStep() != null && getCompareValue() != null);
}
private Expression _value = null;
@@ -439,15 +508,53 @@
* filter object and a reference to the predicate's closure.
*/
public void translateFilter(ClassGenerator classGen,
- MethodGenerator methodGen) {
-
+ MethodGenerator methodGen)
+ {
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
+ // Compile auxiliary class for filter
compileFilter(classGen, methodGen);
+
+ // Create new instance of filter
il.append(new NEW(cpg.addClass(_className)));
il.append(DUP);
il.append(new INVOKESPECIAL(cpg.addMethodref(_className,
"<init>", "()V")));
+
+ // Initialize closure variables
+ final int length = (_closureVars == null) ? 0 : _closureVars.size();
+
+ for (int i = 0; i < length; i++) {
+ VariableRefBase varRef = (VariableRefBase) _closureVars.get(i);
+ VariableBase var = varRef.getVariable();
+ Type varType = var.getType();
+
+ il.append(DUP);
+
+ // Find nearest closure implemented as an inner class
+ Closure variableClosure = _parentClosure;
+ while (variableClosure != null) {
+ if (variableClosure.inInnerClass()) break;
+ variableClosure = variableClosure.getParentClosure();
+ }
+
+ // Use getfield if in an inner class
+ if (variableClosure != null) {
+ il.append(ALOAD_0);
+ il.append(new GETFIELD(
+ cpg.addFieldref(variableClosure.getInnerClassName(),
+ var.getVariable(), varType.toSignature())));
+ }
+ else {
+ // Use a load of instruction if in translet class
+ il.append(var.loadInstruction());
+ }
+
+ // Store variable in new closure
+ il.append(new PUTFIELD(
+ cpg.addFieldref(_className, var.getVariable(),
+ varType.toSignature())));
+ }
}
}
1.12.8.1.2.1 +5 -4
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/RelationalExpr.java
Index: RelationalExpr.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/RelationalExpr.java,v
retrieving revision 1.12.8.1
retrieving revision 1.12.8.1.2.1
diff -u -r1.12.8.1 -r1.12.8.1.2.1
--- RelationalExpr.java 14 Aug 2002 19:21:33 -0000 1.12.8.1
+++ RelationalExpr.java 2 Dec 2002 15:51:17 -0000 1.12.8.1.2.1
@@ -171,11 +171,14 @@
if (tright instanceof NodeType) {
_right = new CastExpr(_right, Type.NodeSet);
}
-
// Promote integer to doubles to have fewer compares
if (tright instanceof IntType) {
_right = new CastExpr(_right, Type.Real);
}
+ // Promote result-trees to strings
+ if (tright instanceof ResultTreeType) {
+ _right = new CastExpr(_right, Type.String);
+ }
return _type = Type.Boolean;
}
@@ -222,7 +225,6 @@
_right.startResetIterator(classGen, methodGen);
il.append(new PUSH(cpg, _op));
- il.append(methodGen.loadContextNode());
il.append(methodGen.loadDOM());
int index = cpg.addMethodref(BASIS_LIBRARY_CLASS, "compare",
@@ -230,7 +232,6 @@
+ _left.getType().toSignature()
+ _right.getType().toSignature()
+ "I"
- + NODE_SIG
+ DOM_INTF_SIG
+ ")Z");
il.append(new INVOKESTATIC(index));
1.15.2.1.2.1 +277 -31
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Sort.java
Index: Sort.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Sort.java,v
retrieving revision 1.15.2.1
retrieving revision 1.15.2.1.2.1
diff -u -r1.15.2.1 -r1.15.2.1.2.1
--- Sort.java 14 Aug 2002 19:21:33 -0000 1.15.2.1
+++ Sort.java 2 Dec 2002 15:51:17 -0000 1.15.2.1.2.1
@@ -65,6 +65,7 @@
package org.apache.xalan.xsltc.compiler;
import java.util.Vector;
+import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.NoSuchElementException;
import java.text.Collator;
@@ -82,7 +83,7 @@
import org.apache.xalan.xsltc.compiler.util.*;
-final class Sort extends Instruction {
+final class Sort extends Instruction implements Closure {
private Expression _select;
private AttributeValue _order;
@@ -93,6 +94,56 @@
public String _lang;
public String _country;
+ private String _className = null;
+ private ArrayList _closureVars = null;
+ private boolean _needsSortRecordFactory = false;
+
+ // -- Begin Closure interface --------------------
+
+ /**
+ * Returns true if this closure is compiled in an inner class (i.e.
+ * if this is a real closure).
+ */
+ public boolean inInnerClass() {
+ return (_className != null);
+ }
+
+ /**
+ * Returns a reference to its parent closure or null if outermost.
+ */
+ public Closure getParentClosure() {
+ return null;
+ }
+
+ /**
+ * Returns the name of the auxiliary class or null if this predicate
+ * is compiled inside the Translet.
+ */
+ public String getInnerClassName() {
+ return _className;
+ }
+
+ /**
+ * Add new variable to the closure.
+ */
+ public void addVariable(VariableRefBase variableRef) {
+ if (_closureVars == null) {
+ _closureVars = new ArrayList();
+ }
+
+ // Only one reference per variable
+ if (!_closureVars.contains(variableRef)) {
+ _closureVars.add(variableRef);
+ _needsSortRecordFactory = true;
+ }
+ }
+
+ // -- End Closure interface ----------------------
+
+ private void setInnerClassName(String className) {
+ _className = className;
+ }
+
/**
* Parse the attributes of the xsl:sort element
*/
@@ -202,9 +253,10 @@
* and a node sort record producing objects as its parameters.
*/
public static void translateSortIterator(ClassGenerator classGen,
- MethodGenerator methodGen,
- Expression nodeSet,
- Vector sortObjects) {
+ MethodGenerator methodGen,
+ Expression nodeSet,
+ Vector sortObjects)
+ {
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
@@ -244,36 +296,38 @@
* will produce NodeSortRecord objects of a specific type.
*/
public static void compileSortRecordFactory(Vector sortObjects,
- ClassGenerator classGen,
- MethodGenerator methodGen) {
+ ClassGenerator classGen, MethodGenerator methodGen)
+ {
+ String sortRecordClass =
+ compileSortRecord(sortObjects, classGen, methodGen);
+
+ boolean needsSortRecordFactory = false;
+ final int nsorts = sortObjects.size();
+ for (int i = 0; i < nsorts; i++) {
+ final Sort sort = (Sort) sortObjects.elementAt(i);
+ needsSortRecordFactory |= sort._needsSortRecordFactory;
+ }
+
+ String sortRecordFactoryClass = NODE_SORT_FACTORY;
+ if (needsSortRecordFactory) {
+ sortRecordFactoryClass =
+ compileSortRecordFactory(sortObjects, classGen, methodGen,
+ sortRecordClass);
+ }
+
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
- // NodeSortRecordFactory.NodeSortRecordFactory(dom,class,levels,trlet);
- final String initParams =
- "("+DOM_INTF_SIG+STRING_SIG+TRANSLET_INTF_SIG+
- "["+STRING_SIG+"["+STRING_SIG+")V";
- final int init = cpg.addMethodref(NODE_SORT_FACTORY,
- "<init>", initParams);
-
- // Compile the object that will encapsulate each sort object (node).
- // NodeSortRecordFactory needs the name of the new class.
- String className = compileSortRecord(sortObjects, classGen, methodGen);
-
- // The constructor for the NodeSortRecord generating class takes no
- // parameters so we must to pass initialization params to other methods
- il.append(new NEW(cpg.addClass(NODE_SORT_FACTORY)));
+ il.append(new NEW(cpg.addClass(sortRecordFactoryClass)));
il.append(DUP);
il.append(methodGen.loadDOM());
- il.append(new PUSH(cpg, className));
+ il.append(new PUSH(cpg, sortRecordClass));
il.append(classGen.loadTranslet());
- // Compile code that initializes the static _compareType array
- final int levels = sortObjects.size();
// Compile code that initializes the static _sortOrder
- il.append(new PUSH(cpg, levels));
+ il.append(new PUSH(cpg, nsorts));
il.append(new ANEWARRAY(cpg.addClass(STRING)));
- for (int level = 0; level < levels; level++) {
+ for (int level = 0; level < nsorts; level++) {
final Sort sort = (Sort)sortObjects.elementAt(level);
il.append(DUP);
il.append(new PUSH(cpg, level));
@@ -281,9 +335,9 @@
il.append(AASTORE);
}
- il.append(new PUSH(cpg,levels));
+ il.append(new PUSH(cpg, nsorts));
il.append(new ANEWARRAY(cpg.addClass(STRING)));
- for (int level = 0; level < levels; level++) {
+ for (int level = 0; level < nsorts; level++) {
final Sort sort = (Sort)sortObjects.elementAt(level);
il.append(DUP);
il.append(new PUSH(cpg, level));
@@ -291,7 +345,172 @@
il.append(AASTORE);
}
- il.append(new INVOKESPECIAL(init));
+ il.append(new INVOKESPECIAL(
+ cpg.addMethodref(sortRecordFactoryClass, "<init>",
+ "(" + DOM_INTF_SIG
+ + STRING_SIG
+ + TRANSLET_INTF_SIG
+ + "[" + STRING_SIG
+ + "[" + STRING_SIG + ")V")));
+
+ // Initialize closure variables in sortRecordFactory
+ final ArrayList dups = new ArrayList();
+
+ for (int j = 0; j < nsorts; j++) {
+ final Sort sort = (Sort) sortObjects.get(j);
+ final int length = (sort._closureVars == null) ? 0 :
+ sort._closureVars.size();
+
+ for (int i = 0; i < length; i++) {
+ VariableRefBase varRef = (VariableRefBase)
sort._closureVars.get(i);
+
+ // Discard duplicate variable references
+ if (dups.contains(varRef)) continue;
+
+ final VariableBase var = varRef.getVariable();
+
+ // Store variable in new closure
+ il.append(DUP);
+ il.append(var.loadInstruction());
+ il.append(new PUTFIELD(
+ cpg.addFieldref(sortRecordFactoryClass,
var.getVariable(),
+ var.getType().toSignature())));
+ dups.add(varRef);
+ }
+ }
+ }
+
+ public static String compileSortRecordFactory(Vector sortObjects,
+ ClassGenerator classGen, MethodGenerator methodGen,
+ String sortRecordClass)
+ {
+ final XSLTC xsltc = ((Sort)sortObjects.firstElement()).getXSLTC();
+ final String className = xsltc.getHelperClassName();
+
+ final NodeSortRecordFactGenerator sortRecordFactory =
+ new NodeSortRecordFactGenerator(className,
+ NODE_SORT_FACTORY,
+ className + ".java",
+ ACC_PUBLIC | ACC_SUPER | ACC_FINAL,
+ new String[] {},
+ classGen.getStylesheet());
+
+ ConstantPoolGen cpg = sortRecordFactory.getConstantPool();
+
+ // Add a new instance variable for each var in closure
+ final int nsorts = sortObjects.size();
+ final ArrayList dups = new ArrayList();
+
+ for (int j = 0; j < nsorts; j++) {
+ final Sort sort = (Sort) sortObjects.get(j);
+ final int length = (sort._closureVars == null) ? 0 :
+ sort._closureVars.size();
+
+ for (int i = 0; i < length; i++) {
+ final VariableRef varRef = (VariableRef)
sort._closureVars.get(i);
+
+ // Discard duplicate variable references
+ if (dups.contains(varRef)) continue;
+
+ final VariableBase var = varRef.getVariable();
+ sortRecordFactory.addField(new Field(ACC_PUBLIC,
+ cpg.addUtf8(var.getVariable()),
+
cpg.addUtf8(var.getType().toSignature()),
+ null, cpg.getConstantPool()));
+ dups.add(varRef);
+ }
+ }
+
+ // Define a constructor for this class
+ final org.apache.bcel.generic.Type[] argTypes =
+ new org.apache.bcel.generic.Type[5];
+ argTypes[0] = Util.getJCRefType(DOM_INTF_SIG);
+ argTypes[1] = Util.getJCRefType(STRING_SIG);
+ argTypes[2] = Util.getJCRefType(TRANSLET_INTF_SIG);
+ argTypes[3] = Util.getJCRefType("[" + STRING_SIG);
+ argTypes[4] = Util.getJCRefType("[" + STRING_SIG);
+
+ final String[] argNames = new String[5];
+ argNames[0] = DOCUMENT_PNAME;
+ argNames[1] = "className";
+ argNames[2] = TRANSLET_PNAME;
+ argNames[3] = "order";
+ argNames[4] = "type";
+
+ InstructionList il = new InstructionList();
+ final MethodGenerator constructor =
+ new MethodGenerator(ACC_PUBLIC,
+ org.apache.bcel.generic.Type.VOID,
+ argTypes, argNames, "<init>",
+ className, il, cpg);
+
+ // Push all parameters onto the stack and called super.<init>()
+ il.append(ALOAD_0);
+ il.append(ALOAD_1);
+ il.append(ALOAD_2);
+ il.append(new ALOAD(3));
+ il.append(new ALOAD(4));
+ il.append(new ALOAD(5));
+ il.append(new INVOKESPECIAL(cpg.addMethodref(NODE_SORT_FACTORY,
+ "<init>",
+ "(" + DOM_INTF_SIG
+ + STRING_SIG
+ + TRANSLET_INTF_SIG
+ + "[" + STRING_SIG
+ + "[" + STRING_SIG + ")V")));
+ il.append(RETURN);
+
+ // Override the definition of makeNodeSortRecord()
+ il = new InstructionList();
+ final MethodGenerator makeNodeSortRecord =
+ new MethodGenerator(ACC_PUBLIC,
+ Util.getJCRefType(NODE_SORT_RECORD_SIG),
+ new org.apache.bcel.generic.Type[] {
+ org.apache.bcel.generic.Type.INT,
+ org.apache.bcel.generic.Type.INT },
+ new String[] { "node", "last" }, "makeNodeSortRecord",
+ className, il, cpg);
+
+ il.append(ALOAD_0);
+ il.append(ILOAD_1);
+ il.append(ILOAD_2);
+ il.append(new INVOKESPECIAL(cpg.addMethodref(NODE_SORT_FACTORY,
+ "makeNodeSortRecord", "(II)" + NODE_SORT_RECORD_SIG)));
+ il.append(DUP);
+ il.append(new CHECKCAST(cpg.addClass(sortRecordClass)));
+
+ // Initialize closure in record class
+ final int ndups = dups.size();
+ for (int i = 0; i < ndups; i++) {
+ final VariableRef varRef = (VariableRef) dups.get(i);
+ final VariableBase var = varRef.getVariable();
+ final Type varType = var.getType();
+
+ il.append(DUP);
+
+ // Get field from factory class
+ il.append(ALOAD_0);
+ il.append(new GETFIELD(
+ cpg.addFieldref(className,
+ var.getVariable(), varType.toSignature())));
+
+ // Put field in record class
+ il.append(new PUTFIELD(
+ cpg.addFieldref(sortRecordClass,
+ var.getVariable(), varType.toSignature())));
+ }
+ il.append(POP);
+ il.append(ARETURN);
+
+ constructor.setMaxLocals();
+ constructor.setMaxStack();
+ sortRecordFactory.addMethod(constructor.getMethod());
+ makeNodeSortRecord.setMaxLocals();
+ makeNodeSortRecord.setMaxStack();
+ sortRecordFactory.addMethod(makeNodeSortRecord.getMethod());
+ xsltc.dumpClass(sortRecordFactory.getJavaClass());
+
+ return className;
}
/**
@@ -313,7 +532,34 @@
classGen.getStylesheet());
final ConstantPoolGen cpg = sortRecord.getConstantPool();
-
+
+ // Add a new instance variable for each var in closure
+ final int nsorts = sortObjects.size();
+ final ArrayList dups = new ArrayList();
+
+ for (int j = 0; j < nsorts; j++) {
+ final Sort sort = (Sort) sortObjects.get(j);
+
+ // Set the name of the inner class in this sort object
+ sort.setInnerClassName(className);
+
+ final int length = (sort._closureVars == null) ? 0 :
+ sort._closureVars.size();
+ for (int i = 0; i < length; i++) {
+ final VariableRef varRef = (VariableRef)
sort._closureVars.get(i);
+
+ // Discard duplicate variable references
+ if (dups.contains(varRef)) continue;
+
+ final VariableBase var = varRef.getVariable();
+ sortRecord.addField(new Field(ACC_PUBLIC,
+ cpg.addUtf8(var.getVariable()),
+ cpg.addUtf8(var.getType().toSignature()),
+ null, cpg.getConstantPool()));
+ dups.add(varRef);
+ }
+ }
+
Method clinit = compileClassInit(sortObjects, sortRecord,
cpg, className);
Method extract = compileExtract(sortObjects, sortRecord,
@@ -349,7 +595,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[] { },
1.37.2.1.2.1 +35 -95
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Step.java
Index: Step.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Step.java,v
retrieving revision 1.37.2.1
retrieving revision 1.37.2.1.2.1
diff -u -r1.37.2.1 -r1.37.2.1.2.1
--- Step.java 14 Aug 2002 19:21:33 -0000 1.37.2.1
+++ Step.java 2 Dec 2002 15:51:18 -0000 1.37.2.1.2.1
@@ -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.
- private int _nodeType;
-
/**
- * Constructor
+ * Type of the node test.
*/
+ private int _nodeType;
+
public Step(int axis, int nodeType, Vector predicates) {
_axis = axis;
_nodeType = nodeType;
@@ -144,10 +149,12 @@
* Returns the vector containing all predicates for this step.
*/
public void addPredicates(Vector predicates) {
- if (_predicates == null)
+ if (_predicates == null) {
_predicates = predicates;
- else
+ }
+ else {
_predicates.addAll(predicates);
+ }
}
/**
@@ -156,16 +163,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
@@ -212,16 +215,12 @@
// combinations of steps and patterns than can be optimised
_hadPredicates = hasPredicates();
- // Special case for '.'
+ // Special case for '.'
+ // in the case where '.' has a context such as book/.
+ // or .[false()] we can not optimize the nodeset to a single node.
if (isAbbreviatedDot()) {
- if (hasParentPattern())
- _type = Type.NodeSet;
- else
- _type = Type.Node;
- }
- // Special case for '..'
- else if (isAbbreviatedDDot()) {
- _type = Type.NodeSet;
+ _type = (hasParentPattern() || hasPredicates() ) ?
+ Type.NodeSet : Type.Node;
}
else {
_type = Type.NodeSet;
@@ -241,45 +240,6 @@
}
/**
- * This method is used to determine whether the node-set produced by
- * this step must be reversed before returned to the parent element.
- * <xsl:apply-templates> should always return nodes in document order,
- * while others, such as <xsl:value-of> and <xsl:for-each> should return
- * nodes in the order of the axis in use.
- */
- private boolean reverseNodeSet() {
- // Check if axis returned nodes in reverse document order
- 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;
-
- // Check if this step occured under an <xsl:apply-templates> element
- SyntaxTreeNode parent = this;
- do {
- // Get the next ancestor element and check its type
- parent = parent.getParent();
-
- // Order node set if descendant of these elements:
- if (parent instanceof ApplyImports) return true;
- if (parent instanceof ApplyTemplates) return true;
- if (parent instanceof ForEach) return true;
- if (parent instanceof FilterParentPath) return true;
- if (parent instanceof WithParam) return true;
-
- // No not order node set if descendant of these elements:
- if (parent instanceof ValueOf) return false;
-
- } while (parent != null);
- }
- return false;
- }
-
- /**
* Translate a step by pushing the appropriate iterator onto the stack.
* The abbreviated steps '.' and '@attr' do not create new iterators
* if they are not part of a LocationPath and have no filters.
@@ -294,9 +254,11 @@
translatePredicates(classGen, methodGen);
}
else {
- // If it is an attribute but not '@*' or '@attr' with a parent
- if ((_axis == Axis.ATTRIBUTE) &&
- (_nodeType != NodeTest.ATTRIBUTE) && (!hasParentPattern())) {
+ // If it is an attribute but not '@*', '@attr' or '@node()' and
+ // has no parent
+ if (_axis == Axis.ATTRIBUTE && _nodeType != NodeTest.ATTRIBUTE &&
+ _nodeType != NodeTest.ANODE && !hasParentPattern())
+ {
int iter = cpg.addInterfaceMethodref(DOM_INTF,
"getTypedAxisIterator",
"(II)"+NODE_ITERATOR_SIG);
@@ -385,7 +347,7 @@
il.append(new PUSH(cpg, _axis));
il.append(new PUSH(cpg, _nodeType));
il.append(new INVOKEINTERFACE(ty, 3));
- orderIterator(classGen, methodGen);
+
break;
}
}
@@ -493,28 +455,6 @@
}
}
}
-
-
- /**
- * This method tests if this step needs to have its axis reversed,
- * and wraps its iterator inside a ReverseIterator to return the node-set
- * in document order.
- */
- public void orderIterator(ClassGenerator classGen,
- MethodGenerator methodGen) {
- // First test if nodes are in reverse document order
- if (!reverseNodeSet()) return;
-
- final ConstantPoolGen cpg = classGen.getConstantPool();
- final InstructionList il = methodGen.getInstructionList();
- final int init = cpg.addMethodref(REVERSE_ITERATOR, "<init>",
- "("+NODE_ITERATOR_SIG+")V");
- il.append(new NEW(cpg.addClass(REVERSE_ITERATOR)));
- il.append(DUP_X1);
- il.append(SWAP);
- il.append(new INVOKESPECIAL(init));
- }
-
/**
* Returns a string representation of this step.
1.17.2.1.2.1 +8 -2
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/StepPattern.java
Index: StepPattern.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/StepPattern.java,v
retrieving revision 1.17.2.1
retrieving revision 1.17.2.1.2.1
diff -u -r1.17.2.1 -r1.17.2.1.2.1
--- StepPattern.java 14 Aug 2002 19:21:33 -0000 1.17.2.1
+++ StepPattern.java 2 Dec 2002 15:51:18 -0000 1.17.2.1.2.1
@@ -142,6 +142,10 @@
}
}
+ public int getAxis() {
+ return _axis;
+ }
+
public void reduceKernelPattern() {
_isEpsilon = true;
}
@@ -150,7 +154,9 @@
final StringBuffer buffer = new StringBuffer("stepPattern(\"");
buffer.append(Axis.names[_axis])
.append("\", ")
- .append(_isEpsilon ? "epsilon" : Integer.toString(_nodeType));
+ .append(_isEpsilon ?
+ ("epsilon{" + Integer.toString(_nodeType) + "}") :
+ Integer.toString(_nodeType));
if (_predicates != null)
buffer.append(", ").append(_predicates.toString());
return buffer.append(')').toString();
1.43.2.1.2.1 +7 -19
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Stylesheet.java
Index: Stylesheet.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Stylesheet.java,v
retrieving revision 1.43.2.1
retrieving revision 1.43.2.1.2.1
diff -u -r1.43.2.1 -r1.43.2.1.2.1
--- Stylesheet.java 14 Aug 2002 19:21:33 -0000 1.43.2.1
+++ Stylesheet.java 2 Dec 2002 15:51:18 -0000 1.43.2.1.2.1
@@ -399,13 +399,12 @@
* Parse all direct children of the <xsl:stylesheet/> element.
*/
public final void parseOwnChildren(Parser parser) {
-
final Vector contents = getContents();
final int count = contents.size();
// We have to scan the stylesheet element's top-level elements for
- // variables and/or parameters before we parse the other elements...
- for (int i=0; i<count; i++) {
+ // variables and/or parameters before we parse the other elements
+ for (int i = 0; i < count; i++) {
SyntaxTreeNode child = (SyntaxTreeNode)contents.elementAt(i);
if ((child instanceof VariableBase) ||
(child instanceof NamespaceAlias)) {
@@ -414,22 +413,11 @@
}
}
- // Then we have to go through the included/imported stylesheets
- for (int i=0; i<count; i++) {
- SyntaxTreeNode child = (SyntaxTreeNode)contents.elementAt(i);
- if ((child instanceof Import) || (child instanceof Include)) {
- parser.getSymbolTable().setCurrentNode(child);
- child.parseContents(parser);
- }
- }
-
// Now go through all the other top-level elements...
- for (int i=0; i<count; i++) {
+ for (int i = 0; i < count; i++) {
SyntaxTreeNode child = (SyntaxTreeNode)contents.elementAt(i);
- if (!(child instanceof VariableBase) &&
- !(child instanceof NamespaceAlias) &&
- !(child instanceof Import) &&
- !(child instanceof Include)) {
+ if (!(child instanceof VariableBase) &&
+ !(child instanceof NamespaceAlias)) {
parser.getSymbolTable().setCurrentNode(child);
child.parseContents(parser);
}
@@ -438,7 +426,7 @@
// <xsl:apply-imports/> element was ever used in this stylesheet
if (!_templateInlining && (child instanceof Template)) {
Template template = (Template)child;
- String name = "template$dot$"+template.getPosition();
+ String name = "template$dot$" + template.getPosition();
template.setName(parser.getQName(name));
}
}
1.20.2.1.2.1 +4 -20
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/SyntaxTreeNode.java
Index: SyntaxTreeNode.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/SyntaxTreeNode.java,v
retrieving revision 1.20.2.1
retrieving revision 1.20.2.1.2.1
diff -u -r1.20.2.1 -r1.20.2.1.2.1
--- SyntaxTreeNode.java 14 Aug 2002 19:21:33 -0000 1.20.2.1
+++ SyntaxTreeNode.java 2 Dec 2002 15:51:18 -0000 1.20.2.1.2.1
@@ -406,23 +406,7 @@
* @return Symbol table.
*/
protected final SymbolTable getSymbolTable() {
- if (_parser != null)
- return _parser.getSymbolTable();
- else
- return null;
- }
-
- /**
- * Local variables that are accessible from a given syntax tree node will
- * be put on the JVM's stack. A closure is a record that contains a
pointer
- * to a node's outer variable frame (not only global variables, but also
- * variables in parent nodes). This method returns true if this node's
code
- * is implemented by code outside of ApplyTemplates (the only such case
is
- * the Predicates class). This methid is only called by the VariableRef).
- * @return 'true' if node's code is implemented outside of ApplyTemplates
- */
- protected boolean isClosureBoundary() {
- return false;
+ return (_parser == null) ? null : _parser.getSymbolTable();
}
/**
@@ -563,12 +547,12 @@
final String DOM_CLASS = classGen.getDOMClass();
- // Create new instance of DOM class (with 64 nodes)
+ // Create new instance of DOM class
int index = cpg.addMethodref(DOM_IMPL, "<init>", "(I)V");
il.append(new NEW(cpg.addClass(DOM_IMPL)));
il.append(DUP);
il.append(DUP);
- il.append(new PUSH(cpg, 64));
+ il.append(new PUSH(cpg, RTF_INITIAL_SIZE));
il.append(new INVOKESPECIAL(index));
// Overwrite old handler with DOM handler
1.17.2.1.2.1 +1 -47
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Template.java
Index: Template.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Template.java,v
retrieving revision 1.17.2.1
retrieving revision 1.17.2.1.2.1
diff -u -r1.17.2.1 -r1.17.2.1.2.1
--- Template.java 14 Aug 2002 19:21:33 -0000 1.17.2.1
+++ Template.java 2 Dec 2002 15:51:18 -0000 1.17.2.1.2.1
@@ -85,14 +85,6 @@
private int _position; // Position within stylesheet (prio.
resolution)
private boolean _disabled = false;
private boolean _compiled = false;//make sure it is compiled only once
-
- /**
- * Set to <tt>true</tt> by the XPath parser if this template
- * needs to create a variable frame. Variable frames are needed
- * when certain parts of a template are compiled in external
- * classes (e.g., predicates, xsl:number, xsl:sort).
- */
- private boolean _hasVariableFrame;
private boolean _hasParams = false;
private boolean _simplified = false;
@@ -165,29 +157,6 @@
return 0;
}
- private Hashtable _variables;
- private int _nextIndex;
-
- public int allocateIndex(QName varName) {
- if (_variables == null) { // first time
- _hasVariableFrame = true;
- (_variables = new Hashtable()).put(varName, new Integer(0));
- _nextIndex = 1;
- return 0;
- }
- else {
- Integer index = (Integer)_variables.get(varName);
- if (index == null) {
- _variables.put(varName, index = new Integer(_nextIndex++));
- }
- return index.intValue();
- }
- }
-
- private final int localVariablesCount() {
- return _variables == null ? 0 : _variables.size();
- }
-
public void display(int indent) {
Util.println('\n');
indent(indent);
@@ -354,24 +323,9 @@
if (_compiled) return;
_compiled = true;
- if (_hasVariableFrame) {
- il.append(classGen.loadTranslet());
- il.append(new PUSH(cpg, localVariablesCount()));
- il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS,
- PUSH_VAR_FRAME,
- PUSH_VAR_FRAME_SIG)));
- }
-
final InstructionHandle start = il.getEnd();
translateContents(classGen, methodGen);
final InstructionHandle end = il.getEnd();
il.setPositions(true);
-
- if (_hasVariableFrame) {
- il.append(classGen.loadTranslet());
- il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS,
- POP_VAR_FRAME,
- POP_VAR_FRAME_SIG)));
- }
}
}
1.8.2.1.2.1 +154 -101
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/TestSeq.java
Index: TestSeq.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/TestSeq.java,v
retrieving revision 1.8.2.1
retrieving revision 1.8.2.1.2.1
diff -u -r1.8.2.1 -r1.8.2.1.2.1
--- TestSeq.java 14 Aug 2002 19:21:33 -0000 1.8.2.1
+++ TestSeq.java 2 Dec 2002 15:51:18 -0000 1.8.2.1.2.1
@@ -69,6 +69,7 @@
import java.util.Hashtable;
import java.util.Dictionary;
import java.util.Enumeration;
+import java.util.Iterator;
import org.apache.bcel.generic.*;
import org.apache.xalan.xsltc.compiler.util.*;
@@ -77,110 +78,149 @@
* 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).
+ * (2) share the same kernel node type (e.g. A/B and C/C/B)
+ * (3) may also contain patterns matching "*" and "node()"
+ * (element sequence only) or matching "@*" (attribute
+ * sequence only).
*
- * 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.
+ * A test sequence may have a default template, which will be
+ * instantiated if none of the other patterns match.
*/
final class TestSeq {
- private Vector _patterns = null; // all patterns
- private Mode _mode = null; // the shared mode
- private Template _default = null; // the default template
+ /**
+ * Integer code for the kernel type of this test sequence
+ */
+ private int _kernelType;
+
+ /**
+ * Vector of all patterns in the test sequence. May include
+ * patterns with "*", "@*" or "node()" kernel.
+ */
+ private Vector _patterns = null;
+
+ /**
+ * A reference to the Mode object.
+ */
+ private Mode _mode = null;
+
+ /**
+ * Default template for this test sequence
+ */
+ private Template _default = null;
+ /**
+ * Instruction list representing this test sequence.
+ */
private InstructionList _instructionList;
/**
- * Creates a new test sequence, given a set of patterns and a mode.
+ * Cached handle to avoid compiling more than once.
+ */
+ private InstructionHandle _start = null;
+
+ /**
+ * Creates a new test sequence given a set of patterns and a mode.
*/
public TestSeq(Vector patterns, Mode mode) {
+ this(patterns, -2, mode);
+ }
+
+ public TestSeq(Vector patterns, int kernelType, Mode mode) {
_patterns = patterns;
+ _kernelType = kernelType;
_mode = mode;
}
/**
- * The priority is only calculated if the test sequence has a default
- * template. This is bad, bad, bad. We should get the priority from the
- * other templates that make up the test sequence.
+ * Returns a string representation of this test sequence. Notice
+ * that test sequences are mutable, so the value returned by this
+ * method is different before and after calling reduce().
*/
- public double getPriority() {
- double prio = (0 - Double.MAX_VALUE);
+ public String toString() {
final int count = _patterns.size();
+ final StringBuffer result = new StringBuffer();
for (int i = 0; i < count; i++) {
- final Pattern pattern = (Pattern)_patterns.elementAt(i);
- final Template template = pattern.getTemplate();
- final double tp = template.getPriority();
- if (tp > prio) prio = tp;
- }
- if (_default != null) {
- final double tp = _default.getPriority();
- if (tp > prio) prio = tp;
+ final LocationPathPattern pattern =
+ (LocationPathPattern) _patterns.elementAt(i);
+
+ if (i == 0) {
+ result.append("Testseq for kernel " + _kernelType)
+ .append('\n');
+ }
+ result.append(" pattern " + i + ": ")
+ .append(pattern.toString())
+ .append('\n');
}
- return prio;
+ return result.toString();
}
/**
- * This method should return the last position of any template included
- * in this test sequence.
+ * Returns the instruction list for this test sequence
*/
- public int getPosition() {
- int pos = Integer.MIN_VALUE;
- final int count = _patterns.size();
+ public InstructionList getInstructionList() {
+ return _instructionList;
+ }
- for (int i = 0; i < count; i++) {
- final Pattern pattern = (Pattern)_patterns.elementAt(i);
- final Template template = pattern.getTemplate();
- final int tp = template.getPosition();
- if (tp > pos) pos = tp;
- }
- if (_default != null) {
- final int tp = _default.getPosition();
- if (tp > pos) pos = tp;
- }
- return pos;
+ /**
+ * Return the highest priority for a pattern in this test
+ * sequence. This is either the priority of the first or
+ * of the default pattern.
+ */
+ public double getPriority() {
+ final Template template = (_patterns.size() == 0) ? _default
+ : ((Pattern) _patterns.elementAt(0)).getTemplate();
+ return template.getPriority();
}
-
+
+ /**
+ * Returns the position of the highest priority pattern in
+ * this test sequence.
+ */
+ public int getPosition() {
+ final Template template = (_patterns.size() == 0) ? _default
+ : ((Pattern) _patterns.elementAt(0)).getTemplate();
+ return template.getPosition();
+ }
+
/**
- * 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 pattern.
+ * Reduce the patterns in this test sequence. Creates a new
+ * vector of patterns and sets the default pattern if it
+ * finds a patterns that is fully reduced.
*/
public void reduce() {
final Vector newPatterns = new Vector();
- final int count = _patterns.size();
- // Traverse the existing set of patterns (they are in prioritised order)
+ final int count = _patterns.size();
for (int i = 0; i < count; i++) {
final LocationPathPattern pattern =
(LocationPathPattern)_patterns.elementAt(i);
- // Reduce this pattern (get rid of kernel node type)
+
+ // Reduce this pattern
pattern.reduceKernelPattern();
- // Add this pattern to the new vector of patterns.
- if (!pattern.isWildcard()) {
- newPatterns.addElement(pattern);
+ // Is this pattern fully reduced?
+ if (pattern.isWildcard()) {
+ _default = pattern.getTemplate();
+ break; // Ignore following patterns
}
- // Set template as default if its pattern matches purely on kernel
else {
- _default = pattern.getTemplate();
- // Following patterns can be ignored since default has priority
- break;
+ newPatterns.addElement(pattern);
}
}
_patterns = newPatterns;
}
/**
- * Returns, by reference, the templates that are included in this test
- * sequence. Remember that a single template can occur in several test
- * sequences if its pattern is a union (ex. match="A/B | A/C").
+ * Returns, by reference, the templates that are included in
+ * this test sequence. Note that a single template can occur
+ * in several test sequences if its pattern is a union.
*/
public void findTemplates(Dictionary templates) {
- if (_default != null)
+ if (_default != null) {
templates.put(_default, this);
+ }
for (int i = 0; i < _patterns.size(); i++) {
final LocationPathPattern pattern =
(LocationPathPattern)_patterns.elementAt(i);
@@ -189,9 +229,10 @@
}
/**
- * Get the instruction handle to a template's code. This is used when
- * a single template occurs in several test sequences; that is, if its
- * pattern is a union of patterns (ex. match="A/B | A/C").
+ * Get the instruction handle to a template's code. This is
+ * used when a single template occurs in several test
+ * sequences; that is, if its pattern is a union of patterns
+ * (e.g. match="A/B | A/C").
*/
private InstructionHandle getTemplateHandle(Template template) {
return (InstructionHandle)_mode.getTemplateInstructionHandle(template);
@@ -204,71 +245,83 @@
return (LocationPathPattern)_patterns.elementAt(n);
}
-
- private InstructionHandle _start = null;
-
/**
- * Copile the code for this test sequence. The code will first test for
- * the pattern with the highest priority, then go on to the next ones,
- * until it hits or finds the default template.
+ * Compile the code for this test sequence. Compile patterns
+ * from highest to lowest priority. Note that since patterns
+ * can be share by multiple test sequences, instruction lists
+ * must be copied before backpatching.
*/
public InstructionHandle compile(ClassGenerator classGen,
MethodGenerator methodGen,
- InstructionHandle continuation) {
+ InstructionHandle continuation)
+ {
+ // Returned cached value if already compiled
+ if (_start != null) {
+ return _start;
+ }
+ // If not patterns, then return handle for default template
final int count = _patterns.size();
-
- if (_start != null) return(_start);
-
- // EZ DC if there is only one (default) pattern
- if (count == 0) getTemplateHandle(_default);
+ if (count == 0) {
+ return (_start = getTemplateHandle(_default));
+ }
- // The 'fail' instruction handle represents a branch to go to when
- // test fails. It is updated in each iteration, so that the tests
- // are linked together in the if-elseif-elseif-else fashion.
- InstructionHandle fail;
+ // Init handle to jump when all patterns failed
+ InstructionHandle fail = (_default == null) ? continuation
+ : getTemplateHandle(_default);
- // Initialize 'fail' to either the code for the default template
- if (_default != null)
- fail = getTemplateHandle(_default);
- // ..or if that does not exist, to a location set by the caller.
- else
- fail = continuation;
-
- for (int n = (count - 1); n >= 0; n--) {
+ // Compile all patterns in reverse order
+ for (int n = count - 1; n >= 0; n--) {
final LocationPathPattern pattern = getPattern(n);
final Template template = pattern.getTemplate();
final InstructionList il = new InstructionList();
// Patterns expect current node on top of stack
il.append(methodGen.loadCurrentNode());
+
// Apply the test-code compiled for the pattern
- il.append(pattern.compile(classGen, methodGen));
+ InstructionList ilist = _mode.getInstructionList(pattern);
+ if (ilist == null) {
+ ilist = pattern.compile(classGen, methodGen);
+ _mode.addInstructionList(pattern, ilist);
+ }
+
+ // Make a copy of the instruction list for backpatching
+ InstructionList copyOfilist = ilist.copy();
+
+ FlowList trueList = pattern.getTrueList();
+ if (trueList != null) {
+ trueList = trueList.copyAndRedirect(ilist, copyOfilist);
+ }
+ FlowList falseList = pattern.getFalseList();
+ if (falseList != null) {
+ falseList = falseList.copyAndRedirect(ilist, copyOfilist);
+ }
+
+ il.append(copyOfilist);
// On success branch to the template code
final InstructionHandle gtmpl = getTemplateHandle(template);
final InstructionHandle success = il.append(new GOTO_W(gtmpl));
- pattern.backPatchTrueList(success);
- pattern.backPatchFalseList(fail);
- // We're working backwards here. The next pattern's 'fail' target
- // is this pattern's first instruction
+ if (trueList != null) {
+ trueList.backPatch(success);
+ }
+ if (falseList != null) {
+ falseList.backPatch(fail);
+ }
+
+ // Next pattern's 'fail' target is this pattern's first instruction
fail = il.getStart();
// Append existing instruction list to the end of this one
- if (_instructionList != null) il.append(_instructionList);
+ if (_instructionList != null) {
+ il.append(_instructionList);
+ }
- // Set current instruction list to be this one.
+ // Set current instruction list to be this one
_instructionList = il;
}
- return(_start = fail);
- }
-
- /**
- * Returns the instruction list for this test sequence
- */
- public InstructionList getInstructionList() {
- return _instructionList;
+ return (_start = fail);
}
-
}
1.7.8.1.2.1 +16 -5
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/TransletOutput.java
Index: TransletOutput.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/TransletOutput.java,v
retrieving revision 1.7.8.1
retrieving revision 1.7.8.1.2.1
diff -u -r1.7.8.1 -r1.7.8.1.2.1
--- TransletOutput.java 14 Aug 2002 19:21:34 -0000 1.7.8.1
+++ TransletOutput.java 2 Dec 2002 15:51:18 -0000 1.7.8.1.2.1
@@ -69,9 +69,7 @@
final class TransletOutput extends Instruction {
private Expression _filename;
-
- private final static String MISSING_FILE_ATTR =
- "The <xsltc:output> element requires a 'file' attribute.";
+ private boolean _append;
/**
* Displays the contents of this <xsltc:output> element.
@@ -88,6 +86,10 @@
public void parseContents(Parser parser) {
// Get the output filename from the 'file' attribute
String filename = getAttribute("file");
+
+ // If the 'append' attribute is set to "yes" or "true",
+ // the output is appended to the file.
+ String append = getAttribute("append");
// Verify that the filename is in fact set
if ((filename == null) || (filename.equals(EMPTYSTRING))) {
@@ -96,6 +98,14 @@
// Save filename as an attribute value template
_filename = AttributeValue.create(this, filename, parser);
+
+ if (append != null && (append.toLowerCase().equals("yes") ||
+ append.toLowerCase().equals("true"))) {
+ _append = true;
+ }
+ else
+ _append = false;
+
parseChildren(parser);
}
@@ -124,7 +134,7 @@
final int open = cpg.addMethodref(TRANSLET_CLASS,
"openOutputHandler",
- "("+STRING_SIG+")"+
+ "(" + STRING_SIG + "Z)" +
TRANSLET_OUTPUT_SIG);
final int close = cpg.addMethodref(TRANSLET_CLASS,
@@ -134,6 +144,7 @@
// Create the new output handler (leave it on stack)
il.append(classGen.loadTranslet());
_filename.translate(classGen, methodGen);
+ il.append(new PUSH(cpg, _append));
il.append(new INVOKEVIRTUAL(open));
// Overwrite current handler
1.22.8.1.2.1 +3 -45
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Variable.java
Index: Variable.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Variable.java,v
retrieving revision 1.22.8.1
retrieving revision 1.22.8.1.2.1
diff -u -r1.22.8.1 -r1.22.8.1.2.1
--- Variable.java 14 Aug 2002 19:21:34 -0000 1.22.8.1
+++ Variable.java 2 Dec 2002 15:51:18 -0000 1.22.8.1.2.1
@@ -77,37 +77,14 @@
final class Variable extends VariableBase {
- // Index of this variable in the variable stack relative to base ptr
- private int _stackIndex = -1;
-
- private boolean _escapes; // 'true' if the variable's value can change
-
- /**
- * This method returns 'true' if the variable value can change over time,
- * such as with varibles inside a for-each loop.
- */
- public void setEscapes() {
- _escapes = true;
- if (_stackIndex == -1) { // unassigned
- Template template = getTemplate();
- if (template != null) {
- _stackIndex = template.allocateIndex(_name);
- }
- }
- }
-
- /**
- *
- */
- public int getStackIndex() {
- return _stackIndex;
+ public int getIndex() {
+ return (_local != null) ? _local.getIndex() : -1;
}
/**
* Parse the contents of the variable
*/
public void parseContents(Parser parser) {
-
// Parse 'name' and 'select' attributes plus parameter contents
super.parseContents(parser);
@@ -210,20 +187,9 @@
_ignore = true;
if (isLocal()) {
- // Push args to call addVariable()
- if (_escapes) {
- il.append(classGen.loadTranslet());
- il.append(new PUSH(cpg, _stackIndex));
- }
-
// Compile variable value computation
translateValue(classGen, methodGen);
- // Dup value only when needed
- if (_escapes) {
- il.append(_type.DUP());
- }
-
// Add a new local variable and store value
if (_refs.isEmpty()) { // Remove it if nobody uses the value
il.append(_type.POP());
@@ -232,14 +198,6 @@
else { // Store in local var slot if referenced
if (_local == null) mapRegister(methodGen);
il.append(_type.STORE(_local.getIndex()));
- }
-
- // Store boxed value into the template's variable stack
- if (_escapes) {
- _type.translateBox(classGen, methodGen);
- il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS,
- ADD_VARIABLE,
-
ADD_VARIABLE_SIG)));
}
}
else {
1.12.2.1.2.1 +25 -40
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/VariableRef.java
Index: VariableRef.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/VariableRef.java,v
retrieving revision 1.12.2.1
retrieving revision 1.12.2.1.2.1
diff -u -r1.12.2.1 -r1.12.2.1.2.1
--- VariableRef.java 14 Aug 2002 19:21:34 -0000 1.12.2.1
+++ VariableRef.java 2 Dec 2002 15:51:19 -0000 1.12.2.1.2.1
@@ -71,33 +71,10 @@
final class VariableRef extends VariableRefBase {
- private boolean _escaped;
-
public VariableRef(Variable variable) {
super(variable);
}
- public Type typeCheck(SymbolTable stable) throws TypeCheckError {
- if ( (_variable.isLocal()) && (_escaped = isEscaped()) )
- ((Variable)_variable).setEscapes();
- return super.typeCheck(stable);
- }
-
- private boolean isEscaped() {
- final SyntaxTreeNode limit = _variable.getParent();
- SyntaxTreeNode parent = getParent();
- do {
- if (parent.isClosureBoundary()) {
- return true;
- }
- else {
- parent = parent.getParent();
- }
- }
- while (parent != limit);
- return limit.isClosureBoundary();
- }
-
public void translate(ClassGenerator classGen, MethodGenerator
methodGen) {
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
@@ -106,17 +83,26 @@
if (_type.implementedAsMethod()) return;
final String name = _variable.getVariable();
+ final String signature = _type.toSignature();
if (_variable.isLocal()) {
- if (classGen.isExternal() || _escaped) {
- il.append(classGen.loadTranslet());
- final int sindex = ((Variable)_variable).getStackIndex();
- il.append(new PUSH(cpg, sindex));
- final int getVar = cpg.addMethodref(TRANSLET_CLASS,
- GET_VARIABLE,
- GET_VARIABLE_SIG);
- il.append(new INVOKEVIRTUAL(getVar));
- _type.translateUnBox(classGen, methodGen);
+ if (classGen.isExternal()) {
+ Closure variableClosure = _closure;
+ while (variableClosure != null) {
+ if (variableClosure.inInnerClass()) break;
+ variableClosure = variableClosure.getParentClosure();
+ }
+
+ if (variableClosure != null) {
+ il.append(ALOAD_0);
+ il.append(new GETFIELD(
+ cpg.addFieldref(variableClosure.getInnerClassName(),
+ name, signature)));
+ }
+ else {
+ il.append(_variable.loadInstruction());
+ _variable.removeReference(this);
+ }
}
else {
il.append(_variable.loadInstruction());
@@ -124,10 +110,8 @@
}
}
else {
- final String signature = _type.toSignature();
final String className = classGen.getClassName();
il.append(classGen.loadTranslet());
- // If inside a predicate we must cast this ref down
if (classGen.isExternal()) {
il.append(new CHECKCAST(cpg.addClass(className)));
}
@@ -135,11 +119,12 @@
}
if (_variable.getType() instanceof NodeSetType) {
- final int reset = cpg.addInterfaceMethodref(NODE_ITERATOR,
- "reset",
- "()"+NODE_ITERATOR_SIG);
- il.append(new INVOKEINTERFACE(reset,1));
+ // The method cloneIterator() also does resetting
+ final int clone = cpg.addInterfaceMethodref(NODE_ITERATOR,
+ "cloneIterator",
+ "()" +
+ NODE_ITERATOR_SIG);
+ il.append(new INVOKEINTERFACE(clone, 1));
}
-
}
}
1.8.8.1.2.1 +50 -14
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/VariableRefBase.java
Index: VariableRefBase.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/VariableRefBase.java,v
retrieving revision 1.8.8.1
retrieving revision 1.8.8.1.2.1
diff -u -r1.8.8.1 -r1.8.8.1.2.1
--- VariableRefBase.java 14 Aug 2002 19:21:34 -0000 1.8.8.1
+++ VariableRefBase.java 2 Dec 2002 15:51:19 -0000 1.8.8.1.2.1
@@ -57,6 +57,7 @@
* <http://www.apache.org/>.
*
* @author Morten Jorgensen
+ * @author Santiago Pericas-Geertsen
*
*/
@@ -68,16 +69,17 @@
class VariableRefBase extends Expression {
- protected final VariableBase _variable; // Reference to the associated
var.
+ /**
+ * A reference to the associated variable.
+ */
+ protected final VariableBase _variable;
/**
- * Created a new variable or parameter reference. Note that this base-
- * class is not here mostly because variable and parameter references
share
- * a lot of functionality. The base class is needed more for having a
- * single class to run 'if (instanceof)' on in the compiler code. The
same
- * holds for the variable base class.
- * @param variable The referenced variable
+ * A reference to the enclosing expression/instruction for which a
+ * closure is needed (Predicate, Number or Sort).
*/
+ protected Closure _closure = null;
+
public VariableRefBase(VariableBase variable) {
_variable = variable;
variable.addReference(this);
@@ -89,23 +91,34 @@
/**
* Returns a reference to the associated variable
- * @return The referenced variable
*/
public VariableBase getVariable() {
- return(_variable);
+ return _variable;
}
/**
* Returns a reference to any parent variable
- * @return Parent variable (or null if none)
*/
public VariableBase findParentVariable() {
SyntaxTreeNode node = this;
- while ((node != null) && (!(node instanceof VariableBase)))
+ while (node != null && !(node instanceof VariableBase)) {
node = node.getParent();
- return (VariableBase)node;
+ }
+ return (VariableBase) node;
}
+ /**
+ * Two variable references are deemed equal if they refer to the
+ * same variable.
+ */
+ public boolean equals(Object obj) {
+ try {
+ return (_variable == ((VariableRefBase) obj)._variable);
+ }
+ catch (ClassCastException e) {
+ return false;
+ }
+ }
/**
* Returns a string representation of this variable reference on the
@@ -116,7 +129,30 @@
return "variable-ref("+_variable.getName()+'/'+_variable.getType()+')';
}
- public Type typeCheck(SymbolTable stable) throws TypeCheckError {
+ public Type typeCheck(SymbolTable stable)
+ throws TypeCheckError
+ {
+ // Returned cached type if available
+ if (_type != null) return _type;
+
+ // Find nearest closure to add a variable reference
+ if (_variable.isLocal()) {
+ SyntaxTreeNode node = getParent();
+ do {
+ if (node instanceof Closure) {
+ _closure = (Closure) node;
+ break;
+ }
+ if (node instanceof TopLevelElement) {
+ break; // way up in the tree
+ }
+ node = node.getParent();
+ } while (node != null);
+
+ if (_closure != null) {
+ _closure.addVariable(this);
+ }
+ }
// Insert a dependency link from one variable to another
VariableBase parent = findParentVariable();
1.10.2.1.2.1 +7 -8
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/When.java
Index: When.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/When.java,v
retrieving revision 1.10.2.1
retrieving revision 1.10.2.1.2.1
diff -u -r1.10.2.1 -r1.10.2.1.2.1
--- When.java 14 Aug 2002 19:21:34 -0000 1.10.2.1
+++ When.java 2 Dec 2002 15:51:19 -0000 1.10.2.1.2.1
@@ -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);
1.42.2.1.2.1 +63 -10
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XSLTC.java
Index: XSLTC.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XSLTC.java,v
retrieving revision 1.42.2.1
retrieving revision 1.42.2.1.2.1
diff -u -r1.42.2.1 -r1.42.2.1.2.1
--- XSLTC.java 14 Aug 2002 19:21:34 -0000 1.42.2.1
+++ XSLTC.java 2 Dec 2002 15:51:19 -0000 1.42.2.1.2.1
@@ -130,6 +130,9 @@
public static final int JAR_OUTPUT = 1;
public static final int BYTEARRAY_OUTPUT = 2;
public static final int CLASSLOADER_OUTPUT = 3;
+ public static final int BYTEARRAY_AND_FILE_OUTPUT = 4;
+ public static final int BYTEARRAY_AND_JAR_OUTPUT = 5;
+
// Compiler options (passed from command line or XSLTC client)
private boolean _debug = false; // -x
@@ -140,9 +143,17 @@
private int _outputType = FILE_OUTPUT; // by default
private Vector _classes;
+ private Vector _bcelClasses;
private boolean _callsNodeset = false;
private boolean _multiDocument = false;
- private boolean _templateInlining = true;
+
+ /**
+ * Set to true if template inlining is requested. Template
+ * inlining used to be the default, but we have found that
+ * Hotspots does a better job with shorter methods, so the
+ * default is *not* to inline now.
+ */
+ private boolean _templateInlining = false;
/**
* XSLTC compiler constructor
@@ -179,6 +190,7 @@
reset();
_reader = null;
_classes = new Vector();
+ _bcelClasses = new Vector();
}
/**
@@ -341,7 +353,11 @@
if ((!_parser.errorsFound()) && (_stylesheet != null)) {
_stylesheet.setCallsNodeset(_callsNodeset);
_stylesheet.setMultiDocument(_multiDocument);
- _stylesheet.translate();
+
+ // Class synchronization is needed for BCEL
+ synchronized (getClass()) {
+ _stylesheet.translate();
+ }
}
}
catch (Exception e) {
@@ -410,15 +426,27 @@
* set of byte arrays. One byte array for each generated class.
* @param name The name of the translet class to generate
* @param input An InputSource that will pass in the stylesheet contents
+ * @param outputType The output type
* @return JVM bytecodes that represent translet class definition
*/
- public byte[][] compile(String name, InputSource input) {
- _outputType = BYTEARRAY_OUTPUT;
+ public byte[][] compile(String name, InputSource input, int outputType) {
+ _outputType = outputType;
if (compile(input, name))
return getBytecodes();
else
return null;
}
+
+ /**
+ * Compiles a stylesheet pointed to by a URL. The result is put in a
+ * set of byte arrays. One byte array for each generated class.
+ * @param name The name of the translet class to generate
+ * @param input An InputSource that will pass in the stylesheet contents
+ * @return JVM bytecodes that represent translet class definition
+ */
+ public byte[][] compile(String name, InputSource input) {
+ return compile(name, input, BYTEARRAY_OUTPUT);
+ }
/**
* Set the XMLReader to use for parsing the next input stylesheet
@@ -685,19 +713,44 @@
}
public void dumpClass(JavaClass clazz) {
+
+ if (_outputType == FILE_OUTPUT ||
+ _outputType == BYTEARRAY_AND_FILE_OUTPUT)
+ {
+ File outFile = getOutputFile(clazz.getClassName());
+ String parentDir = outFile.getParent();
+ if (parentDir != null) {
+ File parentFile = new File(parentDir);
+ if (!parentFile.exists())
+ parentFile.mkdirs();
+ }
+ }
+
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);
+ _bcelClasses.addElement(clazz);
break;
case BYTEARRAY_OUTPUT:
+ case BYTEARRAY_AND_FILE_OUTPUT:
+ case BYTEARRAY_AND_JAR_OUTPUT:
case CLASSLOADER_OUTPUT:
ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
clazz.dump(out);
_classes.addElement(out.toByteArray());
+
+ if (_outputType == BYTEARRAY_AND_FILE_OUTPUT)
+ clazz.dump(new BufferedOutputStream(
+ new
FileOutputStream(getOutputFile(clazz.getClassName()))));
+ else if (_outputType == BYTEARRAY_AND_JAR_OUTPUT)
+ _bcelClasses.addElement(clazz);
+
break;
}
}
@@ -720,11 +773,11 @@
// 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.2");
final Map map = manifest.getEntries();
// create manifest
- Enumeration classes = _classes.elements();
+ Enumeration classes = _bcelClasses.elements();
final String now = (new Date()).toString();
final java.util.jar.Attributes.Name dateAttr =
new java.util.jar.Attributes.Name("Date");
@@ -739,7 +792,7 @@
final File jarFile = new File(_destDir, _jarFileName);
final JarOutputStream jos =
new JarOutputStream(new FileOutputStream(jarFile), manifest);
- classes = _classes.elements();
+ classes = _bcelClasses.elements();
while (classes.hasMoreElements()) {
final JavaClass clazz = (JavaClass)classes.nextElement();
final String className = clazz.getClassName().replace('.','/');
1.17.2.1.2.1 +19 -52
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XslElement.java
Index: XslElement.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XslElement.java,v
retrieving revision 1.17.2.1
retrieving revision 1.17.2.1.2.1
diff -u -r1.17.2.1 -r1.17.2.1.2.1
--- XslElement.java 14 Aug 2002 19:21:34 -0000 1.17.2.1
+++ XslElement.java 2 Dec 2002 15:51:19 -0000 1.17.2.1.2.1
@@ -178,8 +178,7 @@
return;
}
_prefix = prefix;
- _namespace = (namespace == EMPTYSTRING) ? null :
- new AttributeValueTemplate(namespace, parser,
this);
+ _namespace = new AttributeValueTemplate(namespace, parser,
this);
}
else {
if (prefix == EMPTYSTRING) {
@@ -280,62 +279,30 @@
}
if (!_ignore) {
+ // Push handler for call to endElement()
il.append(methodGen.loadHandler());
- _name.translate(classGen, methodGen);
-
- // Call BasisLibrary.getPrefix() and store result in local variable
- il.append(DUP);
- final int getPrefix = cpg.addMethodref(BASIS_LIBRARY_CLASS,
"getPrefix",
- "(" + STRING_SIG + ")" +
STRING_SIG);
- il.append(new INVOKESTATIC(getPrefix));
- il.append(DUP);
- local = methodGen.addLocalVariable("prefix",
-
org.apache.bcel.generic.Type.STRING,
- il.getEnd(), null);
- il.append(new ASTORE(local.getIndex()));
-
- // If prefix is null then generate a prefix at runtime
- final BranchHandle ifNotNull = il.append(new IFNONNULL(null));
- if (_namespace != null) {
- final int generatePrefix =
cpg.addMethodref(BASIS_LIBRARY_CLASS,
- "generatePrefix",
- "()" + STRING_SIG);
- il.append(new INVOKESTATIC(generatePrefix));
- il.append(DUP);
- il.append(new ASTORE(local.getIndex()));
-
- // Prepend newly generated prefix to the name
- final int makeQName = cpg.addMethodref(BASIS_LIBRARY_CLASS,
"makeQName",
- "(" + STRING_SIG + STRING_SIG + ")" +
STRING_SIG);
- il.append(new INVOKESTATIC(makeQName));
- }
- ifNotNull.setTarget(il.append(DUP2));
- il.append(methodGen.startElement());
+ // Push name and namespace URI
+ _name.translate(classGen, methodGen);
if (_namespace != null) {
- il.append(methodGen.loadHandler());
- il.append(new ALOAD(local.getIndex()));
_namespace.translate(classGen, methodGen);
- il.append(methodGen.namespace());
}
else {
- // If prefix not known at compile time, call
DOM.lookupNamespace()
- il.append(new ALOAD(local.getIndex()));
- final BranchHandle ifNull = il.append(new IFNULL(null));
- il.append(methodGen.loadHandler());
- il.append(new ALOAD(local.getIndex()));
-
- il.append(methodGen.loadDOM());
- il.append(methodGen.loadCurrentNode());
- il.append(new ALOAD(local.getIndex()));
-
- final int lookupNamespace = cpg.addInterfaceMethodref(DOM_INTF,
- "lookupNamespace",
- "(I" + STRING_SIG + ")" + STRING_SIG);
- il.append(new INVOKEINTERFACE(lookupNamespace, 3));
- il.append(methodGen.namespace());
- ifNull.setTarget(il.append(NOP));
+ il.append(ACONST_NULL);
}
+
+ // Push additional arguments
+ il.append(methodGen.loadHandler());
+ il.append(methodGen.loadDOM());
+ il.append(methodGen.loadCurrentNode());
+
+ // Invoke BasisLibrary.startXslElement()
+ il.append(new INVOKESTATIC(
+ cpg.addMethodref(BASIS_LIBRARY_CLASS, "startXslElement",
+ "(" + STRING_SIG
+ + STRING_SIG
+ + TRANSLET_OUTPUT_SIG
+ + DOM_INTF_SIG + "I)" + STRING_SIG)));
}
translateContents(classGen, methodGen);
1.39.2.1.2.1 +75 -64
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/xpath.cup
Index: xpath.cup
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/xpath.cup,v
retrieving revision 1.39.2.1
retrieving revision 1.39.2.1.2.1
diff -u -r1.39.2.1 -r1.39.2.1.2.1
--- xpath.cup 14 Aug 2002 19:21:35 -0000 1.39.2.1
+++ xpath.cup 2 Dec 2002 15:51:19 -0000 1.39.2.1.2.1
@@ -70,6 +70,7 @@
import java.io.StringReader;
import java_cup.runtime.*;
+import org.apache.xalan.xsltc.DOM;
import org.apache.xalan.xsltc.dom.Axis;
import org.apache.xalan.xsltc.runtime.Operators;
import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
@@ -116,10 +117,6 @@
return _lineNumber;
}
- public QName getQName(String name) {
- return _parser.getQName(name);
- }
-
public QName getQNameIgnoreDefaultNs(String name) {
return _parser.getQNameIgnoreDefaultNs(name);
}
@@ -133,14 +130,10 @@
}
public int findNodeType(int axis, Object test) {
-
if (test == null) { // *
- if (axis == Axis.ATTRIBUTE)
- return NodeTest.ATTRIBUTE;
- else if (axis == Axis.NAMESPACE)
- return -1;
- else
- return NodeTest.ELEMENT;
+ return (axis == Axis.ATTRIBUTE) ?
+ NodeTest.ATTRIBUTE :
+ (axis == Axis.NAMESPACE) ? -1 : NodeTest.ELEMENT;
}
else if (test instanceof Integer) {
return ((Integer)test).intValue();
@@ -149,30 +142,24 @@
QName name = (QName)test;
if (axis == Axis.NAMESPACE) {
- if (name.toString().equals("*"))
- return -1;
- else
- return _xsltc.registerNamespace(name);
+ return (name.toString().equals("*")) ? -1
+ : _xsltc.registerNamespace(name);
}
- if (name.getPrefix() == null || name.getNamespace() == null) {
- final String local = name.getLocalPart();
- if (local.equals("*")) {
- if (axis == Axis.ATTRIBUTE)
- return(NodeTest.ATTRIBUTE);
- else
- return(NodeTest.ELEMENT);
- }
- else if (local.equals("@*"))
- return(NodeTest.ATTRIBUTE);
- name = new QName(null,null,local);
- }
- if (axis == Axis.ATTRIBUTE) {
- return _xsltc.registerAttribute(name);
- }
- else {
- return _xsltc.registerElement(name);
- }
+ if (name.getNamespace() == null) {
+ final String local = name.getLocalPart();
+
+ if (local.equals("*")) {
+ return (axis == Axis.ATTRIBUTE) ? NodeTest.ATTRIBUTE
+ : NodeTest.ELEMENT;
+ }
+ else if (local.equals("@*")) {
+ return NodeTest.ATTRIBUTE;
+ }
+ }
+
+ return (axis == Axis.ATTRIBUTE) ? _xsltc.registerAttribute(name)
+ : _xsltc.registerElement(name);
}
}
@@ -243,6 +230,16 @@
return rlp;
}
}
+
+ /**
+ * Returns true if the axis applies to elements only. The axes
+ * child, attribute, namespace, descendant result in non-empty
+ * nodesets only if the context node is of type element.
+ */
+ public boolean isElementAxis(int axis) {
+ return (axis == Axis.CHILD || axis == Axis.ATTRIBUTE ||
+ axis == Axis.NAMESPACE || axis == Axis.DESCENDANT);
+ }
:}
terminal SLASH, DOT, LBRACK, RBRACK, VBAR, LPAREN, RPAREN, STAR, COMMA;
@@ -355,9 +352,11 @@
{: RESULT = new AncestorPattern(sp, rpp); :};
StepPattern ::= NodeTestPattern:nt
- {: RESULT = new StepPattern(Axis.CHILD,
- parser.findNodeType(Axis.CHILD, nt),
- null);
+ {:
+ final int nodeType = parser.findNodeType(Axis.CHILD, nt);
+ RESULT = new StepPattern(
+ (nodeType == NodeTest.ATTRIBUTE) ? Axis.ATTRIBUTE :
Axis.CHILD,
+ nodeType, null);
:}
| NodeTestPattern:nt Predicates:pp
@@ -527,12 +526,22 @@
| FilterExpr:fexp DSLASH RelativeLocationPath:rlp
{:
- // Expand '//' into '/descendant-or-self::node()/'
- Step step = new Step(Axis.DESCENDANTORSELF, NodeTest.ANODE, null);
+ //
+ // Expand '//' into '/descendant-or-self::node()/' or
+ // into /descendant-or-self::*/
+ //
+ int nodeType = DOM.NO_TYPE;
+ if (rlp instanceof Step &&
+ parser.isElementAxis(((Step) rlp).getAxis()))
+ {
+ nodeType = DOM.ELEMENT;
+ }
+ final Step step = new Step(Axis.DESCENDANTORSELF, nodeType, null);
FilterParentPath fpp = new FilterParentPath(fexp, step);
fpp = new FilterParentPath(fpp, rlp);
- if (!(fexp instanceof KeyCall))
+ if (fexp instanceof KeyCall == false) {
fpp.setDescendantAxis();
+ }
RESULT = fpp;
:};
@@ -594,13 +603,15 @@
else {
// Expand './/step' -> 'descendant-or-self::*/step'
if (rlp instanceof Step &&
((Step)rlp).isAbbreviatedDot()) {
- Step left = new Step(Axis.DESCENDANTORSELF, -1, null);
+ Step left = new Step(Axis.DESCENDANTORSELF,
+ DOM.ELEMENT, null);
RESULT = new ParentLocationPath(left, right);
}
else {
// Expand 'rlp//step' ->
'rlp/descendant-or-self::*/step'
RelativeLocationPath left = (RelativeLocationPath)rlp;
- Step mid = new Step(Axis.DESCENDANTORSELF, -1, null);
+ Step mid = new Step(Axis.DESCENDANTORSELF,
+ DOM.ELEMENT, null);
ParentLocationPath ppl = new ParentLocationPath(mid,
right);
RESULT = new ParentLocationPath(left, ppl);
}
@@ -609,14 +620,16 @@
else if ((axis == Axis.ATTRIBUTE) || (type ==
NodeTest.ATTRIBUTE)) {
// Expand 'rlp//step' -> 'rlp/descendant-or-self::*/step'
RelativeLocationPath left = (RelativeLocationPath)rlp;
- Step middle = new Step(Axis.DESCENDANTORSELF, -1, null);
+ Step middle = new Step(Axis.DESCENDANTORSELF,
+ DOM.ELEMENT, null);
ParentLocationPath ppl = new ParentLocationPath(middle,
right);
RESULT = new ParentLocationPath(left, ppl);
}
else {
// Expand 'rlp//step' -> 'rlp/descendant-or-self::node()/step'
RelativeLocationPath left = (RelativeLocationPath)rlp;
- Step middle = new Step(Axis.DESCENDANTORSELF, -1, null);
+ Step middle = new Step(Axis.DESCENDANTORSELF,
+ DOM.NO_TYPE, null);
ParentLocationPath ppl = new ParentLocationPath(middle,
right);
RESULT = new ParentLocationPath(left, ppl);
}
@@ -625,11 +638,19 @@
AbbreviatedAbsoluteLocationPath ::= DSLASH RelativeLocationPath:rlp
{:
- final Step step = new Step(Axis.DESCENDANTORSELF, -1, null);
-
- RESULT = new FilteredAbsoluteLocationPath(
- new AbsoluteLocationPath(parser.insertStep(step,
- (RelativeLocationPath) rlp)));
+ //
+ // Expand '//' into '/descendant-or-self::node()/' or
+ // into /descendant-or-self::*/
+ //
+ int nodeType = DOM.NO_TYPE;
+ if (rlp instanceof Step &&
+ parser.isElementAxis(((Step) rlp).getAxis()))
+ {
+ nodeType = DOM.ELEMENT;
+ }
+ final Step step = new Step(Axis.DESCENDANTORSELF, nodeType, null);
+ RESULT = new AbsoluteLocationPath(parser.insertStep(step,
+ (RelativeLocationPath) rlp));
:};
Step ::= NodeTest:ntest
@@ -756,11 +777,9 @@
| 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)
@@ -769,7 +788,7 @@
RESULT = new IntExpr(num.intValue());
else if (num.doubleValue() == 0.0)
RESULT = new RealExpr(num.doubleValue());
- else
+ else
RESULT = new IntExpr(num.intValue());
}
:}
@@ -923,7 +942,7 @@
RESULT = new NamespaceUriCall(fname, argl);
}
// Special case for extension function nodeset()
- else if (fname.getLocalPart().equals("nodeset")) {
+ else if (fname.getLocalPart().equals("nodeset") ||
fname.getLocalPart().equals("node-set")) {
parser.setCallsNodeset(true); // implies MultiDOM
RESULT = new FunctionCall(fname, argl);
}
@@ -944,19 +963,11 @@
FunctionName ::= QName:fname
{:
- final String prefix = fname.getPrefix();
- if (prefix == null || prefix.equals(Constants.EMPTYSTRING)) {
- fname = parser.getQNameIgnoreDefaultNs(fname.getLocalPart());
- }
RESULT = fname;
:};
VariableName ::= QName:vname
{:
- final String prefix = vname.getPrefix();
- if (prefix == null || prefix.equals(Constants.EMPTYSTRING)) {
- vname = parser.getQNameIgnoreDefaultNs(vname.getLocalPart());
- }
RESULT = vname;
:};
@@ -996,7 +1007,7 @@
{: RESULT = qn; :};
QName ::= QNAME:qname
- {: RESULT = parser.getQName(qname); :}
+ {: RESULT = parser.getQNameIgnoreDefaultNs(qname); :}
| DIV
{: RESULT = parser.getQNameIgnoreDefaultNs("div"); :}
1.8.2.1.2.1 +1 -1
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/xpath.lex
Index: xpath.lex
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/xpath.lex,v
retrieving revision 1.8.2.1
retrieving revision 1.8.2.1.2.1
diff -u -r1.8.2.1 -r1.8.2.1.2.1
No revision
No revision
1.1.2.1 +1 -1
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Closure.java
Index: Closure.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Closure.java,v
retrieving revision 1.1
retrieving revision 1.1.2.1
diff -u -r1.1 -r1.1.2.1
1.1.2.1 +1 -1
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ForwardPositionExpr.java
Index: ForwardPositionExpr.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ForwardPositionExpr.java,v
retrieving revision 1.1
retrieving revision 1.1.2.1
diff -u -r1.1 -r1.1.2.1
No revision
No revision
1.3.8.1.2.1 +4 -1
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/BooleanType.java
Index: BooleanType.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/BooleanType.java,v
retrieving revision 1.3.8.1
retrieving revision 1.3.8.1.2.1
diff -u -r1.3.8.1 -r1.3.8.1.2.1
--- BooleanType.java 14 Aug 2002 19:21:40 -0000 1.3.8.1
+++ BooleanType.java 2 Dec 2002 15:51:22 -0000 1.3.8.1.2.1
@@ -172,6 +172,9 @@
if (clazz == java.lang.Boolean.TYPE) {
methodGen.getInstructionList().append(NOP);
}
+ else if (clazz.isAssignableFrom(java.lang.Boolean.class)) {
+ translateTo(classGen, methodGen, Type.Reference);
+ }
else {
ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
toString(), clazz.getName());
1.12.2.1.2.1 +743 -118
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/ErrorMessages.java
Index: ErrorMessages.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/ErrorMessages.java,v
retrieving revision 1.12.2.1
retrieving revision 1.12.2.1.2.1
diff -u -r1.12.2.1 -r1.12.2.1.2.1
--- ErrorMessages.java 14 Aug 2002 19:21:40 -0000 1.12.2.1
+++ ErrorMessages.java 2 Dec 2002 15:51:22 -0000 1.12.2.1.2.1
@@ -68,204 +68,829 @@
public class ErrorMessages extends ResourceBundle {
+/*
+ * XSLTC compile-time error messages.
+ *
+ * General notes to translators and definitions:
+ *
+ * 1) XSLTC is the name of the product. It is an acronym for "XSLT
Compiler".
+ * XSLT is an acronym for "XML Stylesheet Language: Transformations".
+ *
+ * 2) A stylesheet is a description of how to transform an input XML
document
+ * into a resultant XML document (or HTML document or text). The
+ * stylesheet itself is described in the form of an XML document.
+ *
+ * 3) A template is a component of a stylesheet that is used to match a
+ * particular portion of an input document and specifies the form of the
+ * corresponding portion of the output document.
+ *
+ * 4) An axis is a particular "dimension" in a tree representation of an
XML
+ * document; the nodes in the tree are divided along different axes.
+ * Traversing the "child" axis, for instance, means that the program
+ * would visit each child of a particular node; traversing the
"descendant"
+ * axis means that the program would visit the child nodes of a
particular
+ * node, their children, and so on until the leaf nodes of the tree are
+ * reached.
+ *
+ * 5) An iterator is an object that traverses nodes in a tree along a
+ * particular axis, one at a time.
+ *
+ * 6) An element is a mark-up tag in an XML document; an attribute is a
+ * modifier on the tag. For example, in <elem attr='val' attr2='val2'>
+ * "elem" is an element name, "attr" and "attr2" are attribute names
with
+ * the values "val" and "val2", respectively.
+ *
+ * 7) A namespace declaration is a special attribute that is used to
associate
+ * a prefix with a URI (the namespace). The meanings of element names
and
+ * attribute names that use that prefix are defined with respect to that
+ * namespace.
+ *
+ * 8) DOM is an acronym for Document Object Model. It is a tree
+ * representation of an XML document.
+ *
+ * SAX is an acronym for the Simple API for XML processing. It is an
API
+ * used inform an XML processor (in this case XSLTC) of the structure
and
+ * content of an XML document.
+ *
+ * Input to the stylesheet processor can come from an XML parser in the
+ * form of a DOM tree or through the SAX API.
+ *
+ * 9) DTD is a document type declaration. It is a way of specifying the
+ * grammar for an XML file, the names and types of elements, attributes,
+ * etc.
+ *
+ * 10) XPath is a specification that describes a notation for identifying
+ * nodes in a tree-structured representation of an XML document. An
+ * instance of that notation is referred to as an XPath expression.
+ *
+ * 11) Translet is an invented term that refers to the class file that
contains
+ * the compiled form of a stylesheet.
+ */
+
// These message should be read from a locale-specific resource bundle
private static final String errorMessages[] = {
- // MULTIPLE_STYLESHEET_ERR
+ //MULTIPLE_STYLESHEET_ERR
"More than one stylesheet defined in the same file.",
- // TEMPLATE_REDEF_ERR
+
+ /*
+ * Note to translators: The substitution text is the name of a
+ * template. The same name was used on two different templates in the
+ * same stylesheet.
+ */
+ // TEMPLATE_REDEF_ERR
"Template ''{0}'' already defined in this stylesheet.",
- // TEMPLATE_UNDEF_ERR
+
+
+ /*
+ * Note to translators: The substitution text is the name of a
+ * template. A reference to the template name was encountered, but the
+ * template is undefined.
+ */
+ //TEMPLATE_UNDEF_ERR
"Template ''{0}'' not defined in this stylesheet.",
- // VARIABLE_REDEF_ERR
+
+ /*
+ * Note to translators: The substitution text is the name of a variable
+ * that was defined more than once.
+ */
+ //VARIABLE_REDEF_ERR
"Variable ''{0}'' is multiply defined in the same scope.",
- // VARIABLE_UNDEF_ERR
+
+ /*
+ * Note to translators: The substitution text is the name of a variable
+ * or parameter. A reference to the variable or parameter was found,
+ * but it was never defined.
+ */
+ //VARIABLE_UNDEF_ERR
"Variable or parameter ''{0}'' is undefined.",
- // CLASS_NOT_FOUND_ERR
+
+ /*
+ * Note to translators: The word "class" here refers to a Java class.
+ * Processing the stylesheet required a class to be loaded, but it could
+ * not be found. The substitution text is the name of the class.
+ */
+ //CLASS_NOT_FOUND_ERR
"Cannot find class ''{0}''.",
- // METHOD_NOT_FOUND_ERR
- "Cannot find external method ''{0}'' (must be static and public).",
- // ARGUMENT_CONVERSION_ERR
+
+ /*
+ * Note to translators: The word "method" here refers to a Java method.
+ * Processing the stylesheet required a reference to the method named by
+ * the substitution text, but it could not be found. "public" is the
+ * Java keyword.
+ */
+ //METHOD_NOT_FOUND_ERR
+ "Cannot find external method ''{0}'' (must be public).",
+
+ /*
+ * Note to translators: The word "method" here refers to a Java method.
+ * Processing the stylesheet required a reference to the method named by
+ * the substitution text, but no method with the required types of
+ * arguments or return type could be found.
+ */
+ //ARGUMENT_CONVERSION_ERR
"Cannot convert argument/return type in call to method ''{0}''",
- // FILE_NOT_FOUND_ERR
+
+ /*
+ * Note to translators: The file or URI named in the substitution text
+ * is missing.
+ */
+ //FILE_NOT_FOUND_ERR
"File or URI ''{0}'' not found.",
- // INVALID_URI_ERR
+
+ /*
+ * Note to translators: This message is displayed when the URI
+ * mentioned in the substitution text is not well-formed syntactically.
+ */
+ //INVALID_URI_ERR
"Invalid URI ''{0}''.",
- // FILE_ACCESS_ERR
+
+ /*
+ * Note to translators: The file or URI named in the substitution text
+ * exists but could not be opened.
+ */
+ //FILE_ACCESS_ERR
"Cannot open file or URI ''{0}''.",
- // MISSING_ROOT_ERR
+
+ /*
+ * Note to translators: <xsl:stylesheet> and <xsl:transform> are
+ * keywords that should not be translated.
+ */
+ //MISSING_ROOT_ERR
"<xsl:stylesheet> or <xsl:transform> element expected.",
- // NAMESPACE_UNDEF_ERR
+
+ /*
+ * Note to translators: The stylesheet contained a reference to a
+ * namespace prefix that was undefined. The value of the substitution
+ * text is the name of the prefix.
+ */
+ //NAMESPACE_UNDEF_ERR
"Namespace prefix ''{0}'' is undeclared.",
- // FUNCTION_RESOLVE_ERR
+
+ /*
+ * Note to translators: The Java function named in the stylesheet could
+ * not be found.
+ */
+ //FUNCTION_RESOLVE_ERR
"Unable to resolve call to function ''{0}''.",
- // NEED_LITERAL_ERR
+
+ /*
+ * Note to translators: The substitution text is the name of a
+ * function. A literal string here means a constant string value.
+ */
+ //NEED_LITERAL_ERR
"Argument to ''{0}'' must be a literal string.",
- // XPATH_PARSER_ERR
+
+ /*
+ * Note to translators: This message indicates there was a syntactic
+ * error in the form of an XPath expression. The substitution text is
+ * the expression.
+ */
+ //XPATH_PARSER_ERR
"Error parsing XPath expression ''{0}''.",
- // REQUIRED_ATTR_ERR
+
+ /*
+ * Note to translators: An element in the stylesheet requires a
+ * particular attribute named by the substitution text, but that
+ * attribute was not specified in the stylesheet.
+ */
+ //REQUIRED_ATTR_ERR
"Required attribute ''{0}'' is missing.",
- // ILLEGAL_CHAR_ERR
+
+ /*
+ * Note to translators: This message indicates that a character not
+ * permitted in an XPath expression was encountered. The substitution
+ * text is the offending character.
+ */
+ //ILLEGAL_CHAR_ERR
"Illegal character ''{0}'' in XPath expression.",
- // ILLEGAL_PI_ERR
+
+ /*
+ * Note to translators: A processing instruction is a mark-up item in
+ * an XML document that request some behaviour of an XML processor. The
+ * form of the name of was invalid in this case, and the substitution
+ * text is the name.
+ */
+ //ILLEGAL_PI_ERR
"Illegal name ''{0}'' for processing instruction.",
- // STRAY_ATTRIBUTE_ERR
+
+ /*
+ * Note to translators: This message is reported if the stylesheet
+ * being processed attempted to construct an XML document with an
+ * attribute in a place other than on an element. The substitution text
+ * specifies the name of the attribute.
+ */
+ //STRAY_ATTRIBUTE_ERR
"Attribute ''{0}'' outside of element.",
- // ILLEGAL_ATTRIBUTE_ERR
+
+ /*
+ * Note to translators: An attribute that wasn't recognized was
+ * specified on an element in the stylesheet. The attribute is named
+ * by the substitution
+ * text.
+ */
+ //ILLEGAL_ATTRIBUTE_ERR
"Illegal attribute ''{0}''.",
- // CIRCULAR_INCLUDE_ERR
+
+ /*
+ * Note to translators: "import" and "include" are keywords that should
+ * not be translated. This messages indicates that the stylesheet
+ * named in the substitution text imported or included itself either
+ * directly or indirectly.
+ */
+ //CIRCULAR_INCLUDE_ERR
"Circular import/include. Stylesheet ''{0}'' already loaded.",
- // RESULT_TREE_SORT_ERR
- "Result-tree fragments cannot be sorted (<xsl:sort> elements are "+
- "ignored). You must sort the nodes when creating the result tree.",
- // SYMBOLS_REDEF_ERR
+
+ /*
+ * Note to translators: A result-tree fragment is a portion of a
+ * resulting XML document represented as a tree. "<xsl:sort>" is a
+ * keyword and should not be translated.
+ */
+ //RESULT_TREE_SORT_ERR
+ "Result-tree fragments cannot be sorted (<xsl:sort> elements are " +
+ "ignored). You must sort the nodes when creating the result tree.",
+
+ /*
+ * Note to translators: A name can be given to a particular style to be
+ * used to format decimal values. The substitution text gives the name
+ * of such a style for which more than one declaration was encountered.
+ */
+ //SYMBOLS_REDEF_ERR
"Decimal formatting ''{0}'' is already defined.",
- // XSL_VERSION_ERR
+
+ /*
+ * Note to translators: The stylesheet version named in the
+ * substitution text is not supported.
+ */
+ //XSL_VERSION_ERR
"XSL version ''{0}'' is not supported by XSLTC.",
- // CIRCULAR_VARIABLE_ERR
+
+ /*
+ * Note to translators: The definitions of one or more variables or
+ * parameters depend on one another.
+ */
+ //CIRCULAR_VARIABLE_ERR
"Circular variable/parameter reference in ''{0}''.",
- // ILLEGAL_BINARY_OP_ERR
+
+ /*
+ * Note to translators: The operator in an expresion with two operands
was
+ * not recognized.
+ */
+ //ILLEGAL_BINARY_OP_ERR
"Unknown operator for binary expression.",
- // ILLEGAL_ARG_ERR
+
+ /*
+ * Note to translators: This message is produced if a reference to a
+ * function has too many or too few arguments.
+ */
+ //ILLEGAL_ARG_ERR
"Illegal argument(s) for function call.",
- // DOCUMENT_ARG_ERR
+
+ /*
+ * Note to translators: "document()" is the name of function and must
+ * not be translated. A node-set is a set of the nodes in the tree
+ * representation of an XML document.
+ */
+ //DOCUMENT_ARG_ERR
"Second argument to document() function must be a node-set.",
- // MISSING_WHEN_ERR
+
+ /*
+ * Note to translators: "<xsl:when>" and "<xsl:choose>" are keywords
+ * and should not be translated. This message describes a syntax error
+ * in the stylesheet.
+ */
+ //MISSING_WHEN_ERR
"At least one <xsl:when> element required in <xsl:choose>.",
- // MULTIPLE_OTHERWISE_ERR
+
+ /*
+ * Note to translators: "<xsl:otherwise>" and "<xsl:choose>" are
+ * keywords and should not be translated. This message describes a
+ * syntax error in the stylesheet.
+ */
+ //MULTIPLE_OTHERWISE_ERR
"Only one <xsl:otherwise> element allowed in <xsl:choose>.",
- // STRAY_OTHERWISE_ERR
+
+ /*
+ * Note to translators: "<xsl:otherwise>" and "<xsl:choose>" are
+ * keywords and should not be translated. This message describes a
+ * syntax error in the stylesheet.
+ */
+ //STRAY_OTHERWISE_ERR
"<xsl:otherwise> can only be used within <xsl:choose>.",
- // STRAY_WHEN_ERR
+
+ /*
+ * Note to translators: "<xsl:when>" and "<xsl:choose>" are keywords
+ * and should not be translated. This message describes a syntax error
+ * in the stylesheet.
+ */
+ //STRAY_WHEN_ERR
"<xsl:when> can only be used within <xsl:choose>.",
- // WHEN_ELEMENT_ERR
+
+ /*
+ * Note to translators: "<xsl:when>", "<xsl:otherwise>" and
+ * "<xsl:choose>" are keywords and should not be translated. This
+ * message describes a syntax error in the stylesheet.
+ */
+ //WHEN_ELEMENT_ERR
"Only <xsl:when> and <xsl:otherwise> elements allowed in <xsl:choose>.",
- // UNNAMED_ATTRIBSET_ERR
+
+ /*
+ * Note to translators: "<xsl:attribute-set>" and "name" are keywords
+ * that should not be translated.
+ */
+ //UNNAMED_ATTRIBSET_ERR
"<xsl:attribute-set> is missing the 'name' attribute.",
- // ILLEGAL_CHILD_ERR
+
+ /*
+ * Note to translators: An element in the stylesheet contained an
+ * element of a type that it was not permitted to contain.
+ */
+ //ILLEGAL_CHILD_ERR
"Illegal child element.",
- // ILLEGAL_ELEM_NAME_ERR
+
+ /*
+ * Note to translators: The stylesheet tried to create an element with
+ * a name that was not a valid XML name. The substitution text contains
+ * the name.
+ */
+ //ILLEGAL_ELEM_NAME_ERR
"You cannot call an element ''{0}''",
- // ILLEGAL_ATTR_NAME_ERR
+
+ /*
+ * Note to translators: The stylesheet tried to create an attribute
+ * with a name that was not a valid XML name. The substitution text
+ * contains the name.
+ */
+ //ILLEGAL_ATTR_NAME_ERR
"You cannot call an attribute ''{0}''",
- // ILLEGAL_TEXT_NODE_ERR
+
+ /*
+ * Note to translators: The children of the outermost element of a
+ * stylesheet are referred to as top-level elements. No text should
+ * occur within that outermost element unless it is within a top-level
+ * element. This message indicates that that constraint was violated.
+ * "<xsl:stylesheet>" is a keyword that should not be translated.
+ */
+ //ILLEGAL_TEXT_NODE_ERR
"Text data outside of top-level <xsl:stylesheet> element.",
- // SAX_PARSER_CONFIG_ERR
+
+ /*
+ * Note to translators: JAXP is an acronym for the Java API for XML
+ * Processing. This message indicates that the XML parser provided to
+ * XSLTC to process the XML input document had a configuration problem.
+ */
+ //SAX_PARSER_CONFIG_ERR
"JAXP parser not configured correctly",
- // INTERNAL_ERR
+
+ /*
+ * Note to translators: The substitution text names the internal error
+ * encountered.
+ */
+ //INTERNAL_ERR
"Unrecoverable XSLTC-internal error: ''{0}''",
- // UNSUPPORTED_XSL_ERR
+
+ /*
+ * Note to translators: The stylesheet contained an element that was
+ * not recognized as part of the XSL syntax. The substitution text
+ * gives the element name.
+ */
+ //UNSUPPORTED_XSL_ERR
"Unsupported XSL element ''{0}''.",
- // UNSUPPORTED_EXT_ERR
+
+ /*
+ * Note to translators: The stylesheet referred to an extension to the
+ * XSL syntax and indicated that it was defined by XSLTC, but XSTLC does
+ * not recognized the particular extension named. The substitution text
+ * gives the extension name.
+ */
+ //UNSUPPORTED_EXT_ERR
"Unrecognised XSLTC extension ''{0}''.",
- // MISSING_XSLT_URI_ERR
- "The input document is not a stylesheet "+
- "(the XSL namespace is not declared in the root element).",
- // MISSING_XSLT_TARGET_ERR
+
+ /*
+ * Note to translators: The XML document given to XSLTC as a stylesheet
+ * was not, in fact, a stylesheet. XSLTC is able to detect that in this
+ * case because the outermost element in the stylesheet has to be
+ * declared with respect to the XSL namespace URI, but no declaration
+ * for that namespace was seen.
+ */
+ //MISSING_XSLT_URI_ERR
+ "The input document is not a stylesheet (the XSL namespace is not "+
+ "declared in the root element).",
+
+ /*
+ * Note to translators: XSLTC could not find the stylesheet document
+ * with the name specified by the substitution text.
+ */
+ //MISSING_XSLT_TARGET_ERR
"Could not find stylesheet target ''{0}''.",
- // NOT_IMPLEMENTED_ERR
+
+ /*
+ * Note to translators: This message represents an internal error in
+ * condition in XSLTC. The substitution text is the class name in XSLTC
+ * that is missing some functionality.
+ */
+ //NOT_IMPLEMENTED_ERR
"Not implemented: ''{0}''.",
- // NOT_STYLESHEET_ERR
+
+ /*
+ * Note to translators: The XML document given to XSLTC as a stylesheet
+ * was not, in fact, a stylesheet.
+ */
+ //NOT_STYLESHEET_ERR
"The input document does not contain an XSL stylesheet.",
- // ELEMENT_PARSE_ERR
+
+ /*
+ * Note to translators: The element named in the substitution text was
+ * encountered in the stylesheet but is not recognized.
+ */
+ //ELEMENT_PARSE_ERR
"Could not parse element ''{0}''",
- // KEY_USE_ATTR_ERR
- "The use-attribute of <key> must be node, node-set, string or number.",
- // OUTPUT_VERSION_ERR
+
+ /*
+ * Note to translators: "use", "<key>", "node", "node-set", "string"
+ * and "number" are keywords in this context and should not be
+ * translated. This message indicates that the value of the "use"
+ * attribute was not one of the permitted values.
+ */
+ //KEY_USE_ATTR_ERR
+ "The use attribute of <key> must be node, node-set, string or number.",
+
+ /*
+ * Note to translators: An XML document can specify the version of the
+ * XML specification to which it adheres. This message indicates that
+ * the version specified for the output document was not valid.
+ */
+ //OUTPUT_VERSION_ERR
"Output XML document version should be 1.0",
- // ILLEGAL_RELAT_OP_ERR
+
+ /*
+ * Note to translators: The operator in a comparison operation was
+ * not recognized.
+ */
+ //ILLEGAL_RELAT_OP_ERR
"Unknown operator for relational expression",
- // ATTRIBSET_UNDEF_ERR
+
+ /*
+ * Note to translators: An attribute set defines as a set of XML
+ * attributes that can be added to an element in the output XML document
+ * as a group. This message is reported if the name specified was not
+ * used to declare an attribute set. The substitution text is the name
+ * that is in error.
+ */
+ //ATTRIBSET_UNDEF_ERR
"Attempting to use non-existing attribute set ''{0}''.",
- // ATTR_VAL_TEMPLATE_ERR
+
+ /*
+ * Note to translators: The term "attribute value template" is a term
+ * defined by XSLT which describes the value of an attribute that is
+ * determined by an XPath expression. The message indicates that the
+ * expression was syntactically incorrect; the substitution text
+ * contains the expression that was in error.
+ */
+ //ATTR_VAL_TEMPLATE_ERR
"Cannot parse attribute value template ''{0}''.",
- // UNKNOWN_SIG_TYPE_ERR
+
+ /*
+ * Note to translators: ???
+ */
+ //UNKNOWN_SIG_TYPE_ERR
"Unknown data-type in signature for class ''{0}''.",
- // DATA_CONVERSION_ERR
+
+ /*
+ * Note to translators: The substitution text refers to data types.
+ * The message is displayed if a value in a particular context needs to
+ * be converted to type {1}, but that's not possible for a value of
+ * type {0}.
+ */
+ //DATA_CONVERSION_ERR
"Cannot convert data-type ''{0}'' to ''{1}''.",
- // NO_TRANSLET_CLASS_ERR
+ /*
+ * Note to translators: "Templates" is a Java class name that should
+ * not be translated.
+ */
+ //NO_TRANSLET_CLASS_ERR
"This Templates does not contain a valid translet class definition.",
- // NO_MAIN_TRANSLET_ERR
+
+ /*
+ * Note to translators: "Templates" is a Java class name that should
+ * not be translated.
+ */
+ //NO_MAIN_TRANSLET_ERR
"This Templates does not contain a class with the name ''{0}''.",
- // TRANSLET_CLASS_ERR
+
+ /*
+ * Note to translators: The substitution text is the name of a class.
+ */
+ //TRANSLET_CLASS_ERR
"Could not load the translet class ''{0}''.",
- // TRANSLET_OBJECT_ERR
+
+ //TRANSLET_OBJECT_ERR
"Translet class loaded, but unable to create translet instance.",
- // ERROR_LISTENER_NULL_ERR
+
+ /*
+ * Note to translators: "ErrorListener" is a Java interface name that
+ * should not be translated. The message indicates that the user tried
+ * to set an ErrorListener object on object of the class named in the
+ * substitution text with "null" Java value.
+ */
+ //ERROR_LISTENER_NULL_ERR
"Attempting to set ErrorListener for ''{0}'' to null",
- // JAXP_UNKNOWN_SOURCE_ERR
- "Only StreamSource, SAXSource and DOMSOurce are supported by XSLTC",
- // JAXP_NO_SOURCE_ERR
+
+ /*
+ * Note to translators: StreamSource, SAXSource and DOMSource are Java
+ * interface names that should not be translated.
+ */
+ //JAXP_UNKNOWN_SOURCE_ERR
+ "Only StreamSource, SAXSource and DOMSource are supported by XSLTC",
+
+ /*
+ * Note to translators: "Source" is a Java class name that should not
+ * be translated. The substitution text is the name of Java method.
+ */
+ //JAXP_NO_SOURCE_ERR
"Source object passed to ''{0}'' has no contents.",
- // JAXP_COMPILE_ERR
+
+ /*
+ * Note to translators: The message indicates that XSLTC failed to
+ * compile the stylesheet into a translet (class file).
+ */
+ //JAXP_COMPILE_ERR
"Could not compile stylesheet",
- // JAXP_INVALID_ATTR_ERR
+
+ /*
+ * Note to translators: "TransformerFactory" is a class name. In this
+ * context, an attribute is a property or setting of the
+ * TransformerFactory object. The substitution text is the name of the
+ * unrecognised attribute. The method used to retrieve the attribute is
+ * "getAttribute", so it's not clear whether it would be best to
+ * translate the term "attribute".
+ */
+ //JAXP_INVALID_ATTR_ERR
"TransformerFactory does not recognise attribute ''{0}''.",
- // JAXP_SET_RESULT_ERROR
+
+ /*
+ * Note to translators: "setResult()" and "startDocument()" are Java
+ * method names that should not be translated.
+ */
+ //JAXP_SET_RESULT_ERR
"setResult() must be called prior to startDocument().",
- // JAXP_NO_TRANSLET_ERR
- "The transformer has no encapsulated translet object.",
- // JAXP_NO_HANDLER_ERR
+
+ /*
+ * Note to translators: "Transformer" is a Java interface name that
+ * should not be translated. A Transformer object should contained a
+ * reference to a translet object in order to be used for
+ * transformations; this message is produced if that requirement is not
+ * met.
+ */
+ //JAXP_NO_TRANSLET_ERR
+ "The Transformer has no encapsulated translet object.",
+
+ /*
+ * Note to translators: The XML document that results from a
+ * transformation needs to be sent to an output handler object; this
+ * message is produced if that requirement is not met.
+ */
+ //JAXP_NO_HANDLER_ERR
"No defined output handler for transformation result.",
- // JAXP_NO_RESULT_ERR
+
+ /*
+ * Note to translators: "Result" is a Java interface name in this
+ * context. The substitution text is a method name.
+ */
+ //JAXP_NO_RESULT_ERR
"Result object passed to ''{0}'' is invalid.",
- // JAXP_UNKNOWN_PROP_ERR
+
+ /*
+ * Note to translators: "Transformer" is a Java interface name. The
+ * user's program attempted to access an unrecognized property with the
+ * name specified in the substitution text. The method used to retrieve
+ * the property is "getOutputProperty", so it's not clear whether it
+ * would be best to translate the term "property".
+ */
+ //JAXP_UNKNOWN_PROP_ERR
"Attempting to access invalid Transformer property ''{0}''.",
- // SAX2DOM_ADAPTER_ERR
- "Could not crate SAX2DOM adapter: ''{0}''.",
- // XSLTC_SOURCE_ERR
+
+ /*
+ * Note to translators: SAX2DOM is the name of a Java class that should
+ * not be translated. This is an adapter in the sense that it takes a
+ * DOM object and converts it to something that uses the SAX API.
+ */
+ //SAX2DOM_ADAPTER_ERR
+ "Could not create SAX2DOM adapter: ''{0}''.",
+
+ /*
+ * Note to translators: "XSLTCSource.build()" is a Java method name.
+ * "systemId" is an XML term that is short for "system identification".
+ */
+ //XSLTC_SOURCE_ERR
"XSLTCSource.build() called without systemId being set.",
- // COMPILE_STDIN_ERR
+
+ //COMPILE_STDIN_ERR
"The -i option must be used with the -o option.",
- // COMPILE_USAGE_STR
- "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" +
+
+ /*
+ * Note to translators: This message contains usage information for a
+ * means of invoking XSLTC from the command-line. The message is
+ * formatted for presentation in English. The strings <output>,
+ * <directory>, etc. indicate user-specified argument values, and can
+ * be translated - the argument <package> refers to a Java package,
so
+ * it should be handled in the same way the term is handled for JDK
+ * documentation.
+ */
+ //COMPILE_USAGE_STR
+ "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" +
+ " 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"+
+ " 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
- "SYNOPSIS \n" +
+ " translet classes.\n"+
+ " -n enables template inlining (default behavior
better\n"+
+ " on average).\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",
+
+ /*
+ * Note to translators: This message contains usage information for a
+ * means of invoking XSLTC from the command-line. The message is
+ * formatted for presentation in English. The strings <jarfile>,
+ * <document>, etc. indicate user-specified argument values, and can
+ * be translated - the argument <class> refers to a Java class, so it
+ * should be handled in the same way the term is handled for JDK
+ * documentation.
+ */
+ //TRANSFORM_USAGE_STR
+ "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"+
+ " [-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" +
+ "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",
+ " -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
+ /*
+ * Note to translators: "<xsl:sort>", "<xsl:for-each>" and
+ * "<xsl:apply-templates>" are keywords that should not be translated.
+ * The message indicates that an xsl:sort element must be a child of
+ * one of the other kinds of elements mentioned.
+ */
+ //STRAY_SORT_ERR
"<xsl:sort> can only be used within <xsl:for-each> or
<xsl:apply-templates>.",
- // UNSUPPORTED_ENCODING
+
+ /*
+ * Note to translators: The message indicates that the encoding
+ * requested for the output document was on that requires support that
+ * is not available from the Java Virtual Machine being used to execute
+ * the program.
+ */
+ //UNSUPPORTED_ENCODING
"Output encoding ''{0}'' is not supported on this JVM.",
- // SYNTAX_ERR
- "Syntax error in ''{0}''."
+
+ /*
+ * Note to translators: The message indicates that the XPath expression
+ * named in the substitution text was not well formed syntactically.
+ */
+ //SYNTAX_ERR
+ "Syntax error in ''{0}''.",
+
+ /*
+ * Note to translators: The substitution text is the name of a Java
+ * class. The term "constructor" here is the Java term. The message is
+ * displayed if XSLTC could not find a constructor for the specified
+ * class.
+ */
+ //CONSTRUCTOR_NOT_FOUND
+ "Cannot find external constructor ''{0}''.",
+
+ /*
+ * Note to translators: "static" is the Java keyword. The substitution
+ * text is the name of a function. The first argument of that function
+ * is not of the required type.
+ */
+ //NO_JAVA_FUNCT_THIS_REF
+ "The first argument to the non-static Java function ''{0}'' is not a "+
+ "valid object reference.",
+
+ /*
+ * Note to translators: An XPath expression was not of the type
+ * required in a particular context. The substitution text is the
+ * expression that was in error.
+ */
+ //TYPE_CHECK_ERR
+ "Error checking type of the expression ''{0}''.",
+
+ /*
+ * Note to translators: An XPath expression was not of the type
+ * required in a particular context. However, the location of the
+ * problematic expression is unknown.
+ */
+ //TYPE_CHECK_UNK_LOC_ERR
+ "Error checking type of an expression at an unknown location.",
+
+ /*
+ * Note to translators: The substitution text is the name of a command-
+ * line option that was not recognized.
+ */
+ //ILLEGAL_CMDLINE_OPTION_ERR
+ "The command-line option ''{0}'' is not valid.",
+
+ /*
+ * Note to translators: The substitution text is the name of a command-
+ * line option.
+ */
+ //CMDLINE_OPT_MISSING_ARG_ERR
+ "The command-line option ''{0}'' is missing a required argument.",
+
+ /*
+ * Note to translators: This message is used to indicate the severity
+ * of another message. The substitution text contains two error
+ * messages. The spacing before the second substitution text indents
+ * it the same amount as the first in English.
+ */
+ //WARNING_PLUS_WRAPPED_MSG
+ "WARNING: ''{0}''\n :{1}",
+
+ /*
+ * Note to translators: This message is used to indicate the severity
+ * of another message. The substitution text is an error message.
+ */
+ //WARNING_MSG
+ "WARNING: ''{0}''",
+
+ /*
+ * Note to translators: This message is used to indicate the severity
+ * of another message. The substitution text contains two error
+ * messages. The spacing before the second substitution text indents
+ * it the same amount as the first in English.
+ */
+ //FATAL_ERR_PLUS_WRAPPED_MSG
+ "FATAL ERROR: ''{0}''\n :{1}",
+
+ /*
+ * Note to translators: This message is used to indicate the severity
+ * of another message. The substitution text is an error message.
+ */
+ //FATAL_ERR_MSG
+ "FATAL ERROR: ''{0}''",
+
+ /*
+ * Note to translators: This message is used to indicate the severity
+ * of another message. The substitution text contains two error
+ * messages. The spacing before the second substitution text indents
+ * it the same amount as the first in English.
+ */
+ //ERROR_PLUS_WRAPPED_MSG
+ "ERROR: ''{0}''\n :{1}",
+
+ /*
+ * Note to translators: This message is used to indicate the severity
+ * of another message. The substitution text is an error message.
+ */
+ //ERROR_MSG
+ "ERROR: ''{0}''",
+
+ /*
+ * Note to translators: The substitution text is the name of a class.
+ */
+ //TRANSFORM_WITH_TRANSLET_STR
+ "Transform using translet ''{0}'' ",
+
+ /*
+ * Note to translators: The first substitution is the name of a class,
+ * while the second substitution is the name of a jar file.
+ */
+ //TRANSFORM_WITH_JAR_STR
+ "Transform using translet ''{0}'' from jar file ''{1}''",
+
+ /*
+ * Note to translators: "TransformerFactory" is the name of a Java
+ * interface and must not be translated. The substitution text is
+ * the name of the class that could not be instantiated.
+ */
+ //COULD_NOT_CREATE_TRANS_FACT
+ "Could not create an instance of the TransformerFactory class
''{0}''."
};
private static Vector _keys;
1.14.2.1.2.1 +19 -5
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/ErrorMsg.java
Index: ErrorMsg.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/ErrorMsg.java,v
retrieving revision 1.14.2.1
retrieving revision 1.14.2.1.2.1
diff -u -r1.14.2.1 -r1.14.2.1.2.1
--- ErrorMsg.java 14 Aug 2002 19:21:40 -0000 1.14.2.1
+++ ErrorMsg.java 2 Dec 2002 15:51:22 -0000 1.14.2.1.2.1
@@ -163,10 +163,24 @@
public static final int TRANSFORM_USAGE_STR = 73;
// 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;
-
+ public static final int STRAY_SORT_ERR = 74;
+ public static final int UNSUPPORTED_ENCODING = 75;
+ public static final int SYNTAX_ERR = 76;
+ public static final int CONSTRUCTOR_NOT_FOUND = 77;
+ public static final int NO_JAVA_FUNCT_THIS_REF = 78;
+ public static final int TYPE_CHECK_ERR = 79;
+ public static final int TYPE_CHECK_UNK_LOC_ERR = 80;
+ public static final int ILLEGAL_CMDLINE_OPTION_ERR = 81;
+ public static final int CMDLINE_OPT_MISSING_ARG_ERR = 82;
+ public static final int WARNING_PLUS_WRAPPED_MSG = 83;
+ public static final int WARNING_MSG = 84;
+ public static final int FATAL_ERR_PLUS_WRAPPED_MSG = 85;
+ public static final int FATAL_ERR_MSG = 86;
+ public static final int ERROR_PLUS_WRAPPED_MSG = 87;
+ public static final int ERROR_MSG = 88;
+ public static final int TRANSFORM_WITH_TRANSLET_STR = 89;
+ public static final int TRANSFORM_WITH_JAR_STR = 90;
+
// All error messages are localized and are stored in resource bundles.
// This array and the following 4 strings are read from that bundle.
private static String[] _errorMessages;
1.3.8.1.2.1 +4 -1
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/IntType.java
Index: IntType.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/IntType.java,v
retrieving revision 1.3.8.1
retrieving revision 1.3.8.1.2.1
diff -u -r1.3.8.1 -r1.3.8.1.2.1
--- IntType.java 14 Aug 2002 19:21:40 -0000 1.3.8.1
+++ IntType.java 2 Dec 2002 15:51:22 -0000 1.3.8.1.2.1
@@ -231,6 +231,9 @@
else if (clazz == Double.TYPE) {
il.append(I2D);
}
+ else if (clazz.isAssignableFrom(java.lang.Integer.class)) {
+ translateTo(classGen, methodGen, Type.Reference);
+ }
else {
ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
toString(), clazz.getName());
1.3.2.1.2.1 +7 -6
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/MultiHashtable.java
Index: MultiHashtable.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/MultiHashtable.java,v
retrieving revision 1.3.2.1
retrieving revision 1.3.2.1.2.1
diff -u -r1.3.2.1 -r1.3.2.1.2.1
--- MultiHashtable.java 14 Aug 2002 19:21:40 -0000 1.3.2.1
+++ MultiHashtable.java 2 Dec 2002 15:51:22 -0000 1.3.2.1.2.1
@@ -75,17 +75,18 @@
return vector;
}
- public boolean maps(Object from, Object to) {
- if (from == null) return false;
+ public Object maps(Object from, Object to) {
+ if (from == null) return null;
final Vector vector = (Vector) get(from);
if (vector != null) {
final int n = vector.size();
for (int i = 0; i < n; i++) {
- if (vector.elementAt(i).equals(to)) {
- return true;
+ final Object item = vector.elementAt(i);
+ if (item.equals(to)) {
+ return item;
}
}
}
- return false;
+ return null;
}
}
1.10.2.1.2.1 +77 -2
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/NodeSetType.java
Index: NodeSetType.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/NodeSetType.java,v
retrieving revision 1.10.2.1
retrieving revision 1.10.2.1.2.1
diff -u -r1.10.2.1 -r1.10.2.1.2.1
--- NodeSetType.java 14 Aug 2002 19:21:40 -0000 1.10.2.1
+++ NodeSetType.java 2 Dec 2002 15:51:22 -0000 1.10.2.1.2.1
@@ -113,6 +113,9 @@
else if (type == Type.Reference) {
translateTo(classGen, methodGen, (ReferenceType) type);
}
+ else if (type == Type.Object) {
+ translateTo(classGen, methodGen, (ObjectType) type);
+ }
else {
ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
toString(), type.toString());
@@ -121,6 +124,54 @@
}
/**
+ * Translates an external Java Class into an internal type.
+ * Expects the Java object on the stack, pushes the internal type
+ */
+ public void translateFrom(ClassGenerator classGen,
+ MethodGenerator methodGen, Class clazz)
+ {
+
+ InstructionList il = methodGen.getInstructionList();
+ ConstantPoolGen cpg = classGen.getConstantPool();
+ if (clazz.getName().equals("org.w3c.dom.NodeList")) {
+ // w3c NodeList is on the stack from the external Java function call.
+ // call BasisFunction to consume NodeList and leave Iterator on
+ // the stack.
+ il.append(classGen.loadTranslet()); // push translet onto stack
+ il.append(methodGen.loadDOM()); // push DOM onto stack
+ final int convert = cpg.addMethodref(BASIS_LIBRARY_CLASS,
+ "nodeList2Iterator",
+ "("
+ + "Lorg/w3c/dom/NodeList;"
+ + TRANSLET_INTF_SIG
+ + DOM_INTF_SIG
+ + ")" + NODE_ITERATOR_SIG );
+ il.append(new INVOKESTATIC(convert));
+ }
+ else if (clazz.getName().equals("org.w3c.dom.Node")) {
+ // w3c Node is on the stack from the external Java function call.
+ // call BasisLibrary.node2Iterator() to consume Node and leave
+ // Iterator on the stack.
+ il.append(classGen.loadTranslet()); // push translet onto stack
+ il.append(methodGen.loadDOM()); // push DOM onto stack
+ final int convert = cpg.addMethodref(BASIS_LIBRARY_CLASS,
+ "node2Iterator",
+ "("
+ + "Lorg/w3c/dom/Node;"
+ + TRANSLET_INTF_SIG
+ + DOM_INTF_SIG
+ + ")" + NODE_ITERATOR_SIG );
+ il.append(new INVOKESTATIC(convert));
+ }
+ else {
+ ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
+ toString(), clazz.getName());
+ classGen.getParser().reportError(Constants.FATAL, err);
+ }
+ }
+
+
+ /**
* Translates a node-set into a synthesized boolean.
* The boolean value of a node-set is "true" if non-empty
* and "false" otherwise. Notice that the
@@ -180,6 +231,16 @@
}
/**
+ * Subsume node-set into ObjectType.
+ *
+ * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo
+ */
+ public void translateTo(ClassGenerator classGen, MethodGenerator
methodGen,
+ ObjectType type) {
+ methodGen.getInstructionList().append(NOP);
+ }
+
+ /**
* Translates a node-set into 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.
@@ -225,12 +286,26 @@
MAKE_NODE_SIG2);
il.append(new INVOKEINTERFACE(index, 2));
}
- else if (className.equals("org.w3c.dom.NodeList")) {
+ else if (className.equals("org.w3c.dom.NodeList") ||
+ className.equals("java.lang.Object")) {
int index = cpg.addInterfaceMethodref(DOM_INTF,
MAKE_NODE_LIST,
MAKE_NODE_LIST_SIG2);
il.append(new INVOKEINTERFACE(index, 2));
}
+ else if (className.equals("java.lang.String")) {
+ int next = cpg.addInterfaceMethodref(NODE_ITERATOR,
+ "next", "()I");
+ int index = cpg.addInterfaceMethodref(DOM_INTF,
+ GET_NODE_VALUE,
+ "(I)"+STRING_SIG);
+
+ // Get next node from the iterator
+ il.append(new INVOKEINTERFACE(next, 1));
+ // Get the node's string value (from the DOM)
+ il.append(new INVOKEINTERFACE(index, 2));
+
+ }
else if (className.equals("int")) {
int next = cpg.addInterfaceMethodref(NODE_ITERATOR,
"next", "()I");
1.8.2.1.2.1 +22 -3
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/NodeType.java
Index: NodeType.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/NodeType.java,v
retrieving revision 1.8.2.1
retrieving revision 1.8.2.1.2.1
diff -u -r1.8.2.1 -r1.8.2.1.2.1
--- NodeType.java 14 Aug 2002 19:21:40 -0000 1.8.2.1
+++ NodeType.java 2 Dec 2002 15:51:22 -0000 1.8.2.1.2.1
@@ -129,6 +129,9 @@
else if (type == Type.Reference) {
translateTo(classGen, methodGen, (ReferenceType) type);
}
+ else if (type == Type.Object) {
+ translateTo(classGen, methodGen, (ObjectType) type);
+ }
else {
ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
toString(), type.toString());
@@ -228,6 +231,16 @@
}
/**
+ * Subsume Node into ObjectType.
+ *
+ * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo
+ */
+ public void translateTo(ClassGenerator classGen, MethodGenerator
methodGen,
+ ObjectType type) {
+ methodGen.getInstructionList().append(NOP);
+ }
+
+ /**
* Translates a node into 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.
@@ -269,11 +282,17 @@
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
+ String className = clazz.getName();
+ if (className.equals("java.lang.String")) {
+ translateTo(classGen, methodGen, Type.String);
+ return;
+ }
+
il.append(methodGen.loadDOM());
il.append(SWAP); // dom ref must be below node index
- String className = clazz.getName();
- if (className.equals("org.w3c.dom.Node")) {
+ if (className.equals("org.w3c.dom.Node") ||
+ className.equals("java.lang.Object")) {
int index = cpg.addInterfaceMethodref(DOM_INTF,
MAKE_NODE,
MAKE_NODE_SIG);
1.1.4.1 +37 -2
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/ObjectType.java
Index: ObjectType.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/ObjectType.java,v
retrieving revision 1.1
retrieving revision 1.1.4.1
diff -u -r1.1 -r1.1.4.1
--- ObjectType.java 25 Jul 2002 11:42:13 -0000 1.1
+++ ObjectType.java 2 Dec 2002 15:51:22 -0000 1.1.4.1
@@ -67,10 +67,12 @@
import org.apache.bcel.generic.*;
import org.apache.xalan.xsltc.compiler.Parser;
import org.apache.xalan.xsltc.compiler.Constants;
+import org.apache.xalan.xsltc.runtime.TransletLoader;
public final class ObjectType extends Type {
- private String _javaClassName = "java.lang.Object";
+ private String _javaClassName = "java.lang.Object";
+ private Class _clazz = java.lang.Object.class;
/**
* Used to represent an 'any' type.
@@ -84,6 +86,19 @@
*/
public ObjectType(String javaClassName) {
_javaClassName = javaClassName;
+
+ try {
+ TransletLoader loader = new TransletLoader();
+ _clazz = loader.loadClass(javaClassName);
+ }
+ catch (ClassNotFoundException e) {
+ _clazz = null;
+ }
+ }
+
+ public ObjectType(Class clazz) {
+ _clazz = clazz;
+ _javaClassName = clazz.getName();
}
public int hashCode() {
@@ -97,6 +112,10 @@
public String getJavaClassName() {
return _javaClassName;
}
+
+ public Class getJavaClass() {
+ return _clazz;
+ }
public String toString() {
return "object";
@@ -157,6 +176,22 @@
gotobh.setTarget(il.append(NOP));
}
+ /**
+ * Translates an object of this type to the external (Java) type denoted
+ * by <code>clazz</code>. This method is used to translate parameters
+ * when external functions are called.
+ */
+ public void translateTo(ClassGenerator classGen, MethodGenerator
methodGen,
+ Class clazz) {
+ if (clazz.isAssignableFrom(_clazz))
+ methodGen.getInstructionList().append(NOP);
+ else {
+ ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
+ toString(), clazz.getClass().toString());
+ classGen.getParser().reportError(Constants.FATAL, err);
+ }
+ }
+
/**
* Translates an external Java type into an Object type
*/
1.3.8.1.2.1 +4 -1
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/RealType.java
Index: RealType.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/RealType.java,v
retrieving revision 1.3.8.1
retrieving revision 1.3.8.1.2.1
diff -u -r1.3.8.1 -r1.3.8.1.2.1
--- RealType.java 14 Aug 2002 19:21:40 -0000 1.3.8.1
+++ RealType.java 2 Dec 2002 15:51:22 -0000 1.3.8.1.2.1
@@ -260,6 +260,9 @@
else if (clazz == Double.TYPE) {
il.append(NOP);
}
+ else if (clazz.isAssignableFrom(java.lang.Double.class)) {
+ translateTo(classGen, methodGen, Type.Reference);
+ }
else {
ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
toString(), clazz.getName());
1.11.2.1.2.1 +47 -3
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/ReferenceType.java
Index: ReferenceType.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/ReferenceType.java,v
retrieving revision 1.11.2.1
retrieving revision 1.11.2.1.2.1
diff -u -r1.11.2.1 -r1.11.2.1.2.1
--- ReferenceType.java 14 Aug 2002 19:21:40 -0000 1.11.2.1
+++ ReferenceType.java 2 Dec 2002 15:51:22 -0000 1.11.2.1.2.1
@@ -116,6 +116,9 @@
else if (type == Type.ResultTree) {
translateTo(classGen, methodGen, (ResultTreeType) type);
}
+ else if (type == Type.Object) {
+ translateTo(classGen, methodGen, (ObjectType) type);
+ }
else {
ErrorMsg err = new ErrorMsg(ErrorMsg.INTERNAL_ERR, type.toString());
classGen.getParser().reportError(Constants.FATAL, err);
@@ -228,13 +231,54 @@
}
/**
+ * Subsume reference into ObjectType.
+ *
+ * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo
+ */
+ public void translateTo(ClassGenerator classGen, MethodGenerator
methodGen,
+ ObjectType type) {
+ methodGen.getInstructionList().append(NOP);
+ }
+
+ /**
* 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) {
+ final ConstantPoolGen cpg = classGen.getConstantPool();
+ final InstructionList il = methodGen.getInstructionList();
+
if (clazz.getName().equals("java.lang.Object")) {
- methodGen.getInstructionList().append(NOP);
+ il.append(NOP);
+ }
+ else if (clazz == Double.TYPE) {
+ translateTo(classGen, methodGen, Type.Real);
+ }
+ else if (clazz.getName().equals("java.lang.String")) {
+ translateTo(classGen, methodGen, Type.String);
+ }
+ else if (clazz.getName().equals("org.w3c.dom.Node")) {
+ int index = cpg.addMethodref(BASIS_LIBRARY_CLASS,
"referenceToNode",
+ "("
+ + OBJECT_SIG
+ + DOM_INTF_SIG
+ + ")"
+ + "Lorg/w3c/dom/Node;");
+ il.append(methodGen.loadDOM());
+ il.append(new INVOKESTATIC(index));
+ }
+ else if (clazz.getName().equals("org.w3c.dom.NodeList")) {
+ int index = cpg.addMethodref(BASIS_LIBRARY_CLASS,
"referenceToNodeList",
+ "("
+ + OBJECT_SIG
+ + DOM_INTF_SIG
+ + ")"
+ + "Lorg/w3c/dom/NodeList;");
+ il.append(methodGen.loadDOM());
+ il.append(new INVOKESTATIC(index));
+ }
+ else if (clazz.getName().equals("org.apache.xalan.xsltc.DOM")) {
+ translateTo(classGen, methodGen, Type.ResultTree);
}
else {
ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
1.11.2.1.2.1 +29 -8
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/ResultTreeType.java
Index: ResultTreeType.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/ResultTreeType.java,v
retrieving revision 1.11.2.1
retrieving revision 1.11.2.1.2.1
diff -u -r1.11.2.1 -r1.11.2.1.2.1
--- ResultTreeType.java 14 Aug 2002 19:21:40 -0000 1.11.2.1
+++ ResultTreeType.java 2 Dec 2002 15:51:22 -0000 1.11.2.1.2.1
@@ -134,6 +134,9 @@
else if (type == Type.Reference) {
translateTo(classGen, methodGen, (ReferenceType)type);
}
+ else if (type == Type.Object) {
+ translateTo(classGen, methodGen, (ObjectType) type);
+ }
else {
ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
toString(), type.toString());
@@ -264,12 +267,12 @@
}
il.append(methodGen.loadDOM());
- // Create new instance of DOM class (with 64 nodes)
+ // Create new instance of DOM class
int index = cpg.addMethodref(DOM_IMPL, "<init>", "(I)V");
il.append(new NEW(cpg.addClass(DOM_IMPL)));
il.append(DUP);
il.append(DUP);
- il.append(new PUSH(cpg, 64));
+ il.append(new PUSH(cpg, RTF_INITIAL_SIZE));
il.append(new INVOKESPECIAL(index));
// Store new DOM into a local variable
@@ -359,12 +362,21 @@
il.append(new INVOKEINTERFACE(mapping, 3));
il.append(DUP);
- // Create an iterator with all the nodes in the DOM adapter
+ // Create an iterator for the root node of the DOM adapter
final int iter = cpg.addInterfaceMethodref(DOM_INTF,
- "getChildren",
- "(I)"+NODE_ITERATOR_SIG);
- il.append(new PUSH(cpg, DOM.ROOTNODE));
- il.append(new INVOKEINTERFACE(iter, 2));
+ "getIterator",
+ "()"+NODE_ITERATOR_SIG);
+ il.append(new INVOKEINTERFACE(iter, 1));
+ }
+
+ /**
+ * Subsume result tree into ObjectType.
+ *
+ * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo
+ */
+ public void translateTo(ClassGenerator classGen, MethodGenerator
methodGen,
+ ObjectType type) {
+ methodGen.getInstructionList().append(NOP);
}
/**
@@ -417,6 +429,15 @@
MAKE_NODE_LIST_SIG2);
il.append(new INVOKEINTERFACE(index, 2));
}
+ else if (className.equals("java.lang.Object")) {
+ il.append(NOP);
+ }
+ else if (className.equals("java.lang.String")) {
+ translateTo(classGen, methodGen, Type.String);
+ }
+ else if (clazz == Double.TYPE) {
+ translateTo(classGen, methodGen, Type.Real);
+ }
else {
ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
toString(), className);
1.6.2.1.2.1 +23 -6
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/StringType.java
Index: StringType.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/StringType.java,v
retrieving revision 1.6.2.1
retrieving revision 1.6.2.1.2.1
diff -u -r1.6.2.1 -r1.6.2.1.2.1
--- StringType.java 14 Aug 2002 19:21:40 -0000 1.6.2.1
+++ StringType.java 2 Dec 2002 15:51:22 -0000 1.6.2.1.2.1
@@ -182,8 +182,9 @@
* @see org.apache.xalan.xsltc.compiler.util.Type#translateFrom
*/
public void translateTo(ClassGenerator classGen, MethodGenerator
methodGen,
- Class clazz) {
- if (clazz.getName().equals("java.lang.String")) {
+ Class clazz)
+ {
+ if (clazz.isAssignableFrom(java.lang.String.class)) {
// same internal representation
methodGen.getInstructionList().append(NOP);
}
@@ -199,9 +200,25 @@
*
* @see org.apache.xalan.xsltc.compiler.util.Type#translateFrom
*/
- public void translateFrom(ClassGenerator classGen, MethodGenerator
methodGen,
- Class clazz) {
- translateTo(classGen, methodGen, clazz);
+ public void translateFrom(ClassGenerator classGen,
+ MethodGenerator methodGen, Class clazz)
+ {
+ final ConstantPoolGen cpg = classGen.getConstantPool();
+ final InstructionList il = methodGen.getInstructionList();
+
+ if (clazz.getName().equals("java.lang.String")) {
+ // same internal representation, convert null to ""
+ il.append(DUP);
+ final BranchHandle ifNonNull = il.append(new IFNONNULL(null));
+ il.append(POP);
+ il.append(new PUSH(cpg, ""));
+ ifNonNull.setTarget(il.append(NOP));
+ }
+ else {
+ ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
+ toString(), clazz.getName());
+ classGen.getParser().reportError(Constants.FATAL, err);
+ }
}
/**
1.11.2.1.2.1 +2 -2
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/Type.java
Index: Type.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/Type.java,v
retrieving revision 1.11.2.1
retrieving revision 1.11.2.1.2.1
diff -u -r1.11.2.1 -r1.11.2.1.2.1
--- Type.java 14 Aug 2002 19:21:40 -0000 1.11.2.1
+++ Type.java 2 Dec 2002 15:51:22 -0000 1.11.2.1.2.1
@@ -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();
@@ -80,6 +79,7 @@
public static final Type ResultTree = new ResultTreeType();
public static final Type Reference = new ReferenceType();
public static final Type Void = new VoidType();
+ public static final Type Object = new ObjectType();
public static final Type Node = new NodeType(NodeTest.ANODE);
public static final Type Root = new NodeType(NodeTest.ROOT);
1.2.2.1.2.1 +14 -11
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/TypeCheckError.java
Index: TypeCheckError.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/TypeCheckError.java,v
retrieving revision 1.2.2.1
retrieving revision 1.2.2.1.2.1
diff -u -r1.2.2.1 -r1.2.2.1.2.1
--- TypeCheckError.java 14 Aug 2002 19:21:40 -0000 1.2.2.1
+++ TypeCheckError.java 2 Dec 2002 15:51:22 -0000 1.2.2.1.2.1
@@ -89,19 +89,22 @@
_error = new ErrorMsg(code, param1, param2);
}
+ public ErrorMsg getErrorMsg() {
+ return _error;
+ }
+
public String toString() {
String result;
- if (_error != null) {
- result = _error.toString();
- }
- else if (_node != null) {
- result = "Type check error in " + _node.toString() + ".";
- }
- else {
- result = "Type check error (no line information).";
- }
+ if (_error == null) {
+ if (_node != null) {
+ _error = new ErrorMsg(ErrorMsg.TYPE_CHECK_ERR,
+ _node.toString());
+ } else {
+ _error = new ErrorMsg(ErrorMsg.TYPE_CHECK_UNK_LOC_ERR);
+ }
+ }
- return result;
+ return _error.toString();
}
}
1.9.2.1.2.1 +24 -4
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/Util.java
Index: Util.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/Util.java,v
retrieving revision 1.9.2.1
retrieving revision 1.9.2.1.2.1
diff -u -r1.9.2.1 -r1.9.2.1.2.1
--- Util.java 14 Aug 2002 19:21:40 -0000 1.9.2.1
+++ Util.java 2 Dec 2002 15:51:22 -0000 1.9.2.1.2.1
@@ -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;
@@ -85,11 +86,20 @@
* files.
*/
public static String baseName(String name) {
- int index = name.lastIndexOf('/');
+ int index = name.lastIndexOf('\\');
if (index < 0) {
- index = name.lastIndexOf('\\');
+ index = name.lastIndexOf('/');
+ }
+
+ if (index >= 0)
+ return name.substring(index + 1);
+ else {
+ int lastColonIndex = name.lastIndexOf(':');
+ if (lastColonIndex > 0)
+ return name.substring(lastColonIndex + 1);
+ else
+ return name;
}
- return name.substring(index + 1);
}
/**
@@ -186,5 +196,15 @@
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;
+ }
}
No revision
No revision
1.1.2.1 +1 -1
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/NodeSortRecordFactGenerator.java
Index: NodeSortRecordFactGenerator.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/NodeSortRecordFactGenerator.java,v
retrieving revision 1.1
retrieving revision 1.1.2.1
diff -u -r1.1 -r1.1.2.1
No revision
No revision
1.7.2.1.2.1 +43 -13
xml-xalan/java/src/org/apache/xalan/xsltc/dom/AbsoluteIterator.java
Index: AbsoluteIterator.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/AbsoluteIterator.java,v
retrieving revision 1.7.2.1
retrieving revision 1.7.2.1.2.1
diff -u -r1.7.2.1 -r1.7.2.1.2.1
--- AbsoluteIterator.java 14 Aug 2002 19:21:41 -0000 1.7.2.1
+++ AbsoluteIterator.java 2 Dec 2002 15:51:23 -0000 1.7.2.1.2.1
@@ -67,37 +67,67 @@
import org.apache.xalan.xsltc.NodeIterator;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
+/**
+ * Absolute iterators ignore the node that is passed to setStartNode().
+ * Instead, they always start from the root node. The node passed to
+ * setStartNode() is not totally useless, though. It is needed to obtain the
+ * DOM mask, i.e. the index into the MultiDOM table that corresponds to the
+ * DOM "owning" the node.
+ *
+ * The DOM mask is cached, so successive calls to setStartNode() passing
+ * nodes from other DOMs will have no effect (i.e. this iterator cannot
+ * migrate between DOMs).
+ */
public final class AbsoluteIterator extends NodeIteratorBase {
+
+ /**
+ * Initial value for DOM masks.
+ */
+ private static final int NO_MASK = -1;
+
+ /**
+ * Source for this iterator.
+ */
private NodeIterator _source;
+
+ /**
+ * DOM mask cached after first call to setStartNode().
+ */
+ private int _mask = NO_MASK;
public AbsoluteIterator(NodeIterator source) {
_source = source;
- }
-
- public int next() {
- return returnNode(_source.next());
+// System.out.println("AI source = " + source + " this = " + this);
}
public void setRestartable(boolean isRestartable) {
_isRestartable = isRestartable;
_source.setRestartable(isRestartable);
}
-
+
public NodeIterator setStartNode(int node) {
- _startNode = DOM.ROOTNODE;
if (_isRestartable) {
+ if (_mask == NO_MASK) {
+ _mask = node & 0xFF000000;
+ }
+ _startNode = _mask | DOM.ROOTNODE;
+ _source.setStartNode(_startNode);
resetPosition();
- return _source.setStartNode(_startNode = DOM.ROOTNODE);
}
- return reset();
+ return this;
+ }
+
+ public int next() {
+ return returnNode(_source.next());
}
public NodeIterator cloneIterator() {
try {
- final AbsoluteIterator clone = (AbsoluteIterator)super.clone();
- clone.setRestartable(false);
- clone._source = _source.cloneIterator();
- return clone.reset();
+ final AbsoluteIterator clone = (AbsoluteIterator) super.clone();
+ clone._source = _source.cloneIterator(); // resets source
+ clone.resetPosition();
+ clone._isRestartable = false;
+ return clone;
}
catch (CloneNotSupportedException e) {
BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
1.8.2.1.2.1 +57 -22
xml-xalan/java/src/org/apache/xalan/xsltc/dom/CurrentNodeListIterator.java
Index: CurrentNodeListIterator.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/CurrentNodeListIterator.java,v
retrieving revision 1.8.2.1
retrieving revision 1.8.2.1.2.1
diff -u -r1.8.2.1 -r1.8.2.1.2.1
--- CurrentNodeListIterator.java 14 Aug 2002 19:21:41 -0000 1.8.2.1
+++ CurrentNodeListIterator.java 2 Dec 2002 15:51:23 -0000
1.8.2.1.2.1
@@ -69,17 +69,51 @@
import org.apache.xalan.xsltc.util.IntegerArray;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
+/**
+ * Iterators of this kind use a CurrentNodeListFilter to filter a subset of
+ * nodes from a source iterator. For each node from the source, the boolean
+ * method CurrentNodeListFilter.test() is called.
+ *
+ * All nodes from the source are read into an array upon calling
setStartNode()
+ * (this is needed to determine the value of last, a parameter to
+ * CurrentNodeListFilter.test()). The method getLast() returns the last
element
+ * after applying the filter.
+ */
public final class CurrentNodeListIterator extends NodeIteratorBase {
+ /**
+ * A flag indicating if nodes are returned in document order.
+ */
private boolean _docOrder;
+
+ /**
+ * The source for this iterator.
+ */
private NodeIterator _source;
+
+ /**
+ * A reference to a filter object.
+ */
private final CurrentNodeListFilter _filter;
+
+ /**
+ * An integer array to store nodes from source iterator.
+ */
private IntegerArray _nodes = new IntegerArray();
- private int _current; // index in _nodes of the next node to try
- private int _last = -1;
+ /**
+ * Index in _nodes of the next node to filter.
+ */
+ private int _currentIndex;
+ /**
+ * The current node in the stylesheet at the time of evaluation.
+ */
private final int _currentNode;
+
+ /**
+ * A reference to the translet.
+ */
private AbstractTranslet _translet;
public CurrentNodeListIterator(NodeIterator source,
@@ -114,9 +148,10 @@
public NodeIterator cloneIterator() {
try {
final CurrentNodeListIterator clone =
- (CurrentNodeListIterator)super.clone();
- clone._nodes = (IntegerArray)_nodes.clone();
- clone.setRestartable(false);
+ (CurrentNodeListIterator) super.clone();
+ clone._nodes = (IntegerArray) _nodes.clone();
+ clone._source = _source.cloneIterator();
+ clone._isRestartable = false;
return clone.reset();
}
catch (CloneNotSupportedException e) {
@@ -127,7 +162,7 @@
}
public NodeIterator reset() {
- _current = 0;
+ _currentIndex = 0;
return resetPosition();
}
@@ -136,10 +171,12 @@
final int currentNode = _currentNode;
final AbstractTranslet translet = _translet;
- for (int index = _current; index < last; ) {
+ for (int index = _currentIndex; index < last; ) {
+ final int position = _docOrder ? index + 1 : last - index;
final int node = _nodes.at(index++); // note increment
- if (_filter.test(node, index, last, currentNode, translet, this)) {
- _current = index;
+
+ if (_filter.test(node, position, last, currentNode, translet,
this)) {
+ _currentIndex = index;
return returnNode(node);
}
}
@@ -147,8 +184,6 @@
}
public NodeIterator setStartNode(int node) {
- NodeIterator retval = this;
-
if (_isRestartable) {
_source.setStartNode(_startNode = node);
@@ -156,10 +191,10 @@
while ((node = _source.next()) != END) {
_nodes.add(node);
}
- _current = 0;
- retval = resetPosition();
+ _currentIndex = 0;
+ resetPosition();
}
- return retval;
+ return this;
}
public int getLast() {
@@ -170,13 +205,11 @@
}
public void setMark() {
- _source.setMark();
- _markedNode = _current;
+ _markedNode = _currentIndex;
}
public void gotoMark() {
- _source.gotoMark();
- _current = _markedNode;
+ _currentIndex = _markedNode;
}
private int computePositionOfLast() {
@@ -184,10 +217,12 @@
final int currNode = _currentNode;
final AbstractTranslet translet = _translet;
- int lastPosition = 0;
- for (int index = _current; index < last; ) {
+ int lastPosition = _position;
+ for (int index = _currentIndex; index < last; ) {
+ final int position = _docOrder ? index + 1 : last - index;
int nodeIndex = _nodes.at(index++); // note increment
- if (_filter.test(nodeIndex, index, last, currNode, translet,
this)) {
+
+ if (_filter.test(nodeIndex, position, last, currNode, translet,
this)) {
lastPosition++;
}
}
1.1.16.1.2.1 +1 -1
xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOM.java.Palm
Index: DOM.java.Palm
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOM.java.Palm,v
retrieving revision 1.1.16.1
retrieving revision 1.1.16.1.2.1
diff -u -r1.1.16.1 -r1.1.16.1.2.1
1.13.2.1.2.1 +79 -47
xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMAdapter.java
Index: DOMAdapter.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMAdapter.java,v
retrieving revision 1.13.2.1
retrieving revision 1.13.2.1.2.1
diff -u -r1.13.2.1 -r1.13.2.1.2.1
--- DOMAdapter.java 14 Aug 2002 19:21:42 -0000 1.13.2.1
+++ DOMAdapter.java 2 Dec 2002 15:51:23 -0000 1.13.2.1.2.1
@@ -73,11 +73,16 @@
import org.apache.xalan.xsltc.TransletException;
public final class DOMAdapter implements DOM {
+
private final DOMImpl _domImpl;
- private short[] _mapping;
- private short[] _reverse;
- private short[] _NSmapping;
- private short[] _NSreverse;
+ private String[] _namesArray;
+ private String[] _namespaceArray;
+
+ // Cached mappings
+ private short[] _mapping = null;
+ private short[] _reverse = null;
+ private short[] _NSmapping = null;
+ private short[] _NSreverse = null;
private StripFilter _filter = null;
@@ -85,22 +90,49 @@
public DOMAdapter(DOMImpl dom,
String[] namesArray,
- String[] namespaceArray) {
+ String[] namespaceArray)
+ {
_domImpl = dom;
- _mapping = dom.getMapping(namesArray);
- _reverse = dom.getReverseMapping(namesArray);
- _NSmapping = dom.getNamespaceMapping(namespaceArray);
- _NSreverse = dom.getReverseNamespaceMapping(namespaceArray);
+ _namesArray = namesArray;
+ _namespaceArray = namespaceArray;
}
public void setupMapping(String[] names, String[] namespaces) {
- _mapping = _domImpl.getMapping(names);
- _reverse = _domImpl.getReverseMapping(names);
- _NSmapping = _domImpl.getNamespaceMapping(namespaces);
- _NSreverse = _domImpl.getReverseNamespaceMapping(namespaces);
+ _namesArray = names;
+ _namespaceArray = namespaces;
+ }
+
+ private short[] getMapping() {
+ if (_mapping == null) {
+ _mapping = _domImpl.getMapping(_namesArray);
+ }
+ return _mapping;
+ }
+
+ private short[] getReverse() {
+ if (_reverse == null) {
+ _reverse = _domImpl.getReverseMapping(_namesArray);
+ }
+ return _reverse;
+ }
+
+ private short[] getNSMapping() {
+ if (_NSmapping == null) {
+ _NSmapping = _domImpl.getNamespaceMapping(_namespaceArray);
+ }
+ return _NSmapping;
}
- /** returns singleton iterator containg the document root */
+ private short[] getNSReverse() {
+ if (_NSreverse == null) {
+ _NSreverse = _domImpl.getReverseNamespaceMapping(_namespaceArray);
+ }
+ return _NSreverse;
+ }
+
+ /**
+ * Returns singleton iterator containg the document root
+ */
public NodeIterator getIterator() {
return _domImpl.getIterator();
}
@@ -124,11 +156,12 @@
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, getMapping(),
+ _filter);
+ return iterator.setStartNode(node);
}
}
@@ -137,47 +170,54 @@
}
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);
+ final short[] reverse = getReverse();
+
+ NodeIterator iterator = _domImpl.getTypedChildren(reverse[type]);
+ if (reverse[type] == DOM.TEXT && _filter != null) {
+ return _domImpl.strippingIterator(iterator, getMapping(), _filter);
+ }
+ return iterator;
}
public NodeIterator getNamespaceAxisIterator(final int axis, final int
ns) {
- return _domImpl.getNamespaceAxisIterator(axis,_NSreverse[ns]);
+ return _domImpl.getNamespaceAxisIterator(axis, getNSReverse()[ns]);
}
public NodeIterator getAxisIterator(final int axis) {
NodeIterator iterator = _domImpl.getAxisIterator(axis);
if (_filter != null) {
- iterator = _domImpl.strippingIterator(iterator,_mapping,_filter);
+ return _domImpl.strippingIterator(iterator, getMapping(), _filter);
}
- return(iterator);
+ return iterator;
}
public NodeIterator getTypedAxisIterator(final int axis, final int type)
{
NodeIterator iterator;
+ final short[] reverse = getReverse();
+ final short[] NSreverse = getNSReverse();
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 {
+ iterator = _domImpl.getTypedAxisIterator(axis, reverse[type]);
}
- 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, getMapping(),
_filter);
+ }
+ return iterator;
}
public NodeIterator getNthDescendant(int type, int n, boolean
includeself) {
- return _domImpl.getNthDescendant(_reverse[type], n, includeself);
+ return _domImpl.getNthDescendant(getReverse()[type], n, includeself);
}
public NodeIterator getNodeValueIterator(NodeIterator iterator, int type,
- String value, boolean op) {
+ String value, boolean op)
+ {
return _domImpl.getNodeValueIterator(iterator, type, value, op);
}
@@ -186,27 +226,19 @@
}
public int getType(final int node) {
- return _mapping[_domImpl.getType(node)];
+ return getMapping()[_domImpl.getType(node)];
}
public int getNamespaceType(final int node) {
- return _NSmapping[_domImpl.getNamespaceType(node)];
+ return getNSMapping()[_domImpl.getNamespaceType(node)];
}
public int getParent(final int node) {
return _domImpl.getParent(node);
}
- public int getTypedPosition(int type, int node) {
- return _domImpl.getTypedPosition(_reverse[type], node);
- }
-
- public int getTypedLast(int type, int node) {
- return _domImpl.getTypedLast(_reverse[type], node);
- }
-
public int getAttributeNode(final int type, final int element) {
- return _domImpl.getAttributeNode(_reverse[type], element);
+ return _domImpl.getAttributeNode(getReverse()[type], element);
}
public String getNodeName(final int node) {
1.78.2.1.2.1 +196 -234
xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMImpl.java
Index: DOMImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMImpl.java,v
retrieving revision 1.78.2.1
retrieving revision 1.78.2.1.2.1
diff -u -r1.78.2.1 -r1.78.2.1.2.1
--- DOMImpl.java 14 Aug 2002 19:21:42 -0000 1.78.2.1
+++ DOMImpl.java 2 Dec 2002 15:51:23 -0000 1.78.2.1.2.1
@@ -153,6 +153,10 @@
private final static String XML_LANG_ATTRIBUTE =
"http://www.w3.org/XML/1998/namespace:@lang";
+ // Types for generic elements and attributes
+ private final static Integer elementInt = new Integer(ELEMENT);
+ private final static Integer attributeInt = new Integer(ATTRIBUTE);
+
/**
* Define the origin of the document from which the tree was built
*/
@@ -164,7 +168,10 @@
* Returns the origin of the document from which the tree was built
*/
public String getDocumentURI() {
- return (_documentURI != null) ? _documentURI : "rtf" +
_documentURIIndex++;
+ synchronized (getClass()) { // synchornize access to static
+ return (_documentURI != null) ? _documentURI :
+ "rtf" + _documentURIIndex++;
+ }
}
public String getDocumentURI(int node) {
@@ -202,8 +209,8 @@
}
}
- // TODO: Internationalization?
- throw new TransletException("Namespace prefix '" + prefix + "' is
undeclared.");
+ BasisLibrary.runTimeError(BasisLibrary.NAMESPACE_PREFIX_ERR, prefix);
+ return null;
}
/**
@@ -648,14 +655,13 @@
if (node >= _firstAttributeNode) node = NULL;
if (node != _startNode) _last = -1;
_startNode = node;
+
if (_includeSelf) {
_currentChild = -1;
}
else {
- if (hasChildren(node))
- _currentChild = _offsetOrChild[node];
- else
- _currentChild = END;
+ _currentChild = hasChildren(node) ? _offsetOrChild[node]
+ : END;
}
return resetPosition();
}
@@ -667,10 +673,9 @@
if (_includeSelf) {
if (node == -1) {
node = _startNode;
- if (hasChildren(node))
- _currentChild = _offsetOrChild[node];
- else
- _currentChild = END;
+ _currentChild = hasChildren(node) ? _offsetOrChild[node]
+ : END;
+
// IMPORTANT: The start node (parent of all children) is
// returned, but the node position counter (_position)
// should not be increased, so returnNode() is not called
@@ -691,11 +696,16 @@
public int getLast() {
if (_last == -1) {
- _last = 1;
- int node = _offsetOrChild[_startNode];
- while ((node = _nextSibling[node]) != END) _last++;
+ _last = 0;
+
+ int node;
+ if ((node = _offsetOrChild[_startNode]) != END) {
+ do {
+ _last++;
+ } while ((node = _nextSibling[node]) != END);
+ }
}
- return(_last);
+ return _last;
}
} // end of ChildrenIterator
@@ -1144,26 +1154,20 @@
* Iterator that returns preceding siblings of a given node
*/
private class PrecedingSiblingIterator extends NodeIteratorBase {
-
+
private int _node;
- private int _mom;
-
+ private int _sibling;
+
public boolean isReverse() {
return true;
}
public NodeIterator setStartNode(int node) {
if (_isRestartable) {
- if (node >= _firstAttributeNode) node = NULL;
- int tmp = NULL;
- _startNode = node;
- _mom = _parent[node];
- _node = _offsetOrChild[_mom];
- while ((_node != node) && (_node != NULL)) {
- tmp = _node;
- _node = _nextSibling[_node];
- }
- _node = tmp;
+ _node = node;
+ _sibling = _startNode = (node >= _firstAttributeNode) ?
+ NULL : _offsetOrChild[_parent[node]];
+ _last = -1;
return resetPosition();
}
return this;
@@ -1171,27 +1175,30 @@
public int next() {
// Return NULL if end already reached
- if (_node == NULL) return NULL;
-
- int current = _offsetOrChild[_mom];
+ if (_sibling == NULL) {
+ return END;
+ }
- // Otherwise find the next preceeding sibling
- int last = NULL;
- while ((current != _node) && (current != NULL)) {
- last = current;
- current = _nextSibling[current];
+ if (_sibling == _node) {
+ return (_node = END);
}
- current = _node;
- _node = last;
+
+ final int current = _sibling;
+ _sibling = _nextSibling[current];
return returnNode(current);
}
+ public NodeIterator reset() {
+ _sibling = _startNode;
+ return resetPosition();
+ }
+
public void setMark() {
- _markedNode = _node;
+ _markedNode = _sibling;
}
public void gotoMark() {
- _node = _markedNode;
+ _sibling = _markedNode;
}
} // end of PrecedingSiblingIterator
@@ -1202,7 +1209,8 @@
* a given node
*/
private final class TypedPrecedingSiblingIterator
- extends PrecedingSiblingIterator {
+ extends PrecedingSiblingIterator
+ {
private final int _nodeType;
public TypedPrecedingSiblingIterator(int type) {
@@ -1211,9 +1219,10 @@
public int next() {
int node;
- while ((node = super.next()) != NULL && _type[node] != _nodeType)
+ while ((node = super.next()) != NULL && _type[node] != _nodeType) {
_position--;
- return(node);
+ }
+ return node;
}
} // end of PrecedingSiblingIterator
@@ -1226,8 +1235,10 @@
*/
private class PrecedingIterator extends NodeIteratorBase {
- private int _node = 0;
- private int _mom = 0;
+ private int _node;
+ private int _ancestor;
+ private int _index, _markedIndex;
+ private IntegerArray _ancestorOrSelf = new IntegerArray();
public boolean isReverse() {
return true;
@@ -1236,8 +1247,9 @@
public NodeIterator cloneIterator() {
try {
final PrecedingIterator clone =
- (PrecedingIterator)super.clone();
+ (PrecedingIterator) super.clone();
clone.setRestartable(false);
+ clone._ancestorOrSelf = (IntegerArray) _ancestorOrSelf.clone();
return clone.reset();
}
catch (CloneNotSupportedException e) {
@@ -1249,37 +1261,56 @@
public NodeIterator setStartNode(int node) {
if (_isRestartable) {
- if (node >= _firstAttributeNode) node = _parent[node];
- _node = _startNode = node;
- _mom = _parent[_startNode];
+ _ancestorOrSelf.clear();
+
+ if (node >= _firstAttributeNode) {
+ node = _parent[node];
+ }
+ do {
+ _ancestorOrSelf.add(node);
+ } while ((node = _parent[node]) > ROOTNODE);
+
+ _index = _ancestorOrSelf.cardinality() - 1;
+ _node = _ancestorOrSelf.at(_index) + 1;
+ _ancestor = (_index > 0) ? _ancestorOrSelf.at(--_index)
+ : ROOTNODE;
+
+ _last = -1;
return resetPosition();
}
+
return this;
}
-
+
public int next() {
- while (--_node > ROOTNODE) {
- if (_node < _mom) _mom = _parent[_mom];
- if (_node != _mom) return returnNode(_node);
+ while (true) {
+ if (_node < _ancestor) {
+ return returnNode(_node++);
+ }
+ if (--_index < 0) break;
+ _ancestor = _ancestorOrSelf.at(_index);
+ _node++; // skip ancestor
}
- return(NULL);
+ return END;
}
- // redefine NodeIteratorBase's reset
public NodeIterator reset() {
- _node = _startNode;
- _mom = _parent[_startNode];
+ _index = _ancestorOrSelf.cardinality() - 1;
+ _node = _ancestorOrSelf.at(_index) + 1;
+ _ancestor = (_index > 0) ? _ancestorOrSelf.at(--_index) : ROOTNODE;
return resetPosition();
}
public void setMark() {
_markedNode = _node;
+ _markedIndex = _index;
}
public void gotoMark() {
_node = _markedNode;
+ _index = _markedIndex;
+ _ancestor = _ancestorOrSelf.at(_markedIndex);
}
-
} // end of PrecedingIterator
@@ -1297,8 +1328,9 @@
public int next() {
int node;
- while ((node = super.next()) != NULL && _type[node] != _nodeType)
+ while ((node = super.next()) != NULL && _type[node] != _nodeType) {
_position--;
+ }
return node;
}
@@ -1379,26 +1411,13 @@
private class AncestorIterator extends NodeIteratorBase {
protected int _index;
- protected int _last = -1;
-
- public final boolean isReverse() {
- return true;
- }
-
- public int getLast() {
- if (_last > -1) return _last;
- int count = 1;
- int node = _startNode;
- while ((node = _parent[node]) != ROOT) count++;
- _last = count;
- return(count);
- }
+ protected IntegerArray _cache = new IntegerArray();
public NodeIterator cloneIterator() {
try {
final AncestorIterator clone = (AncestorIterator)super.clone();
clone.setRestartable(false); // must set to false for any clone
- clone._startNode = _startNode;
+ clone._cache = (IntegerArray) _cache.clone();
return clone.reset();
}
catch (CloneNotSupportedException e) {
@@ -1410,31 +1429,38 @@
public NodeIterator setStartNode(int node) {
if (_isRestartable) {
- _last = -1;
- if (node >= _firstAttributeNode)
- _startNode = node = _parent[node];
- else if (_includeSelf)
- _startNode = node;
- else
- _startNode = _parent[node];
- _index = _startNode;
+ _cache.clear();
+
+ if (_includeSelf) {
+ _cache.add(node);
+ }
+ while ((node = _parent[node]) != NULL) {
+ _cache.add(node);
+ }
+
+ _last = _cache.cardinality();
+ _startNode = _index = _last - 1;
return resetPosition();
}
return this;
}
+ public boolean isReverse() {
+ return true;
+ }
+
+ public int getLast() {
+ return _last;
+ }
+
public NodeIterator reset() {
_index = _startNode;
return resetPosition();
}
public int next() {
- if (_index >= 0) {
- final int node = _index;
- _index = (_index == 0) ? -1 : _parent[_index];
- return returnNode(node);
- }
- return(NULL);
+ return (_index >= 0) ?
+ returnNode(_cache.at(_index--)) : END;
}
public void setMark() {
@@ -1458,26 +1484,25 @@
_nodeType = type;
}
- public int next() {
- int node;
- while ((node = super.next()) != NULL) {
- if (_type[node] == _nodeType) return(node);
- _position--;
- }
- return(NULL);
- }
+ public NodeIterator setStartNode(int node) {
+ if (_isRestartable) {
+ _cache.clear();
- public int getLast() {
- if (_last > -1) return _last;
- int count = 1;
- int node = _startNode;
- do {
- if (_type[node] == _nodeType) count++;
- } while ((node = _parent[node]) != ROOT);
- _last = count;
- return(count);
- }
+ if (_includeSelf && _type[node] == _nodeType) {
+ _cache.add(node);
+ }
+ while ((node = _parent[node]) != NULL) {
+ if (_nodeType == _type[node]) {
+ _cache.add(node);
+ }
+ }
+ _last = _cache.cardinality();
+ _startNode = _index = _last - 1;
+ return resetPosition();
+ }
+ return this;
+ }
} // end of TypedAncestorIterator
@@ -1887,87 +1912,6 @@
return _parent[node];
}
- public int getElementPosition(int node) {
- // Initialize with the first sbiling of the current node
- int match = 0;
- int curr = _offsetOrChild[_parent[node]];
- if (isElement(curr)) match++;
-
- // Then traverse all other siblings up until the current node
- while (curr != node) {
- curr = _nextSibling[curr];
- if (isElement(curr)) match++;
- }
-
- // And finally return number of matches
- return match;
- }
-
- public int getAttributePosition(int attr) {
- // Initialize with the first sbiling of the current node
- int match = 1;
- int curr = _lengthOrAttr[_parent[attr]];
-
- // Then traverse all other siblings up until the current node
- while (curr != attr) {
- curr = _nextSibling[curr];
- match++;
- }
-
- // And finally return number of matches
- return match;
- }
-
- /**
- * Returns a node's position amongst other nodes of the same type
- */
- public int getTypedPosition(int type, int node) {
- // Just return the basic position if no type is specified
- switch(type) {
- case ELEMENT:
- return getElementPosition(node);
- case ATTRIBUTE:
- return getAttributePosition(node);
- case -1:
- type = _type[node];
- }
-
- // Initialize with the first sbiling of the current node
- int match = 0;
- int curr = _offsetOrChild[_parent[node]];
- if (_type[curr] == type) match++;
-
- // Then traverse all other siblings up until the current node
- while (curr != node) {
- curr = _nextSibling[curr];
- if (_type[curr] == type) match++;
- }
-
- // And finally return number of matches
- return match;
- }
-
- /**
- * Returns an iterator's last node of a given type
- */
- public int getTypedLast(int type, int node) {
- // Just return the basic position if no type is specified
- if (type == -1) type = _type[node];
-
- // Initialize with the first sbiling of the current node
- int match = 0;
- int curr = _offsetOrChild[_parent[node]];
- if (_type[curr] == type) match++;
-
- // Then traverse all other siblings up until the very last one
- while (curr != NULL) {
- curr = _nextSibling[curr];
- if (_type[curr] == type) match++;
- }
-
- return match;
- }
-
/**
* Returns singleton iterator containg the document root
* Works for them main document (mark == 0)
@@ -2050,16 +1994,13 @@
* Returns the internal type associated with an expaneded QName
*/
public int getGeneralizedType(final String name) {
- final Integer type = (Integer)_types.get(name);
+ Integer type = (Integer)_types.get(name);
if (type == null) {
// memorize default type
- final int code = name.charAt(0) == '@' ? ATTRIBUTE : ELEMENT;
- _types.put(name, new Integer(code));
- return code;
- }
- else {
- return type.intValue();
+ _types.put(name,
+ type = (name.charAt(0) == '@') ? attributeInt : elementInt);
}
+ return type.intValue();
}
/**
@@ -2222,24 +2163,30 @@
_types = setupMapping(_namesArray);
}
- /**
- * Constructor - defaults to 32K nodes
- */
+ /*
+ * These init sizes have been tuned for the average case. Do not
+ * change these values unless you know exactly what you're doing.
+ */
+ static private final int SMALL_TEXT_SIZE = 1024;
+ static private final int DEFAULT_INIT_SIZE = 1024;
+ static private final int DEFAULT_TEXT_FACTOR = 10;
+
public DOMImpl() {
- //this(32*1024);
- this(8*1024);
+ this(DEFAULT_INIT_SIZE);
}
-
- /**
- * Constructor - defines initial size
- */
+
public DOMImpl(int size) {
+ initialize(size, size < 128 ? SMALL_TEXT_SIZE :
+ size * DEFAULT_TEXT_FACTOR);
+ }
+
+ private void initialize(int size, int textsize) {
_type = new short[size];
_parent = new int[size];
_nextSibling = new int[size];
_offsetOrChild = new int[size];
_lengthOrAttr = new int[size];
- _text = new char[size * 10];
+ _text = new char[textsize];
_whitespace = new BitArray(size);
_prefix = new short[size];
// _namesArray[] and _uriArray[] are allocated in endDocument
@@ -2698,8 +2645,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) {
@@ -2743,32 +2690,40 @@
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;
}
@@ -2941,14 +2896,13 @@
return c == 0x20 || c == 0x0A || c == 0x0D || c == 0x09;
}
-
/****************************************************************/
/* DOM builder class definition */
/****************************************************************/
private final class DOMBuilderImpl implements DOMBuilder {
private final static int ATTR_ARRAY_SIZE = 32;
- private final static int REUSABLE_TEXT_SIZE = 32;
+ private final static int REUSABLE_TEXT_SIZE = 0; // turned off
private final static int INIT_STACK_LENGTH = 64;
private Hashtable _shortTexts = null;
@@ -2960,8 +2914,8 @@
private int[] _previousSiblingStack = new int[INIT_STACK_LENGTH];
private int _sp;
private int _baseOffset = 0;
- private int _currentOffset = 0;
private int _currentNode = 0;
+ private int _currentOffset = 0;
// Temporary structures for attribute nodes
private int _currentAttributeNode = 1;
@@ -2977,8 +2931,8 @@
private int _uriCount = 0;
private int _prefixCount = 0;
- private int _nextNamespace = DOM.NULL;
private int _lastNamespace = DOM.NULL;
+ private int _nextNamespace = DOM.NULL;
// Stack used to keep track of what whitespace text nodes are protected
// by xml:space="preserve" attributes and which nodes that are not.
@@ -3321,7 +3275,6 @@
_currentOffset += length;
_disableEscaping = !_escaping;
-
}
/**
@@ -3336,8 +3289,9 @@
_currentAttributeNode = 1;
_type2[0] = NAMESPACE;
- startPrefixMapping(EMPTYSTRING, EMPTYSTRING);
+ definePrefixAndUri(EMPTYSTRING, EMPTYSTRING);
startPrefixMapping(XML_PREFIX,
"http://www.w3.org/XML/1998/namespace");
+
_lengthOrAttr[ROOTNODE] = _nextNamespace;
_parent2[_nextNamespace] = ROOTNODE;
_nextNamespace = DOM.NULL;
@@ -3405,8 +3359,9 @@
*/
public void startElement(String uri, String localName,
String qname, Attributes attributes)
- throws SAXException {
-
+ throws SAXException
+ {
+// System.out.println("DOMImpl.startElement() qname = " + qname);
makeTextNode(false);
// Get node index and setup parent/child references
@@ -3531,8 +3486,25 @@
* SAX2: Begin the scope of a prefix-URI Namespace mapping.
*/
public void startPrefixMapping(String prefix, String uri)
- throws SAXException {
+ throws SAXException
+ {
+ final Stack stack = definePrefixAndUri(prefix, uri);
+ makeTextNode(false);
+ int attr = makeNamespaceNode(prefix, uri);
+ if (_nextNamespace == DOM.NULL) {
+ _nextNamespace = attr;
+ }
+ else {
+ _nextSibling2[attr-1] = attr;
+ }
+ _nextSibling2[attr] = DOM.NULL;
+ _prefix2[attr] = ((Integer) stack.elementAt(0)).shortValue();
+ }
+
+ private Stack definePrefixAndUri(String prefix, String uri)
+ throws SAXException
+ {
// Get the stack associated with this namespace prefix
Stack stack = (Stack)_nsPrefixes.get(prefix);
if (stack == null) {
@@ -3548,17 +3520,7 @@
}
stack.push(uri);
- if (!prefix.equals(EMPTYSTRING) || !uri.equals(EMPTYSTRING)) {
- makeTextNode(false);
- int attr = makeNamespaceNode(prefix, uri);
- if (_nextNamespace == DOM.NULL)
- _nextNamespace = attr;
- else
- _nextSibling2[attr-1] = attr;
- _nextSibling2[attr] = DOM.NULL;
- // _prefix2[attr] = idx.shortValue();
- _prefix2[attr] = ((Integer) stack.elementAt(0)).shortValue();
- }
+ return stack;
}
/**
1.7.12.1.2.1 +4 -7
xml-xalan/java/src/org/apache/xalan/xsltc/dom/DTDMonitor.java
Index: DTDMonitor.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DTDMonitor.java,v
retrieving revision 1.7.12.1
retrieving revision 1.7.12.1.2.1
diff -u -r1.7.12.1 -r1.7.12.1.2.1
--- DTDMonitor.java 14 Aug 2002 19:21:42 -0000 1.7.12.1
+++ DTDMonitor.java 2 Dec 2002 15:51:24 -0000 1.7.12.1.2.1
@@ -75,6 +75,7 @@
import org.apache.xalan.xsltc.*;
import org.apache.xalan.xsltc.runtime.AbstractTranslet;
import org.apache.xalan.xsltc.runtime.Hashtable;
+import org.apache.xalan.xsltc.runtime.BasisLibrary;
final public class DTDMonitor implements DTDHandler, DeclHandler {
@@ -91,10 +92,6 @@
private final static String DECL_HANDLER_PROP =
"http://xml.org/sax/properties/declaration-handler";
- // Error message used when the SAX parser does not generate DTD events
- private final static String NO_DTD_SUPPORT_STR =
- "Your SAX parser does not handle DTD declarations";
-
/**
* Constructor - does nothing
*/
@@ -117,10 +114,10 @@
reader.setDTDHandler(this);
}
catch (SAXNotRecognizedException e) {
- throw(new RuntimeException(NO_DTD_SUPPORT_STR));
+ BasisLibrary.runTimeError(BasisLibrary.PARSER_DTD_SUPPORT_ERR);
}
catch (SAXNotSupportedException e) {
- throw(new RuntimeException(NO_DTD_SUPPORT_STR));
+ BasisLibrary.runTimeError(BasisLibrary.PARSER_DTD_SUPPORT_ERR);
}
}
1.6.12.1.2.1 +3 -2
xml-xalan/java/src/org/apache/xalan/xsltc/dom/DocumentCache.java
Index: DocumentCache.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DocumentCache.java,v
retrieving revision 1.6.12.1
retrieving revision 1.6.12.1.2.1
diff -u -r1.6.12.1 -r1.6.12.1.2.1
--- DocumentCache.java 14 Aug 2002 19:21:42 -0000 1.6.12.1
+++ DocumentCache.java 2 Dec 2002 15:51:24 -0000 1.6.12.1.2.1
@@ -86,6 +86,7 @@
import org.apache.xalan.xsltc.dom.DTDMonitor;
import org.apache.xalan.xsltc.runtime.AbstractTranslet;
import org.apache.xalan.xsltc.runtime.Constants;
+import org.apache.xalan.xsltc.runtime.BasisLibrary;
public final class DocumentCache implements DOMCache {
@@ -214,7 +215,7 @@
_reader = _parser.getXMLReader();
}
catch (ParserConfigurationException e) {
- System.err.println("Your SAX parser is not configured correctly.");
+ BasisLibrary.runTimeError(BasisLibrary.NAMESPACES_SUPPORT_ERR);
System.exit(-1);
}
}
1.8.12.1.2.1 +79 -86
xml-xalan/java/src/org/apache/xalan/xsltc/dom/DupFilterIterator.java
Index: DupFilterIterator.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DupFilterIterator.java,v
retrieving revision 1.8.12.1
retrieving revision 1.8.12.1.2.1
diff -u -r1.8.12.1 -r1.8.12.1.2.1
--- DupFilterIterator.java 14 Aug 2002 19:21:42 -0000 1.8.12.1
+++ DupFilterIterator.java 2 Dec 2002 15:51:24 -0000 1.8.12.1.2.1
@@ -66,128 +66,121 @@
import org.apache.xalan.xsltc.NodeIterator;
import org.apache.xalan.xsltc.TransletException;
+import org.apache.xalan.xsltc.util.IntegerArray;
+import org.apache.xalan.xsltc.runtime.BasisLibrary;
+
+/**
+ * Removes duplicates and sorts a source iterator. The nodes from the
+ * source are collected in an array upon calling setStartNode(). This
+ * array is later sorted and duplicates are ignored in next().
+ */
public final class DupFilterIterator extends NodeIteratorBase {
- private final static int INIT_DATA_SIZE = 16;
+ /**
+ * Reference to source iterator.
+ */
+ private NodeIterator _source;
+
+ /**
+ * Array to cache all nodes from source.
+ */
+ private IntegerArray _nodes = new IntegerArray();
- private final NodeIterator _source; // the source iterator
- private int[] _data = null; // cached nodes from the source
- private int _last = 0; // the number of nodes in this
iterator
+ /**
+ * Index in _nodes array to current node.
+ */
private int _current = 0;
/**
- * Creates a new duplicate filter iterator based on an existing iterator.
- * This iterator should be used with union expressions and other complex
- * iterator combinations (like 'get me the parents of all child node in
- * the dom' sort of thing). The iterator is also used to cache node-sets
- * returned by id() and key() iterators.
- * @param source The iterator this iterator will get its nodes from
+ * Cardinality of _nodes array.
+ */
+ private int _nodesSize = 0;
+
+ /**
+ * Last value returned by next().
*/
+ private int _lastNext = END;
+
public DupFilterIterator(NodeIterator source) {
- // Save a reference to the source iterator
_source = source;
+// System.out.println("DFI source = " + source + " this = " + this);
// Cache contents of id() or key() index right away. Necessary for
// union expressions containing multiple calls to the same index, and
// correct as well since start-node is irrelevant for id()/key() exrp.
- if (source instanceof KeyIndex) setStartNode(DOM.ROOTNODE);
- }
-
- /**
- * Returns the next node in this iterator - excludes duplicates.
- * @return The next node in this iterator
- */
- public int next() {
- return _current < _last ? _data[_current++] : END;
+ if (source instanceof KeyIndex) {
+ setStartNode(DOM.ROOTNODE);
+ }
}
- /**
- * Set the start node for this iterator
- * @param node The start node
- * @return A reference to this node iterator
- */
public NodeIterator setStartNode(int node) {
+ if (_isRestartable) {
+ // KeyIndex iterators are always relative to the root node, so there
+ // is never any point in re-reading the iterator (and we SHOULD
NOT).
+ if (_source instanceof KeyIndex && _startNode == DOM.ROOTNODE) {
+ return this;
+ }
- int i, j; // loop variables declared first for speed - don't move!!!
-
- // KeyIndex iterators are always relative to the root node, so there
- // is never any point in re-reading the iterator (and we SHOULD NOT).
- if ((_source instanceof KeyIndex) && (_data != null)) return this;
-
- // If the _data array is populated, and the current start node is
- // equal to the new start node, we know we already have what we need.
- if ((_data == null) || (node != _startNode)) {
-
- _startNode = node;
- _last = 0;
- _source.setStartNode(node);
- _data = new int[INIT_DATA_SIZE];
-
- // Gather all nodes from the source iterator, eliminate dups
- while ((node = _source.next()) != END) {
- if (_last == _data.length) {
- int[] newArray = new int[_data.length * 2];
- System.arraycopy(_data, 0, newArray, 0, _last);
- _data = newArray;
- }
+ if (node != _startNode) {
+ _source.setStartNode(_startNode = node);
- // Go through all nodes in turn
- for (i=0; i<_last; i++) {
- // Is this a duplicate of the new node
- if (_data[i] == node) {
- break;
- }
- // Should the new node be inserted at this position?
- else if (_data[i] > node) {
- for (j = _last++; j>i; j--)
- _data[j] = _data[j-1];
- _data[i] = node;
- break;
- }
+ _nodes.clear();
+ while ((node = _source.next()) != END) {
+ _nodes.add(node);
}
- if (i == _last) _data[_last++] = node;
+ _nodes.sort();
+ _nodesSize = _nodes.cardinality();
+ _current = 0;
+ _lastNext = END;
+ resetPosition();
}
}
-
- _current = 0; // set to beginning
return this;
}
- /**
- * Returns the current position of the iterator. The position is within
the
- * node set covered by this iterator, not within the DOM.
- */
- public int getPosition() {
- return (_current);
+
+ public int next() {
+ while (_current < _nodesSize) {
+ final int next = _nodes.at(_current++);
+ if (next != _lastNext) {
+ return returnNode(_lastNext = next);
+ }
+ }
+ return END;
}
- /**
- * Returns the position of the last node in this iterator. The integer
- * returned is equivalent to the number of nodes in this iterator.
- */
- public int getLast() {
- return _last;
+ public NodeIterator cloneIterator() {
+ try {
+ final DupFilterIterator clone =
+ (DupFilterIterator) super.clone();
+ clone._nodes = (IntegerArray) _nodes.clone();
+ clone._source = _source.cloneIterator();
+ clone._isRestartable = false;
+ return clone.reset();
+ }
+ catch (CloneNotSupportedException e) {
+ BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
+ e.toString());
+ return null;
+ }
+ }
+
+ public void setRestartable(boolean isRestartable) {
+ _isRestartable = isRestartable;
+ _source.setRestartable(isRestartable);
}
- /**
- * Saves the position of this iterator - see gotoMark()
- */
public void setMark() {
- _source.setMark();
_markedNode = _current;
}
- /**
- * Restores the position of this iterator - see setMark()
- */
public void gotoMark() {
- _source.gotoMark();
_current = _markedNode;
}
public NodeIterator reset() {
_current = 0;
- return(this);
+ _lastNext = END;
+ return resetPosition();
}
-
}
1.4.12.1.2.1 +22 -3
xml-xalan/java/src/org/apache/xalan/xsltc/dom/FilterIterator.java
Index: FilterIterator.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/FilterIterator.java,v
retrieving revision 1.4.12.1
retrieving revision 1.4.12.1.2.1
diff -u -r1.4.12.1 -r1.4.12.1.2.1
--- FilterIterator.java 14 Aug 2002 19:21:42 -0000 1.4.12.1
+++ FilterIterator.java 2 Dec 2002 15:51:24 -0000 1.4.12.1.2.1
@@ -66,13 +66,32 @@
import org.apache.xalan.xsltc.NodeIterator;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
+/**
+ * Similar to a CurrentNodeListIterator except that the filter has a
+ * simpler interface (only needs the node, no position, last, etc.)
+ * It takes a source iterator and a Filter object and returns nodes
+ * from the source after filtering them by calling filter.test(node).
+ */
public final class FilterIterator extends NodeIteratorBase {
+
+ /**
+ * Reference to source iterator.
+ */
private NodeIterator _source;
+
+ /**
+ * Reference to a filter object that to be applied to each node.
+ */
private final Filter _filter;
+
+ /**
+ * A flag indicating if position is reversed.
+ */
private final boolean _isReverse;
public FilterIterator(NodeIterator source, Filter filter) {
_source = source;
+// System.out.println("FI souce = " + source + " this = " + this);
_filter = filter;
_isReverse = source.isReverse();
}
@@ -88,9 +107,9 @@
public NodeIterator cloneIterator() {
try {
- final FilterIterator clone = (FilterIterator)super.clone();
- clone.setRestartable(false);
+ final FilterIterator clone = (FilterIterator) super.clone();
clone._source = _source.cloneIterator();
+ clone._isRestartable = false;
return clone.reset();
}
catch (CloneNotSupportedException e) {
1.5.12.1.2.1 +8 -20
xml-xalan/java/src/org/apache/xalan/xsltc/dom/FilteredStepIterator.java
Index: FilteredStepIterator.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/FilteredStepIterator.java,v
retrieving revision 1.5.12.1
retrieving revision 1.5.12.1.2.1
diff -u -r1.5.12.1 -r1.5.12.1.2.1
--- FilteredStepIterator.java 14 Aug 2002 19:21:42 -0000 1.5.12.1
+++ FilteredStepIterator.java 2 Dec 2002 15:51:24 -0000 1.5.12.1.2.1
@@ -67,6 +67,10 @@
import org.apache.xalan.xsltc.NodeIterator;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
+/**
+ * Extends a StepIterator by adding the ability to filter nodes. It
+ * uses filters similar to those of a FilterIterator.
+ */
public final class FilteredStepIterator extends StepIterator {
private Filter _filter;
@@ -78,30 +82,14 @@
_filter = filter;
}
- public NodeIterator cloneIterator() {
- try {
- final FilteredStepIterator clone =
- (FilteredStepIterator)super.clone();
- clone._source = _source.cloneIterator();
- clone._iterator = _iterator.cloneIterator();
- clone._filter = _filter;
- clone.setRestartable(false);
- return clone.reset();
- }
- catch (CloneNotSupportedException e) {
- BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
- e.toString());
- return null;
- }
- }
-
public int next() {
int node;
while ((node = super.next()) != END) {
- if (_filter.test(node))
+ if (_filter.test(node)) {
return returnNode(node);
+ }
}
- return(node);
+ return node;
}
}
1.7.12.1.2.1 +84 -105
xml-xalan/java/src/org/apache/xalan/xsltc/dom/KeyIndex.java
Index: KeyIndex.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/KeyIndex.java,v
retrieving revision 1.7.12.1
retrieving revision 1.7.12.1.2.1
diff -u -r1.7.12.1 -r1.7.12.1.2.1
--- KeyIndex.java 14 Aug 2002 19:21:42 -0000 1.7.12.1
+++ KeyIndex.java 2 Dec 2002 15:51:24 -0000 1.7.12.1.2.1
@@ -57,70 +57,67 @@
* <http://www.apache.org/>.
*
* @author Morten Jorgensen
+ * @author Santiago Pericas-Geertsen
*
*/
package org.apache.xalan.xsltc.dom;
import java.util.Vector;
+import java.util.Enumeration;
import java.util.StringTokenizer;
import org.apache.xalan.xsltc.DOM;
import org.apache.xalan.xsltc.NodeIterator;
+import org.apache.xalan.xsltc.dom.NodeIteratorBase;
import org.apache.xalan.xsltc.runtime.Hashtable;
+import org.apache.xalan.xsltc.util.IntegerArray;
-public class KeyIndex implements NodeIterator {
+public class KeyIndex extends NodeIteratorBase {
+ /**
+ * A mapping between values and nodesets.
+ */
private Hashtable _index = new Hashtable();
- private BitArray _nodes = null;
- private int _pos = 0;
- private int _mark = 0;
- private int _save = 0;
- private int _start = 0;
- private int _arraySize = 0;
- private int _node = -1;
/**
- * Creates an index for a key defined by xsl:key
+ * The node set associated to the current value passed
+ * to lookupKey();
*/
- public KeyIndex(int size) {
- _arraySize = size;
- }
+ private IntegerArray _nodes = null;
- public void setRestartable(boolean flag) {
-
+ /**
+ * Store position after call to setMark()
+ */
+ private int _markedPosition = 0;
+
+ public KeyIndex(int dummy) {
}
-
+
/**
- * Adds a node to the node list for a given value.
- * The BitArray object makes sure duplicate nodes are eliminated.
+ * Adds a node to the node list for a given value. Nodes will
+ * always be added in document order.
*/
public void add(Object value, int node) {
- if ((_nodes = (BitArray)_index.get(value)) == null) {
- _nodes = new BitArray(_arraySize);
- _nodes.setMask(node & 0xff000000);
- _index.put(value,_nodes);
+ IntegerArray nodes;
+ if ((nodes = (IntegerArray) _index.get(value)) == null) {
+ _index.put(value, nodes = new IntegerArray());
}
- _nodes.setBit(node & 0x00ffffff);
-
- /*
- * TODO: A bit array can currently only hold nodes from one DOM.
- * An index will therefore only return nodes from a single document.
- */
+ nodes.add(node);
}
/**
- * Merge this node set with nodes from another index
+ * Merge the current value's nodeset set by lookupKey() with _nodes.
*/
public void merge(KeyIndex other) {
- // Only merge if other node set is not empty
- if (other != null) {
- if (other._nodes != null) {
- // Create new Vector for nodes if this set is empty
- if (_nodes == null)
- _nodes = other._nodes;
- else
- _nodes = _nodes.merge(other._nodes);
+ if (other == null) return;
+
+ if (other._nodes != null) {
+ if (_nodes == null) {
+ _nodes = other._nodes;
+ }
+ else {
+ _nodes.merge(other._nodes);
}
}
}
@@ -133,23 +130,23 @@
* key() function.
*/
public void lookupId(Object value) {
- if (value instanceof String) {
- final String string = (String)value;
- if (string.indexOf(' ') > -1) {
- StringTokenizer values = new StringTokenizer(string);
- while (values.hasMoreElements()) {
- BitArray nodes = (BitArray)_index.get(values.nextElement());
- if (nodes != null) {
- if (_nodes == null)
- _nodes = nodes;
- else
- _nodes = _nodes.merge(nodes);
- }
- }
- return;
+ // Clear _nodes array
+ _nodes = null;
+
+ final StringTokenizer values = new StringTokenizer((String) value);
+ while (values.hasMoreElements()) {
+ final IntegerArray nodes =
+ (IntegerArray) _index.get(values.nextElement());
+
+ if (nodes == null) continue;
+
+ if (_nodes == null) {
+ _nodes = nodes;
+ }
+ else {
+ _nodes.merge(nodes);
}
}
- _nodes = (BitArray)_index.get(value);
}
/**
@@ -157,83 +154,80 @@
* prior to returning the node iterator.
*/
public void lookupKey(Object value) {
- _nodes = (BitArray)_index.get(value);
+ _nodes = (IntegerArray) _index.get(value);
+ _position = 0;
}
/**
* Callers should not call next() after it returns END.
*/
public int next() {
- if (_nodes == null) return(END);
- if ((_node = _nodes.getNextBit(++_node)) == END) return(END);
- _pos++;
- return(_node | _nodes.getMask());
+ if (_nodes == null) return END;
+
+ return (_position < _nodes.cardinality()) ?
+ _nodes.at(_position++) : END;
}
public int containsID(int node, Object value) {
- if (value instanceof String) {
- final String string = (String)value;
- if (string.indexOf(' ') > -1) {
- StringTokenizer values = new StringTokenizer(string);
- while (values.hasMoreElements()) {
- BitArray nodes = (BitArray)_index.get(values.nextElement());
- if ((nodes != null) && (nodes.getBit(node))) return(1);
+ final String string = (String)value;
+ if (string.indexOf(' ') > -1) {
+ final StringTokenizer values = new StringTokenizer(string);
+
+ while (values.hasMoreElements()) {
+ final IntegerArray nodes =
+ (IntegerArray) _index.get(values.nextElement());
+
+ if (nodes != null && nodes.indexOf(node) >= 0) {
+ return 1;
}
- return(0);
}
+ return 0;
+ }
+ else {
+ final IntegerArray nodes = (IntegerArray) _index.get(value);
+ return (nodes != null && nodes.indexOf(node) >= 0) ? 1 : 0;
}
-
- BitArray nodes = (BitArray)_index.get(value);
- if ((nodes != null) && (nodes.getBit(node))) return(1);
- return(0);
}
public int containsKey(int node, Object value) {
- BitArray nodes = (BitArray)_index.get(value);
- if ((nodes != null) && (nodes.getBit(node))) return(1);
- return(0);
+ final IntegerArray nodes = (IntegerArray) _index.get(value);
+ return (nodes != null && nodes.indexOf(node) >= 0) ? 1 : 0;
}
/**
* Resets the iterator to the last start node.
*/
public NodeIterator reset() {
- _pos = _start;
- _node = _start - 1;
- return(this);
+ _position = 0;
+ return this;
}
/**
* Returns the number of elements in this iterator.
*/
public int getLast() {
- if (_nodes == null)
- return(0);
- else
- return(_nodes.size()); // TODO: count actual nodes
+ return (_nodes == null) ? 0 : _nodes.cardinality();
}
/**
* Returns the position of the current node in the set.
*/
public int getPosition() {
- return(_pos);
+ return _position;
}
/**
* Remembers the current node for the next call to gotoMark().
*/
public void setMark() {
- _mark = _pos;
- _save = _node;
+ _markedPosition = _position;
}
/**
* Restores the current node remembered by setMark().
*/
public void gotoMark() {
- _pos = _mark;
- _node = _save;
+ _position = _markedPosition;
}
/**
@@ -245,34 +239,19 @@
_nodes = null;
}
else if (_nodes != null) {
- // Node count starts with 1, while bit arrays count from 0. Must
- // subtract one from 'start' to initialize bit array correctly.
- _start = _nodes.getBitNumber(start-1);
- _node = _start - 1;
+ _position = 0;
}
- return((NodeIterator)this);
- }
-
- /**
- * True if this iterator has a reversed axis.
- */
- public boolean isReverse() {
- return(false);
+ return this;
}
/**
* Returns a deep copy of this iterator.
*/
public NodeIterator cloneIterator() {
- KeyIndex other = new KeyIndex(_arraySize);
-
+ KeyIndex other = new KeyIndex(0);
other._index = _index;
- other._nodes = _nodes.cloneArray();
- other._pos = _pos;
- other._start = _start;
- other._node = _node;
-
- return(other);
+ other._nodes = _nodes;
+ other._position = _position;
+ return other;
}
-
}
1.12.2.1.2.1 +23 -14
xml-xalan/java/src/org/apache/xalan/xsltc/dom/LoadDocument.java
Index: LoadDocument.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/LoadDocument.java,v
retrieving revision 1.12.2.1
retrieving revision 1.12.2.1.2.1
diff -u -r1.12.2.1 -r1.12.2.1.2.1
--- LoadDocument.java 14 Aug 2002 19:21:42 -0000 1.12.2.1
+++ LoadDocument.java 2 Dec 2002 15:51:24 -0000 1.12.2.1.2.1
@@ -62,8 +62,9 @@
package org.apache.xalan.xsltc.dom;
-import java.io.File;
import java.net.URL;
+import java.io.File;
+import java.io.FileNotFoundException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
@@ -90,22 +91,24 @@
*/
public static NodeIterator document(String uri, String base,
AbstractTranslet translet, DOM dom)
- throws Exception {
-
+ throws Exception
+ {
+ final String originalUri = uri;
MultiDOM multiplexer = (MultiDOM)dom;
// Return an empty iterator if the URI is clearly invalid
// (to prevent some unncessary MalformedURL exceptions).
- if ((uri == null) || (uri.equals("")))
- return(new SingletonIterator(DOM.NULL,true));
+ if (uri == null || uri.equals("")) {
+ return new SingletonIterator(DOM.NULL,true);
+ }
// Prepend URI base to URI (from context)
- if ((base != null) && (!base.equals(""))) {
- if ((!uri.startsWith(base)) && // unless URI contains base
- (!uri.startsWith("/")) && // unless URI is abs. file path
- (!uri.startsWith("http:/")) && // unless URI is abs. http URL
- (!uri.startsWith("file:/"))) { // unless URI is abs. file URL
- uri = base+uri;
+ if (base != null && !base.equals("")) {
+ if (!uri.startsWith(base) && // unless URI contains base
+ !uri.startsWith("/") && // unless URI is abs. file path
+ !uri.startsWith("http:/") && // unless URI is abs. http URL
+ !uri.startsWith("file:/")) { // unless URI is abs. file URL
+ uri = base + uri;
}
}
@@ -128,7 +131,11 @@
mask = multiplexer.nextMask(); // peek
if (cache != null) {
- newdom = cache.retrieveDocument(uri, mask, translet);
+ newdom = cache.retrieveDocument(originalUri, mask, translet);
+ if (newdom == null) {
+ final Exception e = new FileNotFoundException(originalUri);
+ throw new TransletException(e);
+ }
}
else {
// Parse the input document and construct DOM object
@@ -247,8 +254,10 @@
throw new IllegalArgumentException(err);
}
}
+ catch (TransletException e) {
+ throw e;
+ }
catch (Exception e) {
- e.printStackTrace();
throw new TransletException(e);
}
}
1.6.12.1.2.1 +42 -16
xml-xalan/java/src/org/apache/xalan/xsltc/dom/MatchingIterator.java
Index: MatchingIterator.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/MatchingIterator.java,v
retrieving revision 1.6.12.1
retrieving revision 1.6.12.1.2.1
diff -u -r1.6.12.1 -r1.6.12.1.2.1
--- MatchingIterator.java 14 Aug 2002 19:21:42 -0000 1.6.12.1
+++ MatchingIterator.java 2 Dec 2002 15:51:24 -0000 1.6.12.1.2.1
@@ -66,11 +66,36 @@
import org.apache.xalan.xsltc.NodeIterator;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
+/**
+ * This is a special kind of iterator that takes a source iterator and a
+ * node N. If initialized with a node M (the parent of N) it computes the
+ * position of N amongst the children of M. This position can be obtained
+ * by calling getPosition().
+ * It is an iterator even though next() will never be called. It is used to
+ * match patterns with a single predicate like:
+ *
+ * BOOK[position() = last()]
+ *
+ * In this example, the source iterator will return elements of type BOOK,
+ * a call to position() will return the position of N. Notice that because
+ * of the way the pattern matching is implemented, N will always be a node
+ * in the source since (i) it is a BOOK or the test sequence would not be
+ * considered and (ii) the source iterator is initialized with M which is
+ * the parent of N. Also, and still in this example, a call to last() will
+ * return the number of elements in the source (i.e. the number of BOOKs).
+ */
public final class MatchingIterator extends NodeIteratorBase {
+
+ /**
+ * A reference to a source iterator.
+ */
private NodeIterator _source;
- private final int _match;
- private int _matchPos, _matchLast = -1;
-
+
+ /**
+ * The node to match.
+ */
+ private final int _match;
+
public MatchingIterator(int match, NodeIterator source) {
_source = source;
_match = match;
@@ -83,10 +108,10 @@
public NodeIterator cloneIterator() {
try {
- final MatchingIterator clone = (MatchingIterator)super.clone();
+ final MatchingIterator clone = (MatchingIterator) super.clone();
clone._source = _source.cloneIterator();
- clone.setRestartable(false);
- return clone;
+ clone._isRestartable = false;
+ return clone.reset();
}
catch (CloneNotSupportedException e) {
BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
@@ -101,17 +126,17 @@
_source.setStartNode(node);
// Calculate the position of the node in the set
- _matchPos = 1;
- _matchLast = -1;
- while ( ((node = _source.next()) != END) && (node != _match) )
- _matchPos++;
+ _position = 1; _last = -1;
+ while ((node = _source.next()) != END && node != _match) {
+ _position++;
+ }
}
return this;
}
public NodeIterator reset() {
_source.reset();
- return this;
+ return resetPosition();
}
public int next() {
@@ -119,13 +144,14 @@
}
public int getLast() {
- if (_matchLast == -1)
- _matchLast = _source.getLast();
- return _matchLast;
+ if (_last == -1) {
+ _last = _source.getLast();
+ }
+ return _last;
}
public int getPosition() {
- return _matchPos;
+ return _position;
}
public void setMark() {
1.20.2.1.2.1 +24 -29
xml-xalan/java/src/org/apache/xalan/xsltc/dom/MultiDOM.java
Index: MultiDOM.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/MultiDOM.java,v
retrieving revision 1.20.2.1
retrieving revision 1.20.2.1.2.1
diff -u -r1.20.2.1 -r1.20.2.1.2.1
--- MultiDOM.java 14 Aug 2002 19:21:42 -0000 1.20.2.1
+++ MultiDOM.java 2 Dec 2002 15:51:24 -0000 1.20.2.1.2.1
@@ -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);
- }
- else if (_axis == Axis.CHILD) {
- _source = _adapters[dom].getTypedChildren(_type);
- }
- else {
- _source = _adapters[dom].getTypedAxisIterator(_axis,_type);
+ // 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);
+ }
}
+
+ _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 Axis.isReverse[_axis];
}
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();
@@ -352,14 +355,6 @@
return _adapters[node>>>24].getParent(node & CLR) | node&SET;
}
- public int getTypedPosition(int type, int node) {
- return _adapters[node>>>24].getTypedPosition(type, node&CLR);
- }
-
- public int getTypedLast(int type, int node) {
- return _adapters[node>>>24].getTypedLast(type, node&CLR);
- }
-
public int getAttributeNode(final int type, final int el) {
return _adapters[el>>>24].getAttributeNode(type, el&CLR) | el&SET;
}
@@ -458,6 +453,6 @@
public String lookupNamespace(int node, String prefix)
throws TransletException
{
- return _adapters[node>>>24].lookupNamespace(node, prefix);
+ return _adapters[node>>>24].lookupNamespace(node & CLR, prefix);
}
}
1.6.12.1.2.1 +14 -6
xml-xalan/java/src/org/apache/xalan/xsltc/dom/NodeCounter.java
Index: NodeCounter.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/NodeCounter.java,v
retrieving revision 1.6.12.1
retrieving revision 1.6.12.1.2.1
diff -u -r1.6.12.1 -r1.6.12.1.2.1
--- NodeCounter.java 14 Aug 2002 19:21:42 -0000 1.6.12.1
+++ NodeCounter.java 2 Dec 2002 15:51:24 -0000 1.6.12.1.2.1
@@ -289,8 +289,8 @@
* lang="en".
*/
private void formatValue(int value, String format, StringBuffer buffer) {
-
char c = format.charAt(0);
+
if (Character.isDigit(c)) {
char zero = (char)(c - Character.getNumericValue(c));
@@ -326,10 +326,18 @@
buffer.append(romanValue(value).toUpperCase());
}
else {
- int min = (int) c;
- int max = (int) c;
- while (Character.isLetterOrDigit((char) (max+1))) {
- max++;
+ int min = (int) c;
+ int max = (int) c;
+
+ // Special case for Greek alphabet
+ if (c >= 0x3b1 && c <= 0x3c9) {
+ max = 0x3c9; // omega
+ }
+ else {
+ // General case: search for end of group
+ while (Character.isLetterOrDigit((char) (max + 1))) {
+ max++;
+ }
}
buffer.append(alphaValue(value, min, max));
}
1.7.2.1.2.1 +69 -3
xml-xalan/java/src/org/apache/xalan/xsltc/dom/NodeIteratorBase.java
Index: NodeIteratorBase.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/NodeIteratorBase.java,v
retrieving revision 1.7.2.1
retrieving revision 1.7.2.1.2.1
diff -u -r1.7.2.1 -r1.7.2.1.2.1
--- NodeIteratorBase.java 14 Aug 2002 19:21:42 -0000 1.7.2.1
+++ NodeIteratorBase.java 2 Dec 2002 15:51:24 -0000 1.7.2.1.2.1
@@ -68,18 +68,56 @@
import org.apache.xalan.xsltc.runtime.BasisLibrary;
public abstract class NodeIteratorBase implements NodeIterator {
- private int _last = -1;
+
+ /**
+ * Cached computed value of last().
+ */
+ protected int _last = -1;
+
+ /**
+ * Value of position() in this iterator. Incremented in
+ * returnNode().
+ */
protected int _position = 0;
+ /**
+ * Store node in call to setMark().
+ */
protected int _markedNode;
+
+ /**
+ * Store node in call to setStartNode().
+ */
protected int _startNode = NodeIterator.END;
+
+ /**
+ * Flag indicating if "self" should be returned.
+ */
protected boolean _includeSelf = false;
+
+ /**
+ * Flag indicating if iterator can be restarted.
+ */
protected boolean _isRestartable = true;
+ /**
+ * Setter for _isRestartable flag.
+ */
public void setRestartable(boolean isRestartable) {
_isRestartable = isRestartable;
}
+ /**
+ * Initialize iterator using a node. If iterator is not
+ * restartable, then do nothing. If node is equal to END then
+ * subsequent calls to next() must return END.
+ */
+ abstract public NodeIterator setStartNode(int node);
+
+ /**
+ * Reset this iterator using state from last call to
+ * setStartNode().
+ */
public NodeIterator reset() {
final boolean temp = _isRestartable;
_isRestartable = true;
@@ -89,11 +127,19 @@
return this;
}
+ /**
+ * Setter for _includeSelf flag.
+ */
public NodeIterator includeSelf() {
_includeSelf = true;
return this;
}
+ /**
+ * Default implementation of getLast(). Stores current position
+ * and current node, resets the iterator, counts all nodes and
+ * restores iterator to original state.
+ */
public int getLast() {
if (_last == -1) {
final int temp = _position;
@@ -108,14 +154,28 @@
return _last;
}
+ /**
+ * Returns the position() in this iterator.
+ */
public int getPosition() {
return _position == 0 ? 1 : _position;
}
+ /**
+ * Indicates if position in this iterator is computed in reverse
+ * document order. Note that nodes are always returned in document
+ * order.
+ */
public boolean isReverse() {
return false;
}
+ /**
+ * Clones and resets this iterator. Note that the cloned iterator is
+ * not restartable. This is because cloning is needed for variable
+ * references, and the context node of the original variable
+ * declaration must be preserved.
+ */
public NodeIterator cloneIterator() {
try {
final NodeIteratorBase clone = (NodeIteratorBase)super.clone();
@@ -129,14 +189,20 @@
}
}
+ /**
+ * Utility method that increments position and returns its
+ * argument.
+ */
protected final int returnNode(final int node) {
_position++;
return node;
}
+ /**
+ * Reset the position in this iterator.
+ */
protected final NodeIterator resetPosition() {
_position = 0;
return this;
}
-
}
1.9.12.1.2.1 +25 -20
xml-xalan/java/src/org/apache/xalan/xsltc/dom/NthIterator.java
Index: NthIterator.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/NthIterator.java,v
retrieving revision 1.9.12.1
retrieving revision 1.9.12.1.2.1
diff -u -r1.9.12.1 -r1.9.12.1.2.1
--- NthIterator.java 14 Aug 2002 19:21:42 -0000 1.9.12.1
+++ NthIterator.java 2 Dec 2002 15:51:24 -0000 1.9.12.1.2.1
@@ -83,21 +83,37 @@
_source.setRestartable(isRestartable);
}
+ public NodeIterator cloneIterator() {
+ try {
+ final NthIterator clone = (NthIterator) super.clone();
+ clone._source = _source.cloneIterator(); // resets source
+ clone._isRestartable = false;
+ return clone;
+ }
+ catch (CloneNotSupportedException e) {
+ BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
+ e.toString());
+ return null;
+ }
+ }
+
public int next() {
if (_ready && _position > 0) {
+ final int pos = _source.isReverse()
+ ? _source.getLast() - _position + 1
+ : _position;
+
_ready = false;
- // skip N-1 nodes
- final int pos = _position;
- for (int n = pos - 1; n-- > 0;) {
- if (_source.next() == NodeIterator.END) {
- return NodeIterator.END;
+ int node;
+ while ((node = _source.next()) != END) {
+ if (pos == _source.getPosition()) {
+ return node;
}
}
- return _source.next();
}
- return NodeIterator.END;
+ return END;
}
-
+
public NodeIterator setStartNode(final int node) {
if (_isRestartable) {
_source.setStartNode(node);
@@ -120,22 +136,11 @@
return 1;
}
- public boolean isReverse() {
- return _source.isReverse();
- }
-
public void setMark() {
_source.setMark();
}
public void gotoMark() {
_source.gotoMark();
- }
-
- public NodeIterator cloneIterator() {
- NodeIterator clone = _source.cloneIterator();
- NthIterator other = new NthIterator(clone, _position);
- other.setRestartable(false);
- return other.reset();
}
}
1.12.2.1.2.1 +28 -4
xml-xalan/java/src/org/apache/xalan/xsltc/dom/StepIterator.java
Index: StepIterator.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/StepIterator.java,v
retrieving revision 1.12.2.1
retrieving revision 1.12.2.1.2.1
diff -u -r1.12.2.1 -r1.12.2.1.2.1
--- StepIterator.java 14 Aug 2002 19:21:42 -0000 1.12.2.1
+++ StepIterator.java 2 Dec 2002 15:51:25 -0000 1.12.2.1.2.1
@@ -68,29 +68,53 @@
import org.apache.xalan.xsltc.NodeIterator;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
+/**
+ * A step iterator is used to evaluate expressions like "BOOK/TITLE".
+ * A better name for this iterator would have been ParentIterator since
+ * both "BOOK" and "TITLE" are steps in XPath lingo. Step iterators are
+ * constructed from two other iterators which we are going to refer to
+ * as "outer" and "inner". Every node from the outer iterator (the one
+ * for BOOK in our example) is used to initialize the inner iterator.
+ * After this initialization, every node from the inner iterator is
+ * returned (in essence, implementing a "nested loop").
+ */
public class StepIterator extends NodeIteratorBase {
+ /**
+ * A reference to the "outer" iterator.
+ */
protected NodeIterator _source;
+
+ /**
+ * A reference to the "inner" iterator.
+ */
protected NodeIterator _iterator;
+
+ /**
+ * Temp variable to store a marked position.
+ */
private int _pos = -1;
public StepIterator(NodeIterator source, NodeIterator iterator) {
_source = source;
_iterator = iterator;
+// System.out.println("SI source = " + source + " this = " + this);
+// System.out.println("SI iterator = " + iterator + " this = " + this);
}
public void setRestartable(boolean isRestartable) {
_isRestartable = isRestartable;
_source.setRestartable(isRestartable);
- _iterator.setRestartable(true); // must _always_ be restartable
+ _iterator.setRestartable(true); // must be restartable
}
public NodeIterator cloneIterator() {
try {
- final StepIterator clone = (StepIterator)super.clone();
+ final StepIterator clone = (StepIterator) super.clone();
clone._source = _source.cloneIterator();
clone._iterator = _iterator.cloneIterator();
- clone.setRestartable(false);
+ clone._iterator.setRestartable(true); // must be restartable
+ clone._isRestartable = false;
return clone.reset();
}
catch (CloneNotSupportedException e) {
1.12.2.1.2.1 +19 -4
xml-xalan/java/src/org/apache/xalan/xsltc/dom/UnionIterator.java
Index: UnionIterator.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/UnionIterator.java,v
retrieving revision 1.12.2.1
retrieving revision 1.12.2.1.2.1
diff -u -r1.12.2.1 -r1.12.2.1.2.1
--- UnionIterator.java 14 Aug 2002 19:21:42 -0000 1.12.2.1
+++ UnionIterator.java 2 Dec 2002 15:51:25 -0000 1.12.2.1.2.1
@@ -81,7 +81,7 @@
private final static class LookAheadIterator {
public int node, markedNode;
- public final NodeIterator iterator;
+ public NodeIterator iterator;
public LookAheadIterator(NodeIterator iterator) {
this.iterator = iterator;
@@ -92,6 +92,14 @@
return node;
}
+ public LookAheadIterator cloneIterator() {
+ final LookAheadIterator clone =
+ new LookAheadIterator(iterator.cloneIterator());
+ clone.node = node;
+ clone.markedNode = node;
+ return clone;
+ }
+
public void setMark() {
markedNode = node;
iterator.setMark();
@@ -124,7 +132,9 @@
new LookAheadIterator[_heap.length];
try {
final UnionIterator clone = (UnionIterator)super.clone();
- System.arraycopy(_heap, 0, heapCopy, 0, _heap.length);
+ for (int i = 0; i < _free; i++) {
+ heapCopy[i] = _heap[i].cloneIterator();
+ }
clone.setRestartable(false);
clone._heap = heapCopy;
return clone.reset();
@@ -225,10 +235,15 @@
}
public NodeIterator reset() {
- super.reset();
for (int i = 0; i < _free; i++) {
_heap[i].iterator.reset();
+ _heap[i].step();
+ }
+ // build heap
+ for (int i = (_heapSize = _free)/2; i >= 0; i--) {
+ heapify(i);
}
+ _returnedLast = END;
return resetPosition();
}
No revision
No revision
1.5.2.1 +1 -1
xml-xalan/java/src/org/apache/xalan/xsltc/dom/ForwardPositionIterator.java
Index: ForwardPositionIterator.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/ForwardPositionIterator.java,v
retrieving revision 1.5
retrieving revision 1.5.2.1
diff -u -r1.5 -r1.5.2.1
No revision
No revision
1.42.2.1.2.1 +18 -53
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java
Index: AbstractTranslet.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java,v
retrieving revision 1.42.2.1
retrieving revision 1.42.2.1.2.1
diff -u -r1.42.2.1 -r1.42.2.1.2.1
--- AbstractTranslet.java 14 Aug 2002 19:21:44 -0000 1.42.2.1
+++ AbstractTranslet.java 2 Dec 2002 15:51:26 -0000 1.42.2.1.2.1
@@ -111,9 +111,6 @@
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());
@@ -137,14 +134,9 @@
}
/************************************************************************
- * Variable and parameter handling
+ * Parameter handling
************************************************************************/
- // 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 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;
@@ -230,47 +222,6 @@
return null;
}
- /**
- * Push a new variable frame.
- */
- public final void pushVarFrame(int frameSize) {
- varsStack.add(vframe, new Integer(vbase));
- vbase = ++vframe;
- vframe += frameSize;
-
- // Clear stack frame
- for (int i = vbase; i <= vframe + 1; i++) {
- varsStack.add(i, null);
- }
- }
-
- /**
- * Pop the topmost variable frame.
- */
- public final void popVarFrame() {
- if (vbase > 0) {
- final int oldvbase = ((Integer)varsStack.get(--vbase)).intValue();
- for (int i = vbase; i < vframe; i++) {
- varsStack.set(i, null); // for the GC
- }
- vframe = vbase; vbase = oldvbase;
- }
- }
-
- /**
- * Get the value of a variable given its index.
- */
- public final Object getVariable(int 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.set(vbase + vindex, value);
- }
-
/************************************************************************
* Message handling - implementation of <xsl:message>
************************************************************************/
@@ -487,7 +438,7 @@
* See compiler/TransletOutput for actual implementation.
************************************************************************/
- public TransletOutputHandler openOutputHandler(String filename)
+ public TransletOutputHandler openOutputHandler(String filename, boolean
append)
throws TransletException
{
try {
@@ -496,7 +447,7 @@
factory.setEncoding(_encoding);
factory.setOutputMethod(_method);
- factory.setWriter(new FileWriter(filename));
+ factory.setWriter(new FileWriter(filename, append));
factory.setOutputType(TransletOutputHandlerFactory.STREAM);
final TransletOutputHandler handler
@@ -511,6 +462,12 @@
}
}
+ public TransletOutputHandler openOutputHandler(String filename)
+ throws TransletException
+ {
+ return openOutputHandler(filename, false);
+ }
+
public void closeOutputHandler(TransletOutputHandler handler) {
try {
handler.endDocument();
@@ -614,5 +571,13 @@
public Class getAuxiliaryClass(String className) {
if (_auxClasses == null) return null;
return((Class)_auxClasses.get(className));
+ }
+
+ // GTM added (see pg 110)
+ public String[] getNamesArray() {
+ return namesArray;
+ }
+ public String[] getNamespaceArray() {
+ return namespaceArray;
}
}
1.45.2.1.2.1 +354 -65
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java
Index: BasisLibrary.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java,v
retrieving revision 1.45.2.1
retrieving revision 1.45.2.1.2.1
diff -u -r1.45.2.1 -r1.45.2.1.2.1
--- BasisLibrary.java 14 Aug 2002 19:21:44 -0000 1.45.2.1
+++ BasisLibrary.java 2 Dec 2002 15:51:26 -0000 1.45.2.1.2.1
@@ -69,6 +69,7 @@
import java.util.Locale;
import java.util.ResourceBundle;
+import java.text.NumberFormat;
import java.text.MessageFormat;
import java.text.FieldPosition;
import java.text.DecimalFormat;
@@ -85,6 +86,17 @@
import org.apache.xalan.xsltc.dom.AbsoluteIterator;
import org.apache.xalan.xsltc.dom.SingletonIterator;
+import org.apache.xalan.xsltc.dom.DOMImpl;
+import org.apache.xalan.xsltc.dom.DOMBuilder;
+import org.apache.xalan.xsltc.dom.StepIterator;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.DocumentBuilder;
+import org.apache.xalan.xsltc.trax.DOM2SAX;
+
/**
* Standard XSLT functions. All standard functions expect the current node
* and the DOM as their last two arguments.
@@ -101,6 +113,15 @@
}
/**
+ * Standard function position()
+ */
+ public static int positionF(NodeIterator iterator) {
+ return iterator.isReverse()
+ ? iterator.getLast() - iterator.getPosition() + 1
+ : iterator.getPosition();
+ }
+
+ /**
* XSLT Standard function sum(node-set).
* stringToDouble is inlined
*/
@@ -452,12 +473,43 @@
}
/**
+ * Implements the object-type() extension function.
+ *
+ * @see <a href="http://www.exslt.org/">EXSLT</a>
+ */
+ public static String objectTypeF(Object obj)
+ {
+ if (obj instanceof String)
+ return "string";
+ else if (obj instanceof Boolean)
+ return "boolean";
+ else if (obj instanceof Number)
+ return "number";
+ else if (obj instanceof DOMAdapter)
+ return "RTF";
+ else if (obj instanceof NodeIterator)
+ return "node-set";
+ else
+ return "unknown";
+ }
+
+ /**
* Implements the nodeset() extension function.
*/
- public static NodeIterator nodesetF(DOM rtf) {
- final DOMAdapter adapter = (DOMAdapter) rtf;
- return new SingletonIterator(
- DOM.ROOTNODE | adapter.getMultiDOMMask(), true);
+ public static NodeIterator nodesetF(Object obj) {
+ if (obj instanceof DOM) {
+ final DOMAdapter adapter = (DOMAdapter) obj;
+ return new SingletonIterator(
+ DOM.ROOTNODE | adapter.getMultiDOMMask(), true);
+ }
+ else if (obj instanceof NodeIterator) {
+ return (NodeIterator) obj;
+ }
+ else {
+ final String className = obj.getClass().getName();
+ runTimeError(DATA_CONVERSION_ERR, "node-set", className);
+ return null;
+ }
}
//-- Begin utility functions
@@ -497,7 +549,8 @@
* Utility function: node-set/node-set compare.
*/
public static boolean compare(NodeIterator left, NodeIterator right,
- int op, int node, DOM dom) {
+ int op, DOM dom)
+ {
int lnode;
left.reset();
@@ -515,24 +568,10 @@
return false;
}
- /**
- * Utility function: node/node-set compare.
- */
- public static boolean compare(int node, NodeIterator nodeSet,
- int op, DOM dom) {
- final String lvalue = dom.getNodeValue(node);
- int rnode;
- //nodeSet.reset();
- while ((rnode = nodeSet.next()) != NodeIterator.END) {
- if (compareStrings(lvalue, dom.getNodeValue(rnode), op, dom)) {
- return true;
- }
- }
- return false;
- }
public static boolean compare(int node, NodeIterator iterator,
- int op, int dummy, DOM dom) {
+ int op, DOM dom)
+ {
//iterator.reset();
int rnode;
@@ -540,46 +579,40 @@
switch(op) {
case EQ:
- /* TODO:
- * This needs figuring out: What sort of comparison is done here?
- * Are we comparing exact node id's, node types, or node values?
- * Values is the obvious for attributes, but what about elements?
- */
value = dom.getNodeValue(node);
- while ((rnode = iterator.next()) != NodeIterator.END)
+ while ((rnode = iterator.next()) != NodeIterator.END) {
if (value.equals(dom.getNodeValue(rnode))) return true;
- // if (rnode == node) return true; It just ain't that easy!!!
+ }
break;
case NE:
value = dom.getNodeValue(node);
- while ((rnode = iterator.next()) != NodeIterator.END)
+ while ((rnode = iterator.next()) != NodeIterator.END) {
if (!value.equals(dom.getNodeValue(rnode))) return true;
- // if (rnode != node) return true;
+ }
break;
case LT:
// Assume we're comparing document order here
- while ((rnode = iterator.next()) != NodeIterator.END)
+ while ((rnode = iterator.next()) != NodeIterator.END) {
if (rnode > node) return true;
+ }
break;
case GT:
// Assume we're comparing document order here
- while ((rnode = iterator.next()) != NodeIterator.END)
+ while ((rnode = iterator.next()) != NodeIterator.END) {
if (rnode < node) return true;
+ }
break;
}
return(false);
}
- public static boolean compare(NodeIterator left, final double rnumber,
- final int op, final int node, DOM dom) {
- return(compare(left,rnumber,op,dom));
- }
/**
* Utility function: node-set/number compare.
*/
public static boolean compare(NodeIterator left, final double rnumber,
- final int op, DOM dom) {
+ final int op, DOM dom)
+ {
int node;
//left.reset();
@@ -637,7 +670,8 @@
* Utility function: node-set/string comparison.
*/
public static boolean compare(NodeIterator left, final String rstring,
- int op, DOM dom) {
+ int op, DOM dom)
+ {
int node;
//left.reset();
while ((node = left.next()) != NodeIterator.END) {
@@ -648,19 +682,10 @@
return false;
}
- public static boolean compare(NodeIterator left, final String rstring,
- int op, int node, DOM dom) {
-
- if (compareStrings(dom.getNodeValue(node), rstring, op, dom)) {
- return true;
- }
- else {
- return false;
- }
- }
public static boolean compare(Object left, Object right,
- int op, int node, DOM dom) {
+ int op, DOM dom)
+ {
boolean result = false;
boolean hasSimpleArgs = hasSimpleType(left) && hasSimpleType(right);
@@ -758,10 +783,9 @@
NodeIterator iter = ((NodeIterator)left).reset();
if (right instanceof NodeIterator) {
- result = compare(iter, (NodeIterator)right, op, node, dom);
+ result = compare(iter, (NodeIterator)right, op, dom);
}
else if (right instanceof String) {
- //result = compare(iter, (String)right, op, node, dom);
result = compare(iter, (String)right, op, dom);
}
else if (right instanceof Number) {
@@ -774,7 +798,7 @@
}
else if (right instanceof DOM) {
result = compare(iter, ((DOM)right).getStringValue(),
- op, node, dom);
+ op, dom);
}
else if (right == null) {
return(false);
@@ -811,7 +835,7 @@
private static boolean hasSimpleType(Object obj) {
return obj instanceof Boolean || obj instanceof Double ||
obj instanceof Integer || obj instanceof String ||
- obj instanceof Node;
+ obj instanceof Node || obj instanceof DOM;
}
/**
@@ -844,7 +868,12 @@
private static String defaultPattern = "";
static {
- defaultFormatter = new DecimalFormat();
+ NumberFormat f = NumberFormat.getInstance(Locale.getDefault());
+ // set max fraction digits so that truncation does not occur,
+ // see conf test string134
+ f.setMaximumFractionDigits(Integer.MAX_VALUE);
+ defaultFormatter = (f instanceof DecimalFormat) ?
+ (DecimalFormat) f : new DecimalFormat();
defaultFormatter.setGroupingUsed(false);
}
@@ -887,9 +916,15 @@
public static String formatNumber(double number, String pattern,
DecimalFormat formatter) {
+ // bugzilla fix 12813
+ if (formatter == null) {
+ formatter = defaultFormatter;
+ }
try {
StringBuffer result = new StringBuffer();
- formatter.applyLocalizedPattern(pattern);
+ if (pattern != defaultPattern) {
+ formatter.applyLocalizedPattern(pattern);
+ }
//------------------------------------------------------
// bug fix # 9179 - make sure localized pattern contains
@@ -943,6 +978,223 @@
return null;
}
}
+
+ /**
+ * Utility function: used to convert reference to org.w3c.dom.NodeList.
+ */
+ public static NodeList referenceToNodeList(Object obj, DOM dom) {
+ if (obj instanceof Node || obj instanceof NodeIterator) {
+ NodeIterator iter = referenceToNodeSet(obj);
+ return dom.makeNodeList(iter);
+ }
+ else if (obj instanceof DOM) {
+ dom = (DOM)obj;
+ return dom.makeNodeList(DOM.ROOTNODE);
+ }
+ else {
+ final String className = obj.getClass().getName();
+ runTimeError(DATA_CONVERSION_ERR, "reference", className);
+ return null;
+ }
+ }
+
+ /**
+ * Utility function: used to convert reference to org.w3c.dom.Node.
+ */
+ public static org.w3c.dom.Node referenceToNode(Object obj, DOM dom) {
+ if (obj instanceof Node || obj instanceof NodeIterator) {
+ NodeIterator iter = referenceToNodeSet(obj);
+ return dom.makeNode(iter);
+ }
+ else if (obj instanceof DOM) {
+ dom = (DOM)obj;
+ NodeIterator iter = dom.getChildren(DOM.ROOTNODE);
+ return dom.makeNode(iter);
+ }
+ else {
+ final String className = obj.getClass().getName();
+ runTimeError(DATA_CONVERSION_ERR, "reference", className);
+ return null;
+ }
+ }
+
+ /**
+ * Utility function used to convert a w3c Node into an internal DOM
iterator.
+ */
+ public static NodeIterator node2Iterator(org.w3c.dom.Node node,
+ Translet translet, DOM dom)
+ {
+ final org.w3c.dom.Node inNode = node;
+ // Create a dummy NodeList which only contains the given node to
make
+ // use of the nodeList2Iterator() interface.
+ org.w3c.dom.NodeList nodelist = new org.w3c.dom.NodeList() {
+ public int getLength() {
+ return 1;
+ }
+
+ public org.w3c.dom.Node item(int index) {
+ if (index == 0)
+ return inNode;
+ else
+ return null;
+ }
+ };
+
+ return nodeList2Iterator(nodelist, translet, dom);
+ }
+
+ /**
+ * Utility function used to copy a node list to be under a parent node.
+ */
+ private static void copyNodes(org.w3c.dom.NodeList nodeList,
+ org.w3c.dom.Document doc, org.w3c.dom.Node parent)
+ {
+ // copy Nodes from NodeList into new w3c DOM
+ for (int i = 0; i < nodeList.getLength(); i++)
+ {
+ org.w3c.dom.Node curr = nodeList.item(i);
+ int nodeType = curr.getNodeType();
+ String value = null;
+ try {
+ value = curr.getNodeValue();
+ } catch (DOMException ex) {
+ runTimeError(RUN_TIME_INTERNAL_ERR, ex.getMessage());
+ return;
+ }
+
+ String nodeName = curr.getNodeName();
+ org.w3c.dom.Node newNode = null;
+ switch (nodeType){
+ case org.w3c.dom.Node.ATTRIBUTE_NODE:
+ newNode = doc.createAttributeNS(curr.getNamespaceURI(),
+ nodeName);
+ break;
+ case org.w3c.dom.Node.CDATA_SECTION_NODE:
+ newNode = doc.createCDATASection(value);
+ break;
+ case org.w3c.dom.Node.COMMENT_NODE:
+ newNode = doc.createComment(value);
+ break;
+ case org.w3c.dom.Node.DOCUMENT_FRAGMENT_NODE:
+ newNode = doc.createDocumentFragment();
+ break;
+ case org.w3c.dom.Node.DOCUMENT_NODE:
+ newNode = doc.createElementNS(null, "__document__");
+ copyNodes(curr.getChildNodes(), doc, newNode);
+ break;
+ case org.w3c.dom.Node.DOCUMENT_TYPE_NODE:
+ // nothing?
+ break;
+ case org.w3c.dom.Node.ELEMENT_NODE:
+ // For Element node, also copy the children and the
+ // attributes.
+ org.w3c.dom.Element element = doc.createElementNS(
+ curr.getNamespaceURI(), nodeName);
+ if (curr.hasAttributes())
+ {
+ org.w3c.dom.NamedNodeMap attributes =
curr.getAttributes();
+ for (int k = 0; k < attributes.getLength(); k++) {
+ org.w3c.dom.Node attr = attributes.item(k);
+ element.setAttribute(attr.getNodeName(),
+ attr.getNodeValue());
+ }
+ }
+ copyNodes(curr.getChildNodes(), doc, element);
+ newNode = element;
+ break;
+ case org.w3c.dom.Node.ENTITY_NODE:
+ // nothing ?
+ break;
+ case org.w3c.dom.Node.ENTITY_REFERENCE_NODE:
+ newNode = doc.createEntityReference(nodeName);
+ break;
+ case org.w3c.dom.Node.NOTATION_NODE:
+ // nothing ?
+ break;
+ case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
+ newNode = doc.createProcessingInstruction(nodeName,
+ value);
+ break;
+ case org.w3c.dom.Node.TEXT_NODE:
+ newNode = doc.createTextNode(value);
+ break;
+ }
+ try {
+ parent.appendChild(newNode);
+ } catch (DOMException e) {
+ runTimeError(RUN_TIME_INTERNAL_ERR, e.getMessage());
+ return;
+ }
+ }
+ }
+
+ /**
+ * Utility function used to convert a w3c NodeList into a internal
+ * DOM iterator.
+ */
+ public static NodeIterator nodeList2Iterator(org.w3c.dom.NodeList
nodeList,
+ Translet translet, DOM dom)
+ {
+ int size = nodeList.getLength();
+
+ // w3c NodeList -> w3c DOM
+ DocumentBuilderFactory dfac = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docbldr = null;
+ try {
+ docbldr = dfac.newDocumentBuilder();
+ } catch (javax.xml.parsers.ParserConfigurationException e) {
+ runTimeError(RUN_TIME_INTERNAL_ERR, e.getMessage());
+ return null;
+
+ }
+ // create new w3c DOM
+ Document doc = docbldr.newDocument();
+ org.w3c.dom.Node topElementNode =
+ doc.appendChild(doc.createElementNS("", "__top__"));
+
+ // Copy all the nodes in the nodelist to be under the top element
+ copyNodes(nodeList, doc, topElementNode);
+
+ // w3c DOM -> DOM2SAX -> DOMBuilder -> DOMImpl
+ DOMImpl idom = new DOMImpl();
+ final DOM2SAX dom2sax = new DOM2SAX(doc);
+ final DOMBuilder domBuilder = idom.getBuilder();
+ dom2sax.setContentHandler(domBuilder);
+ try {
+ dom2sax.parse();
+ }
+ catch (java.io.IOException e){
+ runTimeError(RUN_TIME_INTERNAL_ERR, e.getMessage());
+ return null;
+ }
+ catch (org.xml.sax.SAXException e){
+ runTimeError(RUN_TIME_INTERNAL_ERR, e.getMessage());
+ return null;
+ }
+
+
+ if (dom instanceof MultiDOM) {
+ final MultiDOM multiDOM = (MultiDOM) dom;
+
+ // Create DOMAdapter and register with MultiDOM
+ DOMAdapter domAdapter = new DOMAdapter(idom,
+ translet.getNamesArray(),
+ translet.getNamespaceArray());
+ multiDOM.addDOMAdapter(domAdapter);
+
+ NodeIterator iter1 = multiDOM.getAxisIterator(Axis.CHILD);
+ NodeIterator iter2 = multiDOM.getAxisIterator(Axis.CHILD);
+ NodeIterator iter = new AbsoluteIterator(
+ new StepIterator(iter1, iter2));
+
+ iter.setStartNode(DOM.ROOTNODE | domAdapter.getMultiDOMMask());
+ return iter;
+ }
+ else {
+ runTimeError(RUN_TIME_INTERNAL_ERR, "nodeList2Iterator()");
+ return null;
+ }
+ }
/**
* Utility function used to convert references to DOMs.
@@ -1000,7 +1252,49 @@
runTimeError(RUN_TIME_COPY_ERR);
}
}
-
+
+ /**
+ * Utility function for the implementation of xsl:element.
+ */
+ public static String startXslElement(String qname, String namespace,
+ TransletOutputHandler handler, DOM dom, int node)
+ {
+ try {
+ // Get prefix from qname
+ String prefix;
+ final int index = qname.indexOf(':');
+
+ if (index > 0) {
+ prefix = qname.substring(0, index);
+
+ // Handle case when prefix is not known at compile time
+ if (namespace == null || namespace.length() == 0) {
+ namespace = dom.lookupNamespace(node, prefix);
+ }
+
+ handler.startElement(qname);
+ handler.namespace(prefix, namespace);
+ }
+ else {
+ // Need to generate a prefix?
+ if (namespace != null && namespace.length() > 0) {
+ prefix = generatePrefix();
+ qname = prefix + ':' + qname;
+ handler.startElement(qname);
+ handler.namespace(prefix, namespace);
+ }
+ else {
+ handler.startElement(qname);
+ }
+ }
+ }
+ catch (TransletException e) {
+ throw new RuntimeException(e.getMessage());
+ }
+
+ return qname;
+ }
+
/**
* This function is used in the execution of xsl:element
*/
@@ -1012,18 +1306,11 @@
/**
* This function is used in the execution of xsl:element
*/
- private static int prefixIndex = 0;
+ private static int prefixIndex = 0; // not thread safe!!
public static String generatePrefix() {
return ("ns" + prefixIndex++);
}
- /**
- * This function is used in the execution of xsl:element
- */
- public static String makeQName(String localName, String prefix) {
- return (new
StringBuffer(prefix).append(':').append(localName).toString());
- }
-
public static final int RUN_TIME_INTERNAL_ERR = 0;
public static final int RUN_TIME_COPY_ERR = 1;
public static final int DATA_CONVERSION_ERR = 2;
@@ -1038,6 +1325,8 @@
public static final int STRAY_NAMESPACE_ERR = 11;
public static final int NAMESPACE_PREFIX_ERR = 12;
public static final int DOM_ADAPTER_INIT_ERR = 13;
+ public static final int PARSER_DTD_SUPPORT_ERR = 14;
+ public static final int NAMESPACES_SUPPORT_ERR = 15;
// All error messages are localized and are stored in resource bundles.
// This array and the following 4 strings are read from that bundle.
1.1.12.1.2.1 +163 -2
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/ErrorMessages.java
Index: ErrorMessages.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/ErrorMessages.java,v
retrieving revision 1.1.12.1
retrieving revision 1.1.12.1.2.1
diff -u -r1.1.12.1 -r1.1.12.1.2.1
--- ErrorMessages.java 14 Aug 2002 19:21:44 -0000 1.1.12.1
+++ ErrorMessages.java 2 Dec 2002 15:51:26 -0000 1.1.12.1.2.1
@@ -68,36 +68,197 @@
public class ErrorMessages extends ResourceBundle {
+/*
+ * XSLTC run-time error messages.
+ *
+ * General notes to translators and definitions:
+ *
+ * 1) XSLTC is the name of the product. It is an acronym for XML
Stylesheet:
+ * Transformations Compiler
+ *
+ * 2) A stylesheet is a description of how to transform an input XML
document
+ * into a resultant output XML document (or HTML document or text)
+ *
+ * 3) An axis is a particular "dimension" in a tree representation of an
XML
+ * document; the nodes in the tree are divided along different axes.
+ * Traversing the "child" axis, for instance, means that the program
+ * would visit each child of a particular node; traversing the
"descendant"
+ * axis means that the program would visit the child nodes of a
particular
+ * node, their children, and so on until the leaf nodes of the tree are
+ * reached.
+ *
+ * 4) An iterator is an object that traverses nodes in a tree along a
+ * particular axis, one at a time.
+ *
+ * 5) An element is a mark-up tag in an XML document; an attribute is a
+ * modifier on the tag. For example, in <elem attr='val' attr2='val2'>
+ * "elem" is an element name, "attr" and "attr2" are attribute names
with
+ * the values "val" and "val2", respectively.
+ *
+ * 6) A namespace declaration is a special attribute that is used to
associate
+ * a prefix with a URI (the namespace). The meanings of element names
and
+ * attribute names that use that prefix are defined with respect to that
+ * namespace.
+ *
+ * 7) DOM is an acronym for Document Object Model. It is a tree
+ * representation of an XML document.
+ *
+ * SAX is an acronym for the Simple API for XML processing. It is an
API
+ * used inform an XML processor (in this case XSLTC) of the structure
and
+ * content of an XML document.
+ *
+ * Input to the stylesheet processor can come from an XML parser in the
+ * form of a DOM tree or through the SAX API.
+ *
+ * 8) DTD is a document type declaration. It is a way of specifying the
+ * grammar for an XML file, the names and types of elements, attributes,
+ * etc.
+ *
+ */
+
// These message should be read from a locale-specific resource bundle
private static final String errorMessages[] = {
+
+ /*
+ * Note to translators: the substitution text in the following message
+ * is a class name. Used for internal errors in the processor.
+ */
// RUN_TIME_INTERNAL_ERR
"Run-time internal error in ''{0}''",
+
+ /*
+ * Note to translators: <xsl:copy> is a keyword that should not be
+ * translated.
+ */
// RUN_TIME_COPY_ERR
"Run-time error when executing <xsl:copy>.",
+
+ /*
+ * Note to translators: The substitution text refers to data types.
+ * The message is displayed if a value in a particular context needs to
+ * be converted to type {1}, but that's not possible for a value of type
+ * {0}.
+ */
// DATA_CONVERSION_ERR
"Invalid conversion from ''{0}'' to ''{1}''.",
+
+ /*
+ * Note to translators: This message is displayed if the function named
+ * by the substitution text is not a function that is supported. XSLTC
+ * is the acronym naming the product.
+ */
// EXTERNAL_FUNC_ERR
"External function ''{0}'' not supported by XSLTC.",
+
+ /*
+ * Note to translators: This message is displayed if two values are
+ * compared for equality, but the data type of one of the values is
+ * unknown.
+ */
// EQUALITY_EXPR_ERR
"Unknown argument type in equality expression.",
+
+ /*
+ * Note to translators: The substitution text for {0} will be a data
+ * type; the substitution text for {1} will be the name of a function.
+ * This is displayed if an argument of the particular data type is not
+ * permitted for a call to this function.
+ */
// INVALID_ARGUMENT_ERR
"Invalid argument type ''{0}'' in call to ''{1}''",
+
+ /*
+ * Note to translators: There is way of specifying a format for a
+ * number using a pattern; the processor was unable to format the
+ * particular value using the specified pattern.
+ */
// FORMAT_NUMBER_ERR
"Attempting to format number ''{0}'' using pattern ''{1}''.",
+
+ /*
+ * Note to translators: The following represents an internal error
+ * situation in XSLTC. The processor was unable to create a copy of an
+ * iterator. (See definition of iterator above.)
+ */
// ITERATOR_CLONE_ERR
"Cannot clone iterator ''{0}''.",
+
+ /*
+ * Note to translators: The following represents an internal error
+ * situation in XSLTC. The processor attempted to create an iterator
+ * for a particular axis (see definition above) that it does not
+ * support.
+ */
// AXIS_SUPPORT_ERR
"Iterator for axis ''{0}'' not supported.",
+
+ /*
+ * Note to translators: The following represents an internal error
+ * situation in XSLTC. The processor attempted to create an iterator
+ * for a particular axis (see definition above) that it does not
+ * support.
+ */
// TYPED_AXIS_SUPPORT_ERR
"Iterator for typed axis ''{0}'' not supported.",
+
+ /*
+ * Note to translators: This message is reported if the stylesheet
+ * being processed attempted to construct an XML document with an
+ * attribute in a place other than on an element. The substitution text
+ * specifies the name of the attribute.
+ */
// STRAY_ATTRIBUTE_ERR
"Attribute ''{0}'' outside of element.",
+
+ /*
+ * Note to translators: As with the preceding message, a namespace
+ * declaration has the form of an attribute and is only permitted to
+ * appear on an element. The substitution text {0} is the namespace
+ * prefix and {1} is the URI that was being used in the erroneous
+ * namespace declaration.
+ */
// STRAY_NAMESPACE_ERR
"Namespace declaration ''{0}''=''{1}'' outside of element.",
+
+ /*
+ * Note to translators: The stylesheet contained a reference to a
+ * namespace prefix that was undefined. The value of the substitution
+ * text is the name of the prefix.
+ */
// NAMESPACE_PREFIX_ERR
"Namespace for prefix ''{0}'' has not been declared.",
+
+ /*
+ * Note to translators: The following represents an internal error.
+ * DOMAdapter is a Java class in XSLTC.
+ */
// DOM_ADAPTER_INIT_ERR
- "DOMAdapter created using wrong type of source DOM."
+ "DOMAdapter created using wrong type of source DOM.",
+
+ /*
+ * Note to translators: The following message indicates that the XML
+ * parser that is providing input to XSLTC cannot be used because it
+ * does not describe to XSLTC the structure of the input XML document's
+ * DTD.
+ */
+ // PARSER_DTD_SUPPORT_ERR
+ "The SAX parser you are using does not handle DTD declaration
events.",
+
+ /*
+ * Note to translators: The following message indicates that the XML
+ * parser that is providing input to XSLTC cannot be used because it
+ * does not distinguish between ordinary XML attributes and namespace
+ * declarations.
+ */
+ // NAMESPACES_SUPPORT_ERR
+ "The SAX parser you are using does not have support for XML
Namespaces.",
+
+ /*
+ * Note to translators: The substitution text is the URI that was in
+ * error.
+ */
+ // CANT_RESOLVE_RELATIVE_URI_ERR
+ "Could not resolve the URI reference ''{0}''."
};
private static Vector _keys;
1.14.2.1.2.1 +22 -4
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/SAXAdapter.java
Index: SAXAdapter.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/SAXAdapter.java,v
retrieving revision 1.14.2.1
retrieving revision 1.14.2.1.2.1
diff -u -r1.14.2.1 -r1.14.2.1.2.1
--- SAXAdapter.java 14 Aug 2002 19:21:44 -0000 1.14.2.1
+++ SAXAdapter.java 2 Dec 2002 15:51:26 -0000 1.14.2.1.2.1
@@ -72,9 +72,19 @@
public final class SAXAdapter implements TransletOutputHandler {
+ /**
+ * Reference to DOMBuilder that receives the SAX2 events.
+ */
private final DOMBuilder _domBuilder;
+
+ /**
+ * AttributeList object reused for each element.
+ */
private final AttributeList _attributes = new AttributeList();
+ /**
+ * Name of last element seen but not yet reported.
+ */
private String _openElementName;
public SAXAdapter(DOMBuilder domBuilder) {
@@ -152,9 +162,15 @@
}
}
- public void namespace(String prefix, String uri)
- throws TransletException {
- // ???
+ public void namespace(String prefix, String uri) throws
TransletException
+ {
+ try {
+ // TODO: housekeeping necessary to emit endPrefixMapping()
+ _domBuilder.startPrefixMapping(prefix, uri);
+ }
+ catch (SAXException e) {
+ throw new TransletException(e);
+ }
}
public void comment(String comment) throws TransletException {
@@ -186,6 +202,8 @@
}
// The SAX handler does not handle these:
+ public void startCDATA() throws TransletException {}
+ public void endCDATA() throws TransletException {}
public void setType(int type) {}
public void setHeader(String header) {}
public void setIndent(boolean indent) {}
1.58.2.1.2.1 +9 -1
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/TextOutput.java
Index: TextOutput.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/TextOutput.java,v
retrieving revision 1.58.2.1
retrieving revision 1.58.2.1.2.1
diff -u -r1.58.2.1 -r1.58.2.1.2.1
--- TextOutput.java 14 Aug 2002 19:21:44 -0000 1.58.2.1
+++ TextOutput.java 2 Dec 2002 15:51:26 -0000 1.58.2.1.2.1
@@ -384,6 +384,14 @@
_cdataTagOpen = false;
}
+ public void startCDATA() throws TransletException {
+ // This class is deprecated - use runtime.output package
+ }
+
+ public void endCDATA() throws TransletException {
+ // This class is deprecated - use runtime.output package
+ }
+
/**
* Send characters to the output document
*/
1.10.2.1.2.1 +3 -1
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/TransletOutputBase.java
Index: TransletOutputBase.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/TransletOutputBase.java,v
retrieving revision 1.10.2.1
retrieving revision 1.10.2.1.2.1
diff -u -r1.10.2.1 -r1.10.2.1.2.1
--- TransletOutputBase.java 14 Aug 2002 19:21:44 -0000 1.10.2.1
+++ TransletOutputBase.java 2 Dec 2002 15:51:26 -0000 1.10.2.1.2.1
@@ -85,6 +85,8 @@
throws TransletException {}
public boolean setEscaping(boolean escape)
throws TransletException { return true; }
+ public void startCDATA() throws TransletException {}
+ public void endCDATA() throws TransletException {}
public String expandQName(String withPrefix) { return(withPrefix); }
public void setType(int type) {}
public void setIndent(boolean indent) {}
No revision
No revision
1.8.2.1.2.1 +17 -7
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/OutputBase.java
Index: OutputBase.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/OutputBase.java,v
retrieving revision 1.8.2.1
retrieving revision 1.8.2.1.2.1
diff -u -r1.8.2.1 -r1.8.2.1.2.1
--- OutputBase.java 14 Aug 2002 19:21:45 -0000 1.8.2.1
+++ OutputBase.java 2 Dec 2002 15:51:27 -0000 1.8.2.1.2.1
@@ -181,15 +181,24 @@
* an attribute. If at runtime, when the qname of the attribute is
* known, another prefix is specified for the attribute, then we can get
* a qname of the form "ns?:otherprefix:name". This function patches the
- * qname by simply ignoring "otherprefix".
+ * qname by simply ignoring "otherprefix". In addition, this method
+ * ignores prefixes bound to the empty string "".
*/
- protected static String patchName(String qname) throws TransletException
{
+ protected String patchName(String qname) throws TransletException {
final int lastColon = qname.lastIndexOf(':');
+
if (lastColon > 0) {
final int firstColon = qname.indexOf(':');
- if (firstColon != lastColon) {
- return qname.substring(0, firstColon) +
- qname.substring(lastColon);
+ final String prefix = qname.substring(0, firstColon);
+ final String localName = qname.substring(lastColon + 1);
+
+ // If uri is "" then ignore prefix
+ final String uri = lookupNamespace(prefix);
+ if (uri != null && uri.length() == 0) {
+ return localName;
+ }
+ else if (firstColon != lastColon) {
+ return prefix + ':' + localName;
}
}
return qname;
@@ -288,7 +297,8 @@
return uri;
}
- // -- Temporary
+ public void startCDATA() throws TransletException { }
+ public void endCDATA() throws TransletException { }
public void namespace(String prefix, String uri) throws
TransletException { }
public void setType(int type) { }
public void setIndent(boolean indent) { }
1.9.2.1.2.1 +17 -19
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXHTMLOutput.java
Index: SAXHTMLOutput.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXHTMLOutput.java,v
retrieving revision 1.9.2.1
retrieving revision 1.9.2.1.2.1
diff -u -r1.9.2.1 -r1.9.2.1.2.1
--- SAXHTMLOutput.java 14 Aug 2002 19:21:45 -0000 1.9.2.1
+++ SAXHTMLOutput.java 2 Dec 2002 15:51:27 -0000 1.9.2.1.2.1
@@ -140,7 +140,7 @@
if (_startTagOpen) {
closeStartTag();
}
- _saxHandler.endElement(EMPTYSTRING, EMPTYSTRING, elementName);
+ _saxHandler.endElement(EMPTYSTRING, elementName, elementName);
}
catch (SAXException e) {
throw new TransletException(e);
@@ -151,22 +151,20 @@
public void attribute(String name, final String value)
throws TransletException
{
- final String patchedName = patchName(name);
- final String localName = getLocalName(patchedName);
- final int index = _attributes.getIndex(name);
-
- if (!_startTagOpen) {
- BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR,name);
- }
-
- if (index >= 0) {
- _attributes.setAttribute(index, EMPTYSTRING, EMPTYSTRING,
- name, "CDATA", value);
- }
- else {
- _attributes.addAttribute(EMPTYSTRING, EMPTYSTRING,
+ if (_startTagOpen) {
+ final String patchedName = patchName(name);
+ final String localName = getLocalName(patchedName);
+ final int index = _attributes.getIndex(name);
+
+ if (index >= 0) {
+ _attributes.setAttribute(index, EMPTYSTRING, localName,
+ name, "CDATA", value);
+ }
+ else {
+ _attributes.addAttribute(EMPTYSTRING, localName,
name, "CDATA", value);
- }
+ }
+ }
}
/**
@@ -194,8 +192,8 @@
_startTagOpen = false;
// Now is time to send the startElement event
- _saxHandler.startElement(null, _elementName, _elementName,
- _attributes);
+ _saxHandler.startElement(EMPTYSTRING, _elementName,
+ _elementName, _attributes);
}
catch (SAXException e) {
throw new TransletException(e);
1.12.2.1.2.1 +38 -25
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXXMLOutput.java
Index: SAXXMLOutput.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXXMLOutput.java,v
retrieving revision 1.12.2.1
retrieving revision 1.12.2.1.2.1
diff -u -r1.12.2.1 -r1.12.2.1.2.1
--- SAXXMLOutput.java 14 Aug 2002 19:21:45 -0000 1.12.2.1
+++ SAXXMLOutput.java 2 Dec 2002 15:51:27 -0000 1.12.2.1.2.1
@@ -153,27 +153,24 @@
public void attribute(String name, final String value)
throws TransletException
{
- final String patchedName = patchName(name);
- final String localName = getLocalName(patchedName);
- final String uri = getNamespaceURI(patchedName, false);
-
- final int index = (localName == null) ?
- _attributes.getIndex(name) : /* don't use patchedName */
- _attributes.getIndex(uri, localName);
-
- if (!_startTagOpen) {
- BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR,
- patchedName);
- }
-
- if (index >= 0) { // Duplicate attribute?
- _attributes.setAttribute(index, uri, localName,
- patchedName, "CDATA", value);
+ if (_startTagOpen) {
+ final String patchedName = patchName(name);
+ final String localName = getLocalName(patchedName);
+ final String uri = getNamespaceURI(patchedName, false);
+
+ final int index = (localName == null) ?
+ _attributes.getIndex(name) : /* don't use patchedName */
+ _attributes.getIndex(uri, localName);
+
+ if (index >= 0) { // Duplicate attribute?
+ _attributes.setAttribute(index, uri, localName,
+ patchedName, "CDATA", value);
+ }
+ else {
+ _attributes.addAttribute(uri, localName, patchedName,
+ "CDATA", value);
+ }
}
- else {
- _attributes.addAttribute(uri, localName, patchedName,
- "CDATA", value);
- }
}
public void characters(char[] ch, int off, int len)
@@ -330,10 +327,26 @@
}
}
- protected void closeCDATA() throws SAXException {
- // Output closing bracket - "]]>"
- _saxHandler.characters(ENDCDATA, 0, ENDCDATA.length);
- _cdataTagOpen = false;
+ public void startCDATA() throws TransletException {
+ try {
+ // Output start bracket - "<![CDATA["
+ _saxHandler.characters(BEGCDATA, 0, BEGCDATA.length);
+ _cdataTagOpen = true;
+ }
+ catch (SAXException e) {
+ throw new TransletException(e);
+ }
+ }
+
+ public void closeCDATA() throws TransletException {
+ try {
+ // Output closing bracket - "]]>"
+ _saxHandler.characters(ENDCDATA, 0, ENDCDATA.length);
+ _cdataTagOpen = false;
+ }
+ catch (SAXException e) {
+ throw new TransletException(e);
+ }
}
/**
1.17.2.1.2.1 +90 -8
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamHTMLOutput.java
Index: StreamHTMLOutput.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamHTMLOutput.java,v
retrieving revision 1.17.2.1
retrieving revision 1.17.2.1.2.1
diff -u -r1.17.2.1 -r1.17.2.1.2.1
--- StreamHTMLOutput.java 14 Aug 2002 19:21:45 -0000 1.17.2.1
+++ StreamHTMLOutput.java 2 Dec 2002 15:51:27 -0000 1.17.2.1.2.1
@@ -97,20 +97,25 @@
public StreamHTMLOutput(StreamOutput output) {
super(output);
+ _buffer = new WriterOutputBuffer(_writer);
setIndent(true); // default for HTML
-// System.out.println("StreamHTMLOutput.<init>");
+// System.out.println("StreamHTMLOutput.<init> this = " + this);
}
public StreamHTMLOutput(Writer writer, String encoding) {
super(writer, encoding);
-// System.out.println("StreamHTMLOutput.<init>");
+ _buffer = new WriterOutputBuffer(_writer);
+ setIndent(true); // default for HTML
+//System.out.println("StreamHTMLOutput.<init> this = " + this);
}
public StreamHTMLOutput(OutputStream out, String encoding)
throws IOException
{
super(out, encoding);
-// System.out.println("StreamHTMLOutput.<init>");
+ _buffer = new WriterOutputBuffer(_writer);
+ setIndent(true); // default for HTML
+//System.out.println("StreamHTMLOutput.<init> this = " + this);
}
public void startDocument() throws TransletException {
@@ -181,7 +186,7 @@
if (_indent) {
_indentLevel--;
- _indentNextEndTag = true;
+ _lineFeedNextStartTag = _indentNextEndTag = false;
}
}
else {
@@ -190,8 +195,7 @@
if (_indentNextEndTag) {
indent(_indentNextEndTag);
- _indentNextEndTag = true;
- _lineFeedNextStartTag = true;
+ _lineFeedNextStartTag = _indentNextEndTag = true;
}
}
_buffer.append("</").append(elementName).append('>');
@@ -260,7 +264,7 @@
if (_startTagOpen) {
closeStartTag();
}
- _buffer.append("<!--").append(comment).append("-->");
+ appendComment(comment);
}
public void processingInstruction(String target, String data)
@@ -324,6 +328,33 @@
*/
private String escapeNonURL(String base) {
final int length = base.length();
+ StringBuffer result = null;
+
+ for (int i = 0; i < length; i++){
+ final char ch = base.charAt(i);
+
+ if ((ch >= '\u007F' && ch < '\u00A0') ||
+ (_is8859Encoded && ch > '\u00FF'))
+ {
+ if (result == null) {
+ result = new StringBuffer((int) (1.2 * length));
+ result.append(base.substring(0, i));
+ }
+ result.append(CHAR_ESC_START)
+ .append(Integer.toString((int) ch))
+ .append(';');
+ }
+ else if (result != null) {
+ result.append(ch);
+ }
+ }
+
+ return (result == null) ? base : result.toString();
+ }
+
+/*
+ private String escapeNonURL(String base) {
+ final int length = base.length();
final StringBuffer result = new StringBuffer();
for (int i = 0; i < length; i++){
@@ -342,6 +373,7 @@
}
return result.toString();
}
+*/
/**
* This method escapes special characters used in HTML attribute values
@@ -416,4 +448,54 @@
_headTagOpen = false;
}
}
+
+ /**
+ * This method escapes special characters used in text nodes
+ */
+ protected void escapeCharacters(char[] ch, int off, int len) {
+ int limit = off + len;
+ int offset = off;
+
+ if (limit > ch.length) {
+ limit = ch.length;
+ }
+
+ // Step through characters and escape all special characters
+ for (int i = off; i < limit; i++) {
+ final char current = ch[i];
+
+ switch (current) {
+ case '&':
+ _buffer.append(ch, offset, i - offset).append(AMP);
+ offset = i + 1;
+ break;
+ case '<':
+ _buffer.append(ch, offset, i - offset).append(LT);
+ offset = i + 1;
+ break;
+ case '>':
+ _buffer.append(ch, offset, i - offset).append(GT);
+ offset = i + 1;
+ break;
+ case '\u00A0':
+ _buffer.append(ch, offset, i - offset).append(NBSP);
+ offset = i + 1;
+ break;
+ default:
+ if ((current >= '\u007F' && current < '\u00A0') ||
+ (_is8859Encoded && current > '\u00FF'))
+ {
+ _buffer.append(ch, offset, i - offset)
+ .append(CHAR_ESC_START)
+ .append(Integer.toString((int)ch[i]))
+ .append(';');
+ offset = i + 1;
+ }
+ }
+ }
+ // Output remaining characters (that do not need escaping).
+ if (offset < limit) {
+ _buffer.append(ch, offset, limit - offset);
+ }
+ }
}
1.19.2.1.2.1 +85 -77
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamOutput.java
Index: StreamOutput.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamOutput.java,v
retrieving revision 1.19.2.1
retrieving revision 1.19.2.1.2.1
diff -u -r1.19.2.1 -r1.19.2.1.2.1
--- StreamOutput.java 14 Aug 2002 19:21:45 -0000 1.19.2.1
+++ StreamOutput.java 2 Dec 2002 15:51:27 -0000 1.19.2.1.2.1
@@ -64,22 +64,25 @@
package org.apache.xalan.xsltc.runtime.output;
import java.io.Writer;
+import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.Vector;
+import java.util.Hashtable;
import org.apache.xalan.xsltc.TransletException;
-abstract class StreamOutput extends OutputBase {
+abstract public class StreamOutput extends OutputBase {
protected static final String AMP = "&";
protected static final String LT = "<";
protected static final String GT = ">";
protected static final String CRLF = "
";
- protected static final String QUOTE = """;
+ protected static final String APOS = "'";
+ protected static final String QUOT = """;
protected static final String NBSP = " ";
protected static final String CHAR_ESC_START = "&#";
@@ -88,11 +91,8 @@
protected static final int MAX_INDENT_LEVEL = (INDENT.length >> 1);
protected static final int MAX_INDENT = INDENT.length;
- protected static final int BUFFER_SIZE = 64 * 1024;
- protected static final int OUTPUT_BUFFER_SIZE = 4 * 1024;
-
protected Writer _writer;
- protected StringBuffer _buffer;
+ protected OutputBuffer _buffer;
protected boolean _is8859Encoded = false;
protected boolean _indent = false;
@@ -108,7 +108,8 @@
protected boolean _escaping = true;
protected String _encoding = "UTF-8";
- // protected HashSet _attributes = new HashSet();
+ protected int _indentNumber = 2;
+
protected Vector _attributes = new Vector();
static class Attribute {
@@ -133,31 +134,66 @@
}
}
+ // Canonical encodings
+ private static Hashtable _canonicalEncodings;
+ static {
+ _canonicalEncodings = new Hashtable();
+ _canonicalEncodings.put("ebcdic-cp-us", "Cp037");
+ _canonicalEncodings.put("ebcdic-cp-ca", "Cp037");
+ _canonicalEncodings.put("ebcdic-cp-nl", "Cp037");
+ _canonicalEncodings.put("ebcdic-cp-dk", "Cp277");
+ _canonicalEncodings.put("ebcdic-cp-no", "Cp277");
+ _canonicalEncodings.put("ebcdic-cp-fi", "Cp278");
+ _canonicalEncodings.put("ebcdic-cp-se", "Cp278");
+ _canonicalEncodings.put("ebcdic-cp-it", "Cp280");
+ _canonicalEncodings.put("ebcdic-cp-es", "Cp284");
+ _canonicalEncodings.put("ebcdic-cp-gb", "Cp285");
+ _canonicalEncodings.put("ebcdic-cp-fr", "Cp297");
+ _canonicalEncodings.put("ebcdic-cp-ar1", "Cp420");
+ _canonicalEncodings.put("ebcdic-cp-he", "Cp424");
+ _canonicalEncodings.put("ebcdic-cp-ch", "Cp500");
+ _canonicalEncodings.put("ebcdic-cp-roece", "Cp870");
+ _canonicalEncodings.put("ebcdic-cp-yu", "Cp870");
+ _canonicalEncodings.put("ebcdic-cp-is", "Cp871");
+ _canonicalEncodings.put("ebcdic-cp-ar2", "Cp918");
+ }
+
+ public static String getCanonicalEncoding(String encoding) {
+ String canonical =
+ (String)_canonicalEncodings.get(encoding.toLowerCase());
+ return (canonical != null) ? canonical : encoding;
+ }
+
protected StreamOutput(StreamOutput output) {
_writer = output._writer;
_encoding = output._encoding;
_is8859Encoded = output._is8859Encoded;
_buffer = output._buffer;
+ _indentNumber = output._indentNumber;
}
protected StreamOutput(Writer writer, String encoding) {
_writer = writer;
_encoding = encoding;
_is8859Encoded = encoding.equalsIgnoreCase("iso-8859-1");
- _buffer = new StringBuffer(BUFFER_SIZE);
}
protected StreamOutput(OutputStream out, String encoding)
throws IOException
{
try {
- _writer = new OutputStreamWriter(out, _encoding = encoding);
+ _writer = new OutputStreamWriter(out,
+ getCanonicalEncoding(encoding));
+ _encoding = encoding;
_is8859Encoded = encoding.equalsIgnoreCase("iso-8859-1");
}
catch (UnsupportedEncodingException e) {
_writer = new OutputStreamWriter(out, _encoding = "utf-8");
}
- _buffer = new StringBuffer(BUFFER_SIZE);
+ }
+
+ public void setIndentNumber(int value) {
+ _indentNumber = value;
}
/**
@@ -187,22 +223,9 @@
protected void outputBuffer() {
try {
- int n = 0;
- final int length = _buffer.length();
- final String output = _buffer.toString();
-
- // Output buffer in chunks of OUTPUT_BUFFER_SIZE
- if (length > OUTPUT_BUFFER_SIZE) {
- do {
- _writer.write(output, n, OUTPUT_BUFFER_SIZE);
- n += OUTPUT_BUFFER_SIZE;
- } while (n + OUTPUT_BUFFER_SIZE < length);
- }
- _writer.write(output, n, length - n);
- _writer.flush();
+ _writer.write(_buffer.close());
}
catch (IOException e) {
- // ignore
}
}
@@ -228,62 +251,18 @@
protected void indent(boolean linefeed) {
if (linefeed) {
_buffer.append('\n');
- }
- _buffer.append(INDENT, 0,
- _indentLevel < MAX_INDENT_LEVEL ? _indentLevel + _indentLevel
- : MAX_INDENT);
+ _buffer.append(INDENT, 0,
+ _indentLevel < MAX_INDENT_LEVEL ?
+ _indentLevel * _indentNumber : MAX_INDENT);
+ }
}
+ /**
+ * This method escapes special characters used in text nodes. It
+ * is overriden for XML and HTML output.
+ */
protected void escapeCharacters(char[] ch, int off, int len) {
- int limit = off + len;
- int offset = off;
-
- if (limit > ch.length) {
- limit = ch.length;
- }
-
- // Step through characters and escape all special characters
- for (int i = off; i < limit; i++) {
- final char current = ch[i];
-
- switch (current) {
- case '&':
- _buffer.append(ch, offset, i - offset);
- _buffer.append(AMP);
- offset = i + 1;
- break;
- case '<':
- _buffer.append(ch, offset, i - offset);
- _buffer.append(LT);
- offset = i + 1;
- break;
- case '>':
- _buffer.append(ch, offset, i - offset);
- _buffer.append(GT);
- offset = i + 1;
- break;
- case '\u00a0':
- _buffer.append(ch, offset, i - offset);
- _buffer.append(NBSP);
- offset = i + 1;
- break;
- default:
- if ((current >= '\u007F' && current < '\u00A0') ||
- (_is8859Encoded && current > '\u00FF'))
- {
- _buffer.append(ch, offset, i - offset);
- _buffer.append(CHAR_ESC_START);
- _buffer.append(Integer.toString((int)ch[i]));
- _buffer.append(';');
- offset = i + 1;
- }
- }
- }
- // Output remaining characters (that do not need escaping).
- if (offset < limit) {
- _buffer.append(ch, offset, limit - offset);
- }
}
protected void appendAttributes() {
@@ -306,5 +285,34 @@
appendAttributes();
_buffer.append('>');
_startTagOpen = false;
+ }
+
+ /**
+ * Ensure that comments do not include the sequence "--" and
+ * that they do not end with "-".
+ */
+ protected void appendComment(String comment)
+ throws TransletException
+ {
+ boolean lastIsDash = false;
+ final int n = comment.length();
+
+ _buffer.append("<!--");
+ for (int i = 0; i < n; i++) {
+ final char ch = comment.charAt(i);
+ final boolean isDash = (ch == '-');
+
+ if (lastIsDash && isDash) {
+ _buffer.append(" -");
+ }
+ else {
+ _buffer.append(ch);
+ }
+ lastIsDash = isDash;
+ }
+ if (lastIsDash) {
+ _buffer.append(' ');
+ }
+ _buffer.append("-->");
}
}
1.2.4.1.2.1 +3 -1
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamTextOutput.java
Index: StreamTextOutput.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamTextOutput.java,v
retrieving revision 1.2.4.1
retrieving revision 1.2.4.1.2.1
diff -u -r1.2.4.1 -r1.2.4.1.2.1
--- StreamTextOutput.java 14 Aug 2002 19:21:45 -0000 1.2.4.1
+++ StreamTextOutput.java 2 Dec 2002 15:51:27 -0000 1.2.4.1.2.1
@@ -72,12 +72,14 @@
public StreamTextOutput(Writer writer, String encoding) {
super(writer, encoding);
+ _buffer = new WriterOutputBuffer(_writer);
}
public StreamTextOutput(OutputStream out, String encoding)
throws IOException
{
super(out, encoding);
+ _buffer = new WriterOutputBuffer(_writer);
}
public void startDocument() throws TransletException {
1.7.4.1.2.1 +5 -1
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamUnknownOutput.java
Index: StreamUnknownOutput.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamUnknownOutput.java,v
retrieving revision 1.7.4.1
retrieving revision 1.7.4.1.2.1
diff -u -r1.7.4.1 -r1.7.4.1.2.1
--- StreamUnknownOutput.java 14 Aug 2002 19:21:45 -0000 1.7.4.1
+++ StreamUnknownOutput.java 2 Dec 2002 15:51:27 -0000 1.7.4.1.2.1
@@ -285,6 +285,10 @@
_handler.setCdataElements(elements);
}
+ public void setIndentNumber(int value) {
+ _handler.setIndentNumber(value);
+ }
+
private void initStreamOutput()
throws TransletException
{
1.19.2.1.2.1 +89 -14
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamXMLOutput.java
Index: StreamXMLOutput.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamXMLOutput.java,v
retrieving revision 1.19.2.1
retrieving revision 1.19.2.1.2.1
diff -u -r1.19.2.1 -r1.19.2.1.2.1
--- StreamXMLOutput.java 14 Aug 2002 19:21:45 -0000 1.19.2.1
+++ StreamXMLOutput.java 2 Dec 2002 15:51:27 -0000 1.19.2.1.2.1
@@ -90,6 +90,7 @@
public StreamXMLOutput(Writer writer, String encoding) {
super(writer, encoding);
+ _buffer = new StringOutputBuffer();
initCDATA();
initNamespaces();
//System.out.println("StreamXMLOutput.<init>");
@@ -99,11 +100,22 @@
throws IOException
{
super(out, encoding);
+ _buffer = new StringOutputBuffer();
initCDATA();
initNamespaces();
//System.out.println("StreamXMLOutput.<init>");
}
+ private void insertHeader(String header) {
+ try {
+ _writer.write(header);
+ _writer.write(_buffer.close());
+ _buffer = new WriterOutputBuffer(_writer);
+ }
+ catch (IOException e) {
+ }
+ }
+
public void startDocument() throws TransletException {
//System.out.println("startDocument");
if (!_omitHeader) {
@@ -115,7 +127,11 @@
header.append("\"?>\n");
// Always insert header at the beginning
- _buffer.insert(0, header.toString());
+ insertHeader(header.toString());
+ }
+ else {
+ // Must inform buffer the absence of a header
+ insertHeader(EMPTYSTRING);
}
}
@@ -131,7 +147,7 @@
closeStartTag();
}
else if (_cdataTagOpen) {
- closeCDATA();
+ endCDATA();
}
// Handle document type declaration (for first element only)
@@ -159,7 +175,7 @@
public void endElement(String elementName) throws TransletException {
// System.out.println("endElement = " + elementName);
if (_cdataTagOpen) {
- closeCDATA();
+ endCDATA();
}
if (_startTagOpen) {
@@ -248,10 +264,9 @@
closeStartTag();
}
else if (_cdataTagOpen) {
- closeCDATA();
+ endCDATA();
}
-
- _buffer.append("<!--").append(comment).append("-->");
+ appendComment(comment);
}
public void processingInstruction(String target, String data)
@@ -262,7 +277,7 @@
closeStartTag();
}
else if (_cdataTagOpen) {
- closeCDATA();
+ endCDATA();
}
_buffer.append("<?").append(target).append(' ')
@@ -280,14 +295,23 @@
throws TransletException
{
// System.out.println("namespace prefix = " + prefix + " uri = " + uri);
- String escaped = escapeString(uri);
+ final String escaped = escapeString(uri);
+
if (_startTagOpen) {
if (pushNamespace(prefix, escaped)) {
- _buffer.append(' ').append(XMLNS_PREFIX);
if (prefix != null && prefix != EMPTYSTRING) {
- _buffer.append(':').append(prefix);
+ // Ignore if not default NS and if uri is ""
+ if (escaped.length() > 0) {
+ _buffer.append(' ').append(XMLNS_PREFIX)
+ .append(':').append(prefix)
+ .append("=\"").append(escaped).append('"');
+ }
+ }
+ else {
+ _buffer.append(' ').append(XMLNS_PREFIX)
+ .append("=\"").append(escaped).append('"');
}
- _buffer.append("=\"").append(escaped).append('"');
+
}
}
else if (prefix != EMPTYSTRING || uri != EMPTYSTRING) {
@@ -340,7 +364,12 @@
_cdataTagOpen = true;
}
- private void closeCDATA() {
+ public void startCDATA() throws TransletException {
+ _buffer.append(BEGCDATA);
+ _cdataTagOpen = true;
+ }
+
+ public void endCDATA() throws TransletException {
_buffer.append(ENDCDATA);
_cdataTagOpen = false;
}
@@ -390,7 +419,7 @@
offset = i + 1;
break;
case '"':
- result.append(ch, offset, i - offset).append(QUOTE);
+ result.append(ch, offset, i - offset).append(QUOT);
offset = i + 1;
break;
case '<':
@@ -412,5 +441,51 @@
result.append(ch, offset, limit - offset);
}
return result.toString();
+ }
+
+ /**
+ * This method escapes special characters used in text nodes
+ */
+ protected void escapeCharacters(char[] ch, int off, int len) {
+ int limit = off + len;
+ int offset = off;
+
+ if (limit > ch.length) {
+ limit = ch.length;
+ }
+
+ // Step through characters and escape all special characters
+ for (int i = off; i < limit; i++) {
+ final char current = ch[i];
+
+ switch (current) {
+ case '&':
+ _buffer.append(ch, offset, i - offset).append(AMP);
+ offset = i + 1;
+ break;
+ case '<':
+ _buffer.append(ch, offset, i - offset).append(LT);
+ offset = i + 1;
+ break;
+ case '>':
+ _buffer.append(ch, offset, i - offset).append(GT);
+ offset = i + 1;
+ break;
+ default:
+ if ((current >= '\u007F' && current < '\u00A0') ||
+ (_is8859Encoded && current > '\u00FF'))
+ {
+ _buffer.append(ch, offset, i - offset)
+ .append(CHAR_ESC_START)
+ .append(Integer.toString((int)ch[i]))
+ .append(';');
+ offset = i + 1;
+ }
+ }
+ }
+ // Output remaining characters (that do not need escaping).
+ if (offset < limit) {
+ _buffer.append(ch, offset, limit - offset);
+ }
}
}
1.12.4.1.2.1 +18 -8
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/TransletOutputHandlerFactory.java
Index: TransletOutputHandlerFactory.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/TransletOutputHandlerFactory.java,v
retrieving revision 1.12.4.1
retrieving revision 1.12.4.1.2.1
diff -u -r1.12.4.1 -r1.12.4.1.2.1
--- TransletOutputHandlerFactory.java 14 Aug 2002 19:21:45 -0000 1.12.4.1
+++ TransletOutputHandlerFactory.java 2 Dec 2002 15:51:27 -0000
1.12.4.1.2.1
@@ -89,6 +89,7 @@
private OutputStream _ostream = System.out;
private Writer _writer = null;
private Node _node = null;
+ private int _indentNumber = -1;
private ContentHandler _handler = null;
private LexicalHandler _lexHandler = null;
@@ -135,33 +136,42 @@
: null;
}
+ public void setIndentNumber(int value) {
+ _indentNumber = value;
+ }
+
public TransletOutputHandler getTransletOutputHandler()
throws IOException, ParserConfigurationException
{
switch (_outputType) {
case STREAM:
+ StreamOutput result = null;
+
if (_method == null) {
- return (_writer == null) ?
+ result = (_writer == null) ?
new StreamUnknownOutput(_ostream, _encoding) :
new StreamUnknownOutput(_writer, _encoding);
}
-
- if (_method.equalsIgnoreCase("xml")) {
- return (_writer == null) ?
+ else if (_method.equalsIgnoreCase("xml")) {
+ result = (_writer == null) ?
new StreamXMLOutput(_ostream, _encoding) :
new StreamXMLOutput(_writer, _encoding);
}
else if (_method.equalsIgnoreCase("html")) {
- return (_writer == null) ?
+ result = (_writer == null) ?
new StreamHTMLOutput(_ostream, _encoding) :
new StreamHTMLOutput(_writer, _encoding);
}
else if (_method.equalsIgnoreCase("text")) {
- return (_writer == null) ?
+ result = (_writer == null) ?
new StreamTextOutput(_ostream, _encoding) :
new StreamTextOutput(_writer, _encoding);
}
- break;
+
+ if (result != null && _indentNumber >= 0) {
+ result.setIndentNumber(_indentNumber);
+ }
+ return result;
case DOM:
_handler = (_node != null) ? new SAX2DOM(_node) :
new SAX2DOM();
No revision
No revision
1.1.2.1 +1 -1
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/OutputBuffer.java
Index: OutputBuffer.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/OutputBuffer.java,v
retrieving revision 1.1
retrieving revision 1.1.2.1
diff -u -r1.1 -r1.1.2.1
1.1.2.1 +1 -1
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StringOutputBuffer.java
Index: StringOutputBuffer.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StringOutputBuffer.java,v
retrieving revision 1.1
retrieving revision 1.1.2.1
diff -u -r1.1 -r1.1.2.1
1.2.2.1 +1 -1
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/WriterOutputBuffer.java
Index: WriterOutputBuffer.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/WriterOutputBuffer.java,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -u -r1.2 -r1.2.2.1
No revision
No revision
1.17.2.1.2.1 +18 -2
xml-xalan/java/src/org/apache/xalan/xsltc/trax/DOM2SAX.java
Index: DOM2SAX.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/trax/DOM2SAX.java,v
retrieving revision 1.17.2.1
retrieving revision 1.17.2.1.2.1
diff -u -r1.17.2.1 -r1.17.2.1.2.1
--- DOM2SAX.java 14 Aug 2002 19:21:46 -0000 1.17.2.1
+++ DOM2SAX.java 2 Dec 2002 15:51:28 -0000 1.17.2.1.2.1
@@ -89,7 +89,7 @@
import org.w3c.dom.Entity;
import org.w3c.dom.Notation;
-class DOM2SAX implements XMLReader, Locator {
+public class DOM2SAX implements XMLReader, Locator {
private final static String EMPTYSTRING = "";
private static final String XMLNS_PREFIX = "xmlns";
@@ -184,6 +184,22 @@
public void parse(InputSource unused) throws IOException, SAXException {
parse(_dom);
+ }
+
+ public void parse() throws IOException, SAXException {
+ if (_dom != null) {
+ boolean isIncomplete =
+ (_dom.getNodeType() != org.w3c.dom.Node.DOCUMENT_NODE);
+
+ if (isIncomplete) {
+ _sax.startDocument();
+ parse(_dom);
+ _sax.endDocument();
+ }
+ else {
+ parse(_dom);
+ }
+ }
}
/**
1.1.4.1 +10 -4
xml-xalan/java/src/org/apache/xalan/xsltc/trax/DOM2TO.java
Index: DOM2TO.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/trax/DOM2TO.java,v
retrieving revision 1.1
retrieving revision 1.1.4.1
diff -u -r1.1 -r1.1.4.1
--- DOM2TO.java 12 Aug 2002 19:33:55 -0000 1.1
+++ DOM2TO.java 2 Dec 2002 15:51:28 -0000 1.1.4.1
@@ -132,7 +132,6 @@
switch (node.getNodeType()) {
case Node.ATTRIBUTE_NODE: // handled by ELEMENT_NODE
- case Node.DOCUMENT_FRAGMENT_NODE:
case Node.DOCUMENT_TYPE_NODE :
case Node.ENTITY_NODE :
case Node.ENTITY_REFERENCE_NODE:
@@ -159,11 +158,18 @@
_handler.endDocument();
break;
+ case Node.DOCUMENT_FRAGMENT_NODE:
+ next = node.getFirstChild();
+ while (next != null) {
+ parse(next);
+ next = next.getNextSibling();
+ }
+ break;
+
case Node.ELEMENT_NODE:
// Generate SAX event to start element
final String qname = node.getNodeName();
_handler.startElement(qname);
-
String prefix;
final NamedNodeMap map = node.getAttributes();
final int length = map.getLength();
@@ -184,7 +190,7 @@
else {
final String uriAttr = attr.getNamespaceURI();
// Uri may be implicitly declared
- if (uriAttr != null) {
+ if (uriAttr != null && !uriAttr.equals(EMPTYSTRING) ) {
colon = qnameAttr.lastIndexOf(':');
prefix = (colon > 0) ? qnameAttr.substring(0, colon)
: EMPTYSTRING;
1.14.2.1.2.1 +20 -12
xml-xalan/java/src/org/apache/xalan/xsltc/trax/SAX2DOM.java
Index: SAX2DOM.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/trax/SAX2DOM.java,v
retrieving revision 1.14.2.1
retrieving revision 1.14.2.1.2.1
diff -u -r1.14.2.1 -r1.14.2.1.2.1
--- SAX2DOM.java 14 Aug 2002 19:21:46 -0000 1.14.2.1
+++ SAX2DOM.java 2 Dec 2002 15:51:28 -0000 1.14.2.1.2.1
@@ -86,24 +86,31 @@
public class SAX2DOM implements ContentHandler, LexicalHandler, Constants {
- private Document _root = null;
+ private Node _root = null;
+ private Document _document = null;
private Stack _nodeStk = new Stack();
private Vector _namespaceDecls = null;
public SAX2DOM() throws ParserConfigurationException {
final DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
- _root = factory.newDocumentBuilder().newDocument();
+ _document = factory.newDocumentBuilder().newDocument();
+ _root = _document;
}
public SAX2DOM(Node root) throws ParserConfigurationException {
- if (root != null) {
- _root = (Document) root; // TODO: add support for frags and elems
+ _root = root;
+ if (root instanceof Document) {
+ _document = (Document)root;
+ }
+ else if (root != null) {
+ _document = root.getOwnerDocument();
}
else {
- final DocumentBuilderFactory factory =
+ final DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
- _root = factory.newDocumentBuilder().newDocument();
+ _document = factory.newDocumentBuilder().newDocument();
+ _root = _document;
}
}
@@ -115,9 +122,9 @@
final Node last = (Node)_nodeStk.peek();
// No text nodes can be children of root (DOM006 exception)
- if (last != _root) {
+ if (last != _document) {
final String text = new String(ch, start, length);
- last.appendChild(_root.createTextNode(text));
+ last.appendChild(_document.createTextNode(text));
}
}
@@ -126,12 +133,13 @@
}
public void endDocument() {
+ _nodeStk.pop();
}
public void startElement(String namespace, String localName, String
qName,
Attributes attrs)
{
- final Element tmp = (Element)_root.createElementNS(namespace, qName);
+ final Element tmp = (Element)_document.createElementNS(namespace,
qName);
// Add namespace declarations first
if (_namespaceDecls != null) {
@@ -199,7 +207,7 @@
*/
public void processingInstruction(String target, String data) {
final Node last = (Node)_nodeStk.peek();
- ProcessingInstruction pi = _root.createProcessingInstruction(
+ ProcessingInstruction pi = _document.createProcessingInstruction(
target, data);
if (pi != null) last.appendChild(pi);
}
@@ -224,7 +232,7 @@
*/
public void comment(char[] ch, int start, int length) {
final Node last = (Node)_nodeStk.peek();
- Comment comment = _root.createComment(new String(ch,start,length));
+ Comment comment = _document.createComment(new String(ch,start,length));
if (comment != null) last.appendChild(comment);
}
1.14.2.1.2.1 +85 -13
xml-xalan/java/src/org/apache/xalan/xsltc/trax/TemplatesHandlerImpl.java
Index: TemplatesHandlerImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/trax/TemplatesHandlerImpl.java,v
retrieving revision 1.14.2.1
retrieving revision 1.14.2.1.2.1
diff -u -r1.14.2.1 -r1.14.2.1.2.1
--- TemplatesHandlerImpl.java 14 Aug 2002 19:21:46 -0000 1.14.2.1
+++ TemplatesHandlerImpl.java 2 Dec 2002 15:51:28 -0000 1.14.2.1.2.1
@@ -57,6 +57,7 @@
* <http://www.apache.org/>.
*
* @author Morten Jorgensen
+ * @author Santiago Pericas-Geertsen
*
*/
@@ -66,27 +67,48 @@
import javax.xml.transform.sax.*;
import org.xml.sax.Locator;
+import org.xml.sax.InputSource;
+
+import org.apache.xalan.xsltc.compiler.*;
import org.apache.xalan.xsltc.Translet;
import org.apache.xalan.xsltc.runtime.AbstractTranslet;
-import org.apache.xalan.xsltc.compiler.*;
-import org.apache.xalan.xsltc.compiler.util.Util;
/**
* Implementation of a JAXP1.1 TemplatesHandler
*/
-public class TemplatesHandlerImpl extends Parser implements TemplatesHandler
{
-
+public class TemplatesHandlerImpl extends Parser
+ implements TemplatesHandler, SourceLoader
+{
+ /**
+ * System ID for this stylesheet.
+ */
private String _systemId;
- // Temporary
- private boolean _oldOutputSystem;
+ /**
+ * Number of spaces to add for output indentation.
+ */
+ private int _indentNumber;
+
+ /**
+ * This URIResolver is passed to all Transformers.
+ */
+ private URIResolver _uriResolver = null;
+
+ /**
+ * A reference to the transformer factory that this templates
+ * object belongs to.
+ */
+ private TransformerFactoryImpl _tfactory = null;
/**
* Default constructor
*/
- protected TemplatesHandlerImpl(boolean oldOutputSystem) {
+ protected TemplatesHandlerImpl(int indentNumber,
+ TransformerFactoryImpl tfactory)
+ {
super(null);
- _oldOutputSystem = oldOutputSystem;
+ _indentNumber = indentNumber;
+ _tfactory = tfactory;
}
/**
@@ -123,6 +145,13 @@
}
/**
+ * Store URIResolver needed for Transformers.
+ */
+ public void setURIResolver(URIResolver resolver) {
+ _uriResolver = resolver;
+ }
+
+ /**
* Implements javax.xml.transform.sax.TemplatesHandler.getTemplates()
* When a TemplatesHandler object is used as a ContentHandler or
* DocumentHandler for the parsing of transformation instructions, it
@@ -135,11 +164,19 @@
try {
final XSLTC xsltc = getXSLTC();
+ // Set a document loader (for xsl:include/import) if defined
+ if (_uriResolver != null) {
+ xsltc.setSourceLoader(this);
+ }
+
// Set the translet class name if not already set
- String transletName = TransformerFactoryImpl._defaultTransletName;
+ String transletName = null;
if (_systemId != null) {
transletName = Util.baseName(_systemId);
}
+ else {
+ transletName = (String)_tfactory.getAttribute("translet-name");
+ }
xsltc.setClassName(transletName);
// Get java-legal class name from XSLTC module
@@ -155,6 +192,10 @@
stylesheet.setSystemId(_systemId);
stylesheet.setParentStylesheet(null);
setCurrentStylesheet(stylesheet);
+
+ // Set it as top-level in the XSLTC object
+ xsltc.setStylesheet(stylesheet);
+
// Create AST under the Stylesheet element
createAST(stylesheet);
}
@@ -169,8 +210,15 @@
// Check that the transformation went well before returning
final byte[][] bytecodes = xsltc.getBytecodes();
if (bytecodes != null) {
- return new TemplatesImpl(xsltc.getBytecodes(),
transletName,
- getOutputProperties(), _oldOutputSystem);
+ final TemplatesImpl templates =
+ new TemplatesImpl(xsltc.getBytecodes(), transletName,
+ getOutputProperties(), _indentNumber, _tfactory);
+
+ // Set URIResolver on templates object
+ if (_uriResolver != null) {
+ templates.setURIResolver(_uriResolver);
+ }
+ return templates;
}
}
}
@@ -181,12 +229,36 @@
}
/**
- * recieve an object for locating the origin of SAX document events.
+ * 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) {
+ super.setDocumentLocator(locator);
setSystemId(locator.getSystemId());
+ }
+
+ /**
+ * This method implements XSLTC's SourceLoader interface. It is used to
+ * glue a TrAX URIResolver to the XSLTC compiler's Input and Import
classes.
+ *
+ * @param href The URI of the document to load
+ * @param context The URI of the currently loaded document
+ * @param xsltc The compiler that resuests the document
+ * @return An InputSource with the loaded document
+ */
+ public InputSource loadSource(String href, String context, XSLTC xsltc) {
+ try {
+ // A _uriResolver must be set if this method is called
+ final Source source = _uriResolver.resolve(href, context);
+ if (source != null) {
+ return Util.getInputSource(xsltc, source);
+ }
+ }
+ catch (TransformerException e) {
+ // Falls through
+ }
+ return null;
}
}
1.21.2.1.2.1 +136 -59
xml-xalan/java/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java
Index: TemplatesImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java,v
retrieving revision 1.21.2.1
retrieving revision 1.21.2.1.2.1
diff -u -r1.21.2.1 -r1.21.2.1.2.1
--- TemplatesImpl.java 14 Aug 2002 19:21:46 -0000 1.21.2.1
+++ TemplatesImpl.java 2 Dec 2002 15:51:28 -0000 1.21.2.1.2.1
@@ -68,6 +68,7 @@
import java.io.Serializable;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.io.ObjectInputStream;
import java.io.IOException;
import java.util.Properties;
import java.security.AccessController;
@@ -82,91 +83,161 @@
public final class TemplatesImpl implements Templates, Serializable {
- // Contains the name of the main translet class
- private String _name = null;
+ /**
+ * Name of the superclass of all translets. This is needed to
+ * determine which, among all classes comprising a translet,
+ * is the main one.
+ */
+ private static String ABSTRACT_TRANSLET
+ = "org.apache.xalan.xsltc.runtime.AbstractTranslet";
+
+ /**
+ * Name of the main class or default name if unknown.
+ */
+ private String _name = null;
- // Contains the actual class definition for the translet class and
- // any auxiliary classes (representing node sort records, predicates,
etc.)
+ /**
+ * Contains the actual class definition for the translet class and
+ * any auxiliary classes.
+ */
private byte[][] _bytecodes = null;
- // Contains the translet class definition(s). These are created when this
- // Templates is first instanciated or read back from disk (see
readObject())
- private Class[] _class = null;
+ /**
+ * Contains the translet class definition(s). These are created when
+ * this Templates is created or when it is read back from disk.
+ */
+ private Class[] _class = null;
- // This tells us which index the main translet class has in the _class
- // and _bytecodes arrays (above).
+ /**
+ * The index of the main translet class in the arrays _class[] and
+ * _bytecodes.
+ */
private int _transletIndex = -1;
+ /**
+ * Output properties of this translet.
+ */
private Properties _outputProperties;
- // Temporary
- private boolean _oldOutputSystem;
+ /**
+ * Number of spaces to add for output indentation.
+ */
+ private int _indentNumber;
+
+ /**
+ * This URIResolver is passed to all Transformers.
+ */
+ private URIResolver _uriResolver = null;
+
+ /**
+ * A reference to the transformer factory that this templates
+ * object belongs to.
+ */
+ private transient TransformerFactoryImpl _tfactory = null;
- // Our own private class loader - builds Class definitions from bytecodes
private class TransletClassLoader extends ClassLoader {
protected TransletClassLoader(ClassLoader parent){
super(parent);
}
-
public Class defineClass(byte[] b) {
return super.defineClass(null, b, 0, b.length);
}
}
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeObject(_name);
- out.writeObject(_bytecodes);
- out.flush();
- }
-
- public void readExternal(ObjectInput in)
- throws IOException, ClassNotFoundException {
- _name = (String)in.readObject();
- _bytecodes = (byte[][])in.readObject();
- _class = null; // must be created again...
- }
- /**
+ /**
* The only way to create an XSLTC emplate object
* The bytecodes for the translet and auxiliary classes, plus the name of
* the main translet class, must be supplied
*/
protected TemplatesImpl(byte[][] bytecodes, String transletName,
- Properties outputProperties, boolean oldOutputSystem)
+ Properties outputProperties, int indentNumber,
+ TransformerFactoryImpl tfactory)
{
_bytecodes = bytecodes;
_name = transletName;
_outputProperties = outputProperties;
- _oldOutputSystem = oldOutputSystem;
+ _indentNumber = indentNumber;
+ _tfactory = tfactory;
+ }
+
+ /**
+ * Need for de-serialization, see readObject().
+ */
+ public TemplatesImpl() { }
+
+ /**
+ * Overrides the default readObject implementation since we decided
+ * it would be cleaner not to serialize the entire tranformer
+ * factory. [ ref bugzilla 12317 ]
+ */
+ private void readObject(ObjectInputStream is)
+ throws IOException, ClassNotFoundException
+ {
+ is.defaultReadObject();
+ _tfactory = new TransformerFactoryImpl();
+ }
+
+ /**
+ * Store URIResolver needed for Transformers.
+ */
+ public synchronized void setURIResolver(URIResolver resolver) {
+ _uriResolver = resolver;
}
/**
* The TransformerFactory must pass us the translet bytecodes using this
* method before we can create any translet instances
*/
- protected void setTransletBytecodes(byte[][] bytecodes) {
+ protected synchronized void setTransletBytecodes(byte[][] bytecodes) {
_bytecodes = bytecodes;
}
/**
* Returns the translet bytecodes stored in this template
*/
- protected byte[][] getTransletBytecodes() {
- return(_bytecodes);
+ public synchronized byte[][] getTransletBytecodes() {
+ return _bytecodes;
+ }
+
+ /**
+ * Returns the translet bytecodes stored in this template
+ */
+ public synchronized Class[] getTransletClasses() {
+ try {
+ if (_class == null) defineTransletClasses();
+ }
+ catch (TransformerConfigurationException e) {
+ // Falls through
+ }
+ return _class;
+ }
+
+ /**
+ * Returns the index of the main class in array of bytecodes
+ */
+ public synchronized int getTransletIndex() {
+ try {
+ if (_class == null) defineTransletClasses();
+ }
+ catch (TransformerConfigurationException e) {
+ // Falls through
+ }
+ return _transletIndex;
}
/**
* The TransformerFactory should call this method to set the translet
name
*/
- protected void setTransletName(String name) {
+ protected synchronized void setTransletName(String name) {
_name = name;
}
/**
* Returns the name of the main translet class stored in this template
*/
- protected String getTransletName() {
+ protected synchronized String getTransletName() {
return _name;
}
@@ -203,22 +274,25 @@
for (int i = 0; i < classCount; i++) {
_class[i] = loader.defineClass(_bytecodes[i]);
- if (_class[i].getName().equals(_name))
+ final Class superClass = _class[i].getSuperclass();
+
+ // Check if this is the main class
+ if (superClass.getName().equals(ABSTRACT_TRANSLET)) {
_transletIndex = i;
+ }
}
if (_transletIndex < 0) {
- ErrorMsg err= new ErrorMsg(ErrorMsg.NO_MAIN_TRANSLET_ERR,_name);
+ ErrorMsg err= new ErrorMsg(ErrorMsg.NO_MAIN_TRANSLET_ERR,
_name);
throw new TransformerConfigurationException(err.toString());
}
}
-
catch (ClassFormatError e) {
- ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_CLASS_ERR+_name);
+ ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_CLASS_ERR, _name);
throw new TransformerConfigurationException(err.toString());
}
catch (LinkageError e) {
- ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR+_name);
+ ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR, _name);
throw new TransformerConfigurationException(err.toString());
}
}
@@ -235,25 +309,23 @@
if (_class == null) defineTransletClasses();
- // The translet needs a reference to all its auxiliary class
- // definitions so that it can instanciate them on the fly. You
- // wouldn't think this is necessary, but it seems like the JVM
- // quickly forgets the classes we define here and the translet
- // needs to know them as long as it exists.
- Translet translet = (Translet)_class[_transletIndex].newInstance();
+ // The translet needs to keep a reference to all its auxiliary
+ // class to prevent the GC from collecting them
+ Translet translet = (Translet) _class[_transletIndex].newInstance();
final int classCount = _bytecodes.length;
for (int i = 0; i < classCount; i++) {
- if (i != _transletIndex)
+ if (i != _transletIndex) {
translet.addAuxiliaryClass(_class[i]);
+ }
}
return translet;
}
catch (InstantiationException e) {
- ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR+_name);
+ ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR, _name);
throw new TransformerConfigurationException(err.toString());
}
catch (IllegalAccessException e) {
- ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR+_name);
+ ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR, _name);
throw new TransformerConfigurationException(err.toString());
}
}
@@ -263,22 +335,27 @@
*
* @throws TransformerConfigurationException
*/
- public Transformer newTransformer()
- throws TransformerConfigurationException {
- return new TransformerImpl(getTransletInstance(), _outputProperties,
- _oldOutputSystem);
+ public synchronized Transformer newTransformer()
+ throws TransformerConfigurationException
+ {
+ final TransformerImpl transformer =
+ new TransformerImpl(getTransletInstance(), _outputProperties,
+ _indentNumber, _tfactory);
+ if (_uriResolver != null) {
+ transformer.setURIResolver(_uriResolver);
+ }
+ return transformer;
}
/**
- * Implements JAXP's Templates.getOutputProperties()
+ * Implements JAXP's Templates.getOutputProperties(). We need to
+ * instanciate a translet to get the output settings, so
+ * we might as well just instanciate a Transformer and use its
+ * implementation of this method.
*/
- public Properties getOutputProperties() {
- // We need to instanciate a translet to get the output settings, so
- // we might as well just instanciate a Transformer and use its
- // implementation of this method
+ public synchronized Properties getOutputProperties() {
try {
- Transformer transformer = newTransformer();
- return transformer.getOutputProperties();
+ return newTransformer().getOutputProperties();
}
catch (TransformerConfigurationException e) {
return null;
1.1.12.1.2.1 +81 -3
xml-xalan/java/src/org/apache/xalan/xsltc/trax/TrAXFilter.java
Index: TrAXFilter.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/trax/TrAXFilter.java,v
retrieving revision 1.1.12.1
retrieving revision 1.1.12.1.2.1
diff -u -r1.1.12.1 -r1.1.12.1.2.1
--- TrAXFilter.java 14 Aug 2002 19:21:46 -0000 1.1.12.1
+++ TrAXFilter.java 2 Dec 2002 15:51:28 -0000 1.1.12.1.2.1
@@ -56,6 +56,7 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
+ * @author Santiago Pericas-Geertsen
* @author G. Todd Miller
*
*/
@@ -64,18 +65,95 @@
package org.apache.xalan.xsltc.trax;
import org.xml.sax.XMLFilter;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.InputSource;
import org.xml.sax.helpers.XMLFilterImpl;
+import org.xml.sax.helpers.XMLReaderFactory;
+import org.xml.sax.ContentHandler;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
-
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.FactoryConfigurationError;
+import java.io.IOException;
/**
* skeleton extension of XMLFilterImpl for now.
*/
public class TrAXFilter extends XMLFilterImpl {
+ private Templates _templates;
+ private TransformerHandlerImpl _transformer;
+
public TrAXFilter(Templates templates) throws
TransformerConfigurationException
{
- /* nothing yet */
+ _templates = templates;
+ _transformer = new TransformerHandlerImpl(
+ (TransformerImpl) templates.newTransformer());
}
+
+ private void createParent() throws SAXException {
+ XMLReader parent = null;
+ try {
+ SAXParserFactory pfactory = SAXParserFactory.newInstance();
+ pfactory.setNamespaceAware(true);
+ SAXParser saxparser = pfactory.newSAXParser();
+ parent = saxparser.getXMLReader();
+ }
+ catch (ParserConfigurationException e) {
+ throw new SAXException(e);
+ }
+ catch (FactoryConfigurationError e) {
+ throw new SAXException(e.toString());
+ }
+
+ if (parent == null) {
+ parent = XMLReaderFactory.createXMLReader();
+ }
+
+ // make this XMLReader the parent of this filter
+ setParent(parent);
+ }
+
+ public void parse (InputSource input) throws SAXException, IOException
+ {
+ if (getParent() == null) {
+ try {
+ createParent();
+ }
+ catch (SAXException e) {
+ throw new SAXException(e.toString());
+ }
+ }
+
+ // call parse on the parent
+ getParent().parse(input);
+ }
+
+ public void parse (String systemId) throws SAXException, IOException
+ {
+ parse(new InputSource(systemId));
+ }
+
+ public void setContentHandler (ContentHandler handler)
+ {
+ _transformer.setResult(new SAXResult(handler));
+ if (getParent() == null) {
+ try {
+ createParent();
+ }
+ catch (SAXException e) {
+ return;
+ }
+ }
+ getParent().setContentHandler(_transformer);
+ }
+
+ public void setErrorListener (ErrorListener handler) { }
}
1.45.2.1.2.1 +733 -227
xml-xalan/java/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java
Index: TransformerFactoryImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java,v
retrieving revision 1.45.2.1
retrieving revision 1.45.2.1.2.1
diff -u -r1.45.2.1 -r1.45.2.1.2.1
--- TransformerFactoryImpl.java 14 Aug 2002 19:21:46 -0000 1.45.2.1
+++ TransformerFactoryImpl.java 2 Dec 2002 15:51:28 -0000
1.45.2.1.2.1
@@ -58,28 +58,37 @@
*
* @author G. Todd Miller
* @author Morten Jorgensen
+ * @author Santiago Pericas-Geertsen
*
*/
package org.apache.xalan.xsltc.trax;
import java.io.File;
+import java.io.IOException;
+import java.io.FileNotFoundException;
import java.io.Reader;
import java.io.InputStream;
+import java.io.FileInputStream;
import java.io.ByteArrayInputStream;
+import java.io.FilenameFilter;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Vector;
import java.util.Hashtable;
+import java.util.Properties;
+import java.util.Enumeration;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipEntry;
import javax.xml.transform.*;
import javax.xml.transform.sax.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
+import javax.xml.parsers.SAXParserFactory;
+import org.xml.sax.*;
import org.w3c.dom.Document;
-import org.xml.sax.XMLFilter;
-import org.xml.sax.InputSource;
import org.apache.xalan.xsltc.Translet;
import org.apache.xalan.xsltc.runtime.AbstractTranslet;
@@ -87,48 +96,73 @@
import org.apache.xalan.xsltc.compiler.XSLTC;
import org.apache.xalan.xsltc.compiler.SourceLoader;
import org.apache.xalan.xsltc.compiler.CompilerException;
-import org.apache.xalan.xsltc.compiler.util.Util;
import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
/**
* Implementation of a JAXP1.1 TransformerFactory for Translets.
*/
public class TransformerFactoryImpl
- extends SAXTransformerFactory implements SourceLoader, ErrorListener {
-
- // This error listener is used only for this factory and is not passed to
- // the Templates or Transformer objects that we create!!!
+ extends SAXTransformerFactory implements SourceLoader, ErrorListener
+{
+ /**
+ * This error listener is used only for this factory and is not passed to
+ * the Templates or Transformer objects that we create.
+ */
private ErrorListener _errorListener = this;
- // This URIResolver is passed to all created Templates and Transformers
+ /**
+ * This URIResolver is passed to all created Templates and Transformers
+ */
private URIResolver _uriResolver = null;
- // As Gregor Samsa awoke one morning from uneasy dreams he found himself
- // transformed in his bed into a gigantic insect. He was lying on his
hard,
- // as it were armour plated, back, and if he lifted his head a little he
- // could see his big, brown belly divided into stiff, arched segments, on
- // top of which the bed quilt could hardly keep in position and was about
- // to slide off completely. His numerous legs, which were pitifully thin
- // compared to the rest of his bulk, waved helplessly before his eyes.
- // "What has happened to me?", he thought. It was no dream....
- protected static String _defaultTransletName = "GregorSamsa";
-
- // Cache for the newTransformer() method - see method for details
- private Transformer _copyTransformer = null;
- // XSL document for the default transformer
- private static final String COPY_TRANSLET_CODE =
- "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"+
- "<xsl:template match=\"/\">"+
- " <xsl:copy-of select=\".\"/>"+
- "</xsl:template>"+
- "</xsl:stylesheet>";
+ /**
+ * As Gregor Samsa awoke one morning from uneasy dreams he found himself
+ * transformed in his bed into a gigantic insect. He was lying on his
hard,
+ * as it were armour plated, back, and if he lifted his head a little he
+ * could see his big, brown belly divided into stiff, arched segments, on
+ * top of which the bed quilt could hardly keep in position and was about
+ * to slide off completely. His numerous legs, which were pitifully thin
+ * compared to the rest of his bulk, waved helplessly before his eyes.
+ * "What has happened to me?", he thought. It was no dream....
+ */
+ protected static String DEFAULT_TRANSLET_NAME = "GregorSamsa";
+
+ /**
+ * The class name of the translet
+ */
+ private String _transletName = DEFAULT_TRANSLET_NAME;
+
+ /**
+ * The destination directory for the translet
+ */
+ private String _destinationDirectory = null;
+
+ /**
+ * The package name prefix for all generated translet classes
+ */
+ private String _packageName = null;
+
+ /**
+ * The jar file name which the translet classes are packaged into
+ */
+ private String _jarFileName = null;
- // This Hashtable is used to store parameters for locating
- // <?xml-stylesheet ...?> processing instructions in XML documents.
+ /**
+ * This Hashtable is used to store parameters for locating
+ * <?xml-stylesheet ...?> processing instructions in XML docs.
+ */
private Hashtable _piParams = null;
- // The above hashtable stores objects of this class only:
- private class PIParamWrapper {
+
+ /**
+ * Use a thread local variable to store a copy of an XML Reader.
+ */
+ static ThreadLocal _xmlReader = new ThreadLocal();
+
+ /**
+ * The above hashtable stores objects of this class.
+ */
+ private static class PIParamWrapper {
public String _media = null;
public String _title = null;
public String _charset = null;
@@ -140,17 +174,44 @@
}
}
- // This flags are passed to the compiler
+ /**
+ * Set to <code>true</code> when debugging is enabled.
+ */
private boolean _debug = false;
- private boolean _disableInlining = false;
- private boolean _oldOutputSystem = false;
+
+ /**
+ * Set to <code>true</code> when templates are inlined.
+ */
+ private boolean _enableInlining = false;
+
+ /**
+ * Set to <code>true</code> when we want to generate
+ * translet classes from the stylesheet.
+ */
+ private boolean _generateTranslet = false;
+
+ /**
+ * If this is set to <code>true</code>, we attempt to use translet
classes for
+ * transformation if possible without compiling the stylesheet. The
translet class
+ * is only used if its timestamp is newer than the timestamp of the
stylesheet.
+ */
+ private boolean _autoTranslet = false;
+
+ /**
+ * Number of indent spaces when indentation is turned on.
+ */
+ private int _indentNumber = -1;
+
+ /**
+ * A reference to a SAXParserFactory.
+ */
+ private SAXParserFactory _parserFactory = null;
/**
* javax.xml.transform.sax.TransformerFactory implementation.
* Contains nothing yet
*/
public TransformerFactoryImpl() {
- // Don't need anything here so far...
}
/**
@@ -163,7 +224,8 @@
* @throws IllegalArgumentException
*/
public void setErrorListener(ErrorListener listener)
- throws IllegalArgumentException {
+ throws IllegalArgumentException
+ {
if (listener == null) {
ErrorMsg err = new ErrorMsg(ErrorMsg.ERROR_LISTENER_NULL_ERR,
"TransformerFactory");
@@ -191,9 +253,19 @@
* @throws IllegalArgumentException
*/
public Object getAttribute(String name)
- throws IllegalArgumentException {
+ throws IllegalArgumentException
+ {
// Return value for attribute 'translet-name'
- if (name.equals("translet-name")) return(_defaultTransletName);
+ if (name.equals("translet-name")) {
+ return _transletName;
+ }
+ else if (name.equals("generate-translet")) {
+ return new Boolean(_generateTranslet);
+ }
+ else if (name.equals("auto-translet")) {
+ return new Boolean(_autoTranslet);
+ }
+
// Throw an exception for all other attributes
ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_INVALID_ATTR_ERR, name);
throw new IllegalArgumentException(err.toString());
@@ -208,26 +280,86 @@
* @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) {
+ _transletName = (String) value;
+ return;
}
- else if (name.equals("debug")) {
- _debug = true;
+ else if (name.equals("destination-directory") && value instanceof
String) {
+ _destinationDirectory = (String) value;
+ return;
}
- else if (name.equals("disable-inlining") && value instanceof Boolean) {
- _disableInlining = ((Boolean) value).booleanValue();
+ else if (name.equals("package-name") && value instanceof String) {
+ _packageName = (String) value;
+ return;
}
- else if (name.equals("old-output") && value instanceof Boolean) {
- _oldOutputSystem = ((Boolean) value).booleanValue();
+ else if (name.equals("jar-name") && value instanceof String) {
+ _jarFileName = (String) value;
+ 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("generate-translet")) {
+ if (value instanceof Boolean) {
+ _generateTranslet = ((Boolean) value).booleanValue();
+ return;
+ }
+ else if (value instanceof String) {
+ _generateTranslet = ((String) value).equalsIgnoreCase("true");
+ return;
+ }
+ }
+ else if (name.equals("auto-translet")) {
+ if (value instanceof Boolean) {
+ _autoTranslet = ((Boolean) value).booleanValue();
+ return;
+ }
+ else if (value instanceof String) {
+ _autoTranslet = ((String) value).equalsIgnoreCase("true");
+ return;
+ }
+ }
+ else if (name.equals("debug")) {
+ if (value instanceof Boolean) {
+ _debug = ((Boolean) value).booleanValue();
+ return;
+ }
+ else if (value instanceof String) {
+ _debug = ((String) value).equalsIgnoreCase("true");
+ return;
+ }
}
+ else if (name.equals("enable-inlining")) {
+ if (value instanceof Boolean) {
+ _enableInlining = ((Boolean) value).booleanValue();
+ return;
+ }
+ else if (value instanceof String) {
+ _enableInlining = ((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());
}
/**
@@ -250,10 +382,12 @@
StreamResult.FEATURE
};
- // Inefficient, but it really does not matter in a function like this
- for (int i=0; i<features.length; i++)
- if (name.equals(features[i])) return true;
-
+ // Inefficient, but array is small
+ for (int i =0; i < features.length; i++) {
+ if (name.equals(features[i])) {
+ return true;
+ }
+ }
// Feature not supported
return false;
}
@@ -267,7 +401,7 @@
* Templates and Transformer objects created using this factory
*/
public URIResolver getURIResolver() {
- return(_uriResolver);
+ return _uriResolver;
}
/**
@@ -301,13 +435,16 @@
*/
public Source getAssociatedStylesheet(Source source, String media,
String title, String charset)
- throws TransformerConfigurationException {
+ throws TransformerConfigurationException
+ {
// First create a hashtable that maps Source refs. to parameters
- if (_piParams == null) _piParams = new Hashtable();
+ if (_piParams == null) {
+ _piParams = new Hashtable();
+ }
// Store the parameters for this Source in the Hashtable
_piParams.put(source, new PIParamWrapper(media, title, charset));
// Return the same Source - we'll locate the stylesheet later
- return(source);
+ return source;
}
/**
@@ -318,40 +455,14 @@
* @throws TransformerConfigurationException
*/
public Transformer newTransformer()
- throws TransformerConfigurationException {
-
- if (_copyTransformer != null) {
- if (_uriResolver != null)
- _copyTransformer.setURIResolver(_uriResolver);
- return _copyTransformer;
- }
-
- XSLTC xsltc = new XSLTC();
- if (_debug) xsltc.setDebug(true);
- if (_disableInlining) xsltc.setTemplateInlining(false);
- xsltc.init();
-
- // Compile the default copy-stylesheet
- byte[] bytes = COPY_TRANSLET_CODE.getBytes();
- ByteArrayInputStream bytestream = new ByteArrayInputStream(bytes);
- InputSource input = new InputSource(bytestream);
- input.setSystemId(_defaultTransletName);
- byte[][] bytecodes = xsltc.compile(_defaultTransletName, input);
-
- // Check that the transformation went well before returning
- if (bytecodes == null) {
- ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_COMPILE_ERR);
- throw new TransformerConfigurationException(err.toString());
- }
-
- // Create a Transformer object and store for other calls
- Templates templates = new TemplatesImpl(bytecodes, _defaultTransletName,
- xsltc.getOutputProperties(), _oldOutputSystem);
- _copyTransformer = templates.newTransformer();
+ throws TransformerConfigurationException
+ {
+ TransformerImpl result = new TransformerImpl(new Properties(),
+ _indentNumber, this);
if (_uriResolver != null) {
- _copyTransformer.setURIResolver(_uriResolver);
+ result.setURIResolver(_uriResolver);
}
- return _copyTransformer;
+ return result;
}
/**
@@ -365,10 +476,13 @@
* @throws TransformerConfigurationException
*/
public Transformer newTransformer(Source source) throws
- TransformerConfigurationException {
+ TransformerConfigurationException
+ {
final Templates templates = newTemplates(source);
final Transformer transformer = templates.newTransformer();
- if (_uriResolver != null) transformer.setURIResolver(_uriResolver);
+ if (_uriResolver != null) {
+ transformer.setURIResolver(_uriResolver);
+ }
return(transformer);
}
@@ -378,7 +492,7 @@
private void passWarningsToListener(Vector messages)
throws TransformerException
{
- if (_errorListener == null || messages == null ) {
+ if (_errorListener == null || messages == null) {
return;
}
// Pass messages to listener, one by one
@@ -395,13 +509,12 @@
*/
private void passErrorsToListener(Vector messages) {
try {
- // Nothing to do if there is no registered error listener
- if (_errorListener == null) return;
- // Nothing to do if there are not warning messages
- if (messages == null) return;
+ if (_errorListener == null || messages == null) {
+ return;
+ }
// Pass messages to listener, one by one
final int count = messages.size();
- for (int pos=0; pos<count; pos++) {
+ for (int pos = 0; pos < count; pos++) {
String message = messages.elementAt(pos).toString();
_errorListener.error(new TransformerException(message));
}
@@ -412,70 +525,6 @@
}
/**
- * Creates a SAX2 InputSource object from a TrAX Source object
- */
- private InputSource getInputSource(XSLTC xsltc, Source source)
- throws TransformerConfigurationException {
-
- InputSource input = null;
- String systemId = source.getSystemId();
- if (systemId == null) systemId = "";
-
- try {
-
- // Try to get InputSource from SAXSource input
- if (source instanceof SAXSource) {
- final SAXSource sax = (SAXSource)source;
- input = sax.getInputSource();
- // Pass the SAX parser to the compiler
- xsltc.setXMLReader(sax.getXMLReader());
- }
- // handle DOMSource
- else if (source instanceof DOMSource) {
- final DOMSource domsrc = (DOMSource)source;
- final Document dom = (Document)domsrc.getNode();
- final DOM2SAX dom2sax = new DOM2SAX(dom);
- 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) {
- final StreamSource stream = (StreamSource)source;
- final InputStream istream = stream.getInputStream();
- final Reader reader = stream.getReader();
- // Create InputSource from Reader or InputStream in Source
- if (istream != null)
- input = new InputSource(istream);
- else if (reader != null)
- input = new InputSource(reader);
- else
- input = new InputSource(systemId);
- }
- else {
- ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_SOURCE_ERR);
- throw new TransformerConfigurationException(err.toString());
- }
- input.setSystemId(systemId);
- }
- catch (NullPointerException e) {
- ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_SOURCE_ERR,
- "TransformerFactory.newTemplates()");
- throw new TransformerConfigurationException(err.toString());
- }
- catch (SecurityException e) {
- ErrorMsg err = new ErrorMsg(ErrorMsg.FILE_ACCESS_ERR, systemId);
- throw new TransformerConfigurationException(err.toString());
- }
- finally {
- return(input);
- }
- }
-
- /**
* javax.xml.transform.sax.TransformerFactory implementation.
* Process the Source into a Templates object, which is a a compiled
* representation of the source.
@@ -485,15 +534,47 @@
* @throws TransformerConfigurationException
*/
public Templates newTemplates(Source source)
- throws TransformerConfigurationException {
+ throws TransformerConfigurationException
+ {
+ // If _autoTranslet is true, we will try to load the bytecodes
+ // from the translet classes without compiling the stylesheet.
+ if (_autoTranslet) {
+ byte[][] bytecodes = null;
+ String transletClassName = getTransletClassName(source);
+
+ if (_jarFileName != null)
+ bytecodes = getBytecodesFromJar(source, transletClassName);
+ else
+ bytecodes = getBytecodesFromClasses(source, transletClassName);
+
+ if (bytecodes != null) {
+ if (_debug) {
+ if (_jarFileName != null)
+ System.err.println(new ErrorMsg(
+ ErrorMsg.TRANSFORM_WITH_JAR_STR, transletClassName,
_jarFileName));
+ else
+ System.err.println(new ErrorMsg(
+ ErrorMsg.TRANSFORM_WITH_TRANSLET_STR,
transletClassName));
+ }
+
+ // Reset the per-session attributes to their default values
+ // after each newTemplates() call.
+ resetTransientAttributes();
+
+ return new TemplatesImpl(bytecodes, transletClassName, null,
_indentNumber, this);
+ }
+ }
+
// Create and initialize a stylesheet compiler
final XSLTC xsltc = new XSLTC();
if (_debug) xsltc.setDebug(true);
- if (_disableInlining) xsltc.setTemplateInlining(false);
+ if (_enableInlining) xsltc.setTemplateInlining(true);
xsltc.init();
// Set a document loader (for xsl:include/import) if defined
- if (_uriResolver != null) xsltc.setSourceLoader(this);
+ if (_uriResolver != null) {
+ xsltc.setSourceLoader(this);
+ }
// Pass parameters to the Parser to make sure it locates the correct
// <?xml-stylesheet ...?> PI in an XML input document
@@ -501,15 +582,60 @@
// Get the parameters for this Source object
PIParamWrapper p = (PIParamWrapper)_piParams.get(source);
// Pass them on to the compiler (which will pass then to the parser)
- if (p != null)
+ if (p != null) {
xsltc.setPIParameters(p._media, p._title, p._charset);
+ }
+ }
+
+ // Set the attributes for translet generation
+ int outputType = XSLTC.BYTEARRAY_OUTPUT;
+ if (_generateTranslet || _autoTranslet) {
+ // Set the translet name
+ if (!_transletName.equals(DEFAULT_TRANSLET_NAME))
+ xsltc.setClassName(_transletName);
+
+ if (_destinationDirectory != null)
+ xsltc.setDestDirectory(_destinationDirectory);
+ else {
+ String xslName = getStylesheetFileName(source);
+ if (xslName != null) {
+ File xslFile = new File(xslName);
+ String xslDir = xslFile.getParent();
+
+ if (xslDir != null)
+ xsltc.setDestDirectory(xslDir);
+ }
+ }
+
+ if (_packageName != null)
+ xsltc.setPackageName(_packageName);
+
+ if (_jarFileName != null) {
+ xsltc.setJarFileName(_jarFileName);
+ outputType = XSLTC.BYTEARRAY_AND_JAR_OUTPUT;
+ }
+ else
+ outputType = XSLTC.BYTEARRAY_AND_FILE_OUTPUT;
}
// Compile the stylesheet
- final InputSource input = getInputSource(xsltc, source);
- byte[][] bytecodes = xsltc.compile(null, input);
+ final InputSource input = Util.getInputSource(xsltc, source);
+ byte[][] bytecodes = xsltc.compile(null, input, outputType);
final String transletName = xsltc.getClassName();
+ // Output to the jar file if the jar file name is set.
+ if ((_generateTranslet || _autoTranslet)
+ && bytecodes != null && _jarFileName != null) {
+ try {
+ xsltc.outputToJar();
+ }
+ catch (java.io.IOException e) { }
+ }
+
+ // Reset the per-session attributes to their default values
+ // after each newTemplates() call.
+ resetTransientAttributes();
+
// Pass compiler warnings to the error listener
if (_errorListener != this) {
try {
@@ -526,15 +652,18 @@
// Check that the transformation went well before returning
if (bytecodes == null) {
// Pass compiler errors to the error listener
- if (_errorListener != null)
+ if (_errorListener != null) {
passErrorsToListener(xsltc.getErrors());
- else
+ }
+ else {
xsltc.printErrors();
+ }
ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_COMPILE_ERR);
throw new TransformerConfigurationException(err.toString());
}
+
return new TemplatesImpl(bytecodes, transletName,
- xsltc.getOutputProperties(), _oldOutputSystem);
+ xsltc.getOutputProperties(), _indentNumber, this);
}
/**
@@ -546,10 +675,14 @@
* @throws TransformerConfigurationException
*/
public TemplatesHandler newTemplatesHandler()
- throws TransformerConfigurationException {
+ throws TransformerConfigurationException
+ {
final TemplatesHandlerImpl handler =
- new TemplatesHandlerImpl(_oldOutputSystem);
+ new TemplatesHandlerImpl(_indentNumber, this);
handler.init();
+ if (_uriResolver != null) {
+ handler.setURIResolver(_uriResolver);
+ }
return handler;
}
@@ -562,10 +695,13 @@
* @throws TransformerConfigurationException
*/
public TransformerHandler newTransformerHandler()
- throws TransformerConfigurationException {
+ throws TransformerConfigurationException
+ {
final Transformer transformer = newTransformer();
- final TransformerImpl internal = (TransformerImpl)transformer;
- return(new TransformerHandlerImpl(internal));
+ if (_uriResolver != null) {
+ transformer.setURIResolver(_uriResolver);
+ }
+ return new TransformerHandlerImpl((TransformerImpl) transformer);
}
/**
@@ -579,10 +715,13 @@
* @throws TransformerConfigurationException
*/
public TransformerHandler newTransformerHandler(Source src)
- throws TransformerConfigurationException {
+ throws TransformerConfigurationException
+ {
final Transformer transformer = newTransformer(src);
- final TransformerImpl internal = (TransformerImpl)transformer;
- return(new TransformerHandlerImpl(internal));
+ if (_uriResolver != null) {
+ transformer.setURIResolver(_uriResolver);
+ }
+ return new TransformerHandlerImpl((TransformerImpl) transformer);
}
/**
@@ -596,13 +735,13 @@
* @throws TransformerConfigurationException
*/
public TransformerHandler newTransformerHandler(Templates templates)
- throws TransformerConfigurationException {
+ throws TransformerConfigurationException
+ {
final Transformer transformer = templates.newTransformer();
final TransformerImpl internal = (TransformerImpl)transformer;
- return(new TransformerHandlerImpl(internal));
+ return new TransformerHandlerImpl(internal);
}
-
/**
* javax.xml.transform.sax.SAXTransformerFactory implementation.
* Create an XMLFilter that uses the given source as the
@@ -613,9 +752,10 @@
* @throws TransformerConfigurationException
*/
public XMLFilter newXMLFilter(Source src)
- throws TransformerConfigurationException {
+ throws TransformerConfigurationException
+ {
Templates templates = newTemplates(src);
- if (templates == null ) return null;
+ if (templates == null) return null;
return newXMLFilter(templates);
}
@@ -629,17 +769,18 @@
* @throws TransformerConfigurationException
*/
public XMLFilter newXMLFilter(Templates templates)
- throws TransformerConfigurationException {
+ throws TransformerConfigurationException
+ {
try {
return new
org.apache.xalan.xsltc.trax.TrAXFilter(templates);
}
- catch(TransformerConfigurationException e1) {
- if(_errorListener != null) {
+ catch (TransformerConfigurationException e1) {
+ if (_errorListener != null) {
try {
_errorListener.fatalError(e1);
return null;
}
- catch( TransformerException e2) {
+ catch (TransformerException e2) {
new TransformerConfigurationException(e2);
}
}
@@ -648,29 +789,6 @@
}
/**
- * This method implements XSLTC's SourceLoader interface. It is used to
- * glue a TrAX URIResolver to the XSLTC compiler's Input and Import
classes.
- *
- * @param href The URI of the document to load
- * @param context The URI of the currently loaded document
- * @param xsltc The compiler that resuests the document
- * @return An InputSource with the loaded document
- */
- public InputSource loadSource(String href, String context, XSLTC xsltc) {
- try {
- final Source source = _uriResolver.resolve(href, context);
- final InputSource input = getInputSource(xsltc, source);
- return(input);
- }
- catch (TransformerConfigurationException e) {
- return null;
- }
- catch (TransformerException e) {
- return null;
- }
- }
-
- /**
* Receive notification of a recoverable error.
* The transformer must continue to provide normal parsing events after
* invoking this method. It should still be possible for the application
@@ -682,12 +800,18 @@
* the transformation (always does in our case).
*/
public void error(TransformerException e)
- throws TransformerException {
- System.err.println("ERROR: "+e.getMessageAndLocation());
+ throws TransformerException
+ {
Throwable wrapped = e.getException();
- if (wrapped != null)
- System.err.println(" : "+wrapped.getMessage());
- throw(e);
+ if (wrapped != null) {
+ System.err.println(new ErrorMsg(ErrorMsg.ERROR_PLUS_WRAPPED_MSG,
+ e.getMessageAndLocation(),
+ wrapped.getMessage()));
+ } else {
+ System.err.println(new ErrorMsg(ErrorMsg.ERROR_MSG,
+ e.getMessageAndLocation()));
+ }
+ throw e;
}
/**
@@ -704,12 +828,18 @@
* the transformation (always does in our case).
*/
public void fatalError(TransformerException e)
- throws TransformerException {
- System.err.println("FATAL: "+e.getMessageAndLocation());
+ throws TransformerException
+ {
Throwable wrapped = e.getException();
- if (wrapped != null)
- System.err.println(" : "+wrapped.getMessage());
- throw(e);
+ if (wrapped != null) {
+ System.err.println(new
ErrorMsg(ErrorMsg.FATAL_ERR_PLUS_WRAPPED_MSG,
+ e.getMessageAndLocation(),
+ wrapped.getMessage()));
+ } else {
+ System.err.println(new ErrorMsg(ErrorMsg.FATAL_ERR_MSG,
+ e.getMessageAndLocation()));
+ }
+ throw e;
}
/**
@@ -726,11 +856,387 @@
* the transformation (never does in our case).
*/
public void warning(TransformerException e)
- throws TransformerException {
- System.err.println("WARNING: "+e.getMessageAndLocation());
+ throws TransformerException
+ {
Throwable wrapped = e.getException();
- if (wrapped != null)
- System.err.println(" : "+wrapped.getMessage());
+ if (wrapped != null) {
+ System.err.println(new
ErrorMsg(ErrorMsg.WARNING_PLUS_WRAPPED_MSG,
+ e.getMessageAndLocation(),
+ wrapped.getMessage()));
+ } else {
+ System.err.println(new ErrorMsg(ErrorMsg.WARNING_MSG,
+ e.getMessageAndLocation()));
+ }
}
+ /**
+ * This method implements XSLTC's SourceLoader interface. It is used to
+ * glue a TrAX URIResolver to the XSLTC compiler's Input and Import
classes.
+ *
+ * @param href The URI of the document to load
+ * @param context The URI of the currently loaded document
+ * @param xsltc The compiler that resuests the document
+ * @return An InputSource with the loaded document
+ */
+ public InputSource loadSource(String href, String context, XSLTC xsltc) {
+ try {
+ if (_uriResolver != null) {
+ final Source source = _uriResolver.resolve(href, context);
+ if (source != null) {
+ return Util.getInputSource(xsltc, source);
+ }
+ }
+ }
+ catch (TransformerException e) {
+ // Falls through
+ }
+ return null;
+ }
+
+ /**
+ * This method is synchronized to allow instances of this class to
+ * be shared among threads. A tranformer object will call this
+ * method to get an XMLReader. A different instance of an XMLReader
+ * is returned/cached for each thread.
+ */
+ public synchronized XMLReader getXMLReader() throws Exception {
+ // First check if factory is instantiated
+ if (_parserFactory == null) {
+ _parserFactory = SAXParserFactory.newInstance();
+ _parserFactory.setNamespaceAware(true);
+ }
+ XMLReader result = (XMLReader) _xmlReader.get();
+ if (result == null) {
+ _xmlReader.set(
+ result = _parserFactory.newSAXParser().getXMLReader());
+ }
+ return result;
+ }
+
+ /**
+ * Reset the per-session attributes to their default values
+ */
+ private void resetTransientAttributes() {
+ _transletName = DEFAULT_TRANSLET_NAME;
+ _destinationDirectory = null;
+ _packageName = null;
+ _jarFileName = null;
+ }
+
+ /**
+ * Load the translet classes from local .class files and return
+ * the bytecode array.
+ *
+ * @param source The xsl source
+ * @param fullClassName The full name of the translet
+ * @return The bytecode array
+ */
+ private byte[][] getBytecodesFromClasses(Source source, String
fullClassName)
+ {
+ if (fullClassName == null)
+ return null;
+
+ String xslFileName = getStylesheetFileName(source);
+ File xslFile = null;
+ if (xslFileName != null)
+ xslFile = new File(xslFileName);
+
+ // Find the base name of the translet
+ final String transletName;
+ int lastDotIndex = fullClassName.lastIndexOf('.');
+ if (lastDotIndex > 0)
+ transletName = fullClassName.substring(lastDotIndex+1);
+ else
+ transletName = fullClassName;
+
+ // Construct the path name for the translet class file
+ String transletPath = fullClassName.replace('.', '/');
+ if (_destinationDirectory != null) {
+ transletPath = _destinationDirectory + "/" + transletPath +
".class";
+ }
+ else {
+ if (xslFile != null && xslFile.getParent() != null)
+ transletPath = xslFile.getParent() + "/" + transletPath +
".class";
+ else
+ transletPath = transletPath + ".class";
+ }
+
+ // Return null if the translet class file does not exist.
+ File transletFile = new File(transletPath);
+ if (!transletFile.exists())
+ return null;
+
+ // Compare the timestamps of the translet and the xsl file.
+ // If the translet is older than the xsl file, return null
+ // so that the xsl file is used for the transformation and
+ // the translet is regenerated.
+ if (xslFile != null && xslFile.exists()) {
+ long xslTimestamp = xslFile.lastModified();
+ long transletTimestamp = transletFile.lastModified();
+ if (transletTimestamp < xslTimestamp)
+ return null;
+ }
+
+ // Load the translet into a bytecode array.
+ Vector bytecodes = new Vector();
+ int fileLength = (int)transletFile.length();
+ if (fileLength > 0) {
+ FileInputStream input = null;
+ try {
+ input = new FileInputStream(transletFile);
+ }
+ catch (FileNotFoundException e) {
+ return null;
+ }
+
+ byte[] bytes = new byte[fileLength];
+ try {
+ readFromInputStream(bytes, input, fileLength);
+ input.close();
+ }
+ catch (IOException e) {
+ return null;
+ }
+
+ bytecodes.addElement(bytes);
+ }
+ else
+ return null;
+
+ // Find the parent directory of the translet.
+ String transletParentDir = transletFile.getParent();
+ if (transletParentDir == null)
+ transletParentDir = System.getProperty("user.dir");
+
+ File transletParentFile = new File(transletParentDir);
+
+ // Find all the auxiliary files which have a name pattern of
"transletClass$nnn.class".
+ final String transletAuxPrefix = transletName + "$";
+ File[] auxfiles = transletParentFile.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name)
+ {
+ return (name.endsWith(".class") &&
name.startsWith(transletAuxPrefix));
+ }
+ });
+
+ // Load the auxiliary class files and add them to the bytecode array.
+ for (int i = 0; i < auxfiles.length; i++)
+ {
+ File auxfile = auxfiles[i];
+ int auxlength = (int)auxfile.length();
+ if (auxlength > 0) {
+ FileInputStream auxinput = null;
+ try {
+ auxinput = new FileInputStream(auxfile);
+ }
+ catch (FileNotFoundException e) {
+ continue;
+ }
+
+ byte[] bytes = new byte[auxlength];
+
+ try {
+ readFromInputStream(bytes, auxinput, auxlength);
+ auxinput.close();
+ }
+ catch (IOException e) {
+ continue;
+ }
+
+ bytecodes.addElement(bytes);
+ }
+ }
+
+ // Convert the Vector of byte[] to byte[][].
+ final int count = bytecodes.size();
+ if ( count > 0) {
+ final byte[][] result = new byte[count][1];
+ for (int i = 0; i < count; i++) {
+ result[i] = (byte[])bytecodes.elementAt(i);
+ }
+
+ return result;
+ }
+ else
+ return null;
+ }
+
+ /**
+ * Load the translet classes from the jar file and return the bytecode.
+ *
+ * @param source The xsl source
+ * @param fullClassName The full name of the translet
+ * @return The bytecode array
+ */
+ private byte[][] getBytecodesFromJar(Source source, String fullClassName)
+ {
+ String xslFileName = getStylesheetFileName(source);
+ File xslFile = null;
+ if (xslFileName != null)
+ xslFile = new File(xslFileName);
+
+ // Construct the path for the jar file
+ String jarPath = null;
+ if (_destinationDirectory != null)
+ jarPath = _destinationDirectory + "/" + _jarFileName;
+ else {
+ if (xslFile != null && xslFile.getParent() != null)
+ jarPath = xslFile.getParent() + "/" + _jarFileName;
+ else
+ jarPath = _jarFileName;
+ }
+
+ // Return null if the jar file does not exist.
+ File file = new File(jarPath);
+ if (!file.exists())
+ return null;
+
+ // Compare the timestamps of the jar file and the xsl file.
Return null
+ // if the xsl file is newer than the jar file.
+ if (xslFile != null && xslFile.exists()) {
+ long xslTimestamp = xslFile.lastModified();
+ long transletTimestamp = file.lastModified();
+ if (transletTimestamp < xslTimestamp)
+ return null;
+ }
+
+ // Create a ZipFile object for the jar file
+ ZipFile jarFile = null;
+ try {
+ jarFile = new ZipFile(file);
+ }
+ catch (IOException e) {
+ return null;
+ }
+
+ String transletPath = fullClassName.replace('.', '/');
+ String transletAuxPrefix = transletPath + "$";
+ String transletFullName = transletPath + ".class";
+
+ Vector bytecodes = new Vector();
+
+ // Iterate through all entries in the jar file to find the
+ // translet and auxiliary classes.
+ Enumeration entries = jarFile.entries();
+ while (entries.hasMoreElements())
+ {
+ ZipEntry entry = (ZipEntry)entries.nextElement();
+ String entryName = entry.getName();
+ if (entry.getSize() > 0 &&
+ (entryName.equals(transletFullName) ||
+ (entryName.endsWith(".class") &&
+ entryName.startsWith(transletAuxPrefix))))
+ {
+ try {
+ InputStream input = jarFile.getInputStream(entry);
+ int size = (int)entry.getSize();
+ byte[] bytes = new byte[size];
+ readFromInputStream(bytes, input, size);
+ input.close();
+ bytecodes.addElement(bytes);
+ }
+ catch (IOException e) {
+ return null;
+ }
+ }
+ }
+
+ // Convert the Vector of byte[] to byte[][].
+ final int count = bytecodes.size();
+ if (count > 0) {
+ final byte[][] result = new byte[count][1];
+ for (int i = 0; i < count; i++) {
+ result[i] = (byte[])bytecodes.elementAt(i);
+ }
+
+ return result;
+ }
+ else
+ return null;
+ }
+
+ /**
+ * Read a given number of bytes from the InputStream into a byte array.
+ *
+ * @param bytes The byte array to store the input content.
+ * @param input The input stream.
+ * @param size The number of bytes to read.
+ */
+ private void readFromInputStream(byte[] bytes, InputStream input, int
size)
+ throws IOException
+ {
+ int n = 0;
+ int offset = 0;
+ int length = size;
+ while (length > 0 && (n = input.read(bytes, offset, length)) > 0) {
+ offset = offset + n;
+ length = length - n;
+ }
+ }
+
+ /**
+ * Return the fully qualified class name of the translet
+ *
+ * @param source The Source
+ * @return The full name of the translet class
+ */
+ private String getTransletClassName(Source source)
+ {
+ String transletBaseName = null;
+ if (!_transletName.equals(DEFAULT_TRANSLET_NAME))
+ transletBaseName = _transletName;
+ else {
+ String systemId = source.getSystemId();
+ if (systemId != null) {
+ String baseName = Util.baseName(systemId);
+ //if (baseName != null)
+ // transletBaseName = Util.noExtName(baseName);
+ if (baseName != null) {
+ baseName = Util.noExtName(baseName);
+ transletBaseName = Util.toJavaName(baseName);
+ }
+ }
+ }
+
+ if (transletBaseName == null)
+ transletBaseName = DEFAULT_TRANSLET_NAME;
+
+ if (_packageName != null)
+ return _packageName + "." + transletBaseName;
+ else
+ return transletBaseName;
+ }
+
+ /**
+ * Return the local file name from the systemId of the Source object
+ *
+ * @param source The Source
+ * @return The file name in the local filesystem, or null if the
+ * systemId does not represent a local file.
+ */
+ private String getStylesheetFileName(Source source)
+ {
+ String systemId = source.getSystemId();
+ if (systemId != null) {
+ File file = new File(systemId);
+ if (file.exists())
+ return systemId;
+ else {
+ URL url = null;
+ try {
+ url = new URL(systemId);
+ }
+ catch (MalformedURLException e) {
+ return null;
+ }
+
+ if ("file".equals(url.getProtocol()))
+ return url.getFile();
+ else
+ return null;
+ }
+ }
+ else
+ return null;
+ }
}
1.11.2.1.2.1 +92 -39
xml-xalan/java/src/org/apache/xalan/xsltc/trax/TransformerHandlerImpl.java
Index: TransformerHandlerImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/trax/TransformerHandlerImpl.java,v
retrieving revision 1.11.2.1
retrieving revision 1.11.2.1.2.1
diff -u -r1.11.2.1 -r1.11.2.1.2.1
--- TransformerHandlerImpl.java 14 Aug 2002 19:21:46 -0000 1.11.2.1
+++ TransformerHandlerImpl.java 2 Dec 2002 15:51:28 -0000
1.11.2.1.2.1
@@ -63,12 +63,15 @@
package org.apache.xalan.xsltc.trax;
import org.xml.sax.*;
+import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.ext.DeclHandler;
+import org.xml.sax.helpers.DefaultHandler;
import javax.xml.transform.*;
import javax.xml.transform.sax.*;
import org.apache.xalan.xsltc.Translet;
+import org.apache.xalan.xsltc.TransletOutputHandler;
import org.apache.xalan.xsltc.dom.DOMImpl;
import org.apache.xalan.xsltc.dom.DOMBuilder;
import org.apache.xalan.xsltc.dom.DTDMonitor;
@@ -84,28 +87,43 @@
private AbstractTranslet _translet = null;
private String _systemId;
private DOMImpl _dom = null;
- private DOMBuilder _handler = null;
+ private ContentHandler _handler = null;
+ private LexicalHandler _lexHandler = null;
private DTDMonitor _dtd = null;
private Result _result = null;
private boolean _done = false; // Set in endDocument()
/**
+ * A flag indicating whether this transformer handler implements the
+ * identity transform.
+ */
+ private boolean _isIdentity = false;
+
+ /**
* Cosntructor - pass in reference to a TransformerImpl object
*/
- protected TransformerHandlerImpl(TransformerImpl transformer) {
+ public TransformerHandlerImpl(TransformerImpl transformer) {
// Save the reference to the transformer
_transformer = transformer;
- // 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();
+ if (transformer.isIdentity()) {
+ // Set initial handler to the empty handler
+ _handler = new DefaultHandler();
+ _isIdentity = true;
+ }
+ else {
+ // 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();
+ _lexHandler = (LexicalHandler) _handler;
- // Create a new DTD monitor
- _dtd = new DTDMonitor();
+ // Create a new DTD monitor
+ _dtd = new DTDMonitor();
+ }
}
/**
@@ -148,8 +166,22 @@
public void setResult(Result result) throws IllegalArgumentException {
_result = result;
- // Run the transformation now, if not already done
- if (_done) {
+ if (_isIdentity) {
+ try {
+ // Connect this object with output system directly
+ TransletOutputHandler outputHandler =
+ _transformer.getOutputHandler(result);
+ _transformer.transferOutputProperties(outputHandler);
+
+ _handler = new SAX2TO(outputHandler);
+ _lexHandler = (LexicalHandler) _handler;
+ }
+ catch (TransformerException e) {
+ _result = null;
+ }
+ }
+ else if (_done) {
+ // Run the transformation now, if not already done
try {
_transformer.setDOM(_dom);
_transformer.transform(null, _result);
@@ -182,8 +214,10 @@
throw new SAXException(err.toString());
}
- // Set document URI
- _dom.setDocumentURI(_systemId);
+ if (!_isIdentity) {
+ // Set document URI
+ _dom.setDocumentURI(_systemId);
+ }
// Proxy call
_handler.startDocument();
@@ -197,22 +231,24 @@
// Signal to the DOMBuilder that the document is complete
_handler.endDocument();
- // 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) {
- throw new SAXException(e);
+ if (!_isIdentity) {
+ // 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) {
+ throw new SAXException(e);
+ }
}
- }
- // Signal that the internal DOM is build (see 'setResult()').
- _done = true;
+ // Signal that the internal DOM is build (see 'setResult()').
+ _done = true;
- // Set this DOM as the transformer's DOM
- _transformer.setDOM(_dom);
+ // Set this DOM as the transformer's DOM
+ _transformer.setDOM(_dom);
+ }
}
/**
@@ -221,7 +257,8 @@
*/
public void startElement(String uri, String localName,
String qname, Attributes attributes)
- throws SAXException {
+ throws SAXException
+ {
_handler.startElement(uri, localName, qname, attributes);
}
@@ -230,7 +267,8 @@
* Receive notification of the end of an element.
*/
public void endElement(String namespaceURI, String localName, String
qname)
- throws SAXException {
+ throws SAXException
+ {
_handler.endElement(namespaceURI, localName, qname);
}
@@ -239,7 +277,8 @@
* Receive notification of a processing instruction.
*/
public void processingInstruction(String target, String data)
- throws SAXException {
+ throws SAXException
+ {
_handler.processingInstruction(target, data);
}
@@ -247,14 +286,18 @@
* Implements org.xml.sax.ext.LexicalHandler.startCDATA()
*/
public void startCDATA() throws SAXException {
- _handler.startCDATA();
+ if (_lexHandler != null) {
+ _lexHandler.startCDATA();
+ }
}
/**
* Implements org.xml.sax.ext.LexicalHandler.endCDATA()
*/
public void endCDATA() throws SAXException {
- _handler.endCDATA();
+ if (_lexHandler != null) {
+ _lexHandler.endCDATA();
+ }
}
/**
@@ -264,7 +307,9 @@
public void comment(char[] ch, int start, int length)
throws SAXException
{
- _handler.comment(ch, start, length);
+ if (_lexHandler != null) {
+ _lexHandler.comment(ch, start, length);
+ }
}
/**
@@ -317,28 +362,36 @@
public void startDTD(String name, String publicId, String systemId)
throws SAXException
{
- _handler.startDTD(name, publicId, systemId);
+ if (_lexHandler != null) {
+ _lexHandler.startDTD(name, publicId, systemId);
+ }
}
/**
* Implements org.xml.sax.ext.LexicalHandler.endDTD()
*/
public void endDTD() throws SAXException {
- _handler.endDTD();
+ if (_lexHandler != null) {
+ _lexHandler.endDTD();
+ }
}
/**
* Implements org.xml.sax.ext.LexicalHandler.startEntity()
*/
public void startEntity(String name) throws SAXException {
- _handler.startEntity(name);
+ if (_lexHandler != null) {
+ _lexHandler.startEntity(name);
+ }
}
/**
* Implements org.xml.sax.ext.LexicalHandler.endEntity()
*/
public void endEntity(String name) throws SAXException {
- _handler.endEntity(name);
+ if (_lexHandler != null) {
+ _lexHandler.endEntity(name);
+ }
}
/**
1.55.2.1.2.1 +363 -288
xml-xalan/java/src/org/apache/xalan/xsltc/trax/TransformerImpl.java
Index: TransformerImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/trax/TransformerImpl.java,v
retrieving revision 1.55.2.1
retrieving revision 1.55.2.1.2.1
diff -u -r1.55.2.1 -r1.55.2.1.2.1
--- TransformerImpl.java 14 Aug 2002 19:21:46 -0000 1.55.2.1
+++ TransformerImpl.java 2 Dec 2002 15:51:28 -0000 1.55.2.1.2.1
@@ -58,21 +58,13 @@
*
* @author Morten Jorgensen
* @author G. Todd Miller
+ * @author Santiago Pericas-Geertsen
*
*/
package org.apache.xalan.xsltc.trax;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.Writer;
-import java.io.Reader;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.FileOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
+import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.net.MalformedURLException;
@@ -83,27 +75,26 @@
import java.util.Enumeration;
import java.util.StringTokenizer;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.InputSource;
+import org.xml.sax.*;
import org.xml.sax.ext.LexicalHandler;
import org.w3c.dom.Document;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.sax.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
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.*;
@@ -112,58 +103,122 @@
import java.util.Properties;
public final class TransformerImpl extends Transformer
- implements DOMCache, ErrorListener {
-
- private AbstractTranslet _translet = null;
- private String _method = null;
- private String _encoding = null;
- private ContentHandler _handler = null;
-
- private ErrorListener _errorListener = this;
- private URIResolver _uriResolver = null;
- private Properties _properties, _propertiesClone;
-
- // Used for default output property settings
+ implements DOMCache, ErrorListener
+{
private final static String EMPTY_STRING = "";
private final static String NO_STRING = "no";
private final static String YES_STRING = "yes";
private final static String XML_STRING = "xml";
- // 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";
+ /**
+ * A reference to the translet or null if the identity transform.
+ */
+ private AbstractTranslet _translet = null;
+
+ /**
+ * The output method of this transformation.
+ */
+ private String _method = null;
+
+ /**
+ * The output encoding of this transformation.
+ */
+ private String _encoding = null;
+
+ /**
+ * The systemId set in input source.
+ */
+ private String _sourceSystemId = null;
+
+ /**
+ * An error listener for runtime errors.
+ */
+ private ErrorListener _errorListener = this;
+
+ /**
+ * A reference to a URI resolver for calls to document().
+ */
+ private URIResolver _uriResolver = null;
+
+ /**
+ * Output properties of this transformer instance.
+ */
+ private Properties _properties, _propertiesClone;
+
+ /**
+ * A reference to an output handler factory.
+ */
private TransletOutputHandlerFactory _tohFactory = null;
- // Temporary
- private boolean _oldOutputSystem;
+ /**
+ * A reference to a internal DOM represenation of the input.
+ */
+ private DOMImpl _dom = null;
+
+ /**
+ * DTD monitor needed for id()/key().
+ */
+ private DTDMonitor _dtdMonitor = null;
+
+ /**
+ * Number of indent spaces to add when indentation is on.
+ */
+ private int _indentNumber;
+
+ /**
+ * A reference to the transformer factory that this templates
+ * object belongs to.
+ */
+ private TransformerFactoryImpl _tfactory = null;
+
+ /**
+ * A flag indicating whether this transformer implements the identity
+ * transform.
+ */
+ private boolean _isIdentity = false;
/**
- * Implements JAXP's Transformer constructor
- * Our Transformer objects always need a translet to do the actual work
+ * A hashtable to store parameters for the identity transform. These
+ * are not needed during the transformation, but we must keep track of
+ * them to be fully complaint with the JAXP API.
*/
+ private Hashtable _parameters = null;
+
+ protected TransformerImpl(Properties outputProperties, int indentNumber,
+ TransformerFactoryImpl tfactory)
+ {
+ this(null, outputProperties, indentNumber, tfactory);
+ _isIdentity = true;
+ // _properties.put(OutputKeys.METHOD, "xml");
+ }
+
protected TransformerImpl(Translet translet, Properties outputProperties,
- boolean oldOutputSystem)
+ int indentNumber, TransformerFactoryImpl tfactory)
{
_translet = (AbstractTranslet) translet;
_properties = createOutputProperties(outputProperties);
- _oldOutputSystem = oldOutputSystem;
_propertiesClone = (Properties) _properties.clone();
+ _indentNumber = indentNumber;
+ _tfactory = tfactory;
}
/**
- * Returns the translet wrapped inside this Transformer
+ * Returns the translet wrapped inside this Transformer or
+ * null if this is the identity transform.
*/
protected AbstractTranslet getTranslet() {
return _translet;
}
+ public boolean isIdentity() {
+ return _isIdentity;
+ }
+
/**
* Implements JAXP's Transformer.transform()
*
@@ -174,51 +229,34 @@
public void transform(Source source, Result result)
throws TransformerException
{
- if (_translet == null) {
- ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_TRANSLET_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);
+ if (!_isIdentity) {
+ if (_translet == null) {
+ ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_TRANSLET_ERR);
throw new TransformerException(err.toString());
}
+ // Pass output properties to the translet
+ transferOutputProperties(_translet);
+ }
+
+ 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());
- }
+ if (_uriResolver != null && !_isIdentity) {
+ _translet.setDOMCache(this);
}
- 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);
- }
+ // Pass output properties to handler if identity
+ if (_isIdentity) {
+ transferOutputProperties(toHandler);
+ }
- // Run the transformation
- transform(source, (ContentHandler)_handler, _encoding);
+ transform(source, toHandler, _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());
- }
+ if (result instanceof DOMResult) {
+ ((DOMResult)result).setNode(_tohFactory.getNode());
}
}
@@ -227,7 +265,7 @@
* the type and contents of the TrAX Result object passed to the
* transform() method.
*/
- private TransletOutputHandler getOutputHandler(Result result)
+ public TransletOutputHandler getOutputHandler(Result result)
throws TransformerException
{
// Get output method using get() to ignore defaults
@@ -242,6 +280,11 @@
_tohFactory.setOutputMethod(_method);
}
+ // Set indentation number in the factory
+ if (_indentNumber >= 0) {
+ _tohFactory.setIndentNumber(_indentNumber);
+ }
+
// Return the content handler for this Result object
try {
// Result object could be SAXResult, DOMResult, or StreamResult
@@ -332,102 +375,6 @@
}
/**
- * Create an output handler (SAX2 handler) for the transformation output
- * based on the type and contents of the TrAX Result object passed to
- * the transform() method.
- */
- private ContentHandler getOldOutputHandler(Result result) throws
- TransformerException
- {
- // Try to get the encoding from the translet (may not be set)
- if (_translet._encoding != null) {
- _encoding = _translet._encoding;
- }
- else {
- _encoding = "UTF-8"; // default output 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();
- // Simple as feck, just pass the SAX handler back...
- if (handler != null) return handler;
- }
- else if (result instanceof DOMResult) {
- return new SAX2DOM(((DOMResult) result).getNode());
- }
- 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.
-
- // try to get a Writer from Result object
- final Writer writer = target.getWriter();
- if (writer != null) {
- return (new DefaultSAXOutputHandler(writer, _encoding));
- }
-
- // or try to get an OutputStream from Result object
- final OutputStream ostream = target.getOutputStream();
- if (ostream != null) {
- return (new DefaultSAXOutputHandler(ostream, _encoding));
- }
-
- // 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.
- OutputStream os = null;
- URL url = null;
- if (systemId.startsWith("file:")) {
- url = new URL(systemId);
- os = new FileOutputStream(url.getFile());
- return (new DefaultSAXOutputHandler(os, _encoding));
- }
- else if (systemId.startsWith("http:")) {
- url = new URL(systemId);
- URLConnection connection = url.openConnection();
- os = connection.getOutputStream();
- return (new DefaultSAXOutputHandler(os, _encoding));
- }
- else {
- // system id is just a filename
- File tmp = new File(systemId);
- url = tmp.toURL();
- os = new FileOutputStream(url.getFile());
- return (new DefaultSAXOutputHandler(os, _encoding));
- }
- }
- }
- // 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);
- }
- return null;
- }
-
- /**
* Set the internal DOMImpl that will be used for the next transformation
*/
protected void setDOM(DOMImpl dom) {
@@ -451,28 +398,27 @@
DOMImpl dom = null;
DTDMonitor dtd = null;
- // Handle SAXSource input
+ // Get systemId from source
+ if (source != null) {
+ _sourceSystemId = source.getSystemId();
+ }
+
if (source instanceof SAXSource) {
// Get all info from the input SAXSource object
- final SAXSource sax = (SAXSource)source;
- XMLReader reader = sax.getXMLReader();
- final InputSource input = sax.getInputSource();
- final String systemId = sax.getSystemId();
+ final SAXSource sax = (SAXSource)source;
+ XMLReader reader = sax.getXMLReader();
+ final InputSource input = sax.getInputSource();
- // if reader was not set with setXMLReader by user,
- // then we must create one ourselves.
+ // Create a reader if not set by user
if (reader == null) {
- SAXParserFactory pfactory= SAXParserFactory.newInstance();
- pfactory.setNamespaceAware(true);
- reader = pfactory.newSAXParser().getXMLReader();
+ reader = _tfactory.getXMLReader();
}
// Create a DTD monitor to trap all DTD/declarative events
dtd = new DTDMonitor();
dtd.handleDTD(reader);
- // Create a new internal DOM and set up its builder to trap
- // all content/lexical events
+ // Create a new internal DOM and set up its builder
dom = new DOMImpl();
final DOMBuilder builder = dom.getBuilder();
try {
@@ -485,21 +431,12 @@
// Parse the input and build the internal DOM
reader.parse(input);
- dom.setDocumentURI(systemId);
+ dom.setDocumentURI(_sourceSystemId);
}
- // Handle DOMSource input
else if (source instanceof DOMSource) {
- final DOMSource domsrc = (DOMSource)source;
+ final DOMSource domsrc = (DOMSource) source;
final org.w3c.dom.Node node = domsrc.getNode();
-
- boolean isComplete = true;
- if (node.getNodeType() != org.w3c.dom.Node.DOCUMENT_NODE) {
- isComplete = false;
- }
-
- final DOM2SAX dom2sax = new DOM2SAX(node);
- final InputSource input = null;
- final String systemId = domsrc.getSystemId();
+ final DOM2SAX dom2sax = new DOM2SAX(node);
// Create a DTD monitor to trap all DTD/declarative events
dtd = new DTDMonitor();
@@ -512,34 +449,15 @@
dom2sax.setContentHandler(builder);
// Parse the input and build the internal DOM
- if (!isComplete) {
- builder.startDocument();
- }
- dom2sax.parse(input); // need this parameter?
- if (!isComplete) {
- builder.endDocument();
- }
- dom.setDocumentURI(systemId);
+ dom2sax.parse();
+ dom.setDocumentURI(_sourceSystemId);
}
- // Handle StreamSource input
else if (source instanceof StreamSource) {
// Get all info from the input StreamSource object
final StreamSource stream = (StreamSource)source;
- final InputStream streamInput = stream.getInputStream();
+ final InputStream streamInput = stream.getInputStream();
final Reader streamReader = stream.getReader();
- final String systemId = stream.getSystemId();
-
- // With a StreamSource we need to create our own parser
- final SAXParserFactory factory = SAXParserFactory.newInstance();
- try {
- factory.setFeature(NAMESPACE_FEATURE,true);
- }
- catch (Exception e) {
- factory.setNamespaceAware(true);
- }
-
- final SAXParser parser = factory.newSAXParser();
- final XMLReader reader = parser.getXMLReader();
+ final XMLReader reader = _tfactory.getXMLReader();
// Create a DTD monitor to trap all DTD/declarative events
dtd = new DTDMonitor();
@@ -558,12 +476,17 @@
reader.setContentHandler(builder);
InputSource input;
- if (streamInput != null)
+ if (streamInput != null) {
input = new InputSource(streamInput);
- else if (streamReader != null)
+ input.setSystemId(_sourceSystemId);
+ }
+ else if (streamReader != null) {
input = new InputSource(streamReader);
- else if (systemId != null)
- input = new InputSource(systemId);
+ input.setSystemId(_sourceSystemId);
+ }
+ else if (_sourceSystemId != null) {
+ input = new InputSource(_sourceSystemId);
+ }
else {
ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_SOURCE_ERR);
throw new TransformerException(err.toString());
@@ -571,9 +494,8 @@
// Parse the input and build the internal DOM
reader.parse(input);
- dom.setDocumentURI(systemId);
+ dom.setDocumentURI(_sourceSystemId);
}
- // Handle XSLTC-internal Source input
else if (source instanceof XSLTCSource) {
final XSLTCSource xsltcsrc = (XSLTCSource)source;
dtd = xsltcsrc.getDTD();
@@ -589,12 +511,17 @@
}
// Set size of key/id indices
- _translet.setIndexSize(dom.getSize());
- // If there are any elements with ID attributes, build an index
- dtd.buildIdIndex(dom, mask, _translet);
- // Pass unparsed entity URIs to the translet
- _translet.setDTDMonitor(dtd);
+ if (!_isIdentity) {
+ _translet.setIndexSize(dom.getSize());
+
+ // If there are any elements with ID attributes, build an index
+ dtd.buildIdIndex(dom, mask, _translet);
+
+ // Pass unparsed entity URIs to the translet
+ _translet.setDTDMonitor(dtd);
+ }
return dom;
+
}
catch (FileNotFoundException e) {
if (_errorListener != null) postErrorToListener(e.getMessage());
@@ -614,49 +541,99 @@
}
}
- /**
- * Internal transformation method - uses the internal APIs of XSLTC
- */
- private void transform(Source src, TransletOutputHandler handler,
- String encoding) throws TransformerException
+ private void transformIdentity(Source source, TransletOutputHandler
handler)
+ throws Exception
{
- try {
- _translet.transform(getDOM(src, 0), handler);
+ // Get systemId from source
+ if (source != null) {
+ _sourceSystemId = source.getSystemId();
+ }
+
+ if (source instanceof StreamSource) {
+ final StreamSource stream = (StreamSource) source;
+ final InputStream streamInput = stream.getInputStream();
+ final Reader streamReader = stream.getReader();
+ final XMLReader reader = _tfactory.getXMLReader();
+
+ // Hook up reader and output handler
+ try {
+ reader.setProperty(LEXICAL_HANDLER_PROPERTY, handler);
+ }
+ catch (SAXException e) {
+ // Falls through
+ }
+ reader.setContentHandler(new SAX2TO(handler));
+
+ // Create input source from source
+ InputSource input;
+ if (streamInput != null) {
+ input = new InputSource(streamInput);
+ input.setSystemId(_sourceSystemId);
+ }
+ else if (streamReader != null) {
+ input = new InputSource(streamReader);
+ input.setSystemId(_sourceSystemId);
+ }
+ else if (_sourceSystemId != null) {
+ input = new InputSource(_sourceSystemId);
+ }
+ else {
+ ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_SOURCE_ERR);
+ throw new TransformerException(err.toString());
+ }
+
+ // Start pushing SAX events
+ reader.parse(input);
}
- catch (TransletException e) {
- if (_errorListener != null) postErrorToListener(e.getMessage());
- throw new TransformerException(e);
+ else if (source instanceof SAXSource) {
+ final SAXSource sax = (SAXSource) source;
+ XMLReader reader = sax.getXMLReader();
+ final InputSource input = sax.getInputSource();
+
+ // Create a reader if not set by user
+ if (reader == null) {
+ reader = _tfactory.getXMLReader();
+ }
+
+ // Hook up reader and output handler
+ try {
+ reader.setProperty(LEXICAL_HANDLER_PROPERTY, handler);
+ }
+ catch (SAXException e) {
+ // Falls through
+ }
+ reader.setContentHandler(new SAX2TO(handler));
+
+ // Start pushing SAX events
+ reader.parse(input);
}
- catch (RuntimeException e) {
- if (_errorListener != null) postErrorToListener(e.getMessage());
- throw new TransformerException(e);
+ else if (source instanceof DOMSource) {
+ final DOMSource domsrc = (DOMSource) source;
+ new DOM2TO(domsrc.getNode(), handler).parse();
}
- catch (Exception e) {
- if (_errorListener != null) postErrorToListener(e.getMessage());
- throw new TransformerException(e);
+ else if (source instanceof XSLTCSource) {
+ final DOMImpl dom = ((XSLTCSource) source).getDOM();
+ dom.copy(handler);
+ }
+ else {
+ ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_SOURCE_ERR);
+ throw new TransformerException(err.toString());
}
}
/**
* Internal transformation method - uses the internal APIs of XSLTC
*/
- private void transform(Source src, ContentHandler sax, String encoding)
- throws TransformerException {
+ private void transform(Source source, TransletOutputHandler handler,
+ String encoding) throws TransformerException
+ {
try {
- // Build an iternal DOMImpl from the TrAX Source
- DOMImpl dom = getDOM(src, 0);
-
- // This handler will post-process the translet output
- TextOutput handler;
-
- // Check if the ContentHandler also implements LexicalHandler
- if (sax instanceof LexicalHandler) {
- handler = new TextOutput(sax, (LexicalHandler)sax, encoding);
+ if (_isIdentity) {
+ transformIdentity(source, handler);
}
else {
- handler = new TextOutput(sax, encoding);
+ _translet.transform(getDOM(source, 0), handler);
}
- _translet.transform(dom, handler);
}
catch (TransletException e) {
if (_errorListener != null) postErrorToListener(e.getMessage());
@@ -759,7 +736,7 @@
*
* @return Properties in effect for this Transformer
*/
- public Properties getOutputProperties() {
+ public Properties getOutputProperties() {
return (Properties) _properties.clone();
}
@@ -791,7 +768,7 @@
* @param properties The properties to use for the Transformer
* @throws IllegalArgumentException Never, errors are ignored
*/
- public void setOutputProperties(Properties properties)
+ public void setOutputProperties(Properties properties)
throws IllegalArgumentException
{
if (properties != null) {
@@ -841,18 +818,17 @@
* Internal method to pass any properties to the translet prior to
* initiating the transformation
*/
- private void setOutputProperties(AbstractTranslet translet,
- Properties properties)
+ private void transferOutputProperties(AbstractTranslet translet)
{
// Return right now if no properties are set
- if (properties == null) return;
+ if (_properties == null) return;
// Get a list of all the defined properties
- Enumeration names = properties.propertyNames();
+ Enumeration names = _properties.propertyNames();
while (names.hasMoreElements()) {
// Note the use of get() instead of getProperty()
String name = (String) names.nextElement();
- String value = (String) properties.get(name);
+ String value = (String) _properties.get(name);
// Ignore default properties
if (value == null) continue;
@@ -900,6 +876,71 @@
}
/**
+ * This method is used to pass any properties to the output handler
+ * when running the identity transform.
+ */
+ public void transferOutputProperties(TransletOutputHandler handler)
+ {
+ // Return right now if no properties are set
+ if (_properties == null) return;
+
+ String doctypePublic = null;
+ String doctypeSystem = null;
+
+ // Get a list of all the defined properties
+ Enumeration names = _properties.propertyNames();
+ while (names.hasMoreElements()) {
+ // 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.DOCTYPE_PUBLIC)) {
+ doctypePublic = value;
+ }
+ else if (name.equals(OutputKeys.DOCTYPE_SYSTEM)) {
+ doctypeSystem = value;
+ }
+ else if (name.equals(OutputKeys.MEDIA_TYPE)) {
+ handler.setMediaType(value);
+ }
+ else if (name.equals(OutputKeys.STANDALONE)) {
+ handler.setStandalone(value);
+ }
+ else if (name.equals(OutputKeys.VERSION)) {
+ handler.setVersion(value);
+ }
+ else if (name.equals(OutputKeys.OMIT_XML_DECLARATION)) {
+ handler.omitHeader(
+ value != null && value.toLowerCase().equals("yes"));
+ }
+ else if (name.equals(OutputKeys.INDENT)) {
+ handler.setIndent(
+ value != null && value.toLowerCase().equals("yes"));
+ }
+ else if (name.equals(OutputKeys.CDATA_SECTION_ELEMENTS)) {
+ if (value != null) {
+ Hashtable table = new Hashtable();
+ StringTokenizer e = new StringTokenizer(value);
+ while (e.hasMoreTokens()) {
+ final String token = e.nextToken();
+ table.put(token, token);
+ }
+ handler.setCdataElements(table);
+ }
+ }
+ }
+
+ // Call setDoctype() if needed
+ if (doctypePublic != null || doctypeSystem != null) {
+ handler.setDoctype(doctypeSystem, doctypePublic);
+ }
+ }
+
+ /**
* 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
@@ -976,7 +1017,15 @@
* @param value The value to assign to the parameter
*/
public void setParameter(String name, Object value) {
- _translet.addParameter(name, value, false);
+ if (_isIdentity) {
+ if (_parameters == null) {
+ _parameters = new Hashtable();
+ }
+ _parameters.put(name, value);
+ }
+ else {
+ _translet.addParameter(name, value, false);
+ }
}
/**
@@ -985,7 +1034,12 @@
* parameter stack.
*/
public void clearParameters() {
- _translet.clearParameters();
+ if (_isIdentity && _parameters != null) {
+ _parameters.clear();
+ }
+ else {
+ _translet.clearParameters();
+ }
}
/**
@@ -997,7 +1051,12 @@
* @return An object that contains the value assigned to the parameter
*/
public final Object getParameter(String name) {
- return(_translet.getParameter(name));
+ if (_isIdentity) {
+ return (_parameters != null) ? _parameters.get(name) : null;
+ }
+ else {
+ return _translet.getParameter(name);
+ }
}
/**
@@ -1036,7 +1095,7 @@
*/
public DOMImpl retrieveDocument(String uri, int mask, Translet translet)
{
try {
- return(getDOM(_uriResolver.resolve(uri, ""), mask));
+ return getDOM(_uriResolver.resolve(uri, _sourceSystemId), mask);
}
catch (TransformerException e) {
if (_errorListener != null)
@@ -1059,8 +1118,16 @@
public void error(TransformerException e)
throws TransformerException
{
- System.err.println("ERROR: " + e.getMessageAndLocation());
- throw(e);
+ Throwable wrapped = e.getException();
+ if (wrapped != null) {
+ System.err.println(new ErrorMsg(ErrorMsg.ERROR_PLUS_WRAPPED_MSG,
+ e.getMessageAndLocation(),
+ wrapped.getMessage()));
+ } else {
+ System.err.println(new ErrorMsg(ErrorMsg.ERROR_MSG,
+ e.getMessageAndLocation()));
+ }
+ throw e;
}
/**
@@ -1079,12 +1146,16 @@
public void fatalError(TransformerException e)
throws TransformerException
{
- System.err.println("FATAL: " + e.getMessageAndLocation());
- Throwable wrapped = e.getException();
- if (wrapped != null) {
- System.err.println(" : "+wrapped.getMessage());
- }
- throw(e);
+ Throwable wrapped = e.getException();
+ if (wrapped != null) {
+ System.err.println(new
ErrorMsg(ErrorMsg.FATAL_ERR_PLUS_WRAPPED_MSG,
+ e.getMessageAndLocation(),
+ wrapped.getMessage()));
+ } else {
+ System.err.println(new ErrorMsg(ErrorMsg.FATAL_ERR_MSG,
+ e.getMessageAndLocation()));
+ }
+ throw e;
}
/**
@@ -1103,11 +1174,15 @@
public void warning(TransformerException e)
throws TransformerException
{
- System.err.println("WARNING: " + e.getMessageAndLocation());
- Throwable wrapped = e.getException();
- if (wrapped != null) {
- System.err.println(" : "+wrapped.getMessage());
- }
+ Throwable wrapped = e.getException();
+ if (wrapped != null) {
+ System.err.println(new
ErrorMsg(ErrorMsg.WARNING_PLUS_WRAPPED_MSG,
+ e.getMessageAndLocation(),
+ wrapped.getMessage()));
+ } else {
+ System.err.println(new ErrorMsg(ErrorMsg.WARNING_MSG,
+ e.getMessageAndLocation()));
+ }
}
}
1.1.4.1 +12 -1 xml-xalan/java/src/org/apache/xalan/xsltc/trax/Util.java
Index: Util.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/trax/Util.java,v
retrieving revision 1.1
retrieving revision 1.1.4.1
diff -u -r1.1 -r1.1.4.1
--- Util.java 23 Jul 2002 17:40:41 -0000 1.1
+++ Util.java 2 Dec 2002 15:51:28 -0000 1.1.4.1
@@ -82,7 +82,18 @@
public static String baseName(String name) {
return org.apache.xalan.xsltc.compiler.util.Util.baseName(name);
}
+
+ public static String noExtName(String name) {
+ return org.apache.xalan.xsltc.compiler.util.Util.noExtName(name);
+ }
+ public static String toJavaName(String name) {
+ return org.apache.xalan.xsltc.compiler.util.Util.toJavaName(name);
+ }
+
+
+
+
/**
* Creates a SAX2 InputSource object from a TrAX Source object
*/
No revision
No revision
1.2.2.1.2.1 +104 -11
xml-xalan/java/src/org/apache/xalan/xsltc/util/IntegerArray.java
Index: IntegerArray.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/util/IntegerArray.java,v
retrieving revision 1.2.2.1
retrieving revision 1.2.2.1.2.1
diff -u -r1.2.2.1 -r1.2.2.1.2.1
--- IntegerArray.java 14 Aug 2002 19:21:46 -0000 1.2.2.1
+++ IntegerArray.java 2 Dec 2002 15:51:29 -0000 1.2.2.1.2.1
@@ -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,26 +107,116 @@
}
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 */
+ /**
+ * 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);
}
+ public void reverse() {
+ int left = 0;
+ int right = _free - 1;
+
+ while (left < right) {
+ int temp = _array[left];
+ _array[left++] = _array[right];
+ _array[right--] = temp;
+ }
+ }
+
+ /**
+ * Merge two sorted arrays and eliminate duplicates.
+ */
+ public void merge(IntegerArray other) {
+ final int newSize = _free + other._free;
+// System.out.println("IntegerArray.merge() begin newSize = " + newSize);
+ int[] newArray = new int[newSize];
+
+ // Merge the two arrays
+ int i = 0, j = 0, k;
+ for (k = 0; i < _free && j < other._free; k++) {
+ int x = _array[i];
+ int y = other._array[j];
+
+ if (x < y) {
+ newArray[k] = x;
+ i++;
+ }
+ else if (x > y) {
+ newArray[k] = y;
+ j++;
+ }
+ else {
+ newArray[k] = x;
+ i++; j++;
+ }
+ }
+
+ // Copy the rest if of different lengths
+ if (i >= _free) {
+ while (j < other._free) {
+ newArray[k++] = other._array[j++];
+ }
+ }
+ else {
+ while (i < _free) {
+ newArray[k++] = _array[i++];
+ }
+ }
+
+ // Update reference to this array
+ _array = newArray;
+ _free = _size = newSize;
+// System.out.println("IntegerArray.merge() end");
+ }
+
+ public void sort() {
+ quicksort(_array, 0, _free - 1);
+ }
+
+ private static void quicksort(int[] array, int p, int r) {
+ if (p < r) {
+ final int q = partition(array, p, r);
+ quicksort(array, p, q);
+ quicksort(array, q + 1, r);
+ }
+ }
+
+ private static int partition(int[] array, int p, int r) {
+ final int x = array[p];
+ int i = p - 1; int j = r + 1;
+
+ while (true) {
+ while (x < array[--j]);
+ while (x > array[++i]);
+ if (i < j) {
+ int temp = array[i];
+ array[i] = array[j];
+ array[j] = temp;
+ }
+ else {
+ return j;
+ }
+ }
+ }
+
private void growArray(int size) {
final int[] newArray = new int[_size = size];
System.arraycopy(_array, 0, newArray, 0, _free);
@@ -163,7 +255,8 @@
}
out.println(_array[_free - 1]);
}
- else
+ else {
out.println("IntegerArray: empty");
+ }
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]