package com.sun.org.apache.xalan.internal.xsltc.compiler;
import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
import com.sun.org.apache.bcel.internal.generic.InstructionHandle;
import com.sun.org.apache.bcel.internal.generic.InstructionList;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.NamedMethodGenerator;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;
import com.sun.org.apache.xml.internal.utils.XML11Char;
import java.util.ArrayList;
import java.util.List;
public final class Template extends TopLevelElement {
private QName _name;
private QName _mode;
private Pattern _pattern;
private double _priority;
private int _position;
private boolean _disabled = false;
private boolean _compiled = false;
private boolean _simplified = false;
private boolean _isSimpleNamedTemplate = false;
private List<Param> _parameters = new ArrayList<>();
public boolean hasParams() {
return _parameters.size() > 0;
}
public boolean isSimplified() {
return(_simplified);
}
public void setSimplified() {
_simplified = true;
}
public boolean isSimpleNamedTemplate() {
return _isSimpleNamedTemplate;
}
public void addParameter(Param param) {
_parameters.add(param);
}
public List<Param> getParameters() {
return _parameters;
}
public void disable() {
_disabled = true;
}
public boolean disabled() {
return(_disabled);
}
public double getPriority() {
return _priority;
}
public int getPosition() {
return(_position);
}
public boolean isNamed() {
return _name != null;
}
public Pattern getPattern() {
return _pattern;
}
public QName getName() {
return _name;
}
public void setName(QName qname) {
if (_name == null) _name = qname;
}
public QName getModeName() {
return _mode;
}
public int compareTo(Object template) {
Template other = (Template)template;
if (_priority > other._priority)
return 1;
else if (_priority < other._priority)
return -1;
else if (_position > other._position)
return 1;
else if (_position < other._position)
return -1;
else
return 0;
}
public void display(int indent) {
Util.println('\n');
indent(indent);
if (_name != null) {
indent(indent);
Util.println("name = " + _name);
}
else if (_pattern != null) {
indent(indent);
Util.println("match = " + _pattern.toString());
}
if (_mode != null) {
indent(indent);
Util.println("mode = " + _mode);
}
displayContents(indent + IndentIncrement);
}
private boolean resolveNamedTemplates(Template other, Parser parser) {
if (other == null) return true;
SymbolTable stable = parser.getSymbolTable();
final int us = this.getImportPrecedence();
final int them = other.getImportPrecedence();
if (us > them) {
other.disable();
return true;
}
else if (us < them) {
stable.addTemplate(other);
this.disable();
return true;
}
else {
return false;
}
}
private Stylesheet _stylesheet = null;
public Stylesheet getStylesheet() {
return _stylesheet;
}
public void parseContents(Parser parser) {
final String name = getAttribute("name");
final String mode = getAttribute("mode");
final String match = getAttribute("match");
final String priority = getAttribute("priority");
_stylesheet = super.getStylesheet();
if (name.length() > 0) {
if (!XML11Char.isXML11ValidQName(name)) {
ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, name, this);
parser.reportError(Constants.ERROR, err);
}
_name = parser.getQNameIgnoreDefaultNs(name);
}
if (mode.length() > 0) {
if (!XML11Char.isXML11ValidQName(mode)) {
ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, mode, this);
parser.reportError(Constants.ERROR, err);
}
_mode = parser.getQNameIgnoreDefaultNs(mode);
}
if (match.length() > 0) {
_pattern = parser.parsePattern(this, "match", null);
}
if (priority.length() > 0) {
_priority = Double.parseDouble(priority);
}
else {
if (_pattern != null)
_priority = _pattern.getPriority();
else
_priority = Double.NaN;
}
_position = parser.getTemplateIndex();
if (_name != null) {
Template other = parser.getSymbolTable().addTemplate(this);
if (!resolveNamedTemplates(other, parser)) {
ErrorMsg err =
new ErrorMsg(ErrorMsg.TEMPLATE_REDEF_ERR, _name, this);
parser.reportError(Constants.ERROR, err);
}
if (_pattern == null && _mode == null) {
_isSimpleNamedTemplate = true;
}
}
if (_parent instanceof Stylesheet) {
((Stylesheet)_parent).addTemplate(this);
}
parser.setTemplate(this);
parseChildren(parser);
parser.setTemplate(null);
}
public void parseSimplified(Stylesheet stylesheet, Parser parser) {
_stylesheet = stylesheet;
setParent(stylesheet);
_name = null;
_mode = null;
_priority = Double.NaN;
_pattern = parser.parsePattern(this, "/");
final List<SyntaxTreeNode> contents = _stylesheet.getContents();
final SyntaxTreeNode root = contents.get(0);
if (root instanceof LiteralElement) {
addElement(root);
root.setParent(this);
contents.set(0, this);
parser.setTemplate(this);
root.parseContents(parser);
parser.setTemplate(null);
}
}
public Type typeCheck(SymbolTable stable) throws TypeCheckError {
if (_pattern != null) {
_pattern.typeCheck(stable);
}
return typeCheckContents(stable);
}
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
if (_disabled) return;
String className = classGen.getClassName();
if (_compiled && isNamed()){
String methodName = Util.escape(_name.toString());
il.append(classGen.loadTranslet());
il.append(methodGen.loadDOM());
il.append(methodGen.loadIterator());
il.append(methodGen.loadHandler());
il.append(methodGen.loadCurrentNode());
il.append(new INVOKEVIRTUAL(cpg.addMethodref(className,
methodName,
"("
+ DOM_INTF_SIG
+ NODE_ITERATOR_SIG
+ TRANSLET_OUTPUT_SIG
+ "I)V")));
return;
}
if (_compiled) return;
_compiled = true;
if (_isSimpleNamedTemplate && methodGen instanceof NamedMethodGenerator) {
int numParams = _parameters.size();
NamedMethodGenerator namedMethodGen = (NamedMethodGenerator)methodGen;
for (int i = 0; i < numParams; i++) {
Param param = _parameters.get(i);
param.setLoadInstruction(namedMethodGen.loadParameter(i));
param.setStoreInstruction(namedMethodGen.storeParameter(i));
}
}
translateContents(classGen, methodGen);
il.setPositions(true);
}
}