Package org.apache.geronimo.interop.rmi.iiop

Source Code of org.apache.geronimo.interop.rmi.iiop.PutField

/**
*
*  Copyright 2004-2005 The Apache Software Foundation
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package org.apache.geronimo.interop.rmi.iiop;

import java.io.IOException;
import java.io.ObjectOutput;
import java.io.ObjectStreamClass;
import java.io.ObjectStreamField;
import java.lang.reflect.Method;

/**
** An implementation of java.io.ObjectOutputStream.PutField
** Provide programatic access to the persistent fields to be written
** to ObjectOutput.
**/

public class PutField extends java.io.ObjectOutputStream.PutField
{
    /** class descriptor describing serializable fields */
    private final ObjectStreamClass desc;
    /** primitive field values */
    private final byte[] primVals;
    /** object field values */
    private final Object[] objVals;

    private int primDataSize = 0;
    private int numObjFields = 0;
    private ObjectStreamField[] _fields = null;

    private static Method setOffsetMethod;

    static
    {
        try
        {
            Class osFieldClass = java.io.ObjectStreamField.class;
            Class[] params = new Class[1];
            params[0] = int.class;
            setOffsetMethod = osFieldClass.getDeclaredMethod("setOffset", params);
            setOffsetMethod.setAccessible(true);
        }
        catch (Throwable t)
        {
            t.printStackTrace();
        }
    }

    /**
     * Creates PutField object for writing fields defined in given
     * class descriptor.
     */
    PutField(ObjectStreamClass desc)
    {
        this.desc = desc;
        computeOffsets();
        primVals = new byte[primDataSize];
        objVals = new Object[numObjFields];
    }

    /**
     * Put the value of the named boolean field into the persistent field.
     *
     * @param  name the name of the serializable field
     * @param  val the value to assign to the field
     */
    public void put(String name, boolean val)
    {
        Bits.putBoolean(primVals, getFieldOffset(name, Boolean.TYPE), val);
    }

    /**
     * Put the value of the named byte field into the persistent field.
     *
     * @param  name the name of the serializable field
     * @param  val the value to assign to the field
     */
    public void put(String name, byte val)
    {
        primVals[getFieldOffset(name, Byte.TYPE)] = val;
    }

    /**
     * Put the value of the named char field into the persistent field.
     *
     * @param  name the name of the serializable field
     * @param  val the value to assign to the field
     */
    public void put(String name, char val)
    {
        Bits.putChar(primVals, getFieldOffset(name, Character.TYPE), val);
    }

    /**
     * Put the value of the named short field into the persistent field.
     *
     * @param  name the name of the serializable field
     * @param  val the value to assign to the field
     */
    public void put(String name, short val)
    {
        Bits.putShort(primVals, getFieldOffset(name, Short.TYPE), val);
    }

    /**
     * Put the value of the named int field into the persistent field.
     *
     * @param  name the name of the serializable field
     * @param  val the value to assign to the field
     */
    public void put(String name, int val)
    {
        Bits.putInt(primVals, getFieldOffset(name, Integer.TYPE), val);
    }

    /**
     * Put the value of the named long field into the persistent field.
     *
     * @param  name the name of the serializable field
     * @param  val the value to assign to the field
     */
    public void put(String name, long val)
    {
        Bits.putLong(primVals, getFieldOffset(name, Long.TYPE), val);
    }

    /**
     * Put the value of the named float field into the persistent field.
     *
     * @param  name the name of the serializable field
     * @param  val the value to assign to the field
     */
    public void put(String name, float val)
    {
        Bits.putFloat(primVals, getFieldOffset(name, Float.TYPE), val);
    }

    /**
     * Put the value of the named double field into the persistent field.
     *
     * @param  name the name of the serializable field
     * @param  val the value to assign to the field
     */
    public void put(String name, double val)
    {
        Bits.putDouble(primVals, getFieldOffset(name, Double.TYPE), val);
    }

    /**
     * Put the value of the named Object field into the persistent field.
     *
     * @param  name the name of the serializable field
     * @param  val the value to assign to the field
     */
    public void put(String name, Object val)
    {
        objVals[getFieldOffset(name, Object.class)] = val;
    }

    /**
     * Write the data and fields to the specified ObjectOutput stream.
     *
     * @param  out the stream to write the data and fields to
     * @throws IOException if I/O errors occur while writing to the
     *        underlying stream
     * @deprecated This method does not write the values contained by this
     *        <code>PutField</code> object in a proper format, and may
     *        result in corruption of the serialization stream.  The
     *        correct way to write <code>PutField</code> data is by
     *        calling the {@link java.io.ObjectOutputStream#writeFields()}
     *        method.
     */
    public void write(ObjectOutput out) throws IOException
    {
        /*
         * Applications should *not* use this method to write PutField
         * data, as it will lead to stream corruption if the PutField
         * object writes any primitive data (since block data mode is not
         * unset/set properly, as is done in OOS.writeFields()).  This
         * broken implementation is being retained solely for behavioral
         * compatibility, in order to support applications which use
         * OOS.PutField.write() for writing only non-primitive data.
         *
         * Serialization of unshared objects is not implemented here since
         * it is not necessary for backwards compatibility; also, unshared
         * semantics may not be supported by the given ObjectOutput
         * instance.  Applications which write unshared objects using the
         * PutField API must use OOS.writeFields().
         */
        throw new IOException("PutField.write(ObjectOutput) - not supported for RMI/IIOP");
    }

    /**
     * Writes buffered primitive data and object fields to stream.
     */
    void writeFields(ObjectOutputStream o) throws IOException
    {
        org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream out = (org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream)o;

        out._cdrOutput.write_align(4, 4); // write any necessary padding

        //Write out the primitive values first
        for(int i = 0; i < primVals.length; i++)
        {
            out.writeByte(primVals[i]);
        }

        //Write out the object fields
        java.io.ObjectStreamField[] fields = desc.getFields();
        int numPrimFields = fields.length - objVals.length;
        for (int i = 0; i < objVals.length; i++)
        {
            out.writeObject(ValueType.getInstance(objVals[i].getClass()), objVals[i]);
        }
    }

    /**
     * Returns offset of field with given name and type.  A specified type
     * of null matches all types, Object.class matches all non-primitive
     * types, and any other non-null type matches assignable types only.
     * Throws IllegalArgumentException if no matching field found.
     */
    private int getFieldOffset(String name, Class type)
    {
        ObjectStreamField field = getField(name, type);
        if (field == null)
        {
            throw new IllegalArgumentException("no such field");
        }
        return field.getOffset();
    }

    private ObjectStreamField getField(String name, Class type)
    {
        if(type == null)
        {
            //Return match by name
            for(int i = 0; i < _fields.length; i++)
            {
                if(_fields[i].getName().equals(name))
                {
                    return _fields[i];
                }
            }
            return (ObjectStreamField)null;
        }
        else if(type == java.lang.Object.class)
        {
            //Return match for name, and any non-primitive type
            for(int i = 0; i < _fields.length; i++)
            {
                if(_fields[i].getName().equals(name) && !_fields[i].getType().isPrimitive())
                {
                    return _fields[i];
                }
            }
            return (ObjectStreamField)null;
        }
        else
        {
            for(int i = 0; i < _fields.length; i++)
            {
                if(_fields[i].getName().equals(name) && _fields[i].getType().equals(type))
                {
                    return _fields[i];
                }
            }
            return (ObjectStreamField)null;
        }
    }

    private void computeOffsets()
    {
        try
        {
            computeFieldOffsets();
        }
        catch(Exception e)
        {
            throw new RuntimeException(org.apache.geronimo.interop.util.ExceptionUtil.causedBy(e));
        }
    }

    private void computeFieldOffsets() throws Exception
    {
        primDataSize = 0;
        numObjFields = 0;
        int firstObjIndex = -1;
        java.io.ObjectStreamField[] fields = desc.getFields();
        _fields = new ObjectStreamField[fields.length];
        Object[] args = new Object[1];

        for (int i = 0; i < fields.length; i++)
        {
            java.io.ObjectStreamField f = fields[i];
            _fields[i] = new ObjectStreamField(fields[i].getName(), fields[i].getType());
            ObjectStreamField _f = _fields[i];

            switch (f.getTypeCode())
            {
                case 'Z':
                case 'B':
                    args[0] = new Integer(primDataSize++);
                    setOffsetMethod.invoke(_f, args);
                    break;

                case 'C':
                case 'S':
                    args[0] = new Integer(primDataSize);
                    setOffsetMethod.invoke(_f, args);
                    primDataSize += 2;
                    break;

                case 'I':
                case 'F':
                    args[0] = new Integer(primDataSize);
                    setOffsetMethod.invoke(_f, args);
                    primDataSize += 4;
                    break;

                case 'J':
                case 'D':
                    args[0] = new Integer(primDataSize);
                    setOffsetMethod.invoke(_f, args);
                    primDataSize += 8;
                    break;

                case '[':
                case 'L':
                    args[0] = new Integer(numObjFields++);
                    setOffsetMethod.invoke(_f, args);
                    if (firstObjIndex == -1)
                    {
                        firstObjIndex = i;
                    }
                    break;

                default:
                    break;
            }
        }
        if (firstObjIndex != -1 && firstObjIndex + numObjFields != fields.length)
        {
            //throw new InvalidClassException(name, "illegal field order");
        }
    }

}
TOP

Related Classes of org.apache.geronimo.interop.rmi.iiop.PutField

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.