FileDocCategorySizeDatePackage
TestSeq.javaAPI DocJava SE 5 API8626Fri Aug 26 14:55:36 BST 2005com.sun.org.apache.xalan.internal.xsltc.compiler

TestSeq

public final class TestSeq extends Object
A test sequence is a sequence of patterns that (1) occured in templates in the same mode (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 instantiated if none of the other patterns match.
author
Jacek Ambroziak
author
Santiago Pericas-Geertsen
author
Erwin Bolwidt
author
Morten Jorgensen

Fields Summary
private int
_kernelType
Integer code for the kernel type of this test sequence
private Vector
_patterns
Vector of all patterns in the test sequence. May include patterns with "*", "@*" or "node()" kernel.
private Mode
_mode
A reference to the Mode object.
private Template
_default
Default template for this test sequence
private InstructionList
_instructionList
Instruction list representing this test sequence.
private InstructionHandle
_start
Cached handle to avoid compiling more than once.
Constructors Summary
public TestSeq(Vector patterns, Mode mode)
Creates a new test sequence given a set of patterns and a mode.


                      
         
	this(patterns, -2, mode);
    
public TestSeq(Vector patterns, int kernelType, Mode mode)

	_patterns = patterns;
	_kernelType = kernelType;
	_mode = mode;
    
Methods Summary
public com.sun.org.apache.bcel.internal.generic.InstructionHandlecompile(com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator classGen, com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator methodGen, com.sun.org.apache.bcel.internal.generic.InstructionHandle continuation)
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.

	// 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 (count == 0) {
	    return (_start = getTemplateHandle(_default));
	}

	// Init handle to jump when all patterns failed
	InstructionHandle fail = (_default == null) ? continuation
	    : getTemplateHandle(_default);
	
	// 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
	    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));

	    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);
	    }

	    // Set current instruction list to be this one
	    _instructionList = il;
	}
	return (_start = fail);
    
public voidfindTemplates(java.util.Dictionary templates)
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.

	if (_default != null) {
	    templates.put(_default, this);
	}
	for (int i = 0; i < _patterns.size(); i++) {
	    final LocationPathPattern pattern =
		(LocationPathPattern)_patterns.elementAt(i);
	    templates.put(pattern.getTemplate(), this);
	}
    
public com.sun.org.apache.bcel.internal.generic.InstructionListgetInstructionList()
Returns the instruction list for this test sequence

	return _instructionList;
    
private com.sun.org.apache.xalan.internal.xsltc.compiler.LocationPathPatterngetPattern(int n)
Returns pattern n in this test sequence

	return (LocationPathPattern)_patterns.elementAt(n);
    
public intgetPosition()
Returns the position of the highest priority pattern in this test sequence.

	final Template template = (_patterns.size() == 0) ? _default 
	    : ((Pattern) _patterns.elementAt(0)).getTemplate();
	return template.getPosition();
    
public doublegetPriority()
Return the highest priority for a pattern in this test sequence. This is either the priority of the first or of the default pattern.

	final Template template = (_patterns.size() == 0) ? _default 
	    : ((Pattern) _patterns.elementAt(0)).getTemplate();
	return template.getPriority();
    
private com.sun.org.apache.bcel.internal.generic.InstructionHandlegetTemplateHandle(com.sun.org.apache.xalan.internal.xsltc.compiler.Template template)
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").

	return (InstructionHandle)_mode.getTemplateInstructionHandle(template);
    
public voidreduce()
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.

	final Vector newPatterns = new Vector();

	final int count = _patterns.size();
	for (int i = 0; i < count; i++) {
	    final LocationPathPattern pattern =
		(LocationPathPattern)_patterns.elementAt(i);
		
	    // Reduce this pattern
	    pattern.reduceKernelPattern();
			
	    // Is this pattern fully reduced?
	    if (pattern.isWildcard()) {
		_default = pattern.getTemplate();
		break; 		// Ignore following patterns 
	    }
	    else {
		newPatterns.addElement(pattern);
	    }
	}
	_patterns = newPatterns;
    
public java.lang.StringtoString()
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().

	final int count = _patterns.size();
	final StringBuffer result = new StringBuffer();

	for (int i = 0; i < count; i++) {
	    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 result.toString();