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