FileDocCategorySizeDatePackage
ValueHandlerImpl.javaAPI DocJava SE 5 API31291Fri Aug 26 14:54:22 BST 2005com.sun.corba.se.impl.io

ValueHandlerImpl

public class ValueHandlerImpl extends Object implements javax.rmi.CORBA.ValueHandlerMultiFormat

Fields Summary
public static final String
FORMAT_VERSION_PROPERTY
private static final byte
MAX_SUPPORTED_FORMAT_VERSION
private static final byte
STREAM_FORMAT_VERSION_1
private static final byte
MAX_STREAM_FORMAT_VERSION
public static final short
kRemoteType
public static final short
kAbstractType
public static final short
kValueType
private Hashtable
inputStreamPairs
private Hashtable
outputStreamPairs
private com.sun.org.omg.SendingContext.CodeBase
codeBase
private boolean
useHashtables
private boolean
isInputStream
private com.sun.corba.se.impl.io.IIOPOutputStream
outputStreamBridge
private com.sun.corba.se.impl.io.IIOPInputStream
inputStreamBridge
private com.sun.corba.se.impl.logging.OMGSystemException
omgWrapper
private com.sun.corba.se.impl.logging.UtilSystemException
utilWrapper
Constructors Summary
public ValueHandlerImpl()

public ValueHandlerImpl(boolean isInputStream)

	this();
	useHashtables = false;
	this.isInputStream = isInputStream;
    
Methods Summary
public java.lang.StringcreateForAnyType(java.lang.Class cl)

        return RepositoryId.createForAnyType(cl);
     
private com.sun.corba.se.impl.io.IIOPInputStreamcreateInputStream()

        return (com.sun.corba.se.impl.io.IIOPInputStream)AccessController.doPrivileged(
	    new StreamFactory(getInputStreamClassName()));
    
private com.sun.corba.se.impl.io.IIOPOutputStreamcreateOutputStream()

        return (com.sun.corba.se.impl.io.IIOPOutputStream)AccessController.doPrivileged(
	    new StreamFactory(getOutputStreamClassName()));
    
public java.lang.ClassgetAnyClassFromType(java.lang.String id)

        RepositoryId repId = RepositoryId.cache.getId(id);
        return repId.getAnyClassFromType();
     
public java.lang.ClassgetClassFromType(java.lang.String id)

        RepositoryId repId = RepositoryId.cache.getId(id);
        return repId.getClassFromType();
     
public java.lang.StringgetClassName(java.lang.String id)

        RepositoryId repID = RepositoryId.cache.getId(id);
        return repID.getClassName();
     
public java.lang.StringgetDefinedInId(java.lang.String id)

        RepositoryId repId = RepositoryId.cache.getId(id);
        return repId.getDefinedInId();
     
protected java.lang.StringgetInputStreamClassName()

        return "com.sun.corba.se.impl.io.IIOPInputStream";
    
protected org.omg.CORBA.TCKindgetJavaCharTCKind()
Our JDK 1.3 and JDK 1.3.1 behavior subclasses override this. The correct behavior is for a Java char to map to a CORBA wchar, but our older code mapped it to a CORBA char.

        return TCKind.tk_wchar;
    
private static bytegetMaxStreamFormatVersion()


     
        MAX_STREAM_FORMAT_VERSION = getMaxStreamFormatVersion();
    

        try {

            String propValue = (String) AccessController.doPrivileged(
                                        new PrivilegedAction() {
		public java.lang.Object run() {
	            return System.getProperty(ValueHandlerImpl.FORMAT_VERSION_PROPERTY);
	        }
            });

            // The property wasn't set
            if (propValue == null)
                return MAX_SUPPORTED_FORMAT_VERSION;

            byte result = Byte.parseByte(propValue);

            // REVISIT.  Just set to MAX_SUPPORTED_FORMAT_VERSION
            // or really let the system shutdown with this Error?
            if (result < 1 || result > MAX_SUPPORTED_FORMAT_VERSION)
		// XXX I18N, logging needed.
                throw new ExceptionInInitializerError("Invalid stream format version: "
                                                      + result
                                                      + ".  Valid range is 1 through "
                                                      + MAX_SUPPORTED_FORMAT_VERSION);

            return result;

        } catch (Exception ex) {
            // REVISIT.  Swallow this or really let
            // the system shutdown with this Error?

            Error err = new ExceptionInInitializerError(ex);
	    err.initCause( ex ) ;
	    throw err ;
        }
    
public bytegetMaximumStreamFormatVersion()


    // See javax.rmi.CORBA.ValueHandlerMultiFormat
       
        return MAX_STREAM_FORMAT_VERSION;
    
protected java.lang.StringgetOutputStreamClassName()

        return "com.sun.corba.se.impl.io.IIOPOutputStream";
    
public java.lang.StringgetRMIRepositoryID(java.lang.Class clz)
Returns the repository ID for the given RMI value Class.

param
clz The class to return a repository ID for.
return
the repository ID of the Class.

	return RepositoryId.createForJavaType(clz);
    
public org.omg.SendingContext.RunTimegetRunTimeCodeBase()
Returns the CodeBase for this ValueHandler. This is used by the ORB runtime. The server sends the service context containing the IOR for this CodeBase on the first GIOP reply. The clients do the same on the first GIOP request.

return
the SendingContext.CodeBase of this ValueHandler.

	if (codeBase != null)
	    return codeBase;
	else {
	    codeBase = new FVDCodeBaseImpl();

	    // backward compatability 4365188
            // set the valueHandler so that correct/incorrect RepositoryID
            // calculations can be done based on the ORB version
            FVDCodeBaseImpl fvdImpl = (FVDCodeBaseImpl) codeBase;
            fvdImpl.setValueHandler(this);
	    return codeBase;
	}
    
public java.lang.StringgetSerialVersionUID(java.lang.String id)

        RepositoryId repId = RepositoryId.cache.getId(id);
        return repId.getSerialVersionUID();
     
public java.lang.StringgetUnqualifiedName(java.lang.String id)

        RepositoryId repId = RepositoryId.cache.getId(id);
        return repId.getUnqualifiedName();
     
public booleanisAbstractBase(java.lang.Class clazz)

        return RepositoryId.isAbstractBase(clazz);
     
private booleanisArray(java.lang.String repId)

	return RepositoryId.cache.getId(repId).isSequence();
    
public booleanisCustomMarshaled(java.lang.Class clz)
Indicates whether the given Class performs custom or default marshaling.

param
clz The class to test for custom marshaling.
return
True if the class performs custom marshaling, false if it does not.

	return ObjectStreamClass.lookup(clz).isCustomMarshaled();
    
public booleanisSequence(java.lang.String id)

        RepositoryId repId = RepositoryId.cache.getId(id);
        return repId.isSequence();
     
protected voidreadCharArray(org.omg.CORBA_2_3.portable.InputStream in, char[] array, int offset, int length)
Encapsulates reading of Java char arrays so that the 1.3 subclass can override it without exposing internals across packages. This is a fix for bug 4367783.

  
        in.read_wchar_array(array, offset, length);
    
public java.io.SerializablereadValue(org.omg.CORBA.portable.InputStream _in, int offset, java.lang.Class clazz, java.lang.String repositoryID, org.omg.SendingContext.RunTime _sender)
Reads a value from the stream using java semantics.

param
in The stream to read the value from
param
clazz The type of the value to be read in
param
sender The sending context runtime

        // Must use narrow rather than a direct cast to a com.sun
        // class.  Fix for bug 4379539.
	CodeBase sender = CodeBaseHelper.narrow(_sender);

	org.omg.CORBA_2_3.portable.InputStream in = 
	    (org.omg.CORBA_2_3.portable.InputStream) _in;

	if (!useHashtables) {
            if (inputStreamBridge == null) {
                inputStreamBridge = createInputStream();
                inputStreamBridge.setOrbStream(in);
                inputStreamBridge.setSender(sender); //d11638
                // backward compatability 4365188
                inputStreamBridge.setValueHandler(this); 
            }
			
            java.io.Serializable result = null;

            try {

                inputStreamBridge.increaseRecursionDepth();
                result = (java.io.Serializable) readValueInternal(inputStreamBridge, in, offset, clazz, repositoryID, sender);

            } finally {

                if (inputStreamBridge.decreaseRecursionDepth() == 0) {
                    // Indirections are resolved immediately since
                    // the change to the active recursion manager,
                    // so this will never happen.
                }
            }

            return result;
        }
            
        IIOPInputStream jdkToOrbInputStreamBridge = null;
        if (inputStreamPairs == null)
            inputStreamPairs = new Hashtable();
		
        jdkToOrbInputStreamBridge = (IIOPInputStream)inputStreamPairs.get(_in);

        if (jdkToOrbInputStreamBridge == null) {

            jdkToOrbInputStreamBridge = createInputStream();
            jdkToOrbInputStreamBridge.setOrbStream(in);
            jdkToOrbInputStreamBridge.setSender(sender); //d11638
            // backward compatability 4365188
            jdkToOrbInputStreamBridge.setValueHandler(this); 
            inputStreamPairs.put(_in, jdkToOrbInputStreamBridge);
        }

	java.io.Serializable result = null;
		
    	try {
            
	    jdkToOrbInputStreamBridge.increaseRecursionDepth();
	    result = (java.io.Serializable) readValueInternal(jdkToOrbInputStreamBridge, in, offset, clazz, repositoryID, sender);

        } finally {

            if (jdkToOrbInputStreamBridge.decreaseRecursionDepth() == 0) {
                inputStreamPairs.remove(_in);
            }
        }

        return result;
    
private java.io.SerializablereadValueInternal(com.sun.corba.se.impl.io.IIOPInputStream bridge, org.omg.CORBA_2_3.portable.InputStream in, int offset, java.lang.Class clazz, java.lang.String repositoryID, com.sun.org.omg.SendingContext.CodeBase sender)

	java.io.Serializable result = null;
		
	if (clazz == null) {
	    // clazz == null indicates an FVD situation for a nonexistant class
	    if (isArray(repositoryID)){
		read_Array(bridge, in, null, sender, offset);
	    } else {
		bridge.simpleSkipObject(repositoryID, sender);
	    }
	    return result;
	}
		
        if (clazz.isArray()) {
            result = (java.io.Serializable)read_Array(bridge, in, clazz, sender, offset);
        } else {
            result = (java.io.Serializable)bridge.simpleReadObject(clazz, repositoryID, sender, offset);
        }

	return result;
    
private java.lang.Objectread_Array(com.sun.corba.se.impl.io.IIOPInputStream bridge, org.omg.CORBA_2_3.portable.InputStream in, java.lang.Class sequence, com.sun.org.omg.SendingContext.CodeBase sender, int offset)

    	try {
	    // Read length of coming array
            int length = in.read_ulong();
            int i;

	    if (sequence == null) {
		for (i = 0; i < length; i++)
		    in.read_value();

		return null;
	    }
			
	    Class componentType = sequence.getComponentType();
	    Class actualType = componentType;


            if (componentType.isPrimitive()) {
                if (componentType == Integer.TYPE) {
		    int[] array = new int[length];
		    in.read_long_array(array, 0, length);
		    return ((java.io.Serializable)((Object)array));
                } else if (componentType == Byte.TYPE) {
		    byte[] array = new byte[length];
		    in.read_octet_array(array, 0, length);
		    return ((java.io.Serializable)((Object)array));
                } else if (componentType == Long.TYPE) {
		    long[] array = new long[length];
		    in.read_longlong_array(array, 0, length);
		    return ((java.io.Serializable)((Object)array));
                } else if (componentType == Float.TYPE) {
		    float[] array = new float[length];
		    in.read_float_array(array, 0, length);
		    return ((java.io.Serializable)((Object)array));
                } else if (componentType == Double.TYPE) {
		    double[] array = new double[length];
		    in.read_double_array(array, 0, length);
		    return ((java.io.Serializable)((Object)array));
                } else if (componentType == Short.TYPE) {
		    short[] array = new short[length];
		    in.read_short_array(array, 0, length);
		    return ((java.io.Serializable)((Object)array));
                } else if (componentType == Character.TYPE) {
		    char[] array = new char[length];
		    readCharArray(in, array, 0, length);
		    return ((java.io.Serializable)((Object)array));
                } else if (componentType == Boolean.TYPE) {
		    boolean[] array = new boolean[length];
		    in.read_boolean_array(array, 0, length);
		    return ((java.io.Serializable)((Object)array));
                } else {
		    // XXX I18N, logging needed.
		    throw new Error("Invalid primitive componentType : " + sequence.getName());
                }
            } else if (componentType == java.lang.Object.class) {
		Object[] array = (Object[])java.lang.reflect.Array.newInstance(
		    componentType, length);

                // Store this object and its beginning position
                // since there might be indirections to it while
                // it's been unmarshalled.
                bridge.activeRecursionMgr.addObject(offset, array);

                for (i = 0; i < length; i++) {
                    Object objectValue = null;
                    try {
                        objectValue = Util.readAny(in);
                    } catch(IndirectionException cdrie) {
                        try {
                            // The CDR stream had never seen the given offset 
			    // before, so check the recursion manager (it will 
			    // throw an IOException if it doesn't have a 
			    // reference, either).
                            objectValue = bridge.activeRecursionMgr.getObject(
				cdrie.offset);
                        } catch (IOException ie) {
                            // Translate to a MARSHAL exception since
                            // ValueHandlers aren't allowed to throw
                            // IOExceptions
			    throw utilWrapper.invalidIndirection( ie,
				new Integer( cdrie.offset ) ) ;
                        }
                    }
                    
                    array[i] = objectValue;
                }
                return ((java.io.Serializable)((Object)array));
            } else {
		Object[] array = (Object[])java.lang.reflect.Array.newInstance(
		    componentType, length);
                // Store this object and its beginning position
                // since there might be indirections to it while
                // it's been unmarshalled.				
                bridge.activeRecursionMgr.addObject(offset, array);

		// Decide what method call to make based on the componentType.
		// If it is a componentType for which we need to load a stub,
		// convert the componentType to the correct stub type.
				
                int callType = kValueType;
                boolean narrow = false;
				
                if (componentType.isInterface()) { 
                    boolean loadStubClass = false;
                    // String className = componentType.getName();
                        
                    if (java.rmi.Remote.class.isAssignableFrom(componentType)) {
						
                        // RMI Object reference...
                        callType = kRemoteType;
                        
                        // for better performance, load the stub class once
                        // instead of for each element of the array
                        loadStubClass = true;
                    } else if (org.omg.CORBA.Object.class.isAssignableFrom(componentType)){
                        // IDL Object reference...
                        callType = kRemoteType;
                        loadStubClass = true;
                    } else if (RepositoryId.isAbstractBase(componentType)) {
                        // IDL Abstract Object reference...
                        callType = kAbstractType;
                        loadStubClass = true;
                    } else if (ObjectStreamClassCorbaExt.isAbstractInterface(componentType)) {
                        
                        // RMI Abstract Object reference...
                        
                        // componentType = null;
                        callType = kAbstractType;
                    }

                    if (loadStubClass) {
                        try {
                            String codebase = Util.getCodebase(componentType);
                            String repID = RepositoryId.createForAnyType(componentType);
                            Class stubType = 
				Utility.loadStubClass(repID, codebase, componentType); 
			    actualType = stubType;
                        } catch (ClassNotFoundException e) {
                            narrow = true;
                        }
                    } else {
                        narrow = true;
                    }
                }

                for (i = 0; i < length; i++) {
                    
                    try {
                        switch (callType) {
                        case kRemoteType: 
                            if (!narrow)
                                array[i] = (Object)in.read_Object(actualType); 
                            else {
                                array[i] = Utility.readObjectAndNarrow(in, actualType);
                                
                            }
                            break;
                        case kAbstractType: 
                            if (!narrow)
                                array[i] = (Object)in.read_abstract_interface(actualType); 
                            else {
                                array[i] = Utility.readAbstractAndNarrow(in, actualType);
                            }
                            break;
                        case kValueType:
                            array[i] = (Object)in.read_value(actualType);
                            break;
                        }
                    } catch(IndirectionException cdrie) {
                        // The CDR stream had never seen the given offset before,
                        // so check the recursion manager (it will throw an
                        // IOException if it doesn't have a reference, either).
                        try {
                            array[i] = bridge.activeRecursionMgr.getObject(
				cdrie.offset);
                        } catch (IOException ioe) {
                            // Translate to a MARSHAL exception since
                            // ValueHandlers aren't allowed to throw
                            // IOExceptions
			    throw utilWrapper.invalidIndirection( ioe,
				new Integer( cdrie.offset ) ) ;
                        }
                    }
                    
                }
                
                return ((java.io.Serializable)((Object)array));
	    }
        } finally {
            // We've completed deserializing this object.  Any
            // future indirections will be handled correctly at the
            // CDR level.  The ActiveRecursionManager only deals with
            // objects currently being deserialized.
            bridge.activeRecursionMgr.removeObject(offset);
        }
    
public booleanuseFullValueDescription(java.lang.Class clazz, java.lang.String repositoryID)
Returns a boolean of whether or not RepositoryId indicates FullValueDescriptor. used for backward compatability

	return RepositoryId.useFullValueDescription(clazz, repositoryID);
     
protected voidwriteCharArray(org.omg.CORBA_2_3.portable.OutputStream out, char[] array, int offset, int length)
Encapsulates writing of Java char arrays so that the 1.3 subclass can override it without exposing internals across packages. This is a fix for bug 4367783.

        out.write_wchar_array(array, offset, length);
    
public java.io.SerializablewriteReplace(java.io.Serializable value)
If the value contains a writeReplace method then the result is returned. Otherwise, the value itself is returned.

return
the true value to marshal on the wire.

	return ObjectStreamClass.lookup(value.getClass()).writeReplace(value);
    
public voidwriteValue(org.omg.CORBA.portable.OutputStream out, java.io.Serializable value, byte streamFormatVersion)


        if (streamFormatVersion == 2) {
            if (!(out instanceof org.omg.CORBA.portable.ValueOutputStream)) {
		throw omgWrapper.notAValueoutputstream() ;
            }
        } else if (streamFormatVersion != 1) {
	    throw omgWrapper.invalidStreamFormatVersion( 
		new Integer(streamFormatVersion) ) ;
        }

        writeValueWithVersion(out, value, streamFormatVersion);
    
public voidwriteValue(org.omg.CORBA.portable.OutputStream _out, java.io.Serializable value)
Writes the value to the stream using java semantics.

param
out The stream to write the value to
param
value The value to be written to the stream

        writeValueWithVersion(_out, value, STREAM_FORMAT_VERSION_1);
    
private voidwriteValueInternal(com.sun.corba.se.impl.io.IIOPOutputStream bridge, org.omg.CORBA_2_3.portable.OutputStream out, java.io.Serializable value, byte streamFormatVersion)

	Class clazz = value.getClass();

        if (clazz.isArray())
            write_Array(out, value, clazz.getComponentType());
        else
            bridge.simpleWriteObject(value, streamFormatVersion);
    
private voidwriteValueWithVersion(org.omg.CORBA.portable.OutputStream _out, java.io.Serializable value, byte streamFormatVersion)


	org.omg.CORBA_2_3.portable.OutputStream out =
	    (org.omg.CORBA_2_3.portable.OutputStream) _out;

	if (!useHashtables) {
            if (outputStreamBridge == null) {
                outputStreamBridge = createOutputStream();
                outputStreamBridge.setOrbStream(out);
            }

            try {
                outputStreamBridge.increaseRecursionDepth();
                writeValueInternal(outputStreamBridge, out, value, streamFormatVersion);
            } finally {
                outputStreamBridge.decreaseRecursionDepth();
            }

            return;
        }
		
        IIOPOutputStream jdkToOrbOutputStreamBridge = null;

	if (outputStreamPairs == null)
	    outputStreamPairs = new Hashtable();
		
        jdkToOrbOutputStreamBridge = (IIOPOutputStream)outputStreamPairs.get(_out);

        if (jdkToOrbOutputStreamBridge == null) {
            jdkToOrbOutputStreamBridge = createOutputStream();
            jdkToOrbOutputStreamBridge.setOrbStream(out);
            outputStreamPairs.put(_out, jdkToOrbOutputStreamBridge);
        }

        try {

	    jdkToOrbOutputStreamBridge.increaseRecursionDepth();
	    writeValueInternal(jdkToOrbOutputStreamBridge, out, value, streamFormatVersion);
        } finally {
            if (jdkToOrbOutputStreamBridge.decreaseRecursionDepth() == 0) {
                outputStreamPairs.remove(_out);
	    }
        }
    
private voidwrite_Array(org.omg.CORBA_2_3.portable.OutputStream out, java.io.Serializable obj, java.lang.Class type)


        int i, length;

        if (type.isPrimitive()) {
            if (type == Integer.TYPE) {
		int[] array = (int[])((Object)obj);
		length = array.length;
		out.write_ulong(length);
		out.write_long_array(array, 0, length);
            } else if (type == Byte.TYPE) {
		byte[] array = (byte[])((Object)obj);
		length = array.length;
		out.write_ulong(length);
		out.write_octet_array(array, 0, length);
            } else if (type == Long.TYPE) {
		long[] array = (long[])((Object)obj);
		length = array.length;
		out.write_ulong(length);
		out.write_longlong_array(array, 0, length);
            } else if (type == Float.TYPE) {
		float[] array = (float[])((Object)obj);
		length = array.length;
		out.write_ulong(length);
		out.write_float_array(array, 0, length);
            } else if (type == Double.TYPE) {
		double[] array = (double[])((Object)obj);
		length = array.length;
		out.write_ulong(length);
		out.write_double_array(array, 0, length);
            } else if (type == Short.TYPE) {
		short[] array = (short[])((Object)obj);
		length = array.length;
		out.write_ulong(length);
		out.write_short_array(array, 0, length);
            } else if (type == Character.TYPE) {
		char[] array = (char[])((Object)obj);
		length = array.length;
		out.write_ulong(length);
		writeCharArray(out, array, 0, length);
            } else if (type == Boolean.TYPE) {
		boolean[] array = (boolean[])((Object)obj);
		length = array.length;
		out.write_ulong(length);
		out.write_boolean_array(array, 0, length);
            } else {
		// XXX I18N, logging needed.
		throw new Error("Invalid primitive type : " + 
		    obj.getClass().getName());
            }
        } else if (type == java.lang.Object.class) {
            Object[] array = (Object[])((Object)obj);
            length = array.length;
            out.write_ulong(length);
            for (i = 0; i < length; i++) {               
		Util.writeAny(out, array[i]);
	    }
        } else {
            Object[] array = (Object[])((Object)obj);
            length = array.length;
            out.write_ulong(length);
	    int callType = kValueType;
			
	    if (type.isInterface()) { 
		String className = type.getName();
				
		if (java.rmi.Remote.class.isAssignableFrom(type)) {
		    // RMI Object reference...
		    callType = kRemoteType;
		} else if (org.omg.CORBA.Object.class.isAssignableFrom(type)){
		    // IDL Object reference...
		    callType = kRemoteType;
		} else if (RepositoryId.isAbstractBase(type)) {
		    // IDL Abstract Object reference...
		    callType = kAbstractType;
		} else if (ObjectStreamClassCorbaExt.isAbstractInterface(type)) {
		    callType = kAbstractType;
	        }
	    }
			
	    for (i = 0; i < length; i++) {
		switch (callType) {
		case kRemoteType: 
		    Util.writeRemoteObject(out, array[i]);
		    break;
		case kAbstractType: 
		    Util.writeAbstractObject(out,array[i]);
		    break;
		case kValueType:
		    try{
			out.write_value((java.io.Serializable)array[i]);
		    } catch(ClassCastException cce){
			if (array[i] instanceof java.io.Serializable)
			    throw cce;
			else {
			    Utility.throwNotSerializableForCorba(
				array[i].getClass().getName());
			}
		    }
		    break;
		}
	    }
        }