/*
 * blancoDb
 * Copyright (C) 2004-2005 Yasuo Nakanishi
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */
package blanco.db.conf;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import blanco.db.exception.BlancoDbException;

/**
 * 2005.05.13 不要メソッドをいったんは洗い出し。
 * 
 * @author Yasuo Nakanishi
 */
public abstract class QueryLoader {
    private String _directory = "";

    private Element _documentElement = null;

    private QueryPath _path = null;

    private XmlQuery _xmlQuery = null;

    public QueryLoader(String directory) {
        _directory = directory;
    }

    /**
     * このメソッドは利用されています。
     * 
     * @return
     */
    protected void loadXml(String filePath) throws SAXException, IOException,
            ParserConfigurationException {
        DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = dbfactory.newDocumentBuilder();
        Document documentRoot = builder.parse(new File(getFilePath(filePath)));
        _documentElement = documentRoot.getDocumentElement();
    }

    /**
     * このメソッドは利用されています。
     * 
     * @return
     */
    public void load(QueryPath path) throws SAXException, IOException,
            ParserConfigurationException, BlancoDbException {
        _path = path;

        loadXml(path.getFilePath());
        _xmlQuery = new XmlQuery(getTargetElement(_path.getName()));
        validateQuery();
        parse();
    }

    /**
     * このメソッドは利用されています。
     * 
     * @return
     */
    protected QueryPath getPath() {
        return _path;
    }

    /**
     * サブクラスで実装されます。
     */
    protected abstract void parse();

    /**
     * サブクラスで実装されます。
     */
    protected abstract void validateQuery() throws BlancoDbException;

    private String getFilePath(String filePath) {
        return _directory + "/" + filePath;
    }

    protected boolean findTargetElement(String tagName, String name) {
        boolean result = false;
        NodeList list = _documentElement.getElementsByTagName(tagName);

        Node node = null;
        Element element = null;
        int length = list.getLength();
        for (int i = 0; i < length; i++) {
            node = list.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                element = (Element) node;
                if (element.getAttribute("name").equals(name)) {
                    result = true;
                    break;
                }
            }
        }
        return result;
    }

    protected Element getTargetElement(String name) {
        Element result = null;
        NodeList list = _documentElement.getChildNodes();

        Node node = null;
        Element element = null;
        for (int i = 0; i < list.getLength(); i++) {
            node = list.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                element = (Element) node;
                if (element.getAttribute("name").equals(name)) {
                    result = element;
                    break;
                }
            }
        }
        return result;
    }

    protected String getChildData(Element element) {
        NodeList list = element.getChildNodes();
        Node node = null;
        String result = "";
        for (int i = 0; i < list.getLength(); i++) {
            node = list.item(i);
            if (node.getNodeType() == Node.CDATA_SECTION_NODE) {
                result += node.getNodeValue();
            } else if (node.getNodeType() == Node.TEXT_NODE) {
                result += node.getNodeValue();
            }
        }
        return result;
    }

    protected List getParameters() {
        return _xmlQuery.getParameters();
    }

    protected String getQuery() {
        return _xmlQuery.getQuery();
    }

    protected boolean exsistAttribute(Element element, String attribute) {
        String value = element.getAttribute(attribute);
        return value != null && value != "";
    }

    protected Element getTargetElement() {
        //assert _xmlQuery != null;
        return _xmlQuery.getTarget();
    }

    public XmlQuery getXmlQuery() {
        return _xmlQuery;
    }
}