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 <rtl/alloc.h>
25 #ifndef __REGISTRY_REFLWRIT_HXX__
26 #include <registry/reflwrit.hxx>
27 #endif
28 #include <cppuhelper/servicefactory.hxx>
29 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
30 #include <com/sun/star/reflection/XInterfaceTypeDescription.hpp>
31 #include <com/sun/star/reflection/XConstantsTypeDescription.hpp>
32 #include <com/sun/star/reflection/XConstantTypeDescription.hpp>
33 #include <com/sun/star/reflection/XModuleTypeDescription.hpp>
34 #include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp>
35 #include <com/sun/star/reflection/XInterfaceAttributeTypeDescription.hpp>
36 #include <com/sun/star/reflection/XMethodParameter.hpp>
37 #include <com/sun/star/reflection/XCompoundTypeDescription.hpp>
38 #include <com/sun/star/reflection/XIndirectTypeDescription.hpp>
39 #include <com/sun/star/reflection/XEnumTypeDescription.hpp>
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include <com/sun/star/uno/XComponentContext.hpp>
42 #include <codemaker/global.hxx>
43 
44 using namespace com::sun::star;
45 using namespace com::sun::star::uno;
46 using namespace com::sun::star::reflection;
47 using namespace com::sun::star::lang;
48 using namespace com::sun::star::container;
49 using namespace cppu;
50 //using namespace osl;
51 using namespace rtl;
52 
53 static Reference< XHierarchicalNameAccess > xNameAccess;
54 
writeConstantData(RegistryTypeWriter & rWriter,sal_uInt16 fieldIndex,const Reference<XConstantTypeDescription> & xConstant)55 void writeConstantData( RegistryTypeWriter& rWriter, sal_uInt16 fieldIndex,
56 					  const Reference< XConstantTypeDescription >& xConstant)
57 
58 {
59 	RTConstValue constValue;
60 	OUString uConstTypeName;
61 	OUString uConstName = xConstant->getName();
62 	Any aConstantAny = xConstant->getConstantValue();
63 
64 	switch ( aConstantAny.getValueTypeClass() )
65 	{
66 		case TypeClass_BOOLEAN:
67 			{
68 				uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("boolean") );
69 				constValue.m_type = RT_TYPE_BOOL;
70 				aConstantAny >>= constValue.m_value.aBool;
71 			}
72 			break;
73 		case TypeClass_BYTE:
74 			{
75 				uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("byte") );
76 				constValue.m_type = RT_TYPE_BYTE;
77 				aConstantAny >>= constValue.m_value.aByte;
78 			}
79 			break;
80 		case TypeClass_SHORT:
81 			{
82 				uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("short") );
83 				constValue.m_type = RT_TYPE_INT16;
84 				aConstantAny >>= constValue.m_value.aShort;
85 			}
86 			break;
87 		case TypeClass_UNSIGNED_SHORT:
88 			{
89 				uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("unsigned short") );
90 				constValue.m_type = RT_TYPE_UINT16;
91 				aConstantAny >>= constValue.m_value.aUShort;
92 			}
93 			break;
94 		case TypeClass_LONG:
95 			{
96 				uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("long") );
97 				constValue.m_type = RT_TYPE_INT32;
98 				aConstantAny >>= constValue.m_value.aLong;
99 			}
100 			break;
101 		case TypeClass_UNSIGNED_LONG:
102 			{
103 				uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("unsigned long") );
104 				constValue.m_type = RT_TYPE_UINT32;
105 				aConstantAny >>= constValue.m_value.aULong;
106 			}
107 			break;
108 		case TypeClass_FLOAT:
109 			{
110 				uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("float") );
111 				constValue.m_type = RT_TYPE_FLOAT;
112 				aConstantAny >>= constValue.m_value.aFloat;
113 			}
114 			break;
115 		case TypeClass_DOUBLE:
116 			{
117 				uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("double") );
118 				constValue.m_type = RT_TYPE_DOUBLE;
119 				aConstantAny >>= constValue.m_value.aDouble;
120 			}
121 			break;
122 		case TypeClass_STRING:
123 			{
124 				uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("string") );
125 				constValue.m_type = RT_TYPE_STRING;
126 				constValue.m_value.aString = ((OUString*)aConstantAny.getValue())->getStr();
127 			}
128 			break;
129         default:
130             OSL_ASSERT(false);
131             break;
132 	}
133 
134 	rWriter.setFieldData(fieldIndex, uConstName, uConstTypeName, OUString(),
135 						OUString(), RT_ACCESS_CONST, constValue);
136 }
137 
getInheritedMemberCount(Reference<XTypeDescription> & xType)138 sal_uInt32 getInheritedMemberCount( Reference< XTypeDescription >& xType )
139 {
140 	sal_uInt32 memberCount = 0;
141 	if ( xType->getTypeClass() == TypeClass_INTERFACE )
142 	{
143 		Reference< XInterfaceTypeDescription > xIFace(xType, UNO_QUERY);
144 
145 		if ( !xIFace.is() )
146 			return memberCount;
147 
148 		Reference< XTypeDescription > xSuperType = xIFace->getBaseType();
149 
150 		if ( xSuperType.is() )
151 			memberCount = getInheritedMemberCount( xSuperType );
152 
153 		memberCount += xIFace->getMembers().getLength();
154 	}
155 //	} else
156 //	if ( xType->getTypeClass() == TypeClass_Struct || xType->getTypeClass() == TypeClass_Exception )
157 //	{
158 //		Reference< XCompoundTypeDescription > xComp(xType, UNO_QUERY);
159 //
160 //		if ( xComp.is() )
161 //			return membercount;
162 //
163 //		Reference< XTypeDescription > xSuperType = xComp->getBaseType();
164 //
165 //		if ( xSuperType.is() )
166 //			memberCount = getInheritedMemberCount( xSuperType );
167 //
168 //		memberCount += xComp->getMemberNames().getLength();
169 //	}
170 
171 	return memberCount;
172 }
173 
writeMethodData(RegistryTypeWriter & rWriter,sal_uInt32 calculatedMemberOffset,const Reference<XInterfaceMemberTypeDescription> & xMember,const Reference<XInterfaceMethodTypeDescription> & xMethod)174 void writeMethodData( RegistryTypeWriter& rWriter, sal_uInt32 calculatedMemberOffset,
175 					  const Reference< XInterfaceMemberTypeDescription >& xMember,
176 					  const Reference< XInterfaceMethodTypeDescription >& xMethod )
177 {
178 	RTMethodMode methodMode = RT_MODE_TWOWAY;
179 	if ( xMethod->isOneway() )
180 	{
181 		methodMode = RT_MODE_ONEWAY;
182 	}
183 
184 	Sequence< Reference< XMethodParameter > > parameters( xMethod->getParameters() );
185 	Sequence< Reference< XTypeDescription > > exceptions( xMethod->getExceptions() );
186 	sal_uInt16 methodIndex = (sal_uInt16)(xMember->getPosition() - calculatedMemberOffset);
187 	sal_uInt16 paramCount = (sal_uInt16)parameters.getLength();
188 	sal_uInt16 exceptionCount = (sal_uInt16)exceptions.getLength();
189 
190 	rWriter.setMethodData(methodIndex, xMember->getMemberName(),
191 						  xMethod->getReturnType()->getName().replace('.', '/'),
192 						  methodMode, paramCount, exceptionCount, OUString());
193 
194 	RTParamMode paramMode = RT_PARAM_IN;
195 	sal_uInt16 i;
196 
197 	for ( i=0; i < paramCount; i++)
198 	{
199 		Reference< XMethodParameter > xParam = parameters[i];
200 		if ( xParam->isIn() && xParam->isOut())
201 		{
202 			paramMode = RT_PARAM_INOUT;
203 		} else
204 		if ( xParam->isIn() )
205 		{
206 			paramMode = RT_PARAM_IN;
207 		} else
208 		if ( xParam->isOut() )
209 		{
210 			paramMode = RT_PARAM_OUT;
211 		}
212 
213 		rWriter.setParamData(methodIndex, (sal_uInt16)xParam->getPosition(), xParam->getType()->getName().replace('.', '/'),
214 							 xParam->getName(), paramMode);
215 	}
216 
217 	for (i=0; i < exceptionCount; i++)
218 	{
219 		rWriter.setExcData(methodIndex, i, exceptions[i]->getName().replace('.', '/'));
220 	}
221 }
222 
223 extern "C"
224 {
225 
initTypeMapper(const sal_Char * pRegName)226 sal_Bool SAL_CALL initTypeMapper( const sal_Char* pRegName )
227 {
228 	try
229 	{
230 		if (!pRegName)
231 			return sal_False;
232 
233 		Reference< XMultiServiceFactory > xSMgr( createRegistryServiceFactory( convertToFileUrl(pRegName) ) );
234 
235 		if ( !xSMgr.is() )
236 			return sal_False;
237 
238 		Reference< XHierarchicalNameAccess > xNAccess;
239 
240         Reference< beans::XPropertySet > xProps( xSMgr, UNO_QUERY );
241         if (xProps.is())
242         {
243             try
244             {
245                 Reference< XComponentContext > xContext;
246                 if (xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext)
247                 {
248                     xContext->getValueByName(
249                         OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theTypeDescriptionManager") ) ) >>= xNAccess;
250                 }
251             }
252             catch (beans::UnknownPropertyException &)
253             {
254             }
255         }
256 
257 		if ( !xNAccess.is() )
258 			return sal_False;
259 
260 		xNameAccess = xNAccess;
261 	}
262 	catch( Exception& )
263 	{
264 		return sal_False;
265 	}
266 
267 	return sal_True;
268 }
269 
getTypeBlop(const sal_Char * pTypeName,sal_uInt8 ** pBlop)270 sal_uInt32 SAL_CALL getTypeBlop(const sal_Char* pTypeName, sal_uInt8** pBlop)
271 {
272 	sal_uInt32 length = 0;
273 
274 	if ( !pTypeName )
275 		return length;
276 
277 	OUString uTypeName( OUString::createFromAscii(pTypeName).replace('/', '.') );
278 	try
279 	{
280 		Any aTypeAny( xNameAccess->getByHierarchicalName( uTypeName ) );
281 
282 		if ( !aTypeAny.hasValue() )
283 			return length;
284 
285 		Reference< XTypeDescription > xType;
286 		aTypeAny >>= xType;
287 
288 		if ( !xType.is() )
289 			return length;
290 
291 		switch (xType->getTypeClass())
292 		{
293 			case TypeClass_CONSTANTS:
294 				{
295 					Reference< XConstantsTypeDescription > xCFace(xType, UNO_QUERY);
296 
297 					if ( !xCFace.is() )
298 						return length;
299 
300                   Sequence< Reference< XConstantTypeDescription > > constTypes( xCFace->getConstants());
301 					sal_uInt16 constCount = (sal_uInt16)constTypes.getLength();
302 
303 					RegistryTypeWriter writer(RT_TYPE_MODULE, uTypeName.replace('.', '/'),
304 											  OUString(), constCount, 0, 0);
305 
306                   for (sal_uInt16 i=0; i < constCount; i++)
307                       writeConstantData(writer, i, constTypes[i]);
308 
309 					length = writer.getBlopSize();
310 					*pBlop = (sal_uInt8*)rtl_allocateMemory( length );
311 					rtl_copyMemory(*pBlop, writer.getBlop(), length);
312 				}
313 				break;
314 			case TypeClass_MODULE:
315 				{
316 					Reference< XModuleTypeDescription > xMFace(xType, UNO_QUERY);
317 
318 					if ( !xMFace.is() )
319 						return length;
320 
321                   Sequence< Reference< XTypeDescription > > memberTypes( xMFace->getMembers());
322 
323 					sal_uInt16 memberCount = (sal_uInt16)memberTypes.getLength();
324 					sal_uInt16 constCount = 0;
325 					sal_Int16 i;
326 
327 					for ( i=0; i < memberCount; i++)
328 					{
329 						if ( TypeClass_CONSTANT == memberTypes[i]->getTypeClass() )
330 							constCount++;
331 					}
332 
333 					RegistryTypeWriter writer(RT_TYPE_MODULE, uTypeName.replace('.', '/'),
334 											  OUString(), constCount, 0, 0);
335 
336 					if ( 0 < constCount )
337                   {
338                       Reference< XConstantTypeDescription > xConst;
339                       sal_uInt16 fieldIndex = 0;
340                       for (i=0; i < memberCount; i++)
341                       {
342                           if ( TypeClass_CONSTANT == memberTypes[i]->getTypeClass() )
343                           {
344                               xConst = Reference< XConstantTypeDescription >(memberTypes[i], UNO_QUERY);
345 
346                               writeConstantData(writer, ++fieldIndex, xConst);
347                           }
348                       }
349                   }
350 
351 					length = writer.getBlopSize();
352 					*pBlop = (sal_uInt8*)rtl_allocateMemory( length );
353 					rtl_copyMemory(*pBlop, writer.getBlop(), length);
354 				}
355 				break;
356 			case TypeClass_INTERFACE:
357 				{
358 					Reference< XInterfaceTypeDescription > xIFace(xType, UNO_QUERY);
359 
360 					if ( !xIFace.is() )
361 						return length;
362 
363 					Reference< XInterfaceAttributeTypeDescription > xAttr;
364 					Reference< XInterfaceMethodTypeDescription > xMethod;
365 					Sequence< Reference< XInterfaceMemberTypeDescription > > memberTypes( xIFace->getMembers());
366 					sal_uInt16 memberCount = (sal_uInt16)memberTypes.getLength();
367 					sal_uInt16 attrCount = 0;
368 					sal_uInt16 inheritedMemberCount = 0;
369 					sal_Int32 i;
370 
371 					for ( i=0; i < memberCount; i++)
372 					{
373 						xAttr = Reference< XInterfaceAttributeTypeDescription >(memberTypes[i], UNO_QUERY);
374 						if ( xAttr.is() )
375 						{
376 							attrCount++;
377 						}
378 					}
379 
380 					OUString uSuperType;
381 					Reference< XTypeDescription > xSuperType = xIFace->getBaseType();
382 					if ( xSuperType.is() )
383 					{
384 						uSuperType = xSuperType->getName().replace('.','/');
385 						inheritedMemberCount = (sal_uInt16)getInheritedMemberCount( xSuperType );
386 					}
387 
388 					RegistryTypeWriter writer(RT_TYPE_INTERFACE, uTypeName.replace('.', '/'),
389 											  uSuperType, attrCount, memberCount-attrCount, 0);
390 
391 					Uik	  uik = xIFace->getUik();
392 					RTUik rtUik = { uik.m_Data1, uik.m_Data2, uik.m_Data3, uik.m_Data4, uik.m_Data5 };
393 					writer.setUik( rtUik );
394 
395 					RTFieldAccess attrAccess = RT_ACCESS_READWRITE;
396 					// reset attrCount, used for method index calculation
397 					attrCount = 0;
398 
399 					for (i=0; i < memberCount; i++)
400 					{
401 						xAttr = Reference< XInterfaceAttributeTypeDescription >(memberTypes[i], UNO_QUERY);
402 						if ( xAttr.is() )
403 						{
404 							++attrCount;
405 							if (xAttr->isReadOnly())
406 							{
407 								attrAccess = RT_ACCESS_READONLY;
408 							} else
409 							{
410 								attrAccess = RT_ACCESS_READWRITE;
411 							}
412 							writer.setFieldData(sal::static_int_cast< sal_uInt16 >(memberTypes[i]->getPosition() - inheritedMemberCount),
413 												memberTypes[i]->getMemberName(),
414 												xAttr->getType()->getName().replace('.', '/'),
415 												OUString(), OUString(), attrAccess);
416 							continue;
417 						}
418 
419 						xMethod = Reference< XInterfaceMethodTypeDescription >(memberTypes[i], UNO_QUERY);
420 						if ( xMethod.is() )
421 						{
422 							writeMethodData( writer, attrCount+inheritedMemberCount, memberTypes[i], xMethod );
423 						}
424 					}
425 
426 					length = writer.getBlopSize();
427 					*pBlop = (sal_uInt8*)rtl_allocateMemory( length );
428 					rtl_copyMemory(*pBlop, writer.getBlop(), length);
429 				}
430 				break;
431 			case TypeClass_STRUCT:
432 			case TypeClass_EXCEPTION:
433 				{
434 					RTTypeClass rtTypeClass = RT_TYPE_STRUCT;
435 					if (xType->getTypeClass() == TypeClass_EXCEPTION)
436 					{
437 						rtTypeClass = RT_TYPE_EXCEPTION;
438 					}
439 #include <com/sun/star/reflection/XConstantsTypeDescription.hpp>
440 
441 					Reference< XCompoundTypeDescription > xComp(xType, UNO_QUERY);
442 
443 					if ( !xComp.is() )
444 						return length;
445 
446 					Sequence< OUString > memberNames( xComp->getMemberNames());
447 					Sequence< Reference< XTypeDescription > > memberTypes( xComp->getMemberTypes());
448 					sal_uInt16 memberCount = (sal_uInt16)memberNames.getLength();
449 
450 					OUString uSuperType;
451 					Reference< XTypeDescription > xSuperType = xComp->getBaseType();
452 					if ( xSuperType.is() )
453 					{
454 						uSuperType = xSuperType->getName().replace('.','/');
455 					}
456 
457 					RegistryTypeWriter writer(rtTypeClass, uTypeName.replace('.', '/'),
458 											  uSuperType, memberCount, 0, 0);
459 
460 					for (sal_Int16 i=0; i < memberCount; i++)
461 					{
462 						writer.setFieldData(i , memberNames[i], memberTypes[i]->getName().replace('.', '/'),
463 											OUString(), OUString(), RT_ACCESS_READWRITE);
464 					}
465 
466 					length = writer.getBlopSize();
467 					*pBlop = (sal_uInt8*)rtl_allocateMemory( length );
468 					rtl_copyMemory(*pBlop, writer.getBlop(), length);
469 				}
470 				break;
471 			case TypeClass_ENUM:
472 				{
473 					Reference< XEnumTypeDescription > xEnum(xType, UNO_QUERY);
474 
475 					if ( !xEnum.is() )
476 						return length;
477 
478 					Sequence< OUString > enumNames( xEnum->getEnumNames());
479 					Sequence< sal_Int32 > enumValues( xEnum->getEnumValues());
480 					sal_uInt16 enumCount = (sal_uInt16)enumNames.getLength();
481 
482 					RegistryTypeWriter writer(RT_TYPE_ENUM, uTypeName.replace('.', '/'),
483 											  OUString(), enumCount, 0, 0);
484 
485 					RTConstValue constValue;
486 					for (sal_Int16 i=0; i < enumCount; i++)
487 					{
488 						constValue.m_type = RT_TYPE_INT32;
489 						constValue.m_value.aLong = enumValues[i];
490 
491 						writer.setFieldData(i, enumNames[i], OUString(), OUString(), OUString(),
492 											RT_ACCESS_CONST, constValue);
493 					}
494 
495 					length = writer.getBlopSize();
496 					*pBlop = (sal_uInt8*)rtl_allocateMemory( length );
497 					rtl_copyMemory(*pBlop, writer.getBlop(), length);
498 				}
499 				break;
500 			case TypeClass_TYPEDEF:
501 				{
502 					Reference< XIndirectTypeDescription > xTD(xType, UNO_QUERY);
503 
504 					if ( !xTD.is() )
505 						return length;
506 
507 					RegistryTypeWriter writer(RT_TYPE_TYPEDEF, uTypeName.replace('.', '/'),
508 											  xTD->getReferencedType()->getName().replace('.', '/'),
509 											  0, 0, 0);
510 					length = writer.getBlopSize();
511 					*pBlop = (sal_uInt8*)rtl_allocateMemory( length );
512 					rtl_copyMemory(*pBlop, writer.getBlop(), length);
513 				}
514 				break;
515             default:
516                 OSL_ASSERT(false);
517                 break;
518 		}
519 
520 	}
521 	catch( Exception& )
522 	{
523 	}
524 
525 	return length;
526 }
527 
528 } // extern "C"
529 
530 
531 
532