1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef INCLUDED_CLI_PROXY_H 29 #define INCLUDED_CLI_PROXY_H 30 31 #pragma warning(push, 1) 32 #include "uno/environment.hxx" 33 #pragma warning(pop) 34 #include "uno/mapping.hxx" 35 #include "uno/dispatcher.h" 36 #include "cli_bridge.h" 37 #include "cli_environment.h" 38 39 #using <mscorlib.dll> 40 #using <cli_ure.dll> 41 42 namespace srrp = System::Runtime::Remoting::Proxies; 43 namespace srrm = System::Runtime::Remoting::Messaging; 44 namespace srr = System::Runtime::Remoting; 45 namespace sr = System::Reflection; 46 namespace sc = System::Collections; 47 using namespace uno; 48 49 namespace cli_uno 50 { 51 52 public __gc class UnoInterfaceInfo 53 { 54 public: 55 UnoInterfaceInfo(Bridge const * bridge, uno_Interface* unoI, 56 typelib_InterfaceTypeDescription* td); 57 ~UnoInterfaceInfo(); 58 uno_Interface * m_unoI; // wrapped interface 59 System::Type * m_type; 60 typelib_InterfaceTypeDescription* m_typeDesc; 61 62 Bridge const* m_bridge; 63 }; 64 65 public __gc class UnoInterfaceProxy: public srrp::RealProxy, 66 public srr::IRemotingTypeInfo 67 { 68 /** used for IRemotingTypeInfo.TypeName 69 */ 70 System::String* m_sTypeName; 71 /** The list is filled with UnoInterfaceInfo objects. The list can only 72 grow and elements are never changed. If an element was added it 73 must not be changed! 74 */ 75 sc::ArrayList* m_listIfaces; 76 /** The number of UNO interfaces this proxy represents. It corresponds 77 to the the number of elements in m_listIfaces. 78 */ 79 int m_numUnoIfaces; 80 /** The list is filled with additional UnoInterfaceProxy object due 81 to aggregation via bridges. Though the latter is strongly 82 discouraged, this has to be supported. 83 */ 84 sc::ArrayList* m_listAdditionalProxies; 85 int m_nlistAdditionalProxies; 86 87 UnoInterfaceInfo * findInfo( ::System::Type * type ); 88 89 Bridge const* m_bridge; 90 System::String* m_oid; 91 92 #if OSL_DEBUG_LEVEL >= 2 93 /** The string contains all names of UNO interfaces which are 94 represented by this proxy. It is used to print out the interfaces 95 when this proxy dies. In the destructor it is not allowed to 96 access m_listIfaces or any other managed object. 97 */ 98 rtl_uString * _sInterfaces; 99 // /** Count of interfaces. Used in conjunction with _sInterfaces. 100 // */ 101 int _numInterfaces; 102 #endif 103 104 public: 105 106 /** Creates a proxy and registers it on the dot NET side. 107 */ 108 static System::Object* create(Bridge * bridge, 109 uno_Interface * pUnoI, 110 typelib_InterfaceTypeDescription* pTd, 111 const rtl::OUString& oid); 112 113 /** RealProxy::Invoke */ 114 srrm::IMessage* Invoke(srrm::IMessage* msg); 115 116 /** Must be called from within a synchronized section. 117 Add only the interface if it is not already contained. 118 This method is called from the constructor and as a result 119 of IRemotingTypeInfo::CanCastTo 120 */ 121 void addUnoInterface(uno_Interface* pUnoI, 122 typelib_InterfaceTypeDescription* pTd); 123 ~UnoInterfaceProxy(); 124 125 /** 126 */ 127 inline System::String * getOid() 128 { return m_oid; } 129 130 //IRemotingTypeInfo ---------------------------------------------- 131 bool CanCastTo(System::Type* fromType, System::Object* o); 132 133 __property System::String* get_TypeName() 134 { 135 return m_sTypeName; 136 } 137 __property void set_TypeName(System::String* name) 138 { 139 m_sTypeName = name; 140 } 141 142 143 private: 144 UnoInterfaceProxy( 145 Bridge * bridge, 146 uno_Interface * pUnoI, 147 typelib_InterfaceTypeDescription* pTD, 148 const rtl::OUString& oid ); 149 150 static srrm::IMessage* constructReturnMessage(System::Object* retVal, 151 System::Object* outArgs[], 152 typelib_InterfaceMethodTypeDescription* mtd, 153 srrm::IMessage* msg, System::Object* exc); 154 155 static System::String* m_methodNameString = 156 new System::String("__MethodName"); 157 static System::String* m_typeNameString = new System::String("__TypeName"); 158 static System::String* m_ArgsString = new System::String("__Args"); 159 static System::String* m_CallContextString = 160 new System::String("__CallContext"); 161 static System::String* m_system_Object_String = 162 new System::String("System.Object"); 163 static System::String* m_methodSignatureString = 164 new System::String("__MethodSignature"); 165 static System::String* m_Equals_String = new System::String("Equals"); 166 static System::String* m_GetHashCode_String = 167 new System::String("GetHashCode"); 168 static System::String* m_GetType_String = new System::String("GetType"); 169 static System::String* m_ToString_String = new System::String("ToString"); 170 171 protected: 172 srrm::IMessage* invokeObject(sc::IDictionary* properties, 173 srrm::LogicalCallContext* context, 174 srrm::IMethodCallMessage* mcm); 175 }; 176 177 178 //Cannot make this __gc because a managed type cannot derive from unmanaged type 179 struct CliProxy: public uno_Interface 180 { 181 mutable oslInterlockedCount m_ref; 182 const Bridge* m_bridge; 183 const gcroot<System::Object*> m_cliI; 184 gcroot<System::Type*> m_type; 185 const com::sun::star::uno::TypeDescription m_unoType; 186 const gcroot<System::String*> m_oid; 187 const rtl::OUString m_usOid; 188 189 enum MethodKind {MK_METHOD = 0, MK_SET, MK_GET}; 190 /** The array contains MethodInfos of the cli object. Each one reflects an 191 implemented interface method of the interface for which this proxy was 192 created. The MethodInfos are from the object's method and not from the 193 interface type. That is, they can be used to invoke the methods. The 194 order of the MethodInfo objects corresponds to the order of the 195 interface methods (see member m_type). Position 0 contains the 196 MethodInfo of the first method of the interface which represents the 197 root of the inheritance chain. The last MethodInfo represents the last 198 method of the furthest derived interface. 199 200 The array is completely initialized in the constructor of this object. 201 202 When the uno_DispatchMethod is called for this proxy then it receives 203 a typelib_TypeDescription of the member which is either an attribute 204 (setter or getter) or method. After determining the position of the 205 method within the UNO interface one can use the position to obtain the 206 MethodInfo of the corresponding cli method. To obtain the index for the 207 m_arMethodInfos array the function position has to be decreased by 3. 208 This is becaus, the cli interface does not contain the XInterface 209 methods. 210 */ 211 gcroot<sr::MethodInfo*[]> m_arMethodInfos; 212 213 /** This array is similar to m_arMethodInfos but it contains the MethodInfo 214 objects of the interface (not the object). When a call is made from uno 215 to cli then the uno method name is compared to the cli method name. The 216 cli method name can be obtained from the MethodInfo object in this 217 array. The name of the actual implemented method may not be the same as 218 the interface method. 219 */ 220 gcroot<sr::MethodInfo*[]> m_arInterfaceMethodInfos; 221 222 /** Maps the position of the method in the UNO interface to the position of 223 the corresponding MethodInfo in m_arMethodInfos. The Uno position must 224 not include the XInterface methods. For example, 225 pos 0 = XInterface::queryInterface 226 pos 1 = XInterface::acquire 227 pos 2 = XInterface::release 228 229 That is the real Uno position has to be deducted by 3. Then 230 arUnoPosToCliPos[pos] contains the index for m_arMethodInfos. 231 232 */ 233 gcroot<System::Int32[]> m_arUnoPosToCliPos; 234 235 /** Count of inherited interfaces of the cli interface. 236 */ 237 int m_nInheritedInterfaces; 238 /** Contains the number of methods of each interface. 239 */ 240 gcroot<System::Int32[]> m_arInterfaceMethodCount; 241 242 CliProxy( Bridge const* bridge, System::Object* cliI, 243 typelib_TypeDescription const* pTD, 244 const rtl::OUString& usOid); 245 ~CliProxy(); 246 247 static uno_Interface* create(Bridge const * bridge, 248 System::Object* cliI, 249 typelib_TypeDescription const * TD, 250 rtl::OUString const & usOid ); 251 252 /** Prepares an array (m_arMethoInfos) containing MethodInfo object of the 253 interface and all inherited interfaces. At index null is the first 254 method of the base interface and at the last position is the last method 255 of the furthest derived interface. 256 If a UNO call is received then one can determine the position of the 257 method (or getter or setter for an attribute) from the passed type 258 information. The position minus 3 (there is no XInterface in the cli 259 mapping) corresponds to the index of the cli interface method in the 260 array. 261 */ 262 void makeMethodInfos(); 263 264 /**Obtains a MethodInfo which can be used to invoke the cli object. 265 Internally it maps nUnoFunctionPos to an index that is used to get the 266 corresponding MethodInfo object from m_arMethoInfos. The mapping table 267 is dynamically initialized. If the cli interface has no base interface 268 or exactly one then the mapping table is initialized in one go at the 269 first call. In all ensuing calls the MethodInfo object is immediately 270 retrieved through the mapping table. 271 272 If the interface has more then one interface in its inheritance chain, 273 that is Type.GetInterfaces return more then one Type, then the mapping 274 table is partially initiallized. On the first call the mappings for the 275 methods of the belonging interface are created. 276 277 The implementation assumes that the order of interface methods as 278 provided by InterfaceMapping.InterfaceMethods corresponds to the order 279 of methods in the interface declaration. 280 281 @param nUnoFunctionPos 282 Position of the method in the uno interface. 283 */ 284 sr::MethodInfo* getMethodInfo(int nUnoFunctionPos, 285 const rtl::OUString & usMethodName, 286 MethodKind mk); 287 288 void SAL_CALL uno_DispatchMethod( 289 struct _uno_Interface * pUnoI, 290 const struct _typelib_TypeDescription * pMemberType, 291 void * pReturn, 292 void * pArgs[], 293 uno_Any ** ppException ); 294 295 inline void acquire() const; 296 inline void release() const; 297 }; 298 } 299 #endif 300