If you are familar with java XML programming, such as jdom, dom4j, xerces and etc, then you can catch my idea easily.

JFreeDOM is used to parse some tree feature scripts, such as jsp, asp and php source code to an irragular document tree. It is light weight implementation. Simulated org.xml.sax, provided one parser; and one DocumentBuilder which is similar to javax.xml.parsers.DocumentBuilder, and also extends some new node implementations.

All the original DOM node implementations are from xerces.

One day, our development group plans to make one audit of JSP pages. I get one development task that I need to summary the JSTL tag usage in all our JSP pages and check if some necessary attributes are used explicitly. At first, I used regular expressions to match string in jsp source pages, but I can not move on as the requirements become more and more complicated.

Then I am thinking is there any open source API can parse JSP pages to one document then i can process this document easily? unfortunately, I did not get proper API in sourceforge and google code, so I create one by myself.

import java.net.URL;

import net.sourceforge.jfreedom.JFreeDOMParser;
import net.sourceforge.jfreedom.jsp.JspParser;


public class PrintNode {
	public static void main(String[] args) {
		String url="http://www.google.com";
		try {
			if(args==null||args.length==0){
				System.out.println("Usage url");
			}
			url=(args==null||args.length==0?url:args[0]);
			JFreeDOMParser parser=new JspParser();//Use parser
			parser.addParserListener(new ParseTracer());//add Listener
			parser.parse(new URL(url));
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
import net.sourceforge.jfreedom.JFreeDOMParserListener;

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

public class ParseTracer implements JFreeDOMParserListener {

	public void characters(char[] ch, int start, int length, short type)
			throws SAXException {
		System.out.println("characters:"+new String(ch));
	}

	public void endDocument() throws SAXException {
		System.out.println("endDocument()");
	}

	public void endEl() throws SAXException {
		System.out.println("endEl()");
	}

	public void endElement(String uri, String localName, String name)
			throws SAXException {
		System.out.println("endElement: uri="+uri+" localName="+localName+" name="+name);
	}

	public void endPrefixMapping(String prefix) throws SAXException {
		System.out.println("endPrefixMapping()");
	}

	public void ignorableWhitespace(char[] ch, int start, int length)
			throws SAXException {
		System.out.println("ignorableWhitespace:"+new String(ch));
	}

	public void setDocumentLocator(Locator locator) {
		
	}

	public void startDocument() throws SAXException {
		System.out.println("startDocument()");
	}

	public void startEl(char[] ch, int start, int length) throws SAXException {
		System.out.println("startEl()"+new String(ch));
	}

	public void startElement(String uri, String localName, String name,
			Attributes atts) throws SAXException {
		System.out.print("startElement: uri="+uri+" localName="+localName+" name="+name);
		System.out.print(" {");
		for(int i=0;i<atts.getLength();i++){
			System.out.print("{"+atts.getLocalName(i));
			System.out.print(" "+atts.getQName(i));
			System.out.print(" "+atts.getType(i));
			System.out.print("="+atts.getValue(i)+" }");
		}
		System.out.println("}");
	}

	public void startPrefixMapping(String prefix, String uri)
			throws SAXException {
		
	}

	public void notationDecl(String name, String publicId, String systemId)
			throws SAXException {
		System.out.println("notationDecl() name="+name+" publicId="+publicId+" systemId="+systemId);
	}

	public void unparsedEntityDecl(String name, String publicId,
			String systemId, String notationName) throws SAXException {
		System.out.println("notationDecl() name="+name+" publicId="+publicId+" systemId="+systemId+" notationName="+notationName);
	}
}