org.jboss.iiop.rmi.ir.InterfaceRepository Maven / Gradle / Ivy
The newest version!
/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.iiop.rmi.ir;
import org.omg.CORBA.ORB;
import org.omg.CORBA.Any;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.TCKind;
import org.omg.CORBA.DefinitionKind;
import org.omg.CORBA.Repository;
import org.omg.CORBA.RepositoryHelper;
import org.omg.CORBA.ParameterDescription;
import org.omg.CORBA.ParameterMode;
import org.omg.CORBA.StructMember;
import org.omg.CORBA.ExceptionDef;
import org.omg.CORBA.ExceptionDefHelper;
import org.omg.PortableServer.POA;
import org.jboss.iiop.rmi.Util;
import org.jboss.iiop.rmi.ContainerAnalysis;
import org.jboss.iiop.rmi.InterfaceAnalysis;
import org.jboss.iiop.rmi.ExceptionAnalysis;
import org.jboss.iiop.rmi.ValueAnalysis;
import org.jboss.iiop.rmi.ValueMemberAnalysis;
import org.jboss.iiop.rmi.ConstantAnalysis;
import org.jboss.iiop.rmi.AttributeAnalysis;
import org.jboss.iiop.rmi.OperationAnalysis;
import org.jboss.iiop.rmi.ParameterAnalysis;
import org.jboss.iiop.rmi.RMIIIOPViolationException;
import org.jboss.iiop.rmi.RmiIdlUtil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.naming.InitialContext;
import javax.naming.NamingException;
/**
* An Interface Repository.
*
* @author Ole Husgaard
* @version $Revision: 81018 $
*/
public class InterfaceRepository
{
// Constants -----------------------------------------------------
// Attributes ----------------------------------------------------
// Static --------------------------------------------------------
/**
* Maps java classes to IDL TypeCodes for primitives.
*/
private static Map primitiveTypeCodeMap;
/**
* Maps java classes to IDL TypeCodes for constants.
*/
private static Map constantTypeCodeMap;
static {
// Get an ORB for creating type codes.
ORB orb;
try {
orb = (ORB)new InitialContext().lookup("java:/JBossCorbaORB");
} catch (NamingException ex) {
throw new RuntimeException("Cannot lookup java:/JBossCorbaORB: "+ex);
}
// TypeCodes for primitive types
primitiveTypeCodeMap = new HashMap();
primitiveTypeCodeMap.put(Void.TYPE,
orb.get_primitive_tc(TCKind.tk_void));
primitiveTypeCodeMap.put(Boolean.TYPE,
orb.get_primitive_tc(TCKind.tk_boolean));
primitiveTypeCodeMap.put(Character.TYPE,
orb.get_primitive_tc(TCKind.tk_wchar));
primitiveTypeCodeMap.put(Byte.TYPE,
orb.get_primitive_tc(TCKind.tk_octet));
primitiveTypeCodeMap.put(Short.TYPE,
orb.get_primitive_tc(TCKind.tk_short));
primitiveTypeCodeMap.put(Integer.TYPE,
orb.get_primitive_tc(TCKind.tk_long));
primitiveTypeCodeMap.put(Long.TYPE,
orb.get_primitive_tc(TCKind.tk_longlong));
primitiveTypeCodeMap.put(Float.TYPE,
orb.get_primitive_tc(TCKind.tk_float));
primitiveTypeCodeMap.put(Double.TYPE,
orb.get_primitive_tc(TCKind.tk_double));
// TypeCodes for constant types
constantTypeCodeMap = new HashMap(primitiveTypeCodeMap);
constantTypeCodeMap.put(String.class, orb.create_wstring_tc(0));
}
/**
* Static logger used by the interface repository.
*/
private static final org.jboss.logging.Logger logger =
org.jboss.logging.Logger.getLogger(InterfaceRepository.class);
// Constructors --------------------------------------------------
public InterfaceRepository(ORB orb, POA poa, String name)
{
this.orb = orb;
this.poa = poa;
impl = new RepositoryImpl(orb, poa, name);
}
// Public --------------------------------------------------------
/**
* Add mapping for a class.
*/
public void mapClass(Class cls)
throws RMIIIOPViolationException, IRConstructionException
{
// Just lookup a TypeCode for the class: That will provoke
// mapping the class and adding it to the IR.
getTypeCode(cls);
}
/**
* Finish the build.
*/
public void finishBuild()
throws IRConstructionException
{
impl.allDone();
}
/**
* Return a CORBA reference to this IR.
*/
public Repository getReference()
{
return RepositoryHelper.narrow(impl.getReference());
}
/**
* Deactivate all CORBA objects in this IR.
*/
public void shutdown()
{
impl.shutdown();
}
// Z implementation ----------------------------------------------
// Y overrides ---------------------------------------------------
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
// Private -------------------------------------------------------
/**
* The repository implementation.
*/
RepositoryImpl impl;
/**
* The ORB that I use.
*/
private ORB orb = null;
/**
* The POA that I use.
*/
private POA poa = null;
/**
* Maps java classes to IDL TypeCodes for parameter, result, attribute
* and value member types.
*/
private Map typeCodeMap = new HashMap(primitiveTypeCodeMap);
/**
* Maps java classes to InterfaceDefImpl
s for interfaces.
*/
private Map interfaceMap = new HashMap();
/**
* Maps java classes to ValueDefImpl
s for values.
*/
private Map valueMap = new HashMap();
/**
* Maps java classes to ExceptionDefImpl
s for exceptions.
*/
private Map exceptionMap = new HashMap();
/**
* Maps java classes to ValueBoxDefImpl
s for arrays.
*/
private Map arrayMap = new HashMap();
/**
* java.io.Serializable special mapping, as per section 1.3.10.1.
* Do not use this variable directly, use the
* getJavaIoSerializable()
method instead, as that will
* create the typedef in the IR on demand.
*/
private AliasDefImpl javaIoSerializable = null;
/**
* java.io.Externalizable special mapping, as per section 1.3.10.1.
* Do not use this variable directly, use the
* getJavaIoExternalizable()
method instead, as that will
* create the typedef in the IR on demand.
*/
private AliasDefImpl javaIoExternalizable = null;
/**
* java.lang.Object special mapping, as per section 1.3.10.2.
* Do not use this variable directly, use the
* getJavaLang_Object()
method instead, as that will
* create the typedef in the IR on demand.
*/
private AliasDefImpl javaLang_Object = null;
/**
* java.lang.String special mapping, as per section 1.3.5.10.
* Do not use this variable directly, use the
* getJavaLangString()
method instead, as that will
* create the value type in the IR on demand.
*/
private ValueDefImpl javaLangString = null;
/**
* java.lang.Class special mapping, as per section 1.3.5.11.
* Do not use this variable directly, use the
* getJavaxRmiCORBAClassDesc()
method instead, as that will
* create the value type in the IR on demand.
*/
private ValueDefImpl javaxRmiCORBAClassDesc = null;
/**
* Returns the TypeCode suitable for an IDL constant.
* @param cls The Java class denoting the type of the constant.
*/
private TypeCode getConstantTypeCode(Class cls)
throws IRConstructionException
{
if (cls == null)
throw new IllegalArgumentException("Null class");
TypeCode ret = (TypeCode)constantTypeCodeMap.get(cls);
if (ret == null)
throw new IRConstructionException("Bad class \"" + cls.getName() +
"\" for a constant.");
return ret;
}
/**
* Returns the TypeCode IDL TypeCodes for parameter, result, attribute
* and value member types.
* This may provoke a mapping of the class argument.
*
* Exception classes map to both values and exceptions. For these, this
* method returns the typecode for the value, and you can use the
* getExceptionTypeCode
TODO method to get the typecode for the
* mapping to exception.
*
* @param cls The Java class denoting the java type.
*/
private TypeCode getTypeCode(Class cls)
throws IRConstructionException, RMIIIOPViolationException
{
if (cls == null)
throw new IllegalArgumentException("Null class");
TypeCode ret = (TypeCode)typeCodeMap.get(cls);
if (ret == null) {
if (cls == java.lang.String.class)
ret = getJavaLangString().type();
else if (cls == java.lang.Object.class)
ret = getJavaLang_Object().type();
else if (cls == java.lang.Class.class)
ret = getJavaxRmiCORBAClassDesc().type();
else if (cls == java.io.Serializable.class)
ret = getJavaIoSerializable().type();
else if (cls == java.io.Externalizable.class)
ret = getJavaIoExternalizable().type();
else {
// Try adding a mapping of the the class to the IR
addClass(cls);
// Lookup again, it should be there now.
ret = (TypeCode)typeCodeMap.get(cls);
if (ret == null)
throw new IRConstructionException("TypeCode for class " +
cls.getName() + " unknown.");
else
return ret;
}
typeCodeMap.put(cls, ret);
}
return ret;
}
/**
* Add a new IDL TypeCode for a mapped class.
*
* @param cls The Java class denoting the java type.
* @param typeCode The IDL type code of the mapped java class.
*/
private void addTypeCode(Class cls, TypeCode typeCode)
throws IRConstructionException
{
if (cls == null)
throw new IllegalArgumentException("Null class");
TypeCode tc = (TypeCode)typeCodeMap.get(cls);
if (tc != null)
throw new IllegalArgumentException("Class " + cls.getName() +
" already has TypeCode.");
logger.trace("InterfaceRepository: added typecode for " + cls.getName());
typeCodeMap.put(cls, typeCode);
}
/**
* Get a reference to the special case mapping for java.io.Serializable.
* This is according to "Java(TM) Language to IDL Mapping Specification",
* section 1.3.10.1
*/
private AliasDefImpl getJavaIoSerializable()
throws IRConstructionException
{
if (javaIoSerializable == null) {
final String id = "IDL:java/io/Serializable:1.0";
final String name = "Serializable";
final String version = "1.0";
// Get module to add typedef to.
ModuleDefImpl m = ensurePackageExists("java.io");
TypeCode typeCode = orb.create_alias_tc(id, name,
orb.get_primitive_tc(TCKind.tk_any));
// TypeCode typeCode = new TypeCodeImpl(TCKind._tk_alias, id, name,
// new TypeCodeImpl(TCKind.tk_any));
javaIoSerializable = new AliasDefImpl(id, name, version, m,
typeCode, impl);
m.add(name, javaIoSerializable);
}
return javaIoSerializable;
}
/**
* Get a reference to the special case mapping for java.io.Externalizable.
* This is according to "Java(TM) Language to IDL Mapping Specification",
* section 1.3.10.1
*/
private AliasDefImpl getJavaIoExternalizable()
throws IRConstructionException
{
if (javaIoExternalizable == null) {
final String id = "IDL:java/io/Externalizable:1.0";
final String name = "Externalizable";
final String version = "1.0";
// Get module to add typedef to.
ModuleDefImpl m = ensurePackageExists("java.io");
TypeCode typeCode = orb.create_alias_tc(id, name,
orb.get_primitive_tc(TCKind.tk_any));
// TypeCode typeCode = new TypeCodeImpl(TCKind._tk_alias, id, name,
// new TypeCodeImpl(TCKind.tk_any));
javaIoExternalizable = new AliasDefImpl(id, name, version, m,
typeCode, impl);
m.add(name, javaIoExternalizable);
}
return javaIoExternalizable;
}
/**
* Get a reference to the special case mapping for java.lang.Object.
* This is according to "Java(TM) Language to IDL Mapping Specification",
* section 1.3.10.2
*/
private AliasDefImpl getJavaLang_Object()
throws IRConstructionException
{
if (javaLang_Object == null) {
final String id = "IDL:java/lang/_Object:1.0";
final String name = "_Object";
final String version = "1.0";
// Get module to add typedef to.
ModuleDefImpl m = ensurePackageExists("java.lang");
TypeCode typeCode = orb.create_alias_tc(id, name,
orb.get_primitive_tc(TCKind.tk_any));
// TypeCode typeCode = new TypeCodeImpl(TCKind._tk_alias, id, name,
// new TypeCodeImpl(TCKind.tk_any));
javaLang_Object = new AliasDefImpl(id, name, version, m,
typeCode, impl);
m.add(name, javaLang_Object);
}
return javaLang_Object;
}
/**
* Get a reference to the special case mapping for java.lang.String.
* This is according to "Java(TM) Language to IDL Mapping Specification",
* section 1.3.5.10
*/
private ValueDefImpl getJavaLangString()
throws IRConstructionException
{
if (javaLangString == null) {
ModuleDefImpl m = ensurePackageExists("org.omg.CORBA");
ValueDefImpl val =
new ValueDefImpl("IDL:omg.org/CORBA/WStringValue:1.0",
"WStringValue", "1.0",
m, false, false,
new String[0], new String[0],
orb.get_primitive_tc(TCKind.tk_null),
impl);
ValueMemberDefImpl vmdi =
new ValueMemberDefImpl("IDL:omg.org/CORBA/WStringValue.data:1.0",
"data", "1.0", orb.create_wstring_tc(0),
true, val, impl);
val.add("data", vmdi);
m.add("WStringValue", val);
javaLangString = val;
}
return javaLangString;
}
/**
* Get a reference to the special case mapping for java.lang.Class.
* This is according to "Java(TM) Language to IDL Mapping Specification",
* section 1.3.5.11.
*/
private ValueDefImpl getJavaxRmiCORBAClassDesc()
throws IRConstructionException, RMIIIOPViolationException
{
if (javaxRmiCORBAClassDesc == null) {
// Just map the right value class
ValueAnalysis va = ValueAnalysis.getValueAnalysis(javax.rmi.CORBA.ClassDesc.class);
ValueDefImpl val = addValue(va);
// Warn if it does not conform to the specification.
if (!"RMI:javax.rmi.CORBA.ClassDesc:B7C4E3FC9EBDC311:CFBF02CF5294176B".equals(val.id()) )
logger.debug("Compatibility problem: Class " +
"javax.rmi.CORBA.ClassDesc does not conform " +
"to the Java(TM) Language to IDL Mapping "+
"Specification (01-06-07), section 1.3.5.11.");
javaxRmiCORBAClassDesc = val;
}
return javaxRmiCORBAClassDesc;
}
/**
* Ensure that a package exists in the IR.
* This will create modules in the IR as needed.
*
* @param pkg
* The package that needs to be defined as a module in the IR.
*
* @return A reference to the IR module that represents the package.
*/
private ModuleDefImpl ensurePackageExists(String pkgName)
throws IRConstructionException
{
return ensurePackageExists(impl, "", pkgName);
}
/**
* Ensure that a package exists in the IR.
* This will create modules in the IR as needed.
*
* @param c
* The container that the remainder of modules should be defined in.
* @param previous
* The IDL module name, from root to c
.
* @param remainder
* The java package name, relative to c
.
*
* @return A reference to the IR module that represents the package.
*/
private ModuleDefImpl ensurePackageExists(LocalContainer c,
String previous,
String remainder)
throws IRConstructionException
{
if ("".equals(remainder))
return (ModuleDefImpl)c; // done
int idx = remainder.indexOf('.');
String base;
if (idx == -1)
base = remainder;
else
base = remainder.substring(0, idx);
base = Util.javaToIDLName(base);
if (previous.equals(""))
previous = base;
else
previous = previous + "/" + base;
if (idx == -1)
remainder = "";
else
remainder = remainder.substring(idx + 1);
LocalContainer next = null;
LocalContained contained = (LocalContained)c._lookup(base);
if (contained instanceof LocalContainer)
next = (LocalContainer)contained;
else if (contained != null)
throw new IRConstructionException("Name collision while creating package.");
if (next == null) {
String id = "IDL:" + previous + ":1.0";
// Create module
ModuleDefImpl m = new ModuleDefImpl(id, base, "1.0", c, impl);
logger.trace("Created module \"" + id + "\".");
c.add(base, m);
if (idx == -1)
return m; // done
next = (LocalContainer)c._lookup(base); // Better be there now...
} else // Check that next _is_ a module
if (next.def_kind() != DefinitionKind.dk_Module)
throw new IRConstructionException("Name collision while creating package.");
return ensurePackageExists(next, previous, remainder);
}
/**
* Add a set of constants to a container (interface or value class).
*/
private void addConstants(LocalContainer container,
ContainerAnalysis ca)
throws RMIIIOPViolationException, IRConstructionException
{
ConstantAnalysis[] consts = ca.getConstants();
for (int i = 0; i < consts.length; ++i) {
ConstantDefImpl cDef;
String cid = ca.getMemberRepositoryId(consts[i].getJavaName());
String cName = consts[i].getIDLName();
Class cls = consts[i].getType();
logger.trace("Constant["+i+"] class: " + cls.getName());
TypeCode typeCode = getConstantTypeCode(cls);
Any value = orb.create_any();
consts[i].insertValue(value);
logger.trace("Adding constant: " + cid);
cDef = new ConstantDefImpl(cid, cName, "1.0",
typeCode, value, container, impl);
container.add(cName, cDef);
}
}
/**
* Add a set of attributes to a container (interface or value class).
*/
private void addAttributes(LocalContainer container,
ContainerAnalysis ca)
throws RMIIIOPViolationException, IRConstructionException
{
AttributeAnalysis[] attrs = ca.getAttributes();
logger.trace("Attribute count: " + attrs.length);
for (int i = 0; i < attrs.length; ++i) {
AttributeDefImpl aDef;
String aid = ca.getMemberRepositoryId(attrs[i].getJavaName());
String aName = attrs[i].getIDLName();
Class cls = attrs[i].getCls();
logger.trace("Attribute["+i+"] class: " + cls.getName());
TypeCode typeCode = getTypeCode(cls);
logger.trace("Adding: " + aid);
aDef = new AttributeDefImpl(aid, aName, "1.0", attrs[i].getMode(),
typeCode, container, impl);
container.add(aName, aDef);
}
}
/**
* Add a set of operations to a container (interface or value class).
*/
private void addOperations(LocalContainer container,
ContainerAnalysis ca)
throws RMIIIOPViolationException, IRConstructionException
{
OperationAnalysis[] ops = ca.getOperations();
logger.debug("Operation count: " + ops.length);
for (int i = 0; i < ops.length; ++i) {
OperationDefImpl oDef;
String oName = ops[i].getIDLName();
String oid = ca.getMemberRepositoryId(oName);
Class cls = ops[i].getReturnType();
logger.debug("Operation["+i+"] return type class: " + cls.getName());
TypeCode typeCode = getTypeCode(cls);
ParameterAnalysis[] ps = ops[i].getParameters();
ParameterDescription[] params = new ParameterDescription[ps.length];
for (int j = 0; j < ps.length; ++j) {
params[j] = new ParameterDescription(ps[j].getIDLName(),
getTypeCode(ps[j].getCls()),
null, // filled in later
ParameterMode.PARAM_IN);
}
ExceptionAnalysis[] exc = ops[i].getMappedExceptions();
ExceptionDef[] exceptions = new ExceptionDef[exc.length];
for (int j = 0; j < exc.length; ++j) {
ExceptionDefImpl e = addException(exc[j]);
exceptions[j] = ExceptionDefHelper.narrow(e.getReference());
}
logger.debug("Adding: " + oid);
oDef = new OperationDefImpl(oid, oName, "1.0", container,
typeCode, params, exceptions, impl);
container.add(oName, oDef);
}
}
/**
* Add a set of interfaces to the IR.
*
* @return An array of the IR IDs of the interfaces.
*/
private String[] addInterfaces(ContainerAnalysis ca)
throws RMIIIOPViolationException, IRConstructionException
{
logger.trace("Adding interfaces: ");
InterfaceAnalysis[] interfaces = ca.getInterfaces();
List base_interfaces = new ArrayList();
for (int i = 0; i < interfaces.length; ++i) {
InterfaceDefImpl idi = addInterface(interfaces[i]);
base_interfaces.add(idi.id());
logger.trace(" " + idi.id());
}
String[] strArr = new String[base_interfaces.size()];
return (String[])base_interfaces.toArray(strArr);
}
/**
* Add a set of abstract valuetypes to the IR.
*
* @return An array of the IR IDs of the abstract valuetypes.
*/
private String[] addAbstractBaseValuetypes(ContainerAnalysis ca)
throws RMIIIOPViolationException, IRConstructionException
{
logger.trace("Adding abstract valuetypes: ");
ValueAnalysis[] abstractValuetypes = ca.getAbstractBaseValuetypes();
List abstract_base_valuetypes = new ArrayList();
for (int i = 0; i < abstractValuetypes.length; ++i) {
ValueDefImpl vdi = addValue(abstractValuetypes[i]);
abstract_base_valuetypes.add(vdi.id());
logger.trace(" " + vdi.id());
}
String[] strArr = new String[abstract_base_valuetypes.size()];
return (String[])abstract_base_valuetypes.toArray(strArr);
}
/**
* Map the class and add its IIOP mapping to the repository.
*/
private void addClass(Class cls)
throws RMIIIOPViolationException, IRConstructionException
{
if (cls.isPrimitive())
return; // No need to add primitives.
if (cls.isArray()) {
// Add array mapping
addArray(cls);
} else if (cls.isInterface()) {
if (!RmiIdlUtil.isAbstractValueType(cls)) {
// Analyse the interface
InterfaceAnalysis ia = InterfaceAnalysis.getInterfaceAnalysis(cls);
// Add analyzed interface (which may be abstract)
addInterface(ia);
}
else {
// Analyse the value
ValueAnalysis va = ValueAnalysis.getValueAnalysis(cls);
// Add analyzed value
addValue(va);
}
} else if (Exception.class.isAssignableFrom(cls)) { // Exception type.
// Analyse the exception
ExceptionAnalysis ea = ExceptionAnalysis.getExceptionAnalysis(cls);
// Add analyzed exception
addException(ea);
} else { // Got to be a value type.
// Analyse the value
ValueAnalysis va = ValueAnalysis.getValueAnalysis(cls);
// Add analyzed value
addValue(va);
}
}
/**
* Add an array.
*/
private ValueBoxDefImpl addArray(Class cls)
throws RMIIIOPViolationException, IRConstructionException
{
if (!cls.isArray())
throw new IllegalArgumentException("Not an array class.");
ValueBoxDefImpl vbDef;
// Lookup: Has it already been added?
vbDef = (ValueBoxDefImpl)arrayMap.get(cls);
if (vbDef != null)
return vbDef; // Yes, just return it.
int dimensions = 0;
Class compType = cls;
do {
compType = compType.getComponentType();
++dimensions;
} while (compType.isArray());
String typeName;
String moduleName;
TypeCode typeCode;
if (compType.isPrimitive()) {
if (compType == Boolean.TYPE) {
typeName = "boolean";
typeCode = orb.get_primitive_tc(TCKind.tk_boolean);
} else if (compType == Character.TYPE) {
typeName = "wchar";
typeCode = orb.get_primitive_tc(TCKind.tk_wchar);
} else if (compType == Byte.TYPE) {
typeName = "octet";
typeCode = orb.get_primitive_tc(TCKind.tk_octet);
} else if (compType == Short.TYPE) {
typeName = "short";
typeCode = orb.get_primitive_tc(TCKind.tk_short);
} else if (compType == Integer.TYPE) {
typeName = "long";
typeCode = orb.get_primitive_tc(TCKind.tk_long);
} else if (compType == Long.TYPE) {
typeName = "long_long";
typeCode = orb.get_primitive_tc(TCKind.tk_longlong);
} else if (compType == Float.TYPE) {
typeName = "float";
typeCode = orb.get_primitive_tc(TCKind.tk_float);
} else if (compType == Double.TYPE) {
typeName = "double";
typeCode = orb.get_primitive_tc(TCKind.tk_double);
} else {
throw new IRConstructionException("Unknown primitive type for " +
"array type: " + cls.getName());
}
moduleName = "org.omg.boxedRMI";
} else {
typeCode = getTypeCode(compType); // map the component type.
if (compType == java.lang.String.class)
typeName = getJavaLangString().name();
else if (compType == java.lang.Object.class)
typeName = getJavaLang_Object().name();
else if (compType == java.lang.Class.class)
typeName = getJavaxRmiCORBAClassDesc().name();
else if (compType == java.io.Serializable.class)
typeName = getJavaIoSerializable().name();
else if (compType == java.io.Externalizable.class)
typeName = getJavaIoExternalizable().name();
else if (compType.isInterface() &&
!RmiIdlUtil.isAbstractValueType(compType))
typeName = ((InterfaceDefImpl)interfaceMap.get(compType)).name();
else if (Exception.class.isAssignableFrom(compType)) // exception type
typeName = ((ExceptionDefImpl)exceptionMap.get(compType)).name();
else // must be value type
typeName = ((ValueDefImpl)valueMap.get(compType)).name();
moduleName = "org.omg.boxedRMI." + compType.getPackage().getName();
}
// Get module to add array to.
ModuleDefImpl m = ensurePackageExists(moduleName);
// Create an array of the types for the dimensions
Class[] types = new Class[dimensions];
types[dimensions-1] = cls;
for (int i = dimensions - 2; i >= 0; --i)
types[i] = types[i+1].getComponentType();
// Create boxed sequences for all dimensions.
for (int i = 0; i < dimensions; ++i) {
Class type = types[i];
typeCode = orb.create_sequence_tc(0, typeCode);
vbDef = (ValueBoxDefImpl)arrayMap.get(type);
if (vbDef == null) {
String id = Util.getIRIdentifierOfClass(type);
SequenceDefImpl sdi = new SequenceDefImpl(typeCode, impl);
String name = "seq" + (i+1) + "_" + typeName;
// TypeCode boxTypeCode = new TypeCodeImpl(TCKind._tk_value_box,
// id, name, typeCode);
TypeCode boxTypeCode = orb.create_value_box_tc(id, name, typeCode);
vbDef = new ValueBoxDefImpl(id, name, "1.0", m, boxTypeCode, impl);
addTypeCode(type, vbDef.type());
m.add(name, vbDef);
impl.putSequenceImpl(id, typeCode, sdi, vbDef);
arrayMap.put(type, vbDef); // Remember we mapped this.
typeCode = boxTypeCode;
} else
typeCode = vbDef.type();
}
// Return the box of higest dimension.
return vbDef;
}
/**
* Add an interface.
*/
private InterfaceDefImpl addInterface(InterfaceAnalysis ia)
throws RMIIIOPViolationException, IRConstructionException
{
InterfaceDefImpl iDef;
Class cls = ia.getCls();
// Lookup: Has it already been added?
iDef = (InterfaceDefImpl)interfaceMap.get(cls);
if (iDef != null)
return iDef; // Yes, just return it.
if (ia.isAbstractInterface())
logger.trace("Adding abstract interface: " + ia.getRepositoryId());
// Get module to add interface to.
ModuleDefImpl m = ensurePackageExists(cls.getPackage().getName());
// Add superinterfaces
String[] base_interfaces = addInterfaces(ia);
// Create the interface
String base = cls.getName();
base = base.substring(base.lastIndexOf('.')+1);
base = Util.javaToIDLName(base);
iDef = new InterfaceDefImpl(ia.getRepositoryId(),
base, "1.0", m,
base_interfaces, impl);
addTypeCode(cls, iDef.type());
m.add(base, iDef);
interfaceMap.put(cls, iDef); // Remember we mapped this.
// Fill in constants
addConstants(iDef, ia);
// Add attributes
addAttributes(iDef, ia);
// Fill in operations
addOperations(iDef, ia);
logger.trace("Added interface: " + ia.getRepositoryId());
return iDef;
}
/**
* Add a value type.
*/
private ValueDefImpl addValue(ValueAnalysis va)
throws RMIIIOPViolationException, IRConstructionException
{
ValueDefImpl vDef;
Class cls = va.getCls();
// Lookup: Has it already been added?
vDef = (ValueDefImpl)valueMap.get(cls);
if (vDef != null)
return vDef; // Yes, just return it.
// Get module to add value to.
ModuleDefImpl m = ensurePackageExists(cls.getPackage().getName());
// Add implemented interfaces
String[] supported_interfaces = addInterfaces(va);
// Add abstract base valuetypes
String[] abstract_base_valuetypes = addAbstractBaseValuetypes(va);
// Add superclass
ValueDefImpl superValue = null;
ValueAnalysis superAnalysis = va.getSuperAnalysis();
if (superAnalysis != null)
superValue = addValue(superAnalysis);
// Create the value
String base = cls.getName();
base = base.substring(base.lastIndexOf('.')+1);
base = Util.javaToIDLName(base);
TypeCode baseTypeCode;
if (superValue == null)
baseTypeCode = orb.get_primitive_tc(TCKind.tk_null);
else
baseTypeCode = superValue.type();
vDef = new ValueDefImpl(va.getRepositoryId(), base, "1.0",
m,
va.isAbstractValue(),
va.isCustom(),
supported_interfaces,
abstract_base_valuetypes,
baseTypeCode,
impl);
addTypeCode(cls, vDef.type());
logger.debug("Value: base=" + base);
m.add(base, vDef);
valueMap.put(cls, vDef); // Remember we mapped this.
// Fill in constants.
addConstants(vDef, va);
// Add value members
ValueMemberAnalysis[] vmas = va.getMembers();
logger.debug("Value member count: " + vmas.length);
for (int i = 0; i < vmas.length; ++i) {
ValueMemberDefImpl vmDef;
String vmid = va.getMemberRepositoryId(vmas[i].getJavaName());
String vmName = vmas[i].getIDLName();
Class vmCls = vmas[i].getCls();
logger.debug("ValueMembers["+i+"] class: " + vmCls.getName());
TypeCode typeCode = getTypeCode(vmCls);
boolean vmPublic = vmas[i].isPublic();
logger.debug("Adding value member: " + vmid);
vmDef = new ValueMemberDefImpl(vmid, vmName, "1.0",
typeCode, vmPublic, vDef, impl);
vDef.add(vmName, vmDef);
}
// Add attributes
addAttributes(vDef, va);
// TODO: Fill in operations.
return vDef;
}
/**
* Add an exception type.
*/
private ExceptionDefImpl addException(ExceptionAnalysis ea)
throws RMIIIOPViolationException, IRConstructionException
{
ExceptionDefImpl eDef;
Class cls = ea.getCls();
// Lookup: Has it already been added?
eDef = (ExceptionDefImpl)exceptionMap.get(cls);
if (eDef != null)
return eDef; // Yes, just return it.
// 1.3.7.1: map to value
ValueDefImpl vDef = addValue(ea);
// 1.3.7.2: map to exception
ModuleDefImpl m = ensurePackageExists(cls.getPackage().getName());
String base = cls.getName();
base = base.substring(base.lastIndexOf('.')+1);
if (base.endsWith("Exception"))
base = base.substring(0, base.length()-9);
base = Util.javaToIDLName(base + "Ex");
StructMember[] members = new StructMember[1];
members[0] = new StructMember("value", vDef.type(), null/*ignored*/);
TypeCode typeCode
= orb.create_exception_tc(ea.getExceptionRepositoryId(),
base, members);
eDef = new ExceptionDefImpl(ea.getExceptionRepositoryId(), base, "1.0",
typeCode, vDef, m, impl);
logger.debug("Exception: base=" + base);
m.add(base, eDef);
exceptionMap.put(cls, eDef); // Remember we mapped this.
return eDef;
}
// Inner classes -------------------------------------------------
}