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.Component;
import org.pmdreports.model.Project;
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;

/**
 * CRUD for all project related data. Note this will come both from the XML
 * config file and the other persistence store.
 * 
 * @author Ben Northrop Sep 24, 2007
 */
public class ProjectDAO implements ContentHandler {

	// DATA MEMBERS
	private final String xmlFile;

	private List<Project> projects;

	private Project currentProject;

	// CONSTRUCTORS
	/**
	 * Default constructor taking name of xml file as param.
	 */
	public ProjectDAO(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<Project> retrieveProjectConfig() {
		projects = new ArrayList<Project>();

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

	/**
	 * Projects are created and components added to them.
	 */
	public void startElement(String uri, String local, String qName,
			Attributes atts) {
		if (local != null) {
			if ("project".equals(local)) {
				currentProject = new Project(atts.getValue("name"), atts
						.getValue("srcroot"));
				projects.add(currentProject);
			} else if ("component".equals(local)) {
				Component component = new Component(atts.getValue("name"), atts
						.getValue("src"), currentProject);
				currentProject.addComponent(component);
			}
		}
	}

	// 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) {
	}
}
