/*
 * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.rowset.internal;

import com.sun.rowset.JdbcRowSetResourceBundle;
import java.sql.*;
import javax.sql.*;
import java.io.*;
import java.text.MessageFormat;
import java.util.*;

import javax.sql.rowset.*;
import javax.sql.rowset.spi.*;

/**
 * An implementation of the <code>XmlWriter</code> interface, which writes a
 * <code>WebRowSet</code> object to an output stream as an XML document.
 */

public class WebRowSetXmlWriter implements XmlWriter, Serializable {

    /**
     * The <code>java.io.Writer</code> object to which this <code>WebRowSetXmlWriter</code>
     * object will write when its <code>writeXML</code> method is called. The value
     * for this field is set with the <code>java.io.Writer</code> object given
     * as the second argument to the <code>writeXML</code> method.
     */
    private java.io.Writer writer;

    /**
     * The <code>java.util.Stack</code> object that this <code>WebRowSetXmlWriter</code>
     * object will use for storing the tags to be used for writing the calling
     * <code>WebRowSet</code> object as an XML document.
     */
    private java.util.Stack stack;

    private  JdbcRowSetResourceBundle resBundle;

    public WebRowSetXmlWriter() {

        try {
           resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
        } catch(IOException ioe) {
            throw new RuntimeException(ioe);
        }
    }

    /**
     * Writes the given <code>WebRowSet</code> object as an XML document
     * using the given <code>java.io.Writer</code> object. The XML document
     * will include the <code>WebRowSet</code> object's data, metadata, and
     * properties.  If a data value has been updated, that information is also
     * included.
     * <P>
     * This method is called by the <code>XmlWriter</code> object that is
     * referenced in the calling <code>WebRowSet</code> object's
     * <code>xmlWriter</code> field.  The <code>XmlWriter.writeXML</code>
     * method passes to this method the arguments that were supplied to it.
     *
     * @param caller the <code>WebRowSet</code> object to be written; must
     *        be a rowset for which this <code>WebRowSetXmlWriter</code> object
     *        is the writer
     * @param wrt the <code>java.io.Writer</code> object to which
     *        <code>caller</code> will be written
     * @exception SQLException if a database access error occurs or
     *            this <code>WebRowSetXmlWriter</code> object is not the writer
     *            for the given rowset
     * @see XmlWriter#writeXML
     */
    public void writeXML(WebRowSet caller, java.io.Writer wrt)
    throws SQLException {

        // create a new stack for tag checking.
        stack = new java.util.Stack();
        writer = wrt;
        writeRowSet(caller);
    }

    /**
     * Writes the given <code>WebRowSet</code> object as an XML document
     * using the given <code>java.io.OutputStream</code> object. The XML document
     * will include the <code>WebRowSet</code> object's data, metadata, and
     * properties.  If a data value has been updated, that information is also
     * included.
     * <P>
     * Using stream is a faster way than using <code>java.io.Writer<code/>
     *
     * This method is called by the <code>XmlWriter</code> object that is
     * referenced in the calling <code>WebRowSet</code> object's
     * <code>xmlWriter</code> field.  The <code>XmlWriter.writeXML</code>
     * method passes to this method the arguments that were supplied to it.
     *
     * @param caller the <code>WebRowSet</code> object to be written; must
     *        be a rowset for which this <code>WebRowSetXmlWriter</code> object
     *        is the writer
     * @param oStream the <code>java.io.OutputStream</code> object to which
     *        <code>caller</code> will be written
     * @throws SQLException if a database access error occurs or
     *            this <code>WebRowSetXmlWriter</code> object is not the writer
     *            for the given rowset
     * @see XmlWriter#writeXML
     */
    public void writeXML(WebRowSet caller, java.io.OutputStream oStream)
    throws SQLException {

        // create a new stack for tag checking.
        stack = new java.util.Stack();
        writer = new OutputStreamWriter(oStream);
        writeRowSet(caller);
    }

    /**
     *
     *
     * @exception SQLException if a database access error occurs
     */
    private void writeRowSet(WebRowSet caller) throws SQLException {

        try {

            startHeader();

            writeProperties(caller);
            writeMetaData(caller);
            writeData(caller);

            endHeader();

        } catch (java.io.IOException ex) {
            throw new SQLException(MessageFormat.format(resBundle.handleGetObject("wrsxmlwriter.ioex").toString(), ex.getMessage()));
        }
    }

    private void startHeader() throws java.io.IOException {

        setTag("webRowSet");
        writer.write("<?xml version=\"1.0\"?>\n");
        writer.write("<webRowSet xmlns=\"http://java.sun.com/xml/ns/jdbc\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
        writer.write("xsi:schemaLocation=\"http://java.sun.com/xml/ns/jdbc http://java.sun.com/xml/ns/jdbc/webrowset.xsd\">\n");
    }

    private void endHeader() throws java.io.IOException {
        endTag("webRowSet");
    }

    /**
     *
     *
     * @exception SQLException if a database access error occurs
     */
    private void writeProperties(WebRowSet caller) throws java.io.IOException {

        beginSection("properties");

        try {
            propString("command", processSpecialCharacters(caller.getCommand()));
            propInteger("concurrency", caller.getConcurrency());
            propString("datasource", caller.getDataSourceName());
            propBoolean("escape-processing",
                    caller.getEscapeProcessing());

            try {
                propInteger("fetch-direction", caller.getFetchDirection());
            } catch(SQLException sqle) {
                // it may be the case that fetch direction has not been set
                // fetchDir  == 0
                // in that case it will throw a SQLException.
                // To avoid that catch it here
            }

            propInteger("fetch-size", caller.getFetchSize());
            propInteger("isolation-level",
                    caller.getTransactionIsolation());

            beginSection("key-columns");

            int[] kc = caller.getKeyColumns();
            for (int i = 0; kc != null && i < kc.length; i++)
                propInteger("column", kc[i]);

            endSection("key-columns");

            //Changed to beginSection and endSection for maps for proper indentation
            beginSection("map");
            java.util.Map typeMap = caller.getTypeMap();
            if (typeMap != null) {
                Iterator i = typeMap.keySet().iterator();
                Class c;
                String type;
                while (i.hasNext()) {
                    type = (String)i.next();
                    c = (Class)typeMap.get(type);
                    propString("type", type);
                    propString("class", c.getName());
                }
            }
            endSection("map");

            propInteger("max-field-size", caller.getMaxFieldSize());
            propInteger("max-rows", caller.getMaxRows());
            propInteger("query-timeout", caller.getQueryTimeout());
            propBoolean("read-only", caller.isReadOnly());

            int itype = caller.getType();
            String strType = "";

            if(itype == 1003) {
                strType = "ResultSet.TYPE_FORWARD_ONLY";
            } else if(itype == 1004) {
                strType = "ResultSet.TYPE_SCROLL_INSENSITIVE";
            } else if(itype == 1005) {
                strType = "ResultSet.TYPE_SCROLL_SENSITIVE";
            }

            propString("rowset-type", strType);

            propBoolean("show-deleted", caller.getShowDeleted());
            propString("table-name", caller.getTableName());
            propString("url", caller.getUrl());

            beginSection("sync-provider");
            // Remove the string after "@xxxx"
            // before writing it to the xml file.
            String strProviderInstance = (caller.getSyncProvider()).toString();
            String strProvider = strProviderInstance.substring(0, (caller.getSyncProvider()).toString().indexOf("@"));

            propString("sync-provider-name", strProvider);
            propString("sync-provider-vendor", "Sun Microsystems Inc.");
            propString("sync-provider-version", "1.0");
            propInteger("sync-provider-grade", caller.getSyncProvider().getProviderGrade());
            propInteger("data-source-lock", caller.getSyncProvider().getDataSourceLock());

            endSection("sync-provider");

        } catch (SQLException ex) {
            throw new java.io.IOException(MessageFormat.format(resBundle.handleGetObject("wrsxmlwriter.sqlex").toString(), ex.getMessage()));
        }

        endSection("properties");
    }

    /**
     *
     *
     * @exception SQLException if a database access error occurs
     */
    private void writeMetaData(WebRowSet caller) throws java.io.IOException {
        int columnCount;

        beginSection("metadata");

        try {

            ResultSetMetaData rsmd = caller.getMetaData();
            columnCount = rsmd.getColumnCount();
            propInteger("column-count", columnCount);

            for (int colIndex = 1; colIndex <= columnCount; colIndex++) {
                beginSection("column-definition");

                propInteger("column-index", colIndex);
                propBoolean("auto-increment", rsmd.isAutoIncrement(colIndex));
                propBoolean("case-sensitive", rsmd.isCaseSensitive(colIndex));
                propBoolean("currency", rsmd.isCurrency(colIndex));
                propInteger("nullable", rsmd.isNullable(colIndex));
                propBoolean("signed", rsmd.isSigned(colIndex));
                propBoolean("searchable", rsmd.isSearchable(colIndex));
                propInteger("column-display-size",rsmd.getColumnDisplaySize(colIndex));
                propString("column-label", rsmd.getColumnLabel(colIndex));
                propString("column-name", rsmd.getColumnName(colIndex));
                propString("schema-name", rsmd.getSchemaName(colIndex));
                propInteger("column-precision", rsmd.getPrecision(colIndex));
                propInteger("column-scale", rsmd.getScale(colIndex));
                propString("table-name", rsmd.getTableName(colIndex));
                propString("catalog-name", rsmd.getCatalogName(colIndex));
                propInteger("column-type", rsmd.getColumnType(colIndex));
                propString("column-type-name", rsmd.getColumnTypeName(colIndex));

                endSection("column-definition");
            }
        } catch (SQLException ex) {
            throw new java.io.IOException(MessageFormat.format(resBundle.handleGetObject("wrsxmlwriter.sqlex").toString(), ex.getMessage()));
        }

        endSection("metadata");
    }

    /**
     *
     *
     * @exception SQLException if a database access error occurs
     */
    private void writeData(WebRowSet caller) throws java.io.IOException {
        ResultSet rs;

        try {
            ResultSetMetaData rsmd = caller.getMetaData();
            int columnCount = rsmd.getColumnCount();
            int i;

            beginSection("data");

            caller.beforeFirst();
            caller.setShowDeleted(true);
            while (caller.next()) {
                if (caller.rowDeleted() && caller.rowInserted()) {
                    beginSection("modifyRow");
                } else if (caller.rowDeleted()) {
                    beginSection("deleteRow");
                } else if (caller.rowInserted()) {
                    beginSection("insertRow");
                } else {
                    beginSection("currentRow");
                }

                for (i = 1; i <= columnCount; i++) {
                    if (caller.columnUpdated(i)) {
                        rs = caller.getOriginalRow();
                        rs.next();
                        beginTag("columnValue");
                        writeValue(i, (RowSet)rs);
                        endTag("columnValue");
                        beginTag("updateRow");
                        writeValue(i, caller);
                        endTag("updateRow");
                    } else {
                        beginTag("columnValue");
                        writeValue(i, caller);
                        endTag("columnValue");
                    }
                }

                endSection(); // this is unchecked
            }
            endSection("data");
        } catch (SQLException ex) {
            throw new java.io.IOException(MessageFormat.format(resBundle.handleGetObject("wrsxmlwriter.sqlex").toString(), ex.getMessage()));
        }
    }

    private void writeValue(int idx, RowSet caller) throws java.io.IOException {
        try {
            int type = caller.getMetaData().getColumnType(idx);

            switch (type) {
                case java.sql.Types.BIT:
                case java.sql.Types.BOOLEAN:
                    boolean b = caller.getBoolean(idx);
                    if (caller.wasNull())
                        writeNull();
                    else
                        writeBoolean(b);
                    break;
                case java.sql.Types.TINYINT:
                case java.sql.Types.SMALLINT:
                    short s = caller.getShort(idx);
                    if (caller.wasNull())
                        writeNull();
                    else
                        writeShort(s);
                    break;
                case java.sql.Types.INTEGER:
                    int i = caller.getInt(idx);
                    if (caller.wasNull())
                        writeNull();
                    else
                        writeInteger(caller.getInt(idx));
                    break;
                case java.sql.Types.BIGINT:
                    long l = caller.getLong(idx);
                    if (caller.wasNull())
                        writeNull();
                    else
                        writeLong(l);
                    break;
                case java.sql.Types.REAL:
                case java.sql.Types.FLOAT:
                    float f = caller.getFloat(idx);
                    if (caller.wasNull())
                        writeNull();
                    else
                        writeFloat(f);
                    break;
                case java.sql.Types.DOUBLE:
                    double d = caller.getDouble(idx);
                    if (caller.wasNull())
                        writeNull();
                    else
                        writeDouble(d);
                    break;
                case java.sql.Types.NUMERIC:
                case java.sql.Types.DECIMAL:
                    writeBigDecimal(caller.getBigDecimal(idx));
                    break;
                case java.sql.Types.BINARY:
                case java.sql.Types.VARBINARY:
                case java.sql.Types.LONGVARBINARY:
                    break;
                case java.sql.Types.DATE:
                    java.sql.Date date = caller.getDate(idx);
                    if (caller.wasNull())
                        writeNull();
                    else
                        writeLong(date.getTime());
                    break;
                case java.sql.Types.TIME:
                    java.sql.Time time = caller.getTime(idx);
                    if (caller.wasNull())
                        writeNull();
                    else
                        writeLong(time.getTime());
                    break;
                case java.sql.Types.TIMESTAMP:
                    java.sql.Timestamp ts = caller.getTimestamp(idx);
                    if (caller.wasNull())
                        writeNull();
                    else
                        writeLong(ts.getTime());
                    break;
                case java.sql.Types.CHAR:
                case java.sql.Types.VARCHAR:
                case java.sql.Types.LONGVARCHAR:
                    writeStringData(caller.getString(idx));
                    break;
                default:
                    System.out.println(resBundle.handleGetObject("wsrxmlwriter.notproper").toString());
                    //Need to take care of BLOB, CLOB, Array, Ref here
            }
        } catch (SQLException ex) {
            throw new java.io.IOException(resBundle.handleGetObject("wrsxmlwriter.failedwrite").toString()+ ex.getMessage());
        }
    }

    /*
     * This begins a new tag with a indent
     *
     */
    private void beginSection(String tag) throws java.io.IOException {
        // store the current tag
        setTag(tag);

        writeIndent(stack.size());

        // write it out
        writer.write("<" + tag + ">\n");
    }

    /*
     * This closes a tag started by beginTag with a indent
     *
     */
    private void endSection(String tag) throws java.io.IOException {
        writeIndent(stack.size());

        String beginTag = getTag();

        if(beginTag.indexOf("webRowSet") != -1) {
            beginTag ="webRowSet";
        }

        if (tag.equals(beginTag) ) {
            // get the current tag and write it out
            writer.write("</" + beginTag + ">\n");
        } else {
            ;
        }
        writer.flush();
    }

    private void endSection() throws java.io.IOException {
        writeIndent(stack.size());

        // get the current tag and write it out
        String beginTag = getTag();
        writer.write("</" + beginTag + ">\n");

        writer.flush();
    }

    private void beginTag(String tag) throws java.io.IOException {
        // store the current tag
        setTag(tag);

        writeIndent(stack.size());

        // write tag out
        writer.write("<" + tag + ">");
    }

    private void endTag(String tag) throws java.io.IOException {
        String beginTag = getTag();
        if (tag.equals(beginTag)) {
            // get the current tag and write it out
            writer.write("</" + beginTag + ">\n");
        } else {
            ;
        }
        writer.flush();
    }

    private void emptyTag(String tag) throws java.io.IOException {
        // write an emptyTag
        writer.write("<" + tag + "/>");
    }

    private void setTag(String tag) {
        // add the tag to stack
        stack.push(tag);
    }

    private String getTag() {
        return (String)stack.pop();
    }

    private void writeNull() throws java.io.IOException {
        emptyTag("null");
    }

    private void writeStringData(String s) throws java.io.IOException {
        if (s == null) {
            writeNull();
        } else if (s.equals("")) {
            writeEmptyString();
        } else {

            s = processSpecialCharacters(s);

            writer.write(s);
        }
    }

    private void writeString(String s) throws java.io.IOException {
        if (s != null) {
            writer.write(s);
        } else  {
            writeNull();
        }
    }


    private void writeShort(short s) throws java.io.IOException {
        writer.write(Short.toString(s));
    }

    private void writeLong(long l) throws java.io.IOException {
        writer.write(Long.toString(l));
    }

    private void writeInteger(int i) throws java.io.IOException {
        writer.write(Integer.toString(i));
    }

    private void writeBoolean(boolean b) throws java.io.IOException {
        writer.write(new Boolean(b).toString());
    }

    private void writeFloat(float f) throws java.io.IOException {
        writer.write(Float.toString(f));
    }

    private void writeDouble(double d) throws java.io.IOException {
        writer.write(Double.toString(d));
    }

    private void writeBigDecimal(java.math.BigDecimal bd) throws java.io.IOException {
        if (bd != null)
            writer.write(bd.toString());
        else
            emptyTag("null");
    }

    private void writeIndent(int tabs) throws java.io.IOException {
        // indent...
        for (int i = 1; i < tabs; i++) {
            writer.write("  ");
        }
    }

    private void propString(String tag, String s) throws java.io.IOException {
        beginTag(tag);
        writeString(s);
        endTag(tag);
    }

    private void propInteger(String tag, int i) throws java.io.IOException {
        beginTag(tag);
        writeInteger(i);
        endTag(tag);
    }

    private void propBoolean(String tag, boolean b) throws java.io.IOException {
        beginTag(tag);
        writeBoolean(b);
        endTag(tag);
    }

    private void writeEmptyString() throws java.io.IOException {
        emptyTag("emptyString");
    }
    /**
     * Purely for code coverage purposes..
     */
    public boolean writeData(RowSetInternal caller) {
        return false;
    }


    /**
     * This function has been added for the processing of special characters
     * lik <,>,'," and & in the data to be serialized. These have to be taken
     * of specifically or else there will be parsing error while trying to read
     * the contents of the XML file.
     **/

    private String processSpecialCharacters(String s) {

        if(s == null) {
            return null;
        }
        char []charStr = s.toCharArray();
        String specialStr = new String();

        for(int i = 0; i < charStr.length; i++) {
            if(charStr[i] == '&') {
                specialStr = specialStr.concat("&amp;");
            } else if(charStr[i] == '<') {
                specialStr = specialStr.concat("&lt;");
            } else if(charStr[i] == '>') {
                specialStr = specialStr.concat("&gt;");
            } else if(charStr[i] == '\'') {
                specialStr = specialStr.concat("&apos;");
            } else if(charStr[i] == '\"') {
                specialStr = specialStr.concat("&quot;");
            } else {
                specialStr = specialStr.concat(String.valueOf(charStr[i]));
            }
        }

        s = specialStr;
        return s;
    }

}
