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