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