/*
 * Copyright (c) 1998, 2004, 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.
 *
 * 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.
 */

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.InvocationTargetException;
import java.security.*;

public class XObjectOutputStream extends AbstractObjectOutputStream {
    XObjectOutputStream(OutputStream out) throws IOException {
        super(out);
    }

    protected boolean enableReplaceObject(boolean enable)
    {
        throw new Error("not implemented");
    }

    protected void annotateClass(Class<?> cl) throws IOException {
    }

    public void close() throws IOException{
        out.close();
    }

    protected Object replaceObject(Object obj) throws IOException {
        return obj;
    }

    protected void writeStreamHeader() throws IOException {
        super.writeStreamHeader();
    }

    final protected void writeObjectOverride(Object obj) throws IOException {
        Object prevCurrentObject = currentObject;
        currentObject = obj;
        System.out.println("writeObjectOverride(" + obj.toString() + ")");
        try {
        //     ** Preserving reference semantics.
        //     if (obj already serialized) {
        //       look up streamId for obj and write it into 'this' stream.
        //       return;
        //     }
        //
        //     if (obj instanceof Class) {
        //       //Special processing for classes.
        //       //Might need to call this.annotateClass(obj.getClass())
        //       //someday.
        //       return;
        //     }
        //
        //     **Replacement semantics
        //     Object replacement = obj;
        //     if (enableReplace)
        //       replacement = this.writeReplace(obj);
        //     if (replacement instanceof Replaceable)
        //       replacement = ((Replaceable)replacement).replaceObject(this);
        //     if (obj != replacement) {
        //       //record that all future occurances of obj should be replaced
        //       //with replacement
        //     }
        //
        //     if obj is Externalizeable {
        //      Object[] argList = {this};
        //      invokeMethod(obj, writeExternalMethod, argList);
        //     else

        Method writeObjectMethod = getWriteObjectMethod(obj.getClass());

        if (writeObjectMethod != null) {
            Object[] arglist = {this};
            invokeMethod(obj, writeObjectMethod, arglist);
        } else
            defaultWriteObject();
        } finally {
            currentObject = prevCurrentObject;
        }
    }

    /* Since defaultWriteObject() does not take the object to write as a parameter,
     * implementation is required to store currentObject when writeObject is called.
     */
    public void defaultWriteObject() throws IOException {
        Object obj = currentObject;
        System.out.println("XObjectOutputStream.defaultWriteObject(" +
                            obj.toString() + ")");

        //In order to access package, private and protected fields,
        //one needs to use Priviledged Access and be trusted code.
        //This test will avoid that problem by only serializing public fields.
        Field[] fields = obj.getClass().getFields();
        for (int i= 0; i < fields.length; i++) {
            //Skip non-Serializable fields.
            int mods = fields[i].getModifiers();
            if (Modifier.isStatic(mods) || Modifier.isTransient(mods))
                continue;
            Class FieldType = fields[i].getType();
            if (FieldType.isPrimitive()) {
                System.out.println("Field " + fields[i].getName() +
                                    " has primitive type " + FieldType.toString());
            } else {
                System.out.println("**Field " + fields[i].getName() +
                                   " is an Object of type " + FieldType.toString());
                try {
                    writeObject(fields[i].get(obj));
                    if (FieldType.isArray()) {
                        Object[] array = ((Object[]) fields[i].get(obj));
                        Class componentType = FieldType.getComponentType();
                        if (componentType.isPrimitive())
                            System.out.println("Output " + array.length + " primitive elements of" +
                                               componentType.toString());
                        else {
                            System.out.println("Output " + array.length + " of Object elements of" +
                                               componentType.toString());
                            for (int k = 0; k < array.length; k++) {
                                writeObject(array[k]);
                            }
                        }
                    }
                } catch (IllegalAccessException e) {
                    throw new IOException(e.getMessage());
                }
            }
        }
    }

    public PutField putFields() throws IOException {
        currentPutField = new InternalPutField();
        return currentPutField;
    }

    public void writeFields() throws IOException {
        currentPutField.write(this);
    }

    static final class InternalPutField extends ObjectOutputStream.PutField {
        String fieldName[];
        int    intValue[];
        int next;

        InternalPutField() {
            fieldName = new String[10];
            intValue = new int[10];
            next = 0;
        }
        /**
         * Put the value of the named boolean field into the persistent field.
         */
        public void put(String name, boolean value) {
        }

        /**
         * Put the value of the named char field into the persistent fields.
         */
        public void put(String name, char value) {
        }

        /**
         * Put the value of the named byte field into the persistent fields.
         */
        public void put(String name, byte value) {
        }

        /**
         * Put the value of the named short field into the persistent fields.
         */
        public void put(String name, short value) {
        }

        /**
         * Put the value of the named int field into the persistent fields.
         */
        public void put(String name, int value) {
            if (next < fieldName.length) {
                fieldName[next] = name;
                intValue[next] = value;
                next++;
            }
        }

        /**
         * Put the value of the named long field into the persistent fields.
         */
        public void put(String name, long value) {
        }

        /**
         * Put the value of the named float field into the persistent fields.
         */
        public void put(String name, float value) {
        }

        /**
         * Put the value of the named double field into the persistent field.
         */
        public void put(String name, double value) {
        }

        /**
         * Put the value of the named Object field into the persistent field.
         */
        public void put(String name, Object value) {
        }

        /**
         * Write the data and fields to the specified ObjectOutput stream.
         */
        public void write(ObjectOutput out) throws IOException {
            for (int i = 0; i < next; i++)
                System.out.println(fieldName[i] + "=" + intValue[i]);
        }
    };


    /**
     * Writes a byte. This method will block until the byte is actually
     * written.
     * @param b the byte
     * @exception IOException If an I/O error has occurred.
     * @since     JDK1.1
     */
    public void write(int data) throws IOException {
    }

    /**
     * Writes an array of bytes. This method will block until the bytes
     * are actually written.
     * @param b the data to be written
     * @exception IOException If an I/O error has occurred.
     * @since     JDK1.1
     */
    public void write(byte b[]) throws IOException {
    }

    /**
     * Writes a sub array of bytes.
     * @param b the data to be written
     * @param off       the start offset in the data
     * @param len       the number of bytes that are written
     * @exception IOException If an I/O error has occurred.
     * @since     JDK1.1
     */
    public void write(byte b[], int off, int len) throws IOException {
    }

    public void writeBoolean(boolean data) throws IOException {
    }

    public void writeByte(int data) throws IOException {
    }

    public void writeShort(int data)  throws IOException {
    }

    public void writeChar(int data)  throws IOException {
    }
    public void writeInt(int data)  throws IOException{}
    public void writeLong(long data)  throws IOException{}
    public void writeFloat(float data) throws IOException{}
    public void writeDouble(double data) throws IOException{}
    public void writeBytes(String data) throws IOException{}
    public void writeChars(String data) throws IOException{}
    public void writeUTF(String data) throws IOException{}
    public void reset() throws IOException {}
    public void available() throws IOException {}
    public void drain() throws IOException {}

    private Object currentObject = null;
    private InternalPutField currentPutField;


    /********************************************************************/

    /* CODE LIFTED FROM ObjectStreamClass constuctor.
     * ObjectStreamClass.writeObjectMethod is private.
     *
     * Look for the writeObject method
     * Set the accessible flag on it here.
     * Subclass of AbstractObjectOutputStream will call it as necessary.
     */
    static public Method getWriteObjectMethod(final Class cl) {

        Method writeObjectMethod = (Method)
            java.security.AccessController.doPrivileged
            (new java.security.PrivilegedAction() {
                public Object run() {
                    Method m = null;
                    try {
                        Class[] args = {ObjectOutputStream.class};
                        m = cl.getDeclaredMethod("writeObject", args);
                        int mods = m.getModifiers();
                        // Method must be private and non-static
                        if (!Modifier.isPrivate(mods) ||
                            Modifier.isStatic(mods)) {
                            m = null;
                        } else {
                            m.setAccessible(true);
                        }
                    } catch (NoSuchMethodException e) {
                        m = null;
                    }
                    return m;
                }
            });
        return writeObjectMethod;
    }

    /*************************************************************/

    /* CODE LIFTED FROM ObjectOutputStream. */
    static private void invokeMethod(final Object obj, final Method m,
                                        final Object[] argList)
        throws IOException
    {
        try {
            java.security.AccessController.doPrivileged
                (new java.security.PrivilegedExceptionAction() {
                    public Object run() throws InvocationTargetException,
                                        java.lang.IllegalAccessException {
                        m.invoke(obj, argList);
                        return null;
                    }
                });
        } catch (java.security.PrivilegedActionException e) {
            Exception ex = e.getException();
            if (ex instanceof InvocationTargetException) {
                Throwable t =
                        ((InvocationTargetException)ex).getTargetException();
                if (t instanceof IOException)
                    throw (IOException)t;
                else if (t instanceof RuntimeException)
                    throw (RuntimeException) t;
                else if (t instanceof Error)
                    throw (Error) t;
                else
                    throw new Error("interal error");
            } else {
                // IllegalAccessException cannot happen
            }
        }
    }
};
