xref: /AOO41X/main/unodevtools/source/unodevtools/typemanager.cxx (revision 7ceddb922c36bc48f0711c90dec62c8f86ce5272)
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