Пример #1
0
        /// <summary>
        /// specify a special mapping, e.g. CLS ArrayList <=> java.util.ArrayList.
        /// </summary>
        /// <param name="clsType">the native cls type, e.g. ArrayList</param>
        /// <param name="idlType">the idl type (mapped from idl to CLS) used to describe serialisation / deserialisation, e.g. java.util.ArrayListImpl</param>
        /// <param name="mapper">the mapper, knowing how to map instances of CLS ArrayList to java.util.ArrayListImpl and in the other direction</param>
        public void AddMapping(Type clsType, Type idlType, ICustomMapper mapper)
        {
            // check that idlType implements IIdlEntity:
            if (!(ReflectionHelper.IIdlEntityType.IsAssignableFrom(idlType)))
            {
                throw new Exception("illegal type for custom mapping encountered: " + idlType.FullName);
            }
            // be aware: mapping is not bijektive, because of impl classes; however for an idl type only one
            // cls type is allowed
            if (m_mappingsIdl.ContainsKey(idlType) && (!((CustomMappingDesc)m_mappingsIdl[idlType]).ClsType.Equals(clsType)))
            {
                throw new Exception("mapping constraint violated, tried to insert another cls type " + clsType +
                                    "mapped to the idl type " + idlType);
            }

            CustomMappingDesc desc = new CustomMappingDesc(clsType, idlType, mapper);

            m_mappingsCls[clsType] = desc;
            m_mappingsIdl[idlType] = desc;
            // check for impl class attribute, if present: add impl class here too
            object[] implAttr = idlType.GetCustomAttributes(ReflectionHelper.ImplClassAttributeType, false);
            if ((implAttr != null) && (implAttr.Length > 0))
            {
                ImplClassAttribute implCl = (ImplClassAttribute)implAttr[0];
                // get the type
                Type implIdlType = Repository.GetValueTypeImplClass(implCl.ImplClass);
                if (implIdlType != null)   // if impl type not found, (test needed e.g. when called from CLSToIDLGen)
                {
                    CustomMappingDesc descImpl = new CustomMappingDesc(clsType, implIdlType, mapper);
                    m_mappingsIdl[implIdlType] = descImpl;
                }
            }
        }
Пример #2
0
        /// <summary>
        /// takes an instance deserialised from a cdr stream and maps it to the instance
        /// used in .NET. The mapped instance must be assignable to formalSig.
        /// </summary>
        /// <remarks>
        /// Custom mapping must be present; otherwise an exception is thrown.
        /// </remarks>
        public object CreateClsForIdlInstance(object idlInstance, Type formalSig)
        {
            // for subtype of idl formal support, get acutal mapping
            CustomMappingDesc actualMapping = GetMappingForIdl(idlInstance.GetType());

            if (actualMapping == null)
            {
                throw new BAD_PARAM(12309, CompletionStatus.Completed_MayBe);
            }
            ICustomMapper mapper = actualMapping.Mapper;
            object        result = mapper.CreateClsForIdlInstance(idlInstance);

            // check, if mapped instance is assignable to formal in CLS signature -> otherwise will not work.
            if (!formalSig.IsAssignableFrom(result.GetType()))
            {
                throw new BAD_PARAM(12311, CompletionStatus.Completed_MayBe);
            }
            return(result);
        }
Пример #3
0
        /// <summary>
        /// takes a .NET instance and maps it to the instance, which should be serialised into
        /// the CDR stream. The mapped instance must be assignable to the formal type specified in idl.
        /// </summary>
        /// <remarks>
        /// Custom mapping must be present; otherwise an exception is thrown.
        /// </remarks>
        public object CreateIdlForClsInstance(object clsInstance, Type formal)
        {
            // for subtypes support (subtypes of formal before cls to idl mapping; new formal is idl formal)
            CustomMappingDesc actualMapping =
                GetMappingForCls(clsInstance.GetType());

            if (actualMapping == null)
            {
                throw new BAD_PARAM(12308, CompletionStatus.Completed_MayBe);
            }
            ICustomMapper mapper = actualMapping.Mapper;
            object        actual = mapper.CreateIdlForClsInstance(clsInstance);

            // check, if mapped is instance is assignable to formal -> otherwise will not work on other side ...
            if (!formal.IsAssignableFrom(actual.GetType()))
            {
                throw new BAD_PARAM(12310, CompletionStatus.Completed_MayBe);
            }
            return(actual);
        }
Пример #4
0
        /// <summary>
        /// specify a special mapping, e.g. CLS ArrayList <=> java.util.ArrayList.
        /// </summary>
        /// <param name="clsType">the native cls type, e.g. ArrayList</param>
        /// <param name="idlType">the idl type (mapped from idl to CLS) used to describe serialisation / deserialisation, e.g. java.util.ArrayListImpl</param>
        /// <param name="mapper">the mapper, knowing how to map instances of CLS ArrayList to java.util.ArrayListImpl and in the other direction</param>
        public void AddMapping(Type clsType, Type idlType, ICustomMapper mapper) {
            // check that idlType implements IIdlEntity:
            if (!(ReflectionHelper.IIdlEntityType.IsAssignableFrom(idlType))) {
                throw new Exception("illegal type for custom mapping encountered: " + idlType.FullName);
            }
            // be aware: mapping is not bijektive, because of impl classes; however for an idl type only one
            // cls type is allowed
            if (m_mappingsIdl.ContainsKey(idlType) && (!((CustomMappingDesc)m_mappingsIdl[idlType]).ClsType.Equals(clsType))) {
                throw new Exception("mapping constraint violated, tried to insert another cls type " + clsType +
                                     "mapped to the idl type " + idlType);
            }

            CustomMappingDesc desc = new CustomMappingDesc(clsType, idlType, mapper);
            m_mappingsCls[clsType] = desc;
            m_mappingsIdl[idlType] = desc;
            // check for impl class attribute, if present: add impl class here too
            object[] implAttr = idlType.GetCustomAttributes(ReflectionHelper.ImplClassAttributeType, false);
            if ((implAttr != null) && (implAttr.Length > 0)) {
                ImplClassAttribute implCl = (ImplClassAttribute) implAttr[0];
                // get the type
                Type implIdlType = Repository.GetValueTypeImplClass(implCl.ImplClass);
                if (implIdlType != null) { // if impl type not found, (test needed e.g. when called from CLSToIDLGen)
                    CustomMappingDesc descImpl = new CustomMappingDesc(clsType, implIdlType, mapper);
                    m_mappingsIdl[implIdlType] = descImpl;
                }
            }
        }
Пример #5
0
        /// <summary>uses MappingAction action while mapping a CLS-type to an IDL-type</summary>
        /// <param name="clsType">the type to map. The mapper can decide to transform the type during the mapping, the result of the transformation is returned. Transformation occurs, for example because of attributes</param>
        /// <param name="action">the action to take for the determined mapping</param>
        /// <param name="attributes">the attributes on the param, field, return value; a new collection without the considered attributes is returned</param>
        /// <param name="usedCustomMapping">the custom mapping used if any; otherwise null</param>
        public object MapClsTypeWithTransform(ref Type clsType, ref AttributeExtCollection attributes, MappingAction action,
                                              out CustomMappingDesc usedCustomMapping) {
                                              
            TypeCodeCreater.TypecodeForTypeKey key = new TypeCodeCreater.TypecodeForTypeKey(clsType, attributes);
            MapType mapType = MapType.Unknown;
            
            lock(mapTypes) {
                if(!mapTypes.TryGetValue(key, out mapType))
                    mapType = MapType.Unknown;
            }
            // handle out, ref types correctly: no other action needs to be taken than for in-types
            usedCustomMapping = null;
            AttributeExtCollection originalAttributes = attributes; // used to save reference to the passed in attributes
            if (clsType.IsByRef) {
                clsType = clsType.GetElementType(); 
            }
            
            // check for plugged special mappings, e.g. CLS ArrayList -> java.util.ArrayList
            CustomMapperRegistry cReg = CustomMapperRegistry.GetSingleton();
            if (cReg.IsCustomMappingPresentForCls(clsType)) {
                usedCustomMapping = cReg.GetMappingForCls(clsType);
                clsType = usedCustomMapping.IdlType;
            }

            // check some standard cases
            Attribute boxedValAttr;
            attributes = originalAttributes.RemoveAttributeOfType(s_boxedValAttrType, out boxedValAttr);
            
            if(mapType == MapType.Unknown)
            {
                if (boxedValAttr != null) { 
                    // load the boxed value-type for this attribute
                    Type boxed = GetBoxedValueType((BoxedValueAttribute)boxedValAttr);
                    if (boxed == null) { 
                        Trace.WriteLine("boxed type not found for boxed value attribute"); 
                        mapType = MapType.BoxedValueNotFound;
                    } else {
                        Type needsBoxingFrom = clsType;
                        clsType = boxed; // transformation
                        mapType = MapType.BoxedValue;
                    }
                } else if (IsInterface(clsType) && !(clsType.Equals(ReflectionHelper.CorbaTypeCodeType))) {
                    mapType = MapType.Interface;
                } else if (IsMarshalByRef(clsType)) {
                    mapType = MapType.MarshalByRef;
                } else if (IsMappablePrimitiveType(clsType)) {
                    mapType = MapType.Primitive;
                } else if (IsEnum(clsType)) { 
                    if (HasEnumFlagsAttributes(clsType)) {
                        mapType = MapType.Flags;
                    } else {
                        // enums with more than Int32.MaxValue elements can't be mapped to idl.
                        // but not possibly to check this, because in .NET 1.0, no support for Array.LongLength.
                        mapType = MapType.Enum;
                    }
                } else if (IsArray(clsType)) { 
                    mapType = MapType.Array;
                } else if (clsType.IsSubclassOf(ReflectionHelper.BoxedValueBaseType)) {
                    // a boxed value type, which needs not to be boxed/unboxed but should be handled like a normal value type
                    mapType = MapType.BoxedValue2;
                } else if (clsType.IsSubclassOf(s_exceptType) || clsType.Equals(s_exceptType)) {
                    mapType = MapType.Exception;
                } else if (IsMarshalledAsStruct(clsType)) {
                     mapType = MapType.Struct;
                } else if (IsMarshalledAsUnion(clsType)) {
                    mapType = MapType.Union;
                } else if (clsType.Equals(ReflectionHelper.ObjectType)) {
                    mapType = MapType.Object;
                } else if (clsType.Equals(s_anyType)) {
                    mapType = MapType.Any;
                } else if (clsType.Equals(ReflectionHelper.TypeType) || clsType.IsSubclassOf(ReflectionHelper.TypeType)) {
                    mapType = MapType.TypeDesc;
                } else if (clsType.Equals(s_corbaTypeCodeImplType) || clsType.IsSubclassOf(s_corbaTypeCodeImplType) ||
                           clsType.Equals(ReflectionHelper.CorbaTypeCodeType)) {
                    mapType = MapType.TypeCode;
                } else if (!UnmappableType(clsType)) {
                    if (IsValueTypeConcrete(clsType)) {
                        mapType = MapType.ConcreteValue;
                    } else {
                        // other types are mapped to an abstract value type
                        mapType = MapType.AbstractValue;
                    }
                } else {
                    // not mappable: clsType
                    mapType = MapType.Unmappable;
                }
                
                lock(mapTypes)
                    mapTypes[key] = mapType;
            }
            
            switch(mapType)
            {
                case MapType.BoxedValueNotFound:
                    Trace.WriteLine("boxed type not found for boxed value attribute"); 
                    throw new NO_IMPLEMENT(10001, CompletionStatus.Completed_MayBe);
                case MapType.BoxedValue:
                    Type boxed = GetBoxedValueType((BoxedValueAttribute)boxedValAttr);
                    Type needsBoxingFrom = clsType;
                    clsType = boxed; // transformation
                    return action.MapToIdlBoxedValueType(boxed, needsBoxingFrom);
                case MapType.Interface:
                    return CallActionForDNInterface(ref clsType, action);
                case MapType.MarshalByRef:
                    return action.MapToIdlConcreteInterface(clsType);
                case MapType.Primitive:
                    return CallActionForDNPrimitveType(ref clsType, ref attributes, action);
                case MapType.Flags:
                    return action.MapToIdlFlagsEquivalent(clsType);
                case MapType.Enum:
                    // enums with more than Int32.MaxValue elements can't be mapped to idl.
                    // but not possibly to check this, because in .NET 1.0, no support for Array.LongLength.
                    return action.MapToIdlEnum(clsType);
                case MapType.Array:
                    return CallActionForDNArray(ref clsType, ref attributes, originalAttributes, action);
                case MapType.BoxedValue2:
                    // a boxed value type, which needs not to be boxed/unboxed but should be handled like a normal value type
                    return action.MapToIdlBoxedValueType(clsType, null);
                case MapType.Exception:
                    return action.MapException(clsType);
                case MapType.Struct:
                     return action.MapToIdlStruct(clsType);
                case MapType.Union:
                    return action.MapToIdlUnion(clsType);
                case MapType.Object:
                    return CallActionForDNObject(ref clsType, ref attributes, action);
                case MapType.Any:
                    return action.MapToIdlAny(clsType);
                case MapType.TypeDesc:
                    return action.MapToTypeDesc(clsType);
                case MapType.TypeCode:
                    return action.MapToTypeCode(clsType);
                case MapType.ConcreteValue:
                    return action.MapToIdlConcreateValueType(clsType);
                case MapType.AbstractValue:
                    // other types are mapped to an abstract value type
                    return action.MapToIdlAbstractValueType(clsType);                   
            }
            // not mappable: clsType
            throw new BAD_PARAM(18800, CompletionStatus.Completed_MayBe, "The type " + clsType.AssemblyQualifiedName +
                               " is not mappable to idl");
        }