ASTHandler.java

package edu.udel.cis.vsl.tass.ast.parser;

import edu.udel.cis.vsl.tass.ast.IF.RootNodeIF;

import java.util.Stack;
import java.util.EmptyStackException;

import org.xml.sax.SAXParseException;
import org.xml.sax.SAXException;
import org.xml.sax.Attributes;

import org.xml.sax.helpers.DefaultHandler;

class ASTHandler extends DefaultHandler {

    private Stack<NodeParserIF> parseStack = new Stack<NodeParserIF>();

    private RootNodeIF rootNode = null;

    private final RefMappers refMappers;

    private final NodeTypes nodeTypes;

    public ASTHandler() {
        super();
        refMappers = new RefMappers();
        nodeTypes = new NodeTypes(refMappers);
    }

    public RootNodeIF getRoot() {
        return rootNode;
    }

    @Override
    public void startElement(String uri,
                             String localName,
                             String qName,
                             Attributes attrs) throws SAXException {
        if (parseStack.empty()) {
            parseStack.push(new NodeParser(nodeTypes,refMappers));
        } else {
            parseStack.push(parseStack.peek().makeDescendent(localName));
        }
        parseStack.peek().setAttrs(attrs);
    }
    
    @Override
    public void characters(char[] ch,
                           int start,
                           int length) throws SAXException {
        parseStack.peek().characters(new String(ch,start,length));
    }

    @Override
    public void endElement(String uri,
                           String localName,
                           String qName) throws SAXException {
        try {
            NodeEltWrapperIF lastNode = parseStack.pop().node();

            if (parseStack.empty()) {
                assert(rootNode == null);
                rootNode = (RootNodeIF)(lastNode.getNode());
            } else {
                parseStack.peek().addDescendent(lastNode);
            }

        } catch (EmptyStackException e) {
            throw new ParserException("Encountered more close tags than open tags");
        }
    }

    @Override
    public void endDocument() throws SAXException {
        if (rootNode == null) {
            throw new ParserException("Premature end of document");
        } else {
            refMappers.linkRefs();
        }
    }

    @Override
    public void error(SAXParseException exception) throws SAXException {
        throw exception;
    }
    
    @Override
    public void fatalError(SAXParseException exception) throws SAXException {
        throw exception;
    }
    
    @Override
    public void warning(SAXParseException exception) throws SAXException {
        throw exception;
    }
}