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