blob: cb8e99a93cf9e866822ba05af9bc33ca1051675a [file] [log] [blame]
/**
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.yoko.rmi.impl;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectStreamField;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
import java.util.logging.Level;
import org.apache.yoko.rmi.util.StringUtil;
import org.omg.CORBA.MARSHAL;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.ValueMember;
import org.omg.CORBA.ValueDefPackage.FullValueDescription;
import org.omg.SendingContext.CodeBase;
import org.omg.SendingContext.CodeBaseHelper;
import sun.reflect.ReflectionFactory;
public class ValueDescriptor extends TypeDescriptor {
static final Logger logger = Logger.getLogger(ValueDescriptor.class
.getName());
protected boolean _is_externalizable;
protected boolean _is_serializable;
protected Method _write_replace_method;
protected Method _read_resolve_method;
protected Constructor _constructor;
protected Method _write_object_method;
protected Method _read_object_method;
protected Field _serial_version_uid_field;
protected ValueDescriptor _super_descriptor;
protected FieldDescriptor[] _fields;
protected ObjectDeserializer _object_deserializer;
protected boolean _is_immutable_value;
protected boolean _is_rmi_stub;
private static Set _immutable_value_classes;
private static Object[] NO_ARGS = new Object[0];
static {
_immutable_value_classes = new HashSet();
_immutable_value_classes.add(Integer.class);
_immutable_value_classes.add(Character.class);
_immutable_value_classes.add(Boolean.class);
_immutable_value_classes.add(Byte.class);
_immutable_value_classes.add(Long.class);
_immutable_value_classes.add(Float.class);
_immutable_value_classes.add(Double.class);
_immutable_value_classes.add(Short.class);
}
protected long _hash_code;
ValueDescriptor(Class type, TypeRepository repository) {
super(type, repository);
}
public String getRepositoryID() {
if (_repid == null) {
StringBuffer buf = new StringBuffer("RMI:");
buf.append(StringUtil.convertToValidIDLNames(getJavaClass().getName()));
buf.append(":");
String hashCode = Long.toHexString(_hash_code).toUpperCase();
for (int i = 0; (i + hashCode.length()) != 16; i++)
buf.append('0');
buf.append(hashCode);
long serialVersionUID = getSerialVersionUID();
buf.append(":");
String serialID = Long.toHexString(serialVersionUID).toUpperCase();
for (int i = 0; (i + serialID.length()) != 16; i++)
buf.append('0');
buf.append(serialID);
_repid = buf.toString();
}
return _repid;
}
long getSerialVersionUID() {
if (_serial_version_uid_field != null) {
try {
return _serial_version_uid_field.getLong(null);
} catch (IllegalAccessException ex) {
// skip //
}
}
java.io.ObjectStreamClass serialForm = java.io.ObjectStreamClass.lookup(getJavaClass());
return serialForm != null ? serialForm.getSerialVersionUID() : 0L;
}
public void init() {
try {
init0();
if (_fields == null) {
throw new RuntimeException("fields==null after init!");
}
} catch (RuntimeException ex) {
logger.log(Level.FINE, "runtime error in ValueDescriptor.init " + ex.getMessage(), ex);
} catch (Error ex) {
logger.log(Level.FINE, "runtime error in ValueDescriptor.init " + ex.getMessage(), ex);
}
}
public void init0() {
final Class type = getJavaClass();
final Class superClass = type.getSuperclass();
_is_rmi_stub = RMIStub.class.isAssignableFrom(type);
_is_externalizable = java.io.Externalizable.class
.isAssignableFrom(type);
_is_serializable = java.io.Serializable.class.isAssignableFrom(type);
_is_immutable_value = _immutable_value_classes.contains(type);
if (superClass != null && superClass != java.lang.Object.class) {
TypeDescriptor superDesc = getTypeRepository().getDescriptor(
superClass);
if (superDesc instanceof ValueDescriptor) {
_super_descriptor = (ValueDescriptor) superDesc;
}
}
java.security.AccessController
.doPrivileged(new java.security.PrivilegedAction() {
public Object run() {
for (Class curr = type; curr != null; curr = curr
.getSuperclass()) {
//
// get writeReplace, if any
//
try {
_write_replace_method = curr.getDeclaredMethod(
"writeReplace", new Class[0]);
_write_replace_method.setAccessible(true);
break;
} catch (NoSuchMethodException ex) {
}
}
//
// Get readResolve, if present
//
try {
_read_resolve_method = type.getDeclaredMethod(
"readResolve", new Class[0]);
_read_resolve_method.setAccessible(true);
} catch (NoSuchMethodException ex) {
// skip //
}
//
// get readObject
//
try {
_read_object_method = type
.getDeclaredMethod(
"readObject",
new Class[] { java.io.ObjectInputStream.class });
_read_object_method.setAccessible(true);
} catch (NoSuchMethodException ex) {
// skip //
}
//
// get readObject
//
try {
_write_object_method = type
.getDeclaredMethod(
"writeObject",
new Class[] { java.io.ObjectOutputStream.class });
_write_object_method.setAccessible(true);
} catch (NoSuchMethodException ex) {
// skip //
}
//
// validate readObject
//
if (_write_object_method == null
|| !Modifier.isPrivate(_write_object_method
.getModifiers())
|| Modifier.isStatic(_write_object_method
.getModifiers())
|| _write_object_method.getDeclaringClass() != getJavaClass()) {
_write_object_method = null;
}
//
// validate writeObject
//
if (_read_object_method == null
|| !Modifier.isPrivate(_read_object_method
.getModifiers())
|| Modifier.isStatic(_read_object_method
.getModifiers())) {
_read_object_method = null;
}
//
// get serialVersionUID field
//
try {
_serial_version_uid_field = type
.getDeclaredField("serialVersionUID");
if (Modifier.isStatic(_serial_version_uid_field
.getModifiers())) {
_serial_version_uid_field.setAccessible(true);
} else {
_serial_version_uid_field = null;
}
} catch (NoSuchFieldException ex) {
// skip //
}
//
// get serialPersistentFields field
//
ObjectStreamField[] serial_persistent_fields = null;
try {
Field _serial_persistent_fields_field = type
.getDeclaredField("serialPersistentFields");
_serial_persistent_fields_field.setAccessible(true);
serial_persistent_fields = (ObjectStreamField[]) _serial_persistent_fields_field
.get(null);
} catch (IllegalAccessException ex) {
// skip //
} catch (NoSuchFieldException ex) {
// skip //
}
if (_is_externalizable) {
//
// Get the default constructor
//
try {
_constructor = type
.getDeclaredConstructor(new Class[0]);
_constructor.setAccessible(true);
} catch (NoSuchMethodException ex) {
logger.log(Level.WARNING, "Class " + type.getName()
+ " is not properly externalizable. "
+ "It has not default constructor.", ex);
}
} else if (_is_serializable && !type.isInterface()) {
Class initClass = type;
while (initClass != null
&& java.io.Serializable.class
.isAssignableFrom(initClass)) {
initClass = initClass.getSuperclass();
}
if (initClass == null) {
logger
.warning("Class "
+ type.getName()
+ " is not properly serializable. "
+ "It has no non-serializable super-class");
} else {
try {
Constructor init_cons = initClass
.getDeclaredConstructor(new Class[0]);
if (Modifier.isPublic(init_cons
.getModifiers())
|| Modifier.isProtected(init_cons
.getModifiers())) {
// do nothing - it's accessible
} else if (!samePackage(type, initClass)) {
logger
.warning("Class "
+ type.getName()
+ " is not properly serializable. "
+ "The default constructor of its first "
+ "non-serializable super-class ("
+ initClass.getName()
+ ") is not accessible.");
}
_constructor = ReflectionFactory
.getReflectionFactory()
.newConstructorForSerialization(
type, init_cons);
if (_constructor == null) {
logger
.warning("Unable to get constructor for serialization for class "
+ getJavaName());
} else {
_constructor.setAccessible(true);
}
} catch (NoSuchMethodException ex) {
logger.log(Level.WARNING,
"Class "
+ type.getName()
+ " is not properly serializable. "
+ "First non-serializable super-class ("
+ initClass.getName()
+ ") has not default constructor.", ex);
}
}
}
if (serial_persistent_fields == null) {
//
// Get relevant field definitions
//
Field[] ff = type.getDeclaredFields();
if (ff == null || ff.length == 0) {
_fields = new FieldDescriptor[0];
} else {
java.util.List flist = new java.util.ArrayList();
for (int i = 0; i < ff.length; i++) {
Field f = ff[i];
int mod = f.getModifiers();
if (Modifier.isStatic(mod)
|| Modifier.isTransient(mod)) {
continue;
}
f.setAccessible(true);
FieldDescriptor fd = FieldDescriptor.get(f);
fd.setTypeRepository(getTypeRepository());
flist.add(fd);
}
_fields = new FieldDescriptor[flist.size()];
_fields = (FieldDescriptor[]) flist
.toArray(_fields);
//
// sort the fields
//
java.util.Arrays.sort(_fields);
}
} else {
_fields = new FieldDescriptor[serial_persistent_fields.length];
for (int i = 0; i < serial_persistent_fields.length; i++) {
ObjectStreamField f = serial_persistent_fields[i];
FieldDescriptor fd = null;
try {
java.lang.reflect.Field rf = type
.getField(f.getName());
rf.setAccessible(true);
if (rf.getType() == f.getType()) {
fd = FieldDescriptor.get(rf);
}
} catch (SecurityException ex) {
} catch (NoSuchFieldException ex) {
}
if (fd == null) {
fd = FieldDescriptor.get(type, f);
}
fd.setTypeRepository(getTypeRepository());
_fields[i] = fd;
}
//
// sort the fields (this is also the case for serial
// persistent
// fields, because they have to map to some foreign
// IDL).
//
java.util.Arrays.sort(_fields);
}
//
// Compute the structural hasn
//
_hash_code = computeHashCode();
//
// Setup the default deserializer
//
_object_deserializer = new ObjectDeserializer(
ValueDescriptor.this);
return null;
}
});
}
private boolean samePackage(Class type, Class initClass) {
String pkg1 = getPackageName(type);
String pkg2 = getPackageName(initClass);
return pkg1.equals(pkg2);
}
private String getPackageName(Class type) {
String name = type.getName();
int idx = name.lastIndexOf('.');
if (idx == -1) {
return "";
} else {
return name.substring(0, idx);
}
}
/** Read an instance of this value from a CDR stream */
public Object read(org.omg.CORBA.portable.InputStream in) {
org.omg.CORBA_2_3.portable.InputStream _in = (org.omg.CORBA_2_3.portable.InputStream) in;
return _in.read_value();
}
/** Write an instance of this value to a CDR stream */
public void write(org.omg.CORBA.portable.OutputStream out, Object value) {
org.omg.CORBA_2_3.portable.OutputStream _out = (org.omg.CORBA_2_3.portable.OutputStream) out;
_out.write_value((java.io.Serializable) value);
}
public boolean isCustomMarshalled() {
if (_is_externalizable)
return true;
if (_write_object_method != null)
return true;
return false;
}
public java.io.Serializable writeReplace(java.io.Serializable val) {
if (_write_replace_method != null) {
try {
return (java.io.Serializable) _write_replace_method.invoke(val,
NO_ARGS);
} catch (java.lang.IllegalAccessException ex) {
throw (MARSHAL)new MARSHAL("cannot call " + _write_replace_method).initCause(ex);
} catch (IllegalArgumentException ex) {
throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
} catch (InvocationTargetException ex) {
throw new org.omg.CORBA.portable.UnknownException(ex
.getTargetException());
}
}
return val;
}
public java.io.Serializable readResolve(java.io.Serializable val) {
if (_read_resolve_method != null) {
try {
return (java.io.Serializable) _read_resolve_method.invoke(val,
NO_ARGS);
} catch (java.lang.IllegalAccessException ex) {
throw (MARSHAL)new MARSHAL("cannot call " + _read_resolve_method).initCause(ex);
} catch (IllegalArgumentException ex) {
throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
} catch (InvocationTargetException ex) {
throw new org.omg.CORBA.portable.UnknownException(ex
.getTargetException());
}
}
return val;
}
public void writeValue(final org.omg.CORBA.portable.OutputStream out,
final java.io.Serializable value) {
try {
ObjectWriter writer = (ObjectWriter) java.security.AccessController
.doPrivileged(new java.security.PrivilegedAction() {
public Object run() {
try {
return new CorbaObjectWriter(out, value);
} catch (java.io.IOException ex) {
throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
}
}
});
writeValue(writer, value);
} catch (java.io.IOException ex) {
throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
}
}
protected void defaultWriteValue(ObjectWriter writer,
java.io.Serializable val) throws java.io.IOException {
logger.finer("writing fields for " + getJavaClass());
FieldDescriptor[] fields = _fields;
if (fields == null) {
return;
}
for (int i = 0; i < fields.length; i++) {
logger.finer("writing field " + _fields[i].getJavaName());
fields[i].write(writer, val);
}
}
protected void writeValue(ObjectWriter writer, java.io.Serializable val)
throws java.io.IOException {
if (_is_externalizable) {
writer.invokeWriteExternal((java.io.Externalizable) val);
return;
}
if (_super_descriptor != null) {
_super_descriptor.writeValue(writer, val);
}
if (_write_object_method != null) {
try {
writer.invokeWriteObject(this, val, _write_object_method);
} catch (IllegalAccessException ex) {
throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
} catch (IllegalArgumentException ex) {
throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
} catch (InvocationTargetException ex) {
throw new org.omg.CORBA.portable.UnknownException(ex
.getTargetException());
}
} else {
defaultWriteValue(writer, val);
}
}
public java.io.Serializable createBlankInstance() {
if (_constructor != null) {
try {
return (java.io.Serializable) _constructor
.newInstance(new Object[0]);
} catch (java.lang.IllegalAccessException ex) {
throw (MARSHAL)new MARSHAL("cannot call " + _constructor).initCause(ex);
} catch (IllegalArgumentException ex) {
throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
} catch (InstantiationException ex) {
throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
} catch (InvocationTargetException ex) {
throw new org.omg.CORBA.portable.UnknownException(ex
.getTargetException());
} catch (NullPointerException ex) {
logger.log(Level.WARNING,
"unable to create instance of " + getJavaClass().getName(), ex);
logger.warning("constructor => " + _constructor);
throw ex;
}
} else {
return null;
}
}
public java.io.Serializable readValue(
final org.omg.CORBA.portable.InputStream in,
final java.util.Map offsetMap, final java.lang.Integer offset) {
final java.io.Serializable value = createBlankInstance();
offsetMap.put(offset, value);
try {
ObjectReader reader = (ObjectReader) java.security.AccessController
.doPrivileged(new java.security.PrivilegedAction() {
public Object run() {
try {
return new CorbaObjectReader(in, offsetMap,
value);
} catch (java.io.IOException ex) {
throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
}
}
});
readValue(reader, value);
return readResolve(value);
} catch (java.io.IOException ex) {
throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
}
}
void print(java.io.PrintWriter pw, java.util.Map recurse, Object val) {
if (val == null) {
pw.print("null");
}
Integer old = (Integer) recurse.get(val);
if (old != null) {
pw.print("^" + old);
} else {
Integer key = new Integer(System.identityHashCode(val));
recurse.put(val, key);
pw.println(getJavaClass().getName() + "@"
+ Integer.toHexString(key.intValue()) + "[");
printFields(pw, recurse, val);
pw.println("]");
}
}
void printFields(java.io.PrintWriter pw, java.util.Map recurse, Object val) {
pw.print("(" + getClass().getName() + ")");
if (_super_descriptor != null) {
_super_descriptor.printFields(pw, recurse, val);
}
if (_fields == null)
return;
for (int i = 0; i < _fields.length; i++) {
if (i != 0) {
pw.print("; ");
}
_fields[i].print(pw, recurse, val);
}
}
protected void defaultReadValue(ObjectReader reader,
java.io.Serializable value) throws java.io.IOException {
// System.out.println ("defaultReadValue "+getJavaClass());
if (_fields == null) {
// System.out.println ("fields == null for "+getJavaClass ());
return;
}
logger.fine("reading fields for " + getJavaClass().getName());
for (int i = 0; i < _fields.length; i++) {
logger.fine("reading field " + _fields[i].getJavaName() + " of type " + _fields[i].getType().getName() + " using " + _fields[i].getClass().getName());
try {
_fields[i].read(reader, value);
} catch (org.omg.CORBA.MARSHAL ex) {
if (ex.getMessage() == null) {
org.omg.CORBA.MARSHAL exx = new org.omg.CORBA.MARSHAL(ex
.getMessage()
+ ", while reading "
+ getJavaName()
+ "."
+ _fields[i].getJavaName(), ex.minor, ex.completed);
exx.initCause(ex);
throw exx;
} else {
throw ex;
}
}
}
}
java.util.Map readFields(ObjectReader reader) throws java.io.IOException {
if (_fields == null || _fields.length == 0) {
return Collections.EMPTY_MAP;
}
logger.finer("reading fields for " + getJavaClass().getName());
java.util.Map map = new HashMap();
for (int i = 0; i < _fields.length; i++) {
logger.finer("reading field " + _fields[i].getJavaName());
_fields[i].readFieldIntoMap(reader, map);
}
return map;
}
void writeFields(ObjectWriter writer, java.util.Map fieldMap)
throws java.io.IOException {
if (_fields == null || _fields.length == 0) {
return;
}
logger.finer("writing fields for " + getJavaClass().getName());
for (int i = 0; i < _fields.length; i++) {
logger.finer("writing field " + _fields[i].getJavaName());
_fields[i].writeFieldFromMap(writer, fieldMap);
}
}
/**
* This methods reads the fields of a single class slice.
*/
protected void readValue(ObjectReader reader, java.io.Serializable value)
throws java.io.IOException {
if (_is_externalizable) {
java.io.Externalizable ext = (java.io.Externalizable) value;
try {
reader.readExternal(ext);
} catch (ClassNotFoundException e) {
IOException ex = new IOException("cannot instantiate class");
ex.initCause(e);
throw ex;
}
return;
}
if (_super_descriptor != null) {
_super_descriptor.readValue(reader, value);
}
// System.out.println ("readValue "+getJavaClass());
if (isCustomMarshalled()) {
// read custom marshalling value header
byte streamFormatVersion = reader.readByte();
boolean writeDefaultStateCalled = reader.readBoolean();
logger.log(Level.FINE, "Reading value in streamFormatVersion=" + streamFormatVersion
+ " IsCalleddefaultWriteObject=" + writeDefaultStateCalled);
}
if (_read_object_method != null) {
// System.out.println ("readValue "+getJavaClass()+" calling
// readObject");
try {
reader.setCurrentValueDescriptor(this);
_read_object_method.invoke(value, new Object[] { reader });
reader.setCurrentValueDescriptor(null);
} catch (IllegalAccessException ex) {
throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
} catch (IllegalArgumentException ex) {
throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
} catch (InvocationTargetException ex) {
throw new org.omg.CORBA.portable.UnknownException(ex
.getTargetException());
}
} else {
defaultReadValue(reader, value);
}
}
protected long computeHashCode() {
Class type = getJavaClass();
long hash = 0L;
if (_is_externalizable) {
return 1L;
} else if (!java.io.Serializable.class.isAssignableFrom(type)) {
return 0;
} else
try {
ByteArrayOutputStream barr = new ByteArrayOutputStream(512);
MessageDigest md = MessageDigest.getInstance("SHA");
DigestOutputStream digestout = new DigestOutputStream(barr, md);
DataOutputStream out = new DataOutputStream(digestout);
Class superType = type.getSuperclass();
if (superType != null) {
TypeDescriptor desc = getTypeRepository().getDescriptor(
superType);
out.writeLong(desc.getHashCode());
}
if (_write_object_method == null)
out.writeInt(1);
else
out.writeInt(2);
FieldDescriptor[] fds = new FieldDescriptor[_fields.length];
for (int i = 0; i < _fields.length; i++) {
fds[i] = _fields[i];
}
if (fds.length > 1)
java.util.Arrays.sort(fds, compareByName);
for (int i = 0; i < fds.length; i++) {
FieldDescriptor f = fds[i];
out.writeUTF(f.getJavaName());
out.writeUTF(makeSignature(f.getType()));
}
/*
* Field[] fields = type.getDeclaredFields ();
*
* if (fields.length > 1) java.util.Arrays.sort (fields,
* compareByName);
*
* for(int i = 0; i < fields.length; i++) { Field f = fields[i];
* int mod = f.getModifiers (); if (!Modifier.isTransient(mod) &&
* !Modifier.isStatic (mod)) { out.writeUTF(f.getName());
* out.writeUTF( makeSignature (f.getType ())); } }
*/
out.flush();
byte data[] = md.digest();
int end = Math.min(8, data.length);
for (int j = 0; j < end; j++) {
hash += (long) (data[j] & 0xff) << j * 8;
}
} catch (java.lang.Exception ex) {
throw new RuntimeException("cannot compute RMI hash code", ex);
}
return hash;
}
private static java.util.Comparator compareByName = new java.util.Comparator() {
public int compare(Object f1, Object f2) {
String n1 = ((FieldDescriptor) f1).getJavaName();
String n2 = ((FieldDescriptor) f2).getJavaName();
return n1.compareTo(n2);
}
};
long getHashCode() {
return _hash_code;
}
protected org.omg.CORBA.ValueMember[] _value_members = null;
org.omg.CORBA.ValueMember[] getValueMembers() {
if (_value_members == null) {
_value_members = new org.omg.CORBA.ValueMember[_fields.length];
for (int i = 0; i < _fields.length; i++) {
_value_members[i] = _fields[i]
.getValueMember(getTypeRepository());
}
}
return _value_members;
}
org.omg.CORBA.TypeCode getTypeCode() {
if (_type_code != null)
return _type_code;
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init();
_type_code = orb.create_recursive_tc(getRepositoryID());
org.omg.CORBA.TypeCode _base = (_super_descriptor == null ? null
: _super_descriptor.getTypeCode());
Class javaClass = getJavaClass();
if (!javaClass.isArray()) {
_type_code = orb.create_value_tc(getRepositoryID(), javaClass
.getSimpleName(), org.omg.CORBA.VM_NONE.value, _base,
getValueMembers());
} else {
TypeDescriptor desc = getTypeRepository().getDescriptor(javaClass.getComponentType());
_type_code = desc.getTypeCode();
_type_code = orb.create_sequence_tc(0, _type_code);
_type_code = orb.create_value_box_tc(getRepositoryID(), "Sequence", _type_code);
}
return _type_code;
}
org.omg.CORBA.ValueDefPackage.FullValueDescription getFullValueDescription() {
return new org.omg.CORBA.ValueDefPackage.FullValueDescription(
getJavaClass().getName(), getRepositoryID(), false, // is_abstract
isCustomMarshalled(), "", "1.0",
new org.omg.CORBA.OperationDescription[0],
new org.omg.CORBA.AttributeDescription[0],
getValueMembers(),
new org.omg.CORBA.Initializer[0], new String[0], new String[0],
false, // is_truncatable
(_super_descriptor == null ? "" : _super_descriptor
.getRepositoryID()), getTypeCode());
}
class ObjectDeserializer {
ObjectDeserializer super_descriptor;
String repository_id;
FieldDescriptor[] fields;
ValueDescriptor localDescriptor() {
return ValueDescriptor.this;
}
ObjectDeserializer(ValueDescriptor desc) {
fields = desc._fields;
repository_id = desc.getRepositoryID();
if (desc._super_descriptor != null) {
super_descriptor = desc._super_descriptor._object_deserializer;
}
}
ObjectDeserializer(FullValueDescription desc,
org.omg.SendingContext.RunTime runtime) throws IOException {
Class myClass = ValueDescriptor.this.getJavaClass();
ValueMember[] members = desc.members;
fields = new FieldDescriptor[members.length];
for (int i = 0; i < members.length; i++) {
Class type = getClassFromTypeCode(members[i].type);
fields[i] = FieldDescriptor.get(myClass, type, members[i].name,
null);
}
if (!"".equals(desc.base_value)) {
Class clz = ValueHandlerImpl
.getClassFromRepositoryID(desc.base_value);
TypeDescriptor tdesc = getTypeRepository().getDescriptor(clz);
if (tdesc != null && tdesc instanceof ValueDescriptor) {
super_descriptor = ((ValueDescriptor) tdesc)
.getObjectDeserializer(desc.base_value, runtime);
}
}
}
}
ObjectDeserializer getObjectDeserializer(String repositoryID,
org.omg.SendingContext.RunTime runtime) throws java.io.IOException {
if (repositoryID.equals(getRepositoryID())) {
return _object_deserializer;
}
CodeBase codebase = CodeBaseHelper.narrow(runtime);
if (codebase == null) {
throw new IOException("cannot narrow RunTime -> CodeBase");
}
FullValueDescription desc = codebase.meta(repositoryID);
return new ObjectDeserializer(desc, codebase);
}
static Class getClassFromTypeCode(TypeCode tc) {
return null;
}
public boolean copyWithinState() {
return !(_is_immutable_value | _is_rmi_stub);
}
Object copyObject(Object orig, CopyState state) {
if (_is_immutable_value || _is_rmi_stub) {
return orig;
}
java.io.Serializable oorig = (java.io.Serializable) orig;
logger.finer("copying " + orig);
oorig = writeReplace(oorig);
ValueDescriptor wdesc;
if (oorig != orig) {
wdesc = (ValueDescriptor) getTypeRepository().getDescriptor(
oorig.getClass());
logger.finer("writeReplace -> " + getJavaClass().getName());
} else {
wdesc = this;
}
return wdesc.copyObject2(oorig, state);
}
/**
* this is called after write-replace on the type descriptor of the correct
* type for writing
*/
Serializable copyObject2(Serializable oorig, CopyState state) {
// create instance of copied object, and register
Serializable copy = createBlankInstance();
state.put(oorig, copy);
// write original object
ObjectWriter writer = writeObject(oorig, state);
// read into copy
return readObject(writer, copy);
}
ObjectWriter writeObject(java.io.Serializable oorig, CopyState state) {
ObjectWriter writer = null;
try {
writer = state.createObjectWriter(oorig);
writeValue(writer, oorig);
return writer;
} catch (java.io.IOException ex) {
throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
}
}
java.io.Serializable readObject(ObjectWriter writer,
java.io.Serializable copy) {
ObjectReader reader = writer.getObjectReader(copy);
try {
readValue(reader, copy);
} catch (java.io.IOException ex) {
MARSHAL m = new MARSHAL(ex.getMessage() + " reading instance of "
+ getJavaClass().getName());
m.initCause(ex);
throw m;
}
return readResolve(copy);
}
void writeMarshalValue(java.io.PrintWriter pw, String outName,
String paramName) {
pw.print(outName);
pw.print('.');
pw.print("write_value");
// this ValueDescriptor could represent an Abstract Value,
// in which case we need to cast the first argument.
// We'll just always do that, because most of the time
// HotSpot will remove this cast anyway.
pw.print("((java.io.Serializable)");
pw.print(paramName);
pw.print(',');
MethodDescriptor.writeJavaType(pw, getJavaClass());
pw.print(".class)");
}
void writeUnmarshalValue(java.io.PrintWriter pw, String inName) {
pw.print(inName);
pw.print('.');
pw.print("read_value");
pw.print('(');
MethodDescriptor.writeJavaType(pw, getJavaClass());
pw.print(".class)");
}
void addDependencies(java.util.Set classes) {
Class c = getJavaClass();
if (c == java.lang.Object.class || classes.contains(c))
return;
classes.add(c);
if (c.getSuperclass() != null) {
TypeDescriptor desc = getTypeRepository().getDescriptor(
c.getSuperclass());
desc.addDependencies(classes);
}
Class[] ifaces = c.getInterfaces();
for (int i = 0; i < ifaces.length; i++) {
TypeDescriptor desc = getTypeRepository().getDescriptor(ifaces[i]);
desc.addDependencies(classes);
}
if (_fields != null) {
for (int i = 0; i < _fields.length; i++) {
if (_fields[i].isPrimitive())
continue;
TypeDescriptor desc = getTypeRepository().getDescriptor(
_fields[i].type);
desc.addDependencies(classes);
}
}
}
}