This is a RMI/IIOP metadata conversion utility class.
Routines here are conforming to the "Java(TM) Language to IDL Mapping
Specification", version 1.1 (01-06-07).
| Method from org.jboss.iiop.rmi.Util Detail: |
static long getClassHashCode(Class cls) {
// The simple cases
if (cls.isInterface())
return 0;
if (!Serializable.class.isAssignableFrom(cls))
return 0;
if (Externalizable.class.isAssignableFrom(cls))
return 1;
// Try cache
Long l = (Long)classHashCodeCache.get(cls);
if (l != null)
return l.longValue();
// Has to calculate the hash.
ByteArrayOutputStream baos = new ByteArrayOutputStream(256);
DataOutputStream dos = new DataOutputStream(baos);
// Step 1
Class superClass = cls.getSuperclass();
if (superClass != null && superClass != Object.class) {
try {
dos.writeLong(getClassHashCode(superClass));
} catch (IOException ex) {
throw new RuntimeException("Unexpected IOException: " + ex);
}
}
// Step 2
boolean hasWriteObject = false;
try {
Method m;
int mods;
m = cls.getDeclaredMethod("writeObject",
new Class[] { ObjectOutputStream.class });
mods = m.getModifiers();
if (!Modifier.isPrivate(mods) && !Modifier.isStatic(mods))
hasWriteObject = true;
} catch (NoSuchMethodException ex) {
// ignore
}
try {
dos.writeInt(hasWriteObject ? 2 : 1);
} catch (IOException ex) {
throw new RuntimeException("Unexpected IOException: " + ex);
}
// Step 3
Field[] fields = cls.getDeclaredFields();
SortedSet set = new TreeSet(new FieldComparator());
for (int i = 0; i < fields.length; ++i) {
int mods = fields[i].getModifiers();
if (!Modifier.isStatic(mods) && !Modifier.isTransient(mods))
set.add(fields[i]);
}
Iterator iter = set.iterator();
try {
while (iter.hasNext()) {
Field f = (Field)iter.next();
dos.writeUTF(f.getName());
dos.writeUTF(getSignature(f.getType()));
}
} catch (IOException ex) {
throw new RuntimeException("Unexpected IOException: " + ex);
}
// Convert to byte[]
try {
dos.flush();
} catch (IOException ex) {
throw new RuntimeException("Unexpected IOException: " + ex);
}
byte[] bytes = baos.toByteArray();
// Calculate SHA digest
MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA");
} catch (NoSuchAlgorithmException ex) {
throw new RuntimeException("No SHA MEssageDigest: " + ex);
}
digest.update(bytes);
byte[] sha = digest.digest();
// Calculate hash as per section 10.6.2
long hash = 0;
for (int i = 0; i < Math.min(8, sha.length); i++) {
hash += (long)(sha[i] & 255) < < (i * 8);
}
// Save in cache
classHashCodeCache.put(cls, new Long(hash));
return hash;
}
Return the class hash code, as specified in "The Common Object
Request Broker: Architecture and Specification" (01-02-33),
section 10.6.2. |
public static String getIRIdentifierOfClass(Class cls) {
if (cls.isPrimitive())
throw new IllegalArgumentException("Primitives have no IR IDs.");
String result = (String)classIRIdentifierCache.get(cls);
if (result != null)
return result;
String name = cls.getName();
StringBuffer b = new StringBuffer("RMI:");
for (int i = 0; i < name.length(); ++i) {
char c = name.charAt(i);
if (c < 256)
b.append(c);
else
b.append("\\U").append(toHexString((int)c));
}
long clsHash = getClassHashCode(cls);
b.append(':").append(toHexString(clsHash));
ObjectStreamClass osClass = ObjectStreamClass.lookup(cls);
if (osClass != null) {
long serialVersionUID = osClass.getSerialVersionUID();
if (clsHash != serialVersionUID)
b.append(':").append(toHexString(serialVersionUID));
}
result = b.toString();
classIRIdentifierCache.put(cls, result);
return result;
}
Return the IR global ID of the given class or interface.
This is described in section 1.3.5.7.
The returned string is in the RMI hashed format, like
"RMI:java.util.Hashtable:C03324C0EA357270:13BB0F25214AE4B8". |
public static String getTypeIDLName(Class cls) throws RMIIIOPViolationException {
logger.debug("getTypeIDLName " + cls);
if (cls.isPrimitive())
return PrimitiveAnalysis.getPrimitiveAnalysis(cls).getIDLName();
if (cls.isArray())
{
// boxedRMI 1.3.6
Class componentClass = cls;
int sequence = 0;
while (componentClass.isArray())
{
componentClass = componentClass.getComponentType();
++sequence;
}
String idlName = getTypeIDLName(componentClass);
int idx = idlName.lastIndexOf("::");
String idlModule = idlName.substring(0, idx+2);
String baseName = idlName.substring(idx+2);
return "::org::omg::boxedRMI" + idlModule + "seq" + sequence + "_" + baseName;
}
// special classes
if (cls == java.lang.String.class)
return "::CORBA::WStringValue";
if (cls == java.lang.Object.class)
return "::java::lang::_Object";
if (cls == java.lang.Class.class)
return "::javax::rmi::CORBA::ClassDesc";
if (cls == java.io.Serializable.class)
return "::java::io::Serializable";
if (cls == java.io.Externalizable.class)
return "::java::io::Externalizable";
if (cls == java.rmi.Remote.class)
return "::java::rmi::Remote";
if (cls == org.omg.CORBA.Object.class)
return "::CORBA::Object";
// remote interface?
if (cls.isInterface() && java.rmi.Remote.class.isAssignableFrom(cls)) {
InterfaceAnalysis ia = InterfaceAnalysis.getInterfaceAnalysis(cls);
return ia.getIDLModuleName() + "::" + ia.getIDLName();
}
// IDL interface?
if (cls.isInterface() &&
org.omg.CORBA.Object.class.isAssignableFrom(cls) &&
org.omg.CORBA.portable.IDLEntity.class.isAssignableFrom(cls)) {
InterfaceAnalysis ia = InterfaceAnalysis.getInterfaceAnalysis(cls);
return ia.getIDLModuleName() + "::" + ia.getIDLName();
}
// exception?
if (Throwable.class.isAssignableFrom(cls)) {
if (Exception.class.isAssignableFrom(cls) &&
!RuntimeException.class.isAssignableFrom(cls)) {
ExceptionAnalysis ea = ExceptionAnalysis.getExceptionAnalysis(cls);
return ea.getIDLModuleName() + "::" + ea.getIDLName();
}
}
// got to be value
ValueAnalysis va = ValueAnalysis.getValueAnalysis(cls);
return va.getIDLModuleName() + "::" + va.getIDLName();
}
Return the IDL type name for the given class.
Here we use the mapping for parameter types and return values. |
public static void insertAnyPrimitive(Any any,
Object primitive) {
Class type = primitive.getClass();
if (type == Boolean.class)
any.insert_boolean(((Boolean)primitive).booleanValue());
else if (type == Character.class)
any.insert_wchar(((Character)primitive).charValue());
else if (type == Byte.class)
any.insert_octet(((Byte)primitive).byteValue());
else if (type == Short.class)
any.insert_short(((Short)primitive).shortValue());
else if (type == Integer.class)
any.insert_long(((Integer)primitive).intValue());
else if (type == Long.class)
any.insert_longlong(((Long)primitive).longValue());
else if (type == Float.class)
any.insert_float(((Float)primitive).floatValue());
else if (type == Double.class)
any.insert_double(((Double)primitive).doubleValue());
else
throw new IllegalArgumentException("Not a primitive type: " +
type.getName());
}
Insert a java primitive into an Any.
The primitive is assumed to be wrapped in one of the primitive
wrapper classes. |
public static boolean isValidRMIIIOP(Class cls) throws RMIIIOPViolationException {
if (cls.isPrimitive())
return true;
if (cls.isArray())
return isValidRMIIIOP(cls.getComponentType());
// special interfaces
if (cls == Serializable.class || cls == Externalizable.class)
return true;
// interface?
if (cls.isInterface() && java.rmi.Remote.class.isAssignableFrom(cls)) {
logger.debug("Util.isValidRMIIIOP(): doing interface analysis on " +
cls.getName());
InterfaceAnalysis.getInterfaceAnalysis(cls);
return true;
}
// exception?
if (Throwable.class.isAssignableFrom(cls)) {
if (Exception.class.isAssignableFrom(cls) &&
!RuntimeException.class.isAssignableFrom(cls)) {
logger.debug("Util.isValidRMIIIOP(): doing exception analysis on "
+ cls.getName());
ExceptionAnalysis.getExceptionAnalysis(cls);
}
return true;
}
// special values
if (cls == Object.class || cls == String.class || cls == Class.class)
return true;
// got to be value
logger.debug("Util.isValidRMIIIOP(): doing value analysis on " +
cls.getName());
ValueAnalysis.getValueAnalysis(cls);
return true;
}
Check if this class is valid for RMI/IIOP mapping.
This method will either throw an exception or return true. |
public static String javaToIDLName(String name) {
if (name == null)
throw new IllegalArgumentException("Null name.");
if ("".equals(name))
throw new IllegalArgumentException("Empty name.");
if (name.indexOf('.") != -1)
throw new IllegalArgumentException("No qualified name allowed here.");
StringBuffer res = new StringBuffer(name.length());
if (name.charAt(0) == '_")
res.append('J"); // 1.3.2.3
for (int i = 0; i < name.length(); ++i) {
char c = name.charAt(i);
if (isLegalIDLIdentifierChar(c))
res.append(c);
else // 1.3.2.4
res.append('U").append(toHexString((int)c));
}
String s = res.toString();
if (isReservedIDLKeyword(s))
return "_" + s;
else
return s;
}
Map Java name to IDL name, as per sections 1.3.2.3, 1.3.2.4 and
1.3.2.2.
This only works for a single name component, without a qualifying
dot. |
static String primitiveTypeIDLName(Class type) {
if (type == Void.TYPE)
return "void";
if (type == Boolean.TYPE)
return "boolean";
if (type == Character.TYPE)
return "wchar";
if (type == Byte.TYPE)
return "octet";
if (type == Short.TYPE)
return "short";
if (type == Integer.TYPE)
return "long";
if (type == Long.TYPE)
return "long long";
if (type == Float.TYPE)
return "float";
if (type == Double.TYPE)
return "double";
throw new IllegalArgumentException("Not a primitive type.");
}
Handle mappings for primitive types, as per section 1.3.3. |