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