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 "osl/thread.hxx"
25 
26 #include "codemaker/commonjava.hxx"
27 #include "codemaker/commoncpp.hxx"
28 #include "codemaker/generatedtypeset.hxx"
29 
30 #include "skeletoncommon.hxx"
31 
32 #include <iostream>
33 
34 using namespace ::rtl;
35 using namespace ::codemaker::cpp;
36 
37 namespace skeletonmaker {
38 
printLicenseHeader(std::ostream & o,rtl::OString const & filename)39 void printLicenseHeader(std::ostream& o, rtl::OString const & filename)
40 {
41     sal_Int32 index = -1;
42 #ifdef SAL_UNX
43 	index = filename.lastIndexOf('/');
44 #else
45 	index = filename.lastIndexOf('\\');
46 #endif
47     OString shortfilename(filename);
48     if ( index != -1 )
49         shortfilename = filename.copy(index+1);
50 
51     o << "/**************************************************************\n"
52         " * \n"
53         " * Licensed to the Apache Software Foundation (ASF) under one\n"
54         " * or more contributor license agreements.  See the NOTICE file\n"
55         " * distributed with this work for additional information\n"
56         " * regarding copyright ownership.  The ASF licenses this file\n"
57         " * to you under the Apache License, Version 2.0 (the\n"
58         " * \"License\"); you may not use this file except in compliance\n"
59         " * with the License.  You may obtain a copy of the License at\n"
60         " * \n"
61         " *   http://www.apache.org/licenses/LICENSE-2.0\n"
62         " * \n"
63         " * Unless required by applicable law or agreed to in writing,\n"
64         " * software distributed under the License is distributed on an\n"
65         " * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n"
66         " * KIND, either express or implied.  See the License for the\n"
67         " * specific language governing permissions and limitations\n"
68         " * under the License.\n"
69         " * \n"
70         " *************************************************************/\n\n";
71 }
72 
getOutputStream(ProgramOptions const & options,OString const & extension,std::ostream ** ppOutputStream,OString & targetSourceFileName,OString & tmpSourceFileName)73 bool getOutputStream(ProgramOptions const & options,
74                      OString const & extension,
75                      std::ostream** ppOutputStream,
76                      OString & targetSourceFileName,
77                      OString & tmpSourceFileName)
78 {
79     bool bStandardout = false;
80     if ( options.outputpath.equals("stdout") )
81     {
82         bStandardout = true;
83         *ppOutputStream = &std::cout;
84         return bStandardout;
85     }
86 
87     targetSourceFileName = createFileNameFromType(
88         options.outputpath, options.implname.replace('.','/'), extension);
89 
90     OString tmpDir = getTempDir(targetSourceFileName);
91     FileStream file;
92     file.createTempFile(tmpDir);
93 
94     if( !file.isValid() )
95     {
96         OString message("cannot open ");
97         message += targetSourceFileName + " for writing";
98         throw CannotDumpException(message);
99     } else {
100         tmpSourceFileName = file.getName();
101     }
102     file.close();
103     *ppOutputStream = new std::ofstream(tmpSourceFileName.getStr(),
104                                         std::ios_base::binary);
105 
106     return bStandardout;
107 }
108 
decomposeResolveAndCheck(TypeManager const & manager,OString const & type,bool resolveTypedefs,bool allowVoid,bool allowExtraEntities,RTTypeClass * typeClass,OString * name,sal_Int32 * rank,std::vector<OString> * arguments)109 codemaker::UnoType::Sort decomposeResolveAndCheck(
110     TypeManager const & manager, OString const & type,
111     bool resolveTypedefs, bool allowVoid, bool allowExtraEntities,
112     RTTypeClass * typeClass, OString * name, sal_Int32 * rank,
113     std::vector< OString > * arguments)
114 {
115     codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve(
116         manager, type, resolveTypedefs, allowVoid, allowExtraEntities,
117         typeClass, name, rank, arguments);
118     for ( std::vector< OString >::iterator i(arguments->begin());
119           i != arguments->end(); ++i )
120     {
121         RTTypeClass typeClass2;
122         OString name2;
123         sal_Int32 rank2;
124         std::vector< OString > arguments2;
125         decomposeResolveAndCheck(
126             manager, *i, true, false, false, &typeClass2, &name2, &rank2,
127             &arguments2);
128     }
129     return sort;
130 }
131 
containsAttribute(AttributeInfo & attributes,OString const & attrname)132 bool containsAttribute(AttributeInfo& attributes, OString const & attrname)
133 {
134     for ( AttributeInfo::const_iterator i(attributes.begin());
135           i != attributes.end(); ++i ) {
136         if ( (*i).first == attrname ) {
137             return true;
138         }
139     }
140     return false;
141 }
142 
143 // collect attributes including inherited attributes
checkAttributes(TypeManager const & manager,const typereg::Reader & reader,AttributeInfo & attributes,std::hash_set<OString,OStringHash> & propinterfaces)144 void checkAttributes(TypeManager const & manager,
145                      const typereg::Reader& reader,
146                      AttributeInfo& attributes,
147                      std::hash_set< OString, OStringHash >& propinterfaces)
148 {
149     OString typeName = codemaker::convertString(reader.getTypeName());
150     if ( typeName.equals("com/sun/star/beans/XPropertySet") ||
151          typeName.equals("com/sun/star/beans/XFastPropertySet") ||
152 //        typeName.equals("com/sun/star/beans/XMultiPropertySet") ||
153          typeName.equals("com/sun/star/beans/XPropertyAccess") )
154     {
155         propinterfaces.insert(typeName);
156     }
157 
158     for ( sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i ) {
159         typereg::Reader supertype(manager.getTypeReader(
160                                   codemaker::convertString(
161                                       reader.getSuperTypeName(i))));
162         if ( !supertype.isValid() ) {
163             throw CannotDumpException(
164                 "Bad type library entity "
165                 + codemaker::convertString(reader.getSuperTypeName(i)));
166         }
167         checkAttributes(manager, supertype, attributes, propinterfaces);
168     }
169 
170     for ( sal_uInt16 i = 0; i < reader.getFieldCount(); ++i ) {
171         OString fieldName(
172             codemaker::convertString(reader.getFieldName(i)).
173             replace('/', '.'));
174 
175         if ( !containsAttribute(attributes, fieldName) ) {
176             OString fieldType(
177                 codemaker::convertString(reader.getFieldTypeName(i)).
178                 replace('/', '.'));
179             attributes.push_back(AttributeInfo::value_type(
180                                      fieldName, std::pair<OString, sal_Int16>(
181                                          fieldType, reader.getFieldFlags(i))));
182         }
183     }
184 }
185 
checkType(TypeManager const & manager,OString const & type,std::hash_set<OString,OStringHash> & interfaceTypes,std::hash_set<OString,OStringHash> & serviceTypes,AttributeInfo & properties)186 void checkType(TypeManager const & manager,
187                OString const & type,
188                std::hash_set< OString, OStringHash >& interfaceTypes,
189                std::hash_set< OString, OStringHash >& serviceTypes,
190                AttributeInfo& properties)
191 {
192 
193     OString binType(type.replace('.', '/'));
194     typereg::Reader reader(manager.getTypeReader(binType));
195     if ( !reader.isValid() ) {
196         throw CannotDumpException("Bad type library entity " + binType);
197     }
198 
199     switch ( reader.getTypeClass() )
200     {
201     case RT_TYPE_INTERFACE:
202     {
203         // com/sun/star/lang/XComponent should be also not in the list
204         // but it will be used for checking the impl helper and will be
205         // removed later if necessary.
206         if ( binType.equals("com/sun/star/lang/XTypeProvider") ||
207              binType.equals("com/sun/star/uno/XWeak") )
208             return;
209         if (interfaceTypes.find(type) == interfaceTypes.end()) {
210             interfaceTypes.insert(type);
211         }
212     }
213         break;
214     case RT_TYPE_SERVICE:
215         if ( serviceTypes.find(binType) == serviceTypes.end() ) {
216             serviceTypes.insert(binType);
217 
218             if ( reader.getSuperTypeCount() > 0 ) {
219                 OString supername(codemaker::convertString(
220                     reader.getSuperTypeName(0).replace('/', '.')));
221 				if ( interfaceTypes.find(supername) == interfaceTypes.end() ) {
222                     interfaceTypes.insert(supername);
223 
224 					typereg::Reader supertype(manager.getTypeReader(
225                                   codemaker::convertString(
226                                       reader.getSuperTypeName(0))));
227 					if ( !supertype.isValid() ) {
228 						throw CannotDumpException(
229 							"Bad type library entity "
230 							+ codemaker::convertString(reader.getSuperTypeName(0)));
231 					}
232 				}
233 
234                 // check if constructors are specified, if yes automatically
235                 // support of XInitialization. We will take care of the default
236                 // constructor because in this case XInitialization is not called.
237                 if ( reader.getMethodCount() > 1 ||
238                      ( reader.getMethodCount() == 1 &&
239                        reader.getMethodName(0).getLength() > 0 ) )
240                 {
241                     OString s("com.sun.star.lang.XInitialization");
242                     if ( interfaceTypes.find(s) == interfaceTypes.end() )
243                         interfaceTypes.insert(s);
244                 }
245             } else {
246                 for ( sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i ) {
247                     OString referenceType(
248                         codemaker::convertString(
249                             reader.getReferenceTypeName(i)).replace('/', '.'));
250 
251                     if ( reader.getReferenceSort(i) == RT_REF_SUPPORTS ) {
252                         checkType(manager, referenceType, interfaceTypes,
253                                   serviceTypes, properties);
254                     } else if ( reader.getReferenceSort(i) == RT_REF_EXPORTS ) {
255                         checkType(manager, referenceType, interfaceTypes,
256                                   serviceTypes, properties);
257                     }
258                 }
259 
260                 for ( sal_uInt16 i = 0; i < reader.getFieldCount(); ++i ) {
261                     OString fieldName(
262                         codemaker::convertString(reader.getFieldName(i)).
263                         replace('/', '.'));
264                     OString fieldType(
265                         codemaker::convertString(reader.getFieldTypeName(i)).
266                         replace('/', '.'));
267 
268                     properties.push_back(AttributeInfo::value_type(
269                         fieldName, std::pair<OString, sal_Int16>(
270                             fieldType, reader.getFieldFlags(i))));
271                 }
272             }
273         }
274         break;
275     default:
276         OSL_ASSERT(false);
277         break;
278     }
279 }
280 
checkDefaultInterfaces(std::hash_set<OString,OStringHash> & interfaces,const std::hash_set<OString,OStringHash> & services,const OString & propertyhelper)281 void checkDefaultInterfaces(
282          std::hash_set< OString, OStringHash >& interfaces,
283          const std::hash_set< OString, OStringHash >& services,
284        const OString & propertyhelper)
285 {
286     if ( services.empty() ) {
287         if (interfaces.find("com.sun.star.lang.XServiceInfo") != interfaces.end())
288             interfaces.erase("com.sun.star.lang.XServiceInfo");
289     } else {
290         if (interfaces.find("com.sun.star.lang.XServiceInfo") == interfaces.end())
291             interfaces.insert("com.sun.star.lang.XServiceInfo");
292     }
293 
294     if ( propertyhelper.equals("_") ) {
295         if (interfaces.find("com.sun.star.beans.XPropertySet")
296             != interfaces.end())
297             interfaces.erase("com.sun.star.beans.XPropertySet");
298         if (interfaces.find("com.sun.star.beans.XFastPropertySet")
299             != interfaces.end())
300             interfaces.erase("com.sun.star.beans.XFastPropertySet");
301         if (interfaces.find("com.sun.star.beans.XPropertyAccess")
302             != interfaces.end())
303             interfaces.erase("com.sun.star.beans.XPropertyAccess");
304     }
305 }
306 
checkServiceProperties(TypeManager const & manager,const typereg::Reader & reader)307 bool checkServiceProperties(TypeManager const & manager,
308                             const typereg::Reader & reader)
309 {
310     if ( reader.getFieldCount() > 0 )
311         return true;
312 
313     if ( reader.getReferenceCount() > 0 ) {
314         for ( sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i ) {
315             if ( reader.getReferenceSort(i) == RT_REF_EXPORTS ) {
316                 typereg::Reader refreader(
317                     manager.getTypeReader(
318                         codemaker::convertString(reader.getReferenceTypeName(i))));
319 
320                 if ( checkServiceProperties(manager, refreader) )
321                     return true;
322             }
323         }
324     }
325     return false;
326 }
327 
328 
checkPropertyHelper(ProgramOptions const & options,TypeManager const & manager,const std::hash_set<OString,OStringHash> & services,const std::hash_set<OString,OStringHash> & interfaces,AttributeInfo & attributes,std::hash_set<OString,OStringHash> & propinterfaces)329 OString checkPropertyHelper(
330     ProgramOptions const & options,
331     TypeManager const & manager,
332     const std::hash_set< OString, OStringHash >& services,
333     const std::hash_set< OString, OStringHash >& interfaces,
334     AttributeInfo& attributes,
335     std::hash_set< OString, OStringHash >& propinterfaces)
336 {
337     std::hash_set< OString, OStringHash >::const_iterator iter;
338     std::hash_set< OString, OStringHash >::const_iterator end;
339 
340     if ( !services.empty() ) {
341         iter = services.begin();
342         end = services.end();
343     } else {
344         iter = interfaces.begin();
345         end = interfaces.end();
346     }
347 
348     bool oldStyleWithProperties = false;
349     while ( iter != end ) {
350         typereg::Reader reader(manager.getTypeReader((*iter).replace('.', '/')));
351 
352         if ( !services.empty() ) {
353             if ( options.supportpropertysetmixin && reader.getSuperTypeCount() > 0 )
354             {
355                 typereg::Reader supertype(
356                     manager.getTypeReader(
357                         codemaker::convertString(
358                             reader.getSuperTypeName(0))));
359                 if ( !supertype.isValid() ) {
360                     throw CannotDumpException(
361                         "Bad type library entity "
362                         + codemaker::convertString(
363                             reader.getSuperTypeName(0)));
364                 }
365 
366                 checkAttributes(manager, supertype, attributes, propinterfaces);
367 
368                 if ( !(attributes.empty() || propinterfaces.empty()) ) {
369                     return OUStringToOString(
370                         supertype.getTypeName().replace('/', '.'),
371                         osl_getThreadTextEncoding());
372                 }
373             } else {
374                 oldStyleWithProperties = checkServiceProperties(manager, reader);
375             }
376         } else {
377             checkAttributes(manager, reader, attributes, propinterfaces);
378             if ( !(attributes.empty() || propinterfaces.empty()) ) {
379                 return OUStringToOString(
380                     reader.getTypeName().replace('/', '.'),
381                     osl_getThreadTextEncoding());
382             }
383         }
384         iter++;
385     }
386 
387     return (oldStyleWithProperties ? "_" : "");
388 }
389 
checkXComponentSupport(TypeManager const & manager,typereg::Reader const & reader)390 bool checkXComponentSupport(TypeManager const & manager,
391                             typereg::Reader const & reader)
392 {
393     static OUString s(RTL_CONSTASCII_USTRINGPARAM(
394                                "com/sun/star/lang/XComponent"));
395     if ( reader.getTypeName().equals(s) )
396         return true;
397 
398     for ( sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i ) {
399         typereg::Reader super(
400             manager.getTypeReader(
401                 codemaker::convertString(
402                     reader.getSuperTypeName(i))));
403         if ( !super.isValid() ) {
404             throw CannotDumpException(
405                 "Bad type library entity "
406                 + codemaker::convertString(
407                     reader.getSuperTypeName(i)));
408         }
409         if ( checkXComponentSupport(manager, super) )
410             return true;
411     }
412 
413     return false;
414 }
415 
416 
417 // if XComponent is directly specified, return true and remove it from the
418 // supported interfaces list
checkXComponentSupport(TypeManager const & manager,std::hash_set<OString,OStringHash> & interfaces)419 bool checkXComponentSupport(TypeManager const & manager,
420          std::hash_set< OString, OStringHash >& interfaces)
421 {
422     if ( interfaces.empty() )
423         return false;
424 
425     std::hash_set< OString, OStringHash >::const_iterator iter =
426         interfaces.begin();
427     while ( iter != interfaces.end() ) {
428         if ( (*iter).equals("com.sun.star.lang.XComponent") ) {
429             interfaces.erase("com.sun.star.lang.XComponent");
430             return true;
431         }
432         typereg::Reader reader(manager.getTypeReader((*iter).replace('.', '/')));
433         if ( checkXComponentSupport(manager, reader) )
434             return true;
435         iter++;
436     }
437 
438     return false;
439 }
440 
checkAdditionalPropertyFlags(typereg::Reader const & reader,sal_uInt16 field,sal_uInt16 method)441 sal_uInt16 checkAdditionalPropertyFlags(typereg::Reader const & reader,
442                                         sal_uInt16 field, sal_uInt16 method)
443 {
444     sal_uInt16 flags = 0;
445     bool getterSupportsUnknown = false;
446 
447     OUString su(RTL_CONSTASCII_USTRINGPARAM(
448                    "com/sun/star/beans/UnknownPropertyException"));
449     if ( method < reader.getMethodCount()
450          && reader.getMethodFlags(method) == RT_MODE_ATTRIBUTE_GET
451          && reader.getMethodName(method) == reader.getFieldName(field) )
452     {
453         if ( reader.getMethodExceptionCount(method) > 0 ) {
454             for ( sal_uInt16 i = 0; i < reader.getMethodExceptionCount(method);
455                   ++i )
456             {
457                 if (su.equals(reader.getMethodExceptionTypeName(method, i)))
458                     getterSupportsUnknown = true;
459             }
460         }
461         method++;
462     }
463     if ( method < reader.getMethodCount()
464          && reader.getMethodFlags(method) == RT_MODE_ATTRIBUTE_SET
465          && reader.getMethodName(method) == reader.getFieldName(field) )
466     {
467         if ( reader.getMethodExceptionCount(method) > 0 ) {
468             OUString s(RTL_CONSTASCII_USTRINGPARAM(
469                            "com/sun/star/beans/PropertyVetoException"));
470             for ( sal_uInt16 i = 0; i < reader.getMethodExceptionCount(method);
471                   ++i )
472             {
473                 if ( s.equals(reader.getMethodExceptionTypeName(method, i)) )
474                     flags |= RT_ACCESS_CONSTRAINED;
475                 if ( getterSupportsUnknown &&
476                      su.equals(reader.getMethodExceptionTypeName(method, i)) )
477                     flags |= RT_ACCESS_OPTIONAL;
478             }
479         }
480     }
481     return flags;
482 }
483 
484 // This function checks if the specified types for parameters and return
485 // types are allowed add-in types, for more info see the com.sun.star.sheet.AddIn
486 // service description
checkAddinType(TypeManager const & manager,OString const & type,bool & bLastAny,bool & bHasXPropertySet,bool bIsReturn)487 bool checkAddinType(TypeManager const & manager,
488                     OString const & type, bool & bLastAny,
489                     bool & bHasXPropertySet, bool bIsReturn)
490 {
491     RTTypeClass typeClass;
492     OString name;
493     sal_Int32 rank;
494     std::vector< OString > arguments;
495     codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve(
496         manager, type, true, true, true, &typeClass, &name, &rank, &arguments);
497 
498     if ( sort == codemaker::UnoType::SORT_LONG ||
499          sort == codemaker::UnoType::SORT_DOUBLE ||
500          sort == codemaker::UnoType::SORT_STRING )
501     {
502         if ( rank == 0 || rank ==2 )
503             return true;
504     }
505     if ( sort == codemaker::UnoType::SORT_ANY )
506     {
507         if ( rank <= 2 ) {
508             if ( rank ==1 ) {
509                 if ( bIsReturn )
510                     return false;
511                 bLastAny = true;
512             }
513 
514             return true;
515         }
516     }
517     if ( sort == codemaker::UnoType::SORT_COMPLEX &&
518          typeClass == RT_TYPE_INTERFACE )
519     {
520         if ( bIsReturn && type.equals("com/sun/star/sheet/XVolatileResult") )
521             return true;
522         if ( !bIsReturn && type.equals("com/sun/star/table/XCellRange") )
523             return true;
524         if ( !bIsReturn && type.equals("com/sun/star/beans/XPropertySet") )
525         {
526             if ( bHasXPropertySet ) {
527                 return false;
528             } else {
529                 bHasXPropertySet = true;
530                 return true;
531             }
532         }
533     }
534     return false;
535 }
536 
checkAddInTypes(TypeManager const & manager,typereg::Reader const & reader)537 void checkAddInTypes(TypeManager const & manager,
538                      typereg::Reader const & reader)
539 {
540     OString sType(codemaker::convertString(reader.getTypeName()).replace('/', '.'));
541     bool bLastAny = false;
542     bool bHasXPropertySet = false;
543     for ( sal_uInt16 m = 0; m < reader.getMethodCount(); ++m ) {
544         OString sMethod(codemaker::convertString(reader.getMethodName(m)));
545 
546         OString sReturnType(codemaker::convertString(
547                                 reader.getMethodReturnTypeName(m)));
548         if ( !checkAddinType(
549                  manager, sReturnType, bLastAny, bHasXPropertySet, true) )
550         {
551             OStringBuffer msg("the return type of the calc add-in function '");
552             msg.append(sType);
553             msg.append(":");
554             msg.append(sMethod);
555             msg.append("' is invalid. Please check your IDL definition.");
556             throw CannotDumpException(msg.makeStringAndClear());
557         }
558 
559         bHasXPropertySet = false;
560         for ( sal_uInt16 p = 0; p < reader.getMethodParameterCount(m); ++p ) {
561             bLastAny = false;
562             OString sParamType(codemaker::convertString(
563                                    reader.getMethodParameterTypeName(m, p)));
564             if ( !checkAddinType(manager, sParamType,
565                                 bLastAny, bHasXPropertySet, false) ||
566                  bLastAny )
567             {
568                 OStringBuffer msg("the type of the ");
569                 msg.append((sal_Int32)p+1);
570                 msg.append(". parameter of the calc add-in function '");
571                 msg.append(sType);
572                 msg.append(":");
573                 msg.append(sMethod);
574                 msg.append("' is invalid.");
575                 if ( bLastAny )
576                     msg.append(" The type 'sequence<any>' is allowed as last "
577                                "parameter only.");
578                 if ( bHasXPropertySet )
579                     msg.append(" The type 'XPropertySet' is allowed only once.");
580 
581                 msg.append(" Please check your IDL definition.");
582                 throw CannotDumpException(msg.makeStringAndClear());
583             }
584         }
585     }
586 }
587 
generateFunctionParamterMap(std::ostream & o,ProgramOptions const & options,TypeManager const & manager,typereg::Reader const & reader,::codemaker::GeneratedTypeSet & generated,bool bFirst)588 void generateFunctionParamterMap(std::ostream& o,
589                                  ProgramOptions const & options,
590                                  TypeManager const & manager,
591                                  typereg::Reader const & reader,
592                                  ::codemaker::GeneratedTypeSet & generated,
593                                  bool bFirst)
594 {
595     OString sType(codemaker::convertString(reader.getTypeName()));
596     if ( sType.equals("com/sun/star/uno/XInterface") ||
597          sType.equals("com/sun/star/lang/XLocalizable") ||
598          sType.equals("com/sun/star/lang/XServiceInfo") ||
599          // the next three checks becomes obsolete when configuration is used
600          sType.equals("com/sun/star/sheet/XAddIn") ||
601          sType.equals("com/sun/star/sheet/XCompatibilityNames") ||
602          sType.equals("com/sun/star/lang/XServiceName") )
603     {
604         return;
605     }
606 
607     // check if the specified add-in functions supports valid types
608     checkAddInTypes(manager, reader);
609 
610     for ( sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i ) {
611         typereg::Reader super(
612             manager.getTypeReader(
613                 codemaker::convertString(
614                     reader.getSuperTypeName(i))));
615         if ( !super.isValid() ) {
616             throw CannotDumpException(
617                 "Bad type library entity "
618                 + codemaker::convertString(
619                     reader.getSuperTypeName(i)));
620         }
621         generateFunctionParamterMap(o, options, manager, super, generated, bFirst);
622     }
623 
624     OString type(codemaker::convertString(reader.getTypeName()));
625     if ( generated.contains(type) )
626         return;
627     else
628         generated.add(type);
629 
630     for ( sal_uInt16 m = 0; m < reader.getMethodCount(); ++m ) {
631         OString sMethod(codemaker::convertString(reader.getMethodName(m)));
632 
633         if ( bFirst ) {
634             if (options.language == 2) {
635                 o << "        ParamMap fpm;\n";
636             }
637             else {
638                 if ( options.java5 )
639                     o << "        java.util.Hashtable< Integer, String > fpm = "
640                         "new java.util.Hashtable< Integer, String >();\n";
641                 else
642                     o << "        java.util.Hashtable fpm = "
643                         "new java.util.Hashtable();\n";
644             }
645             bFirst = false;
646         } else
647             if ( options.language == 2 ) {
648                 o << "        fpm = ParamMap();\n";
649             }
650             else {
651                 if ( options.java5 )
652                     o << "        fpm = new java.util.Hashtable< "
653                         "Integer, String >();\n";
654                 else
655                     o << "        fpm = new java.util.Hashtable();\n";
656             }
657 
658         for ( sal_uInt16 p = 0; p < reader.getMethodParameterCount(m); ++p ) {
659             if ( options.language == 2 ) {
660                 o << "        fpm[" << p
661                   << "] = ::rtl::OUString::createFromAscii(\""
662                   << codemaker::convertString(reader.getMethodParameterName(m, p))
663                   << "\");\n";
664             }
665             else {
666                 if ( options.java5 )
667                     o << "        fpm.put(" << p << ", \""
668                       << codemaker::convertString(
669                           reader.getMethodParameterName(m, p))
670                       << "\");\n";
671                 else
672                     o << "       fpm.put(new Integer(" << p << "), \""
673                       << codemaker::convertString(
674                           reader.getMethodParameterName(m, p))
675                       << "\");\n";
676             }
677         }
678 
679         if ( options.language == 2 ) {
680             o << "        m_functionMap[::rtl::OUString::createFromAscii(\""
681               << sMethod << "\")] = fpm;\n\n";
682         }
683         else {
684             o << "        m_functionMap.put(\"" << sMethod << "\", fpm);\n\n";
685         }
686     }
687 }
688 
generateFunctionParameterMap(std::ostream & o,ProgramOptions const & options,TypeManager const & manager,const std::hash_set<OString,OStringHash> & interfaces)689 void generateFunctionParameterMap(std::ostream& o,
690          ProgramOptions const & options,
691          TypeManager const & manager,
692          const std::hash_set< OString, OStringHash >& interfaces)
693 {
694     ::codemaker::GeneratedTypeSet generated;
695     bool bFirst = true;
696     std::hash_set< OString, OStringHash >::const_iterator iter = interfaces.begin();
697     while ( iter != interfaces.end() ) {
698         typereg::Reader reader(manager.getTypeReader((*iter).replace('.','/')));
699         if (!reader.isValid()) {
700             throw CannotDumpException(
701                 "Bad type library entity "
702                 + codemaker::convertString(
703                     reader.getTypeName()));
704         }
705 
706         generateFunctionParamterMap(o, options, manager, reader, generated, bFirst);
707         iter++;
708     }
709 }
710 
711 }
712 
713