 /*
 * Copyright (C) 09-sept.-2003  Jean-Yves Beaujean 
 * This program 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 of the License, or (at your option)
 * any later version.
 * This program 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 program; if not, write to the Free Software Foundation, Inc.,  59
 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * 
 */
package jxtray.dump;



import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Connection;
import java.util.Date;

import jxtray.Jxtray;
import java.io.FileWriter;

import org.jdom.output.*;
import org.jdom.*;

import jxtray.util.TimeUtilities;

import jxtray.io.WriterContext;

/** This class dump data in XML format.
 *  
 */ 
public class JxtXMLDumpStrategy extends JxtDumpStrategy
{
	private FileWriter _xsdoutput = null;
	private FileWriter _xoutput = null;
	
	private static String XML_HEAD ="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
	private static String XSD_HEAD ="<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchemas\">\n";

	
	public JxtXMLDumpStrategy(String filename,DumperListener listener,Connection connection,String lib, String table,WriterContext writer)
	{
		super(filename,listener,connection,lib,table,writer);
	}
	
	public void run()
	{
		_finished=false;
		try
		{
			_xoutput = new FileWriter(_filename); 
			_xsdoutput = new FileWriter(_filename.substring(0,_filename.indexOf(".xml"))+".xsd");
			_xsdoutput.write(XSD_HEAD);
			double t = System.currentTimeMillis();
			dumpStructure();
			dumpData();
			double diff = System.currentTimeMillis()-t;
			_listener.dumpLog("\n"+Jxtray.getLang("dump.operation_time")+ TimeUtilities.smartTime(diff/1000) );
			_xoutput.close();
			_xsdoutput.close();
		}
		catch ( Exception e )
		{
			_listener.dumpError(e.getMessage());
		}
		catch ( Error e )
		{
			_listener.dumpError(e.getMessage());
		}		
		_listener.dumpEnded();
		_finished=true;
		_thread=null;
	}
	
	public String getName() { return "XML Dumper";}
		
		

	protected void dumpData()
	{
		
		Element root = new Element(_lib+"."+_table);
		Document doconnection = new Document(root);

		Element element = null;
		Element subelement = null;
		
		
		StringBuffer query = new StringBuffer();
		try
		{
			if ( _connection.getMetaData().supportsCatalogsInDataManipulation() || _connection.getMetaData().supportsSchemasInDataManipulation() )
				query.append("select * from ").append(_lib).append(".").append(_table);
			else
				query.append("select * from ").append(_table);		

			_listener.dumpLog("\n"+Jxtray.getLang("dump.execute_query")+query);
			_listener.dumpState(Jxtray.getLang("dump.select_datas"));
			Statement stmt = _connection.createStatement();
			ResultSet res = stmt.executeQuery(query.toString());
			ResultSetMetaData rmtd =  res.getMetaData();

			StringBuffer record = null;
			while ( res.next())
			{
				_cpt++; 
				_listener.dumpNextRecord(_cpt);	
				element = new Element(_table+"Record");
				
				for ( int i = 0 ; i < rmtd.getColumnCount();i++)
				{
					subelement = new Element(rmtd.getColumnName(i+1));
					subelement.addContent(res.getString(i+1));
					element.addContent(subelement);
				}
				
				root.addContent(element);
				
			}
			XMLOutputter outputter = new XMLOutputter();
			try
			{
				outputter.output(doconnection, _xoutput);
			}
			catch( Exception e )
			{
				_listener.dumpError(e.getMessage());
			}
			
			res.close();
			stmt.close();

		}
		catch ( Exception e )
		{
			_listener.dumpError(e.getMessage());
		}
		catch ( Error e )
		{
			_listener.dumpError(e.getMessage());
		}	
		
		_listener.dumpLog("\n"+_cpt+Jxtray.getLang("dump.recordsdumped"));
			
	}
	
	protected void dumpStructure()
	{
		_listener.dumpState(Jxtray.getLang("dump.structure"));
		try
		{
			_xsdoutput.write("<xsd:annotation>\n");
			_xsdoutput.write("<xsd:documentation>\n");
			_xsdoutput.write("date : "+(new Date().toString())+"\n");
			_xsdoutput.write("</xsd:documentation>\n");
			_xsdoutput.write("</xsd:annotation>\n");

			//res1 = connection.getMetaData().getColumns((String) comboCatalog.getSelectedItem(),(String) comboSchema.getSelectedItem(),(String) comboTable.getSelectedItem(),"%");

			java.sql.ResultSet res = _connection.getMetaData().getColumns(_lib,null,_table,"%");
			_xsdoutput.write("<xsd:element name=\""+_table+"Record\" type=\""+_table+"Record\">\n");
			_xsdoutput.write("\t<xsd:complexType name=\""+_table+"Record\">\n");
			_xsdoutput.write("\t\t<xsd:sequence>\n");
			StringBuffer field = null;
			while ( res.next() )
			{
				_xsdoutput.write("\t\t\t<xsd:simpleType name=\""+res.getString(4)+"\" type=\""+res.getString(6)+"\">\n");
			}
			_xsdoutput.write("\t\t</xsd:sequence>\n");
			_xsdoutput.write("\t</xsd:complexType>\n");
			_xsdoutput.write("</xsd:element>\n");
			_xsdoutput.write("</xsd:shema>\n");
			
			res.close();
		}
		catch ( SQLException e )
		{
			_listener.dumpError(e.getMessage());
		}
		catch ( Exception e )
		{
			_listener.dumpError(e.getMessage());
		}
		
	}	
}
