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