package org.pmdreports.dao;

import java.io.IOException;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.List;

import org.apache.xerces.parsers.SAXParser;
import org.pmdreports.model.Ruleset;
import org.pmdreports.util.PMDReportsException;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;

/**
 * DAO for reading in config file and returning config data. Note that the
 * config file is in XML, so this DAO uses a SAX parser.
 * 
 * @author Ben Northrop Sep 24, 2007
 */
public class RulesetDAO implements ContentHandler {

	// DATA MEMBERS
	private final String xmlFile;

	private List<Ruleset> rulesets;

	// CONSTRUCTORS
	/**
	 * Default constructor taking name of xml file as param.
	 */
	public RulesetDAO(String xmlFile) {
		if (xmlFile == null || "".equals(xmlFile)) {
			throw new InvalidParameterException("xmlFile not defined!");
		}
		this.xmlFile = xmlFile;
	}

	/**
	 * Retrieve the Rulesets that will be used from PMD (custom or pre-defined).
	 */
	public List<Ruleset> retrieveRulesets() {
		rulesets = new ArrayList<Ruleset>();

		synchronized (this) {
			SAXParser parser = new SAXParser();
			parser.setContentHandler(this);
			try {
				parser.parse(xmlFile);
			} catch (SAXException e) {
				throw new PMDReportsException(
						"SAXException when parsing file: " + xmlFile, e);
			} catch (IOException e) {
				throw new PMDReportsException("IOException when parsing file: "
						+ xmlFile, e);
			}
		}
		return rulesets;
	}

	/**
	 * A PMD ruleset element is read in.
	 */
	public void startElement(String uri, String local, String qName,
			Attributes atts) {
		if (local != null && local.equals("ruleset")) {
			Ruleset ruleset = new Ruleset(atts.getValue("name"), atts
					.getValue("description"), atts.getValue("filename"), atts
					.getValue("minViolations"), atts.getValue("maxViolations"),
					atts.getValue("isShowAbsolute"));
			rulesets.add(ruleset);
		}
	}

	// the remaining callback handlers
	// they don't do anything right now...but keep reading!
	public void setDocumentLocator(Locator locator) {
	}

	public void startDocument() {
	}

	public void endDocument() {
	}

	public void characters(char[] text, int start, int length) {
	}

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

	public void endPrefixMapping(String prefix) {
	}

	public void endElement(String namespaceURI, String localName,
			String qualifiedName) {

	}

	public void ignorableWhitespace(char[] text, int start, int length)
			throws SAXException {
	}

	public void processingInstruction(String target, String data) {
	}

	public void skippedEntity(String name) {
	}
}
