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 #include "unodevtools/typemanager.hxx"
25
26 #include "rtl/alloc.h"
27 #include "registry/reader.hxx"
28 #include "cppuhelper/bootstrap.hxx"
29
30 #include "com/sun/star/container/XSet.hpp"
31 #include "com/sun/star/reflection/XTypeDescription.hpp"
32 #include "com/sun/star/registry/XSimpleRegistry.hpp"
33 #include "com/sun/star/uno/XComponentContext.hpp"
34
35 using namespace ::rtl;
36 using namespace ::cppu;
37 using namespace ::com::sun::star::uno;
38 using namespace ::com::sun::star::lang;
39 using namespace ::com::sun::star::container;
40 using namespace ::com::sun::star::registry;
41 using namespace ::com::sun::star::reflection;
42
43 namespace unodevtools {
44
mapTypeClass(TypeClass typeclass)45 static RTTypeClass mapTypeClass(TypeClass typeclass) {
46 switch(typeclass) {
47 case TypeClass_ENUM:
48 return RT_TYPE_ENUM;
49 case TypeClass_TYPEDEF:
50 return RT_TYPE_TYPEDEF;
51 case TypeClass_STRUCT:
52 return RT_TYPE_STRUCT;
53 case TypeClass_UNION:
54 return RT_TYPE_UNION;
55 case TypeClass_EXCEPTION:
56 return RT_TYPE_EXCEPTION;
57 case TypeClass_INTERFACE:
58 return RT_TYPE_INTERFACE;
59 case TypeClass_SERVICE:
60 return RT_TYPE_SERVICE;
61 case TypeClass_MODULE:
62 return RT_TYPE_MODULE;
63 case TypeClass_CONSTANTS:
64 return RT_TYPE_CONSTANTS;
65 case TypeClass_SINGLETON:
66 return RT_TYPE_SINGLETON;
67 default:
68 break;
69 }
70 return RT_TYPE_INVALID;
71 }
72
73
UnoTypeManager()74 UnoTypeManager::UnoTypeManager()
75 {
76 m_pImpl = new UnoTypeManagerImpl();
77 acquire();
78 }
79
~UnoTypeManager()80 UnoTypeManager::~UnoTypeManager()
81 {
82 release();
83 }
84
release()85 void UnoTypeManager::release()
86 {
87 if (0 == TypeManager::release())
88 delete m_pImpl;
89 }
90
init(const::std::vector<::rtl::OUString> registries)91 sal_Bool UnoTypeManager::init(
92 const ::std::vector< ::rtl::OUString > registries)
93 {
94 Reference< XComponentContext > xContext=
95 defaultBootstrap_InitialComponentContext();
96
97 if ( !xContext.is() ) {
98 OUString msg(RTL_CONSTASCII_USTRINGPARAM(
99 "internal UNO problem, can't create initial UNO component context"));
100 throw RuntimeException( msg, Reference< XInterface >());
101 }
102 Any a = xContext->getValueByName(
103 OUString(RTL_CONSTASCII_USTRINGPARAM(
104 "/singletons/com.sun.star.reflection.theTypeDescriptionManager")));
105
106 a >>= m_pImpl->m_tdmgr;
107
108 if ( !m_pImpl->m_tdmgr.is() ) {
109 OUString msg(RTL_CONSTASCII_USTRINGPARAM(
110 "internal UNO problem, can't get TypeDescriptionManager"));
111 throw RuntimeException( msg, Reference< XInterface >());
112 }
113
114 if ( !registries.empty() ) {
115
116 Reference< XMultiComponentFactory > xServiceManager(
117 xContext->getServiceManager() );
118 if ( !xServiceManager.is() ) {
119 OUString msg(RTL_CONSTASCII_USTRINGPARAM(
120 "internal UNO problem, can't get ServiceManager"));
121 throw RuntimeException( msg, Reference< XInterface >());
122 }
123
124 Sequence<Any> seqArgs(registries.size());
125
126 std::vector< OUString >::const_iterator iter = registries.begin();
127 int i = 0;
128 while ( iter != registries.end() )
129 {
130 Reference< XSimpleRegistry > xReg(
131 xServiceManager->createInstanceWithContext(
132 OUString(RTL_CONSTASCII_USTRINGPARAM(
133 "com.sun.star.registry.SimpleRegistry")),
134 xContext), UNO_QUERY);
135 xReg->open(convertToFileUrl(
136 OUStringToOString(*iter, RTL_TEXTENCODING_UTF8)),
137 sal_True, sal_False);
138
139 seqArgs[i++] = makeAny(xReg);
140 iter++;
141 }
142
143 Reference< XHierarchicalNameAccess > xTDProvider(
144 xServiceManager->createInstanceWithArgumentsAndContext(
145 OUString(RTL_CONSTASCII_USTRINGPARAM(
146 "com.sun.star.reflection.TypeDescriptionProvider")),
147 seqArgs, xContext),
148 UNO_QUERY);
149 if ( !xTDProvider.is() ) {
150 OUString msg(RTL_CONSTASCII_USTRINGPARAM(
151 "internal UNO problem, can't create local"
152 " type description provider"));
153 throw RuntimeException( msg, Reference< XInterface >());
154 }
155
156 a = makeAny(xTDProvider);
157 Reference< XSet > xSet(m_pImpl->m_tdmgr, UNO_QUERY);
158 xSet->insert(a);
159 }
160
161 return sal_True;
162 }
163
isValidType(const::rtl::OString & name) const164 sal_Bool UnoTypeManager::isValidType(const ::rtl::OString& name) const
165 {
166 return m_pImpl->m_tdmgr->hasByHierarchicalName(
167 OStringToOUString(name, RTL_TEXTENCODING_UTF8));
168 }
169
getTypeName(RegistryKey & rTypeKey) const170 OString UnoTypeManager::getTypeName(RegistryKey& rTypeKey) const
171 {
172 OString typeName = OUStringToOString(rTypeKey.getName(), RTL_TEXTENCODING_UTF8);
173 static OString sBase("/UCR");
174 if (typeName.indexOf(sBase) == 0) {
175 typeName = typeName.copy(typeName.indexOf('/', 1) + 1);
176 } else {
177 typeName = typeName.copy(1);
178 }
179 return typeName;
180 }
181
182 // extern
183 void* getTypeBlob(Reference< XHierarchicalNameAccess > xTDmgr,
184 const OString& typeName, sal_uInt32* pBlob);
185
getTypeReader(const OString & name,sal_Bool *) const186 typereg::Reader UnoTypeManager::getTypeReader(
187 const OString& name, sal_Bool * /*pIsExtraType*/ ) const
188 {
189 typereg::Reader reader;
190
191 void* pBlob = NULL;
192 sal_uInt32 blobsize = 0;
193
194 if ( (pBlob = getTypeBlob(m_pImpl->m_tdmgr, name, &blobsize)) != NULL )
195 reader = typereg::Reader(pBlob, blobsize, sal_True, TYPEREG_VERSION_1);
196
197 if ( pBlob )
198 rtl_freeMemory(pBlob);
199
200 return reader;
201 }
202
getTypeReader(RegistryKey & rTypeKey) const203 typereg::Reader UnoTypeManager::getTypeReader(RegistryKey& rTypeKey) const
204 {
205 typereg::Reader reader;
206
207 if (rTypeKey.isValid()) {
208 RegValueType valueType;
209 sal_uInt32 valueSize;
210
211 if (!rTypeKey.getValueInfo(OUString(), &valueType, &valueSize)) {
212 sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
213 if ( !rTypeKey.getValue(OUString(), pBuffer) ) {
214 reader = typereg::Reader(
215 pBuffer, valueSize, true, TYPEREG_VERSION_1);
216 }
217 rtl_freeMemory(pBuffer);
218 }
219 }
220 return reader;
221 }
222
223
getTypeClass(const OString & name) const224 RTTypeClass UnoTypeManager::getTypeClass(const OString& name) const
225 {
226 if ( m_pImpl->m_t2TypeClass.count(name) > 0 ) {
227 return m_pImpl->m_t2TypeClass[name];
228 } else {
229 Reference< XTypeDescription > xTD;
230 Any a = m_pImpl->m_tdmgr->getByHierarchicalName(
231 OStringToOUString(name, RTL_TEXTENCODING_UTF8));
232 a >>= xTD;
233
234 if ( xTD.is() ) {
235 RTTypeClass tc = mapTypeClass(xTD->getTypeClass());
236 if (tc != RT_TYPE_INVALID)
237 m_pImpl->m_t2TypeClass[name] = tc;
238 return tc;
239 }
240 }
241
242 return RT_TYPE_INVALID;
243 }
244
getTypeClass(RegistryKey & rTypeKey) const245 RTTypeClass UnoTypeManager::getTypeClass(RegistryKey& rTypeKey) const
246 {
247 OString name = getTypeName(rTypeKey);
248
249 if ( m_pImpl->m_t2TypeClass.count(name) > 0 ) {
250 return m_pImpl->m_t2TypeClass[name];
251 } else {
252 if ( rTypeKey.isValid() ) {
253 RegValueType valueType;
254 sal_uInt32 valueSize;
255
256 if ( !rTypeKey.getValueInfo(OUString(), &valueType, &valueSize) ) {
257 sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
258 if ( !rTypeKey.getValue(OUString(), pBuffer) ) {
259 typereg::Reader reader(
260 pBuffer, valueSize, false, TYPEREG_VERSION_1);
261
262 RTTypeClass ret = reader.getTypeClass();
263
264 rtl_freeMemory(pBuffer);
265
266 m_pImpl->m_t2TypeClass[name] = ret;
267 return ret;
268 }
269 rtl_freeMemory(pBuffer);
270 }
271 }
272 }
273
274 return RT_TYPE_INVALID;
275 }
276
277 } // end of namespace unodevtools
278