1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_cli_ure.hxx"
26 
27 #include "Cli_environment.h"
28 
29 #using <mscorlib.dll>
30 #using <cli_ure.dll>
31 #using <system.dll>
32 #include "osl/diagnose.h"
33 #include "cli_proxy.h"
34 
35 using namespace System::Runtime::Remoting;
36 using namespace System::Runtime::Remoting::Proxies;
37 using namespace System::Collections;
38 using namespace System::Text;
39 using namespace System::Diagnostics;
40 using namespace System::Threading;
41 
42 namespace cli_uno
43 {
44 
createKey(System::String * oid,System::Type * t)45 inline System::String* Cli_environment::createKey(System::String* oid, System::Type* t)
46 {
47     return System::String::Concat(oid, t->get_FullName());
48 }
49 
50 
Cli_environment()51 inline Cli_environment::Cli_environment()
52 {
53 #if OSL_DEBUG_LEVEL >= 2
54     _numRegisteredObjects = 0;
55 #endif
56 }
57 
~Cli_environment()58 Cli_environment::~Cli_environment()
59 {
60     OSL_ENSURE(_numRegisteredObjects == 0,
61                "cli uno bridge: CLI environment contains unrevoked objects");
62 }
63 
64 
registerInterface(System::Object * obj,System::String * oid)65 System::Object* Cli_environment::registerInterface(
66     System::Object* obj, System::String* oid)
67 {
68 #if OSL_DEBUG_LEVEL >= 1
69     //obj must be a transparent proxy
70     OSL_ASSERT(RemotingServices::IsTransparentProxy(obj));
71     _numRegisteredObjects ++;
72 #endif
73     OSL_ASSERT( ! m_objects->ContainsKey(oid));
74     m_objects->Add(oid, new WeakReference(obj));
75     return obj;
76 }
registerInterface(System::Object * obj,System::String * oid,System::Type * type)77 System::Object* Cli_environment::registerInterface      (
78     System::Object* obj, System::String* oid, System::Type* type)
79 {
80 #if OSL_DEBUG_LEVEL >= 1
81     //obj must be a real cli object
82     OSL_ASSERT( ! RemotingServices::IsTransparentProxy(obj));
83     _numRegisteredObjects ++;
84 #endif
85     System::String* key = createKey(oid, type);
86     //see synchronization in map_uno2cli in cli_data.cxx
87     OSL_ASSERT( ! m_objects->ContainsKey(key));
88     m_objects->Add(key, new WeakReference(obj));
89     return obj;
90 }
91 
revokeInterface(System::String * oid,System::Type * type)92 void Cli_environment::revokeInterface(System::String* oid, System::Type* type)
93 {
94     System::String* key = type != NULL ? createKey(oid, type) : oid;
95 #if OSL_DEBUG_LEVEL >= 1
96     _numRegisteredObjects --;
97 #endif
98 #if OSL_DEBUG_LEVEL >= 2
99     int i = 1;
100     if (m_objects->ContainsKey(key) == false)
101     {
102         Trace::WriteLine("cli uno bridge: try to revoke unregistered interface");
103         Trace::WriteLine(oid);
104         i = 0;
105     }
106     Trace::WriteLine(System::String::Format(
107                          new System::String(S"cli uno bridge: {0} remaining registered interfaces"),
108                          __box(m_objects->get_Count() - 1)));
109 #endif
110     m_objects->Remove(key);
111 }
112 
revokeInterface(System::String * oid)113 inline void Cli_environment::revokeInterface(System::String* oid)
114 {
115     return revokeInterface(oid, NULL);
116 }
117 
getRegisteredInterface(System::String * oid,System::Type * type)118 System::Object* Cli_environment::getRegisteredInterface(System::String* oid,
119                                                         System::Type* type)
120 {
121     //try if it is a UNO interface
122     System::Object* ret = NULL;
123     ret = m_objects->get_Item(oid);
124     if (! ret)
125     {
126         //try if if it is a proxy for a cli object
127         oid = createKey(oid, type);
128         ret = m_objects->get_Item( oid );
129     }
130     if (ret != 0)
131     {
132         System::WeakReference* weakIface =
133             static_cast< System::WeakReference * >( ret );
134         ret = weakIface->Target;
135     }
136     if (ret == 0)
137         m_objects->Remove( oid );
138     return ret;
139 }
140 
getObjectIdentifier(System::Object * obj)141 System::String* Cli_environment::getObjectIdentifier(System::Object* obj)
142 {
143     System::String* oId= 0;
144     RealProxy* aProxy= RemotingServices::GetRealProxy(obj);
145     if (aProxy)
146     {
147         UnoInterfaceProxy* proxyImpl= dynamic_cast<UnoInterfaceProxy*>(aProxy);
148         if (proxyImpl)
149             oId= proxyImpl->getOid();
150     }
151 
152     if (oId == 0)
153     {
154         StringBuilder * buf= new StringBuilder(256);
155 		bool bFirst = false;
156 		System::Threading::Monitor::Enter(__typeof(Cli_environment));
157 		try {
158 			buf->Append(m_IDGen->GetId(obj, & bFirst));
159 		} __finally
160         {
161             System::Threading::Monitor::Exit(__typeof(Cli_environment));
162         }
163 
164         buf->Append(sOidPart);
165         oId= buf->ToString();
166     }
167     return oId;
168 }
169 } //namespace cli_uno
170