import GCF.*;
import java.net.URL;
import java.lang.reflect.Array;

/**
 * Class to show the use of the GXL Converter Framework.
 * A gxl document is read, its syntax tree is modified and then the result document
 * is written.
 */
public class Demo2 extends Object {

     /**
      * Method to traverse the syntax tree of a document and to generate
      * an event stream for the GXLConnector given in the parameter con.
     */
     public static void outputTree (int depth, DefaultImpl2.GXLStandardAPI tree, 
                                    GCF.GXLConnector con) {
        if (depth==0) con.create ("gxl"); 
        else {
            // if the depth is > 0, first read the attributes...
            Object attributes = tree.getAttributes();
            if (attributes!=null) {                
                // iterate the attributes
                java.util.Iterator it = ((java.util.Vector)attributes).iterator();
                while (it.hasNext()) {
                    Object next = it.next();
                    con.setAttributeValue ((String)Array.get(next,0), 
                                           (String)Array.get(next,1));
                }
            }
        }
        
        //... then read the child elements
        Object children = tree.getChildElements();
        if (children!=null) {
            // iterate the child elements
            java.util.Iterator it = ((java.util.Vector)children).iterator();
            while (it.hasNext()) {
                Object next = it.next();
                if (next instanceof DefaultImpl2.GXLStandardAPI) {
                    // if the next object is an instance of the GXLStandardAPI, 
                    // it might have child elements...
                    con.create (next.toString());
                    outputTree (depth+1, (DefaultImpl2.GXLStandardAPI)next, con);
                    con.close (next.toString());
                }
                else {
                    // if not, it is a simple type. 
                    // So there's no further recursion necessary
                    con.create ((String)Array.get(next,0));
                    con.printData ((String)Array.get(next,1));
                    con.close ((String)Array.get(next,0));
                }
            }
        }
        
        if (depth==0) con.close("gxl");
    } // outputTree
    
    
    /** Empty constructor.  */    
    public Demo2() {
    }
    
    /**
     * Main method.
     */
    public static void main (String[] args) {

        try {
            
            // -------------------------------------------------------
            // Initialize the GCF and use the default implementation 2
            // -------------------------------------------------------
            
            // create the GXL Object
            GCF.GXLConverterAPI.createGXL(new DefaultImpl2.GXLGXLAPIImpl());
            // set the URL where the implementatio of the abstract classes is located
            GCF.GXLConverterAPI.setImplementationURL(
               new URL ("file:///C:/Programme/Programmierung/Java/Forte4j/Projects/GCF/"));
            GCF.GXLConverterAPI.setPackageName("DefaultImpl2");
            // IMPORTANT : 1st create the connector (here the GXLConnector)...
            GCF.GXLConverterAPI.createConnector(GCF.GXLConverterAPI.CONNECTOR);
            // ...and then the documentHandler !!!
            GCF.GXLConverterAPI.createDocumentHandler();

            // now parse the file given in the command line or parse gxldemo.xml 
            // if no file was specified...
            if (args.length<=0)
                GCF.GXLConverterAPI.parse("Projects\\GCF\\GXL-Bsp\\gxldemo.xml");
            else GCF.GXLConverterAPI.parse (args[0]);
          
            // read the syntax tree of the document
            Object result = GCF.GXLConverterAPI.getResultObject();
            
            // -------------------------------------------------------------------- 
            // Instantiate the GCF again, but use the default implementation 1 this
            // time.
            // After the instantiation the event stream for the new GXLConnector is
            // generated throug the method outputTree().
            // --------------------------------------------------------------------
            
            // change the GXLObject to GXLGXLAPIImpl (of the package DefaultImpl1 !!)
            GCF.GXLConverterAPI.createGXL(new DefaultImpl1.GXLGXLAPIImpl());
           
            // change the package to DefaultImpl1
            GCF.GXLConverterAPI.setPackageName("DefaultImpl1");
            
            // again create the GXLConnector and the GXLDocumentHandler
            GCF.GXLConverterAPI.createConnector(GCF.GXLConverterAPI.CONNECTOR);
            GCF.GXLConverterAPI.createDocumentHandler();
            
            // optionally create an outputFile, the default output
            // stream is System.out
            DefaultImpl1.GXLOutputAPI.createOutputFile ("Projects\\Demo2.xml");
            
            // now traverse the tree (result) and thus generate the event stream for
            // the GCF; the result is automatically written to the file Demo2.xml
            outputTree (0,(DefaultImpl2.GXLStandardAPI)result,GCF.GXLConverterAPI.getConnector());
            
            // close the output file
            DefaultImpl1.GXLOutputAPI.closeOutputFile();
            
        }
        catch (java.net.MalformedURLException mfue) {}
    }
} // public class Demo2 extends Object