Branch data 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: */
|