Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "unodevtools/typemanager.hxx"
21 :
22 : #include "rtl/alloc.h"
23 : #include "registry/reader.hxx"
24 : #include "cppuhelper/bootstrap.hxx"
25 :
26 : #include "com/sun/star/container/XSet.hpp"
27 : #include "com/sun/star/reflection/XTypeDescription.hpp"
28 : #include "com/sun/star/registry/XSimpleRegistry.hpp"
29 : #include "com/sun/star/uno/XComponentContext.hpp"
30 :
31 : using namespace ::rtl;
32 : using namespace ::cppu;
33 : using namespace ::com::sun::star::uno;
34 : using namespace ::com::sun::star::lang;
35 : using namespace ::com::sun::star::container;
36 : using namespace ::com::sun::star::registry;
37 : using namespace ::com::sun::star::reflection;
38 :
39 : namespace unodevtools {
40 :
41 0 : static RTTypeClass mapTypeClass(TypeClass typeclass) {
42 0 : switch(typeclass) {
43 : case TypeClass_ENUM:
44 0 : return RT_TYPE_ENUM;
45 : case TypeClass_TYPEDEF:
46 0 : return RT_TYPE_TYPEDEF;
47 : case TypeClass_STRUCT:
48 0 : return RT_TYPE_STRUCT;
49 : case TypeClass_UNION:
50 0 : return RT_TYPE_UNION;
51 : case TypeClass_EXCEPTION:
52 0 : return RT_TYPE_EXCEPTION;
53 : case TypeClass_INTERFACE:
54 0 : return RT_TYPE_INTERFACE;
55 : case TypeClass_SERVICE:
56 0 : return RT_TYPE_SERVICE;
57 : case TypeClass_MODULE:
58 0 : return RT_TYPE_MODULE;
59 : case TypeClass_CONSTANTS:
60 0 : return RT_TYPE_CONSTANTS;
61 : case TypeClass_SINGLETON:
62 0 : return RT_TYPE_SINGLETON;
63 : default:
64 0 : break;
65 : }
66 0 : return RT_TYPE_INVALID;
67 : }
68 :
69 :
70 0 : UnoTypeManager::UnoTypeManager()
71 : {
72 0 : m_pImpl = new UnoTypeManagerImpl();
73 0 : acquire();
74 0 : }
75 :
76 0 : UnoTypeManager::~UnoTypeManager()
77 : {
78 0 : release();
79 0 : }
80 :
81 0 : void UnoTypeManager::release()
82 : {
83 0 : if (0 == TypeManager::release())
84 0 : delete m_pImpl;
85 0 : }
86 :
87 0 : sal_Bool UnoTypeManager::init(
88 : const ::std::vector< ::rtl::OUString > registries)
89 : {
90 : Reference< XComponentContext > xContext=
91 0 : defaultBootstrap_InitialComponentContext();
92 :
93 0 : if ( !xContext.is() ) {
94 : OUString msg(RTL_CONSTASCII_USTRINGPARAM(
95 0 : "internal UNO problem, can't create initial UNO component context"));
96 0 : throw RuntimeException( msg, Reference< XInterface >());
97 : }
98 0 : Any a = xContext->getValueByName(
99 : OUString(RTL_CONSTASCII_USTRINGPARAM(
100 0 : "/singletons/com.sun.star.reflection.theTypeDescriptionManager")));
101 :
102 0 : a >>= m_pImpl->m_tdmgr;
103 :
104 0 : if ( !m_pImpl->m_tdmgr.is() ) {
105 : OUString msg(RTL_CONSTASCII_USTRINGPARAM(
106 0 : "internal UNO problem, can't get TypeDescriptionManager"));
107 0 : throw RuntimeException( msg, Reference< XInterface >());
108 : }
109 :
110 0 : if ( !registries.empty() ) {
111 :
112 : Reference< XMultiComponentFactory > xServiceManager(
113 0 : xContext->getServiceManager() );
114 0 : if ( !xServiceManager.is() ) {
115 : OUString msg(RTL_CONSTASCII_USTRINGPARAM(
116 0 : "internal UNO problem, can't get ServiceManager"));
117 0 : throw RuntimeException( msg, Reference< XInterface >());
118 : }
119 :
120 0 : Sequence<Any> seqArgs(registries.size());
121 :
122 0 : std::vector< OUString >::const_iterator iter = registries.begin();
123 0 : int i = 0;
124 0 : while ( iter != registries.end() )
125 : {
126 : Reference< XSimpleRegistry > xReg(
127 0 : xServiceManager->createInstanceWithContext(
128 : OUString(RTL_CONSTASCII_USTRINGPARAM(
129 : "com.sun.star.registry.SimpleRegistry")),
130 0 : xContext), UNO_QUERY);
131 0 : xReg->open(convertToFileUrl(
132 0 : OUStringToOString(*iter, RTL_TEXTENCODING_UTF8)),
133 0 : sal_True, sal_False);
134 :
135 0 : seqArgs[i++] = makeAny(xReg);
136 0 : ++iter;
137 0 : }
138 :
139 : Reference< XHierarchicalNameAccess > xTDProvider(
140 0 : xServiceManager->createInstanceWithArgumentsAndContext(
141 : OUString(RTL_CONSTASCII_USTRINGPARAM(
142 : "com.sun.star.reflection.TypeDescriptionProvider")),
143 0 : seqArgs, xContext),
144 0 : UNO_QUERY);
145 0 : if ( !xTDProvider.is() ) {
146 : OUString msg(RTL_CONSTASCII_USTRINGPARAM(
147 : "internal UNO problem, can't create local"
148 0 : " type description provider"));
149 0 : throw RuntimeException( msg, Reference< XInterface >());
150 : }
151 :
152 0 : a = makeAny(xTDProvider);
153 0 : Reference< XSet > xSet(m_pImpl->m_tdmgr, UNO_QUERY);
154 0 : xSet->insert(a);
155 : }
156 :
157 0 : return sal_True;
158 : }
159 :
160 0 : sal_Bool UnoTypeManager::isValidType(const ::rtl::OString& name) const
161 : {
162 0 : return m_pImpl->m_tdmgr->hasByHierarchicalName(
163 0 : OStringToOUString(name, RTL_TEXTENCODING_UTF8));
164 : }
165 :
166 0 : OString UnoTypeManager::getTypeName(RegistryKey& rTypeKey) const
167 : {
168 0 : OString typeName = OUStringToOString(rTypeKey.getName(), RTL_TEXTENCODING_UTF8);
169 0 : static OString sBase("/UCR");
170 0 : if (typeName.indexOf(sBase) == 0) {
171 0 : typeName = typeName.copy(typeName.indexOf('/', 1) + 1);
172 : } else {
173 0 : typeName = typeName.copy(1);
174 : }
175 0 : return typeName;
176 : }
177 :
178 : // extern
179 : void* getTypeBlob(Reference< XHierarchicalNameAccess > xTDmgr,
180 : const OString& typeName, sal_uInt32* pBlob);
181 :
182 0 : typereg::Reader UnoTypeManager::getTypeReader(
183 : const OString& name, sal_Bool * /*pIsExtraType*/ ) const
184 : {
185 0 : typereg::Reader reader;
186 :
187 0 : void* pBlob = NULL;
188 0 : sal_uInt32 blobsize = 0;
189 :
190 0 : if ( (pBlob = getTypeBlob(m_pImpl->m_tdmgr, name, &blobsize)) != NULL )
191 0 : reader = typereg::Reader(pBlob, blobsize, sal_True, TYPEREG_VERSION_1);
192 :
193 0 : if ( pBlob )
194 0 : rtl_freeMemory(pBlob);
195 :
196 0 : return reader;
197 : }
198 :
199 0 : typereg::Reader UnoTypeManager::getTypeReader(RegistryKey& rTypeKey) const
200 : {
201 0 : typereg::Reader reader;
202 :
203 0 : if (rTypeKey.isValid()) {
204 : RegValueType valueType;
205 : sal_uInt32 valueSize;
206 :
207 0 : if (!rTypeKey.getValueInfo(OUString(), &valueType, &valueSize)) {
208 0 : sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
209 0 : if ( !rTypeKey.getValue(OUString(), pBuffer) ) {
210 : reader = typereg::Reader(
211 0 : pBuffer, valueSize, true, TYPEREG_VERSION_1);
212 : }
213 0 : rtl_freeMemory(pBuffer);
214 : }
215 : }
216 0 : return reader;
217 : }
218 :
219 :
220 0 : RTTypeClass UnoTypeManager::getTypeClass(const OString& name) const
221 : {
222 0 : if ( m_pImpl->m_t2TypeClass.count(name) > 0 ) {
223 0 : return m_pImpl->m_t2TypeClass[name];
224 : } else {
225 0 : Reference< XTypeDescription > xTD;
226 0 : Any a = m_pImpl->m_tdmgr->getByHierarchicalName(
227 0 : OStringToOUString(name, RTL_TEXTENCODING_UTF8));
228 0 : a >>= xTD;
229 :
230 0 : if ( xTD.is() ) {
231 0 : RTTypeClass tc = mapTypeClass(xTD->getTypeClass());
232 0 : if (tc != RT_TYPE_INVALID)
233 0 : m_pImpl->m_t2TypeClass[name] = tc;
234 0 : return tc;
235 0 : }
236 : }
237 :
238 0 : return RT_TYPE_INVALID;
239 : }
240 :
241 0 : RTTypeClass UnoTypeManager::getTypeClass(RegistryKey& rTypeKey) const
242 : {
243 0 : OString name = getTypeName(rTypeKey);
244 :
245 0 : if ( m_pImpl->m_t2TypeClass.count(name) > 0 ) {
246 0 : return m_pImpl->m_t2TypeClass[name];
247 : } else {
248 0 : if ( rTypeKey.isValid() ) {
249 : RegValueType valueType;
250 : sal_uInt32 valueSize;
251 :
252 0 : if ( !rTypeKey.getValueInfo(OUString(), &valueType, &valueSize) ) {
253 0 : sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
254 0 : if ( !rTypeKey.getValue(OUString(), pBuffer) ) {
255 : typereg::Reader reader(
256 0 : pBuffer, valueSize, false, TYPEREG_VERSION_1);
257 :
258 0 : RTTypeClass ret = reader.getTypeClass();
259 :
260 0 : rtl_freeMemory(pBuffer);
261 :
262 0 : m_pImpl->m_t2TypeClass[name] = ret;
263 0 : return ret;
264 : }
265 0 : rtl_freeMemory(pBuffer);
266 : }
267 : }
268 : }
269 :
270 0 : return RT_TYPE_INVALID;
271 : }
272 :
273 : } // end of namespace unodevtools
274 :
275 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|