net.sf.saxon.trace.ContextStackFrame Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of saxon-he Show documentation
Show all versions of saxon-he Show documentation
An OSGi bundle for Saxon-HE
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2013 Saxonica Limited.
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package net.sf.saxon.trace;
import net.sf.saxon.expr.Container;
import net.sf.saxon.expr.instruct.*;
import net.sf.saxon.lib.NamespaceConstant;
import net.sf.saxon.om.Item;
import net.sf.saxon.om.NodeInfo;
import net.sf.saxon.om.StructuredQName;
import net.sf.saxon.trans.KeyDefinition;
import net.sf.saxon.tree.util.Navigator;
import java.io.PrintStream;
/**
* An entry on the context stack. A new entry is created every time the context changes. This is a
* representation of the stack created on request; it does not hold live data.
*/
public abstract class ContextStackFrame {
private String moduleUri;
private int lineNumber;
private Container container;
private Item contextItem;
/**
* Set the system ID representing the location of the instruction that caused this new context
* to be created
* @param uri the system ID (base URI/module URI) of the module containing the instruction
*/
public void setSystemId(String uri) {
this.moduleUri = uri;
}
/**
* Get the system ID representing the location of the instruction that caused this new context
* to be created
* @return the system ID (base URI/module URI) of the module containing the instruction
*/
public String getSystemId() {
return moduleUri;
}
/**
* Set the line number of the location of the instruction that caused this new context
* to be created
* @param lineNumber the line number of the instruction within its containing module
*/
public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
}
/**
* Get the line number of the location of the instruction that caused this new context
* to be created
* @return the line number of the instruction within its containing module
*/
public int getLineNumber() {
return lineNumber;
}
/**
* Set the container of the instruction that caused this new context to be created. This will
* generally be an object such as an XSLT Template or a user-defined function
* @param container the container of the instruction
*/
public void setContainer(Container container) {
this.container = container;
}
/**
* Get the container of the instruction that caused this new context to be created. This will
* generally be an object such as an XSLT Template or a user-defined function
* @return the container of the instruction in the expression tree
*/
public Container getContainer() {
return container;
}
/**
* Set the value of the context item at this level of the context stack
* @param contextItem the context item as it was when this new context was created
*/
public void setContextItem(Item contextItem) {
this.contextItem = contextItem;
}
/**
* Get the value of the context item at this level of the context stack
* @return the context item as it was when this new context was created
*/
public Item getContextItem() {
return contextItem;
}
/**
* Display a representation of the stack frame on the specified output stream
* @param out the output stream
*/
public abstract void print(PrintStream out);
/**
* Show the location of a call (for use by subclasses)
* @return typically "(" + systemId() + "#" + lineNumber() + ")"
*/
protected String showLocation() {
if (getSystemId() == null) {
return "";
}
int line = getLineNumber();
if (line == -1 || line == 0xfffff) {
return "(" + getSystemId() + ")";
} else {
return "(" + getSystemId() + "#" + getLineNumber() + ")";
}
}
/**
* Subclass of ContextStackFrame representing the outermost stack frame,
* for the calling application
*/
public static class CallingApplication extends ContextStackFrame {
public void print(PrintStream out) {
//out.println(" (called from external application)");
}
}
/**
* Subclass of ContextStackFrame representing a built-in template rule in XSLT
*/
public static class BuiltInTemplateRule extends ContextStackFrame {
public void print(PrintStream out) {
out.println(" in built-in template rule");
}
}
/**
* Subclass of ContextStackFrame representing a call to a user-defined function
* either in XSLT or XQuery
*/
public static class FunctionCall extends ContextStackFrame {
StructuredQName functionName;
/**
* Get the name of the function being called
* @return the name of the function being called
*/
public StructuredQName getFunctionName() {
return functionName;
}
/**
* Set the name of the function being called
* @param functionName the name of the function being called
*/
public void setFunctionName(StructuredQName functionName) {
this.functionName = functionName;
}
/**
* Display a representation of the stack frame on the specified output stream
* @param out the output stream
*/
public void print(PrintStream out) {
out.println(" at " + (functionName==null ? "(anonymous)" : functionName.getDisplayName()) + "() " + showLocation());
}
}
/**
* Subclass of ContextStackFrame representing an xsl:apply-templates call in XSLT
*/
public static class ApplyTemplates extends ContextStackFrame {
/**
* Display a representation of the stack frame on the specified output stream
* @param out the output stream
*/
public void print(PrintStream out) {
out.println(" at xsl:apply-templates " + showLocation());
Item node = getContextItem();
if (node instanceof NodeInfo) {
out.println(" processing " + Navigator.getPath((NodeInfo)node));
}
}
}
/**
* Subclass of ContextStackFrame representing an xsl:call-template instruction in XSLT
*/
public static class CallTemplate extends ContextStackFrame {
/**
* Get the name of the template being called
* @return the name of the template being called. Note this may be null in the case of the
* extension instruction saxon:call-template
*/
public StructuredQName getTemplateName() {
return templateName;
}
/**
* Set the name of the template being called
* @param templateName the name of the template being called.
*/
public void setTemplateName(StructuredQName templateName) {
this.templateName = templateName;
}
StructuredQName templateName;
/**
* Display a representation of the stack frame on the specified output stream
* @param out the output stream
*/
public void print(PrintStream out) {
String name = templateName == null ? "??" : templateName.getDisplayName();
out.println(" at xsl:call-template name=\"" + name + "\" " + showLocation());
}
}
/**
* Subclass of ContextStackFrame representing the evaluation of a variable (typically a global variable)
*/
public static class VariableEvaluation extends ContextStackFrame {
/**
* Get the name of the variable
* @return the name of the variable
*/
public StructuredQName getVariableName() {
return variableName;
}
/**
* Set the name of the variable
* @param variableName the name of the variable
*/
public void setVariableName(StructuredQName variableName) {
this.variableName = variableName;
}
StructuredQName variableName;
/**
* Display a representation of the stack frame on the specified output stream
* @param out the output stream
*/
public void print(PrintStream out) {
out.println(" in " + displayContainer(getContainer()) + " " + showLocation());
}
}
private static String displayContainer(/*@NotNull*/ Container container) {
if (container instanceof Procedure) {
StructuredQName name = ((Procedure)container).getObjectName();
String objectName = (name==null ? "" : name.getDisplayName());
if (container instanceof Template) {
if (name == null) {
//NamePool pool = container.getExecutable().getConfiguration().getNamePool();
return "template match=\"" + ((Template)container).getMatchPattern().toString() + "\"";
} else {
return "template name=\"" + objectName + "\"";
}
} else if (container instanceof UserFunction) {
return "function " + objectName + "()";
} else if (container instanceof AttributeSet) {
return "attribute-set " + objectName;
} else if (container instanceof KeyDefinition) {
return "key " + objectName;
}
} else if (container instanceof GlobalVariable) {
StructuredQName qName = ((GlobalVariable)container).getVariableQName();
if (NamespaceConstant.SAXON_GENERATED_GLOBAL.equals(qName.getURI())) {
return "optimizer-created global variable";
} else {
return "variable " + qName.getDisplayName();
}
} else {
return "";
}
return "";
}
}