/*
 * Copyright (C) 2001-2006 University Bayreuth, BayCEER, Dept. of Mycology 
 * 
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License 
 * along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
/*
 * File:           Delta_pre_selectionScanner.java
 * Generated from: delta_pre_selection.dtd
 * Date:           2. Dezember 2005  15:20
 *
 * @author  didi
 * @version generated by NetBeans XML module
 */
package net.metadiversity.diversity.navikey.util;
/**
 *
 * This is a scanner of DOM tree.
 *
 * Example:
 * <pre>
 *     javax.xml.parsers.DocumentBuilderFactory builderFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
 *     javax.xml.parsers.DocumentBuilder builder = builderFactory.newDocumentBuilder();
 *     org.w3c.dom.Document document = builder.parse (new org.xml.sax.InputSource (???));
 *     <font color="blue">Delta_pre_selectionScanner scanner = new Delta_pre_selectionScanner (document);</font>
 *     <font color="blue">scanner.visitDocument();</font>
 * </pre>
 *
 * @see org.w3c.dom.Document
 * @see org.w3c.dom.Element
 * @see org.w3c.dom.NamedNodeMap
 */
public class Delta_pre_selectionScanner
{
    /**
     * org.w3c.dom.Document document
     */
    org.w3c.dom.Document document;
    
    StringBuffer        selection;      // for building selection SQL
    StringBuffer        exclude;
    String              selectionName;
    java.util.HashMap   selectionMap;   // SelectionName, SQL
    java.util.HashMap   excludeMap;     // SelectionName, exclude CharacterID's SQL
    
    boolean firstSelection;
    boolean firstCharacter;
    boolean firstExclude;
    boolean firstState;
    int     closeCounter = 0;
    
    // select * from "Lias_DESCR" WHERE ( ("CID" = 8 AND "CS" IN ( 2, 3, 4, 5 ) AND "IID" IN ( SELECT "IID" FROM "Lias_DESCR" WHERE ("CID" = 13 AND "CS" IN ( 11 ) ) ) ) );
    // Example:
    // Sonora Desert from LIASlight
    // checklist record --> "CID" = 13
    // Sonora Desert    --> "CS" = 20
    // SELECT DISTINCT "IID" FROM "LIASlight_DESCR" WHERE ( ("CID" = 13 AND "CS" IN ( 20 ) ) );
    final static String     CHAR = "\"CID\"";
    final static String     IID  = "\"IID\"";
    final static String     STATE = "\"CS\"";
    
    final static String     TABLE_SUFFIX = "_DESCR"; 
    String tableName = null;
    /**
     * Create new Delta_pre_selectionScanner with org.w3c.dom.Document.
     */
    public Delta_pre_selectionScanner( String tablePrefix, org.w3c.dom.Document document)
    {
        this.document = document;
        
        // setup tableName
        tableName = "\"" + tablePrefix + TABLE_SUFFIX + "\"";
        selectionMap  = new java.util.HashMap();
        excludeMap    = new java.util.HashMap();
    }
    
    /**
     * Scan through org.w3c.dom.Document document.
     */
    public void visitDocument()
    {
        selection = new StringBuffer();
        exclude   = new StringBuffer();
        org.w3c.dom.Element element = document.getDocumentElement();
        if ((element != null) && element.getTagName().equals("root"))
        {
            visitElement_root(element);
        }
        if ((element != null) && element.getTagName().equals("selection"))
        {
            visitElement_selection(element);
        }
        if ((element != null) && element.getTagName().equals("character"))
        {
            visitElement_character(element);
        }
        if ((element != null) && element.getTagName().equals("state"))
        {
            visitElement_state(element);
        }
        if ((element != null) && element.getTagName().equals("exclude"))
        {
            visitElement_exclude(element);
        }
    }
    
    /**
     * Scan through org.w3c.dom.Element named root.
     */
    void visitElement_root(org.w3c.dom.Element element)
    { // <root>
        // element.getValue();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++)
        {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType())
            {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element)node;
                    if (nodeElement.getTagName().equals("selection"))
                    {
                        visitElement_selection(nodeElement);
                    }
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
            }
        }
    }
    
    /**
     * Scan through org.w3c.dom.Element named selection.
     */
    void visitElement_selection(org.w3c.dom.Element element)
    { // <selection>

            selection       = new StringBuffer();
            exclude         = new StringBuffer();
            firstCharacter  = true;
            firstState      = true;
            firstExclude    = true;

        // element.getValue();
        org.w3c.dom.NamedNodeMap attrs = element.getAttributes();
        for (int i = 0; i < attrs.getLength(); i++)
        {
            org.w3c.dom.Attr attr = (org.w3c.dom.Attr)attrs.item(i);
            if (attr.getName().equals("name"))
            {
                // <selection name="???">
                // System.out.println( "selection name : " + attr.getValue() );
                selectionName = attr.getValue();
            }
        }
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++)
        {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType())
            {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element)node;
                    if (nodeElement.getTagName().equals("character"))
                    {
                        visitElement_character( nodeElement );
                    }
                    else if( nodeElement.getTagName().equals("exclude"))
                    {
                        visitElement_exclude( nodeElement );
                    }
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
            }
        }
        while( closeCounter-- > 0)
        {        
            selection.append( " )" );
        }
        if( ! firstExclude )
        {    
            exclude.append( " )" );    
        }
        System.out.println( selectionName + " : " + selection.toString() );
        System.out.println( selectionName + " : " + exclude.toString() );
        
        // Add Selection to HashMap
        selectionMap.put( selectionName, selection.toString() );
        excludeMap.put(   selectionName, exclude.toString()   );
    }
    
    /**
     * Scan through org.w3c.dom.Element named character.
     */
    void visitElement_character(org.w3c.dom.Element element)
    { // <character>
        firstState = true;
        
        // element.getValue();
        org.w3c.dom.NamedNodeMap attrs = element.getAttributes();
        for (int i = 0; i < attrs.getLength(); i++)
        {
            org.w3c.dom.Attr attr = (org.w3c.dom.Attr)attrs.item(i);
            if (attr.getName().equals("id"))
            {
                // <character id="???">
                // System.out.println( "<character id= " + attr.getValue() );
                if( firstCharacter )
                {
                    selection.append( "SELECT DISTINCT " + IID + " FROM " + tableName + " WHERE ( (" + CHAR  + " = " + attr.getValue() + " AND " + STATE + " IN (" );
                    firstCharacter = false;
                    closeCounter = 3;
                }
                else
                {
                    selection.append( " ) ) AND " + IID + " IN ( SELECT DISTINCT " + IID + " FROM " + tableName + " WHERE ( " + CHAR + " = " + attr.getValue() + " AND " + STATE +  " IN (" );
                    closeCounter++;
                }
            }
        }
        
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++)
        {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType())
            {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element)node;
                    if (nodeElement.getTagName().equals("state"))
                    {
                        visitElement_state(nodeElement);
                    }
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
            }
        }
    }
    /**
     * Scan through org.w3c.dom.Element named exclude.
     */
    void visitElement_exclude(org.w3c.dom.Element element)
    { // <character>
        
        // element.getValue();
        org.w3c.dom.NamedNodeMap attrs = element.getAttributes();
        for (int i = 0; i < attrs.getLength(); i++)
        {
            org.w3c.dom.Attr attr = (org.w3c.dom.Attr)attrs.item(i);
            if( attr.getName().equals( "CharID" ) )
            {
                // <character id="???">
                System.out.println( "<exclude CharID= " + attr.getValue() + " >");

                if( firstExclude )
                {
                    exclude.append( "( " + attr.getValue() );
                    firstExclude = false;
                }
                else
                {
                    exclude.append( ", " + attr.getValue() );
                }
            }
        }
/*        
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++)
        {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType())
            {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element)node;
                    if (nodeElement.getTagName().equals("state"))
                    {
                        visitElement_state(nodeElement);
                    }
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
            }
        }
 */
    }
    
    /**
     * Scan through org.w3c.dom.Element named state.
     */
    void visitElement_state(org.w3c.dom.Element element)
    { // <state>        
        // System.out.println( element.getValue() );
        
        org.w3c.dom.NamedNodeMap attrs = element.getAttributes();
        for (int i = 0; i < attrs.getLength(); i++)
        {
            org.w3c.dom.Attr attr = (org.w3c.dom.Attr)attrs.item(i);
            if (attr.getName().equals("number"))
            { // <state number="???">
                // System.out.println( "<state number= " + attr.getValue() );

                if( firstState )
                {
                    selection.append( " " + attr.getValue() );
                    firstState = false;
                }
                else
                {
                    selection.append( ", " + attr.getValue() );            
                }
            }
        }
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++)
        {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType())
            {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element)node;
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
            }
        }
    }
    
    public String getSql( String selection )
    {
        return (String) selectionMap.get( selection );
    }    

    public String getExclude( String selection )
    {
        return (String) excludeMap.get( selection );
    }
    
    public String [] getPreSelectionNames()
    {
        
        java.util.Collection c = selectionMap.keySet();
        java.util.Iterator   i = c.iterator();
        
        String ret[] = new String[ c.size() ];
        int ii = 0;
        while( i.hasNext() )
        {
            ret[ ii++ ] = i.next().toString();
        }
        
        return ret;
    }
    
    public static void main(String args[]) throws org.xml.sax.SAXException, javax.xml.parsers.ParserConfigurationException, java.io.IOException
    {
        String databaseName = "LIASlight";
        
        javax.xml.parsers.DocumentBuilderFactory builderFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
        javax.xml.parsers.DocumentBuilder builder = builderFactory.newDocumentBuilder();
        org.w3c.dom.Document document = builder.parse( new org.xml.sax.InputSource( "delta_pre_selection_" + databaseName + ".xml" ) );
        Delta_pre_selectionScanner scanner = new Delta_pre_selectionScanner( databaseName, document);
        scanner.visitDocument();          
        
        String [] names = scanner.getPreSelectionNames();

        System.out.println( "--- all subsets ---" );        
        for( int i = 0; i < names.length; i++ )
        {    
            String subsetName = names[ i ];
            System.out.println( "--- get Sql for " + subsetName );
            System.out.println( scanner.getSql( subsetName ) );
            String fileSuffix = subsetName.replace( ' ', '_' );
            System.out.println( "--- build " + databaseName + "." + fileSuffix );            
            System.out.println( "--- exclude --- " + scanner.getExclude(  subsetName ) );
        }
    }
    
}
