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 "codemaker/commonjava.hxx"
25 
26 #include "skeletoncommon.hxx"
27 #include "skeletonjava.hxx"
28 
29 using namespace ::rtl;
30 
31 namespace skeletonmaker { namespace java {
32 
33 void printType(std::ostream & o,
34                ProgramOptions const & options, TypeManager const & manager,
35                OString const & type, bool referenceType,
36                bool defaultvalue);
37 
printType(std::ostream & o,ProgramOptions const & options,TypeManager const & manager,codemaker::UnoType::Sort sort,RTTypeClass typeClass,OString const & name,sal_Int32 rank,std::vector<OString> const & arguments,bool referenceType,bool defaultvalue)38 void printType(std::ostream & o,
39                ProgramOptions const & options, TypeManager const & manager,
40                codemaker::UnoType::Sort sort, RTTypeClass typeClass,
41                OString const & name, sal_Int32 rank,
42                std::vector< OString > const & arguments, bool referenceType,
43                bool defaultvalue)
44 {
45     if ( defaultvalue && rank == 0 && sort <= codemaker::UnoType::SORT_CHAR ) {
46         switch (sort)
47         {
48         case codemaker::UnoType::SORT_BOOLEAN:
49             o << "false";
50             return;
51         case codemaker::UnoType::SORT_CHAR:
52         case codemaker::UnoType::SORT_BYTE:
53         case codemaker::UnoType::SORT_SHORT:
54         case codemaker::UnoType::SORT_UNSIGNED_SHORT:
55         case codemaker::UnoType::SORT_LONG:
56         case codemaker::UnoType::SORT_UNSIGNED_LONG:
57         case codemaker::UnoType::SORT_HYPER:
58         case codemaker::UnoType::SORT_UNSIGNED_HYPER:
59         case codemaker::UnoType::SORT_FLOAT:
60         case codemaker::UnoType::SORT_DOUBLE:
61             o << "0";
62             return;
63         case codemaker::UnoType::SORT_VOID:
64         case codemaker::UnoType::SORT_STRING:
65         case codemaker::UnoType::SORT_TYPE:
66         case codemaker::UnoType::SORT_ANY:
67         case codemaker::UnoType::SORT_COMPLEX:
68             break;
69         }
70     }
71 
72     if ( defaultvalue ) {
73         if ( sort == codemaker::UnoType::SORT_COMPLEX &&
74             typeClass == RT_TYPE_INTERFACE ) {
75             o << "null";
76             return;
77         } else if ( sort == codemaker::UnoType::SORT_ANY && rank==0 ) {
78             o << "com.sun.star.uno.Any.VOID";
79             return;
80         } else if ( sort == codemaker::UnoType::SORT_TYPE && rank==0 ) {
81             o << "com.sun.star.uno.Type.VOID";
82             return;
83         } else
84             if ( typeClass != RT_TYPE_ENUM || rank > 0 )
85                 o << "new ";
86     }
87 
88     OString sType(codemaker::java::translateUnoToJavaType(
89                       sort, typeClass, name, referenceType && rank==0).replace('/', '.'));
90     if ( sType.indexOf("java.lang.") == 0 )
91         sType = sType.copy(10);
92     o << sType.getStr();
93     if ( !arguments.empty() && options.java5 ) {
94         o << '<';
95         for ( std::vector< OString >::const_iterator i(arguments.begin());
96               i != arguments.end(); ++i )
97         {
98             if ( i != arguments.begin() ) {
99                 o << ", ";
100             }
101 
102             printType(o, options, manager, *i, true, false);
103         }
104         o << '>';
105     }
106     for ( sal_Int32 i = 0; i < rank; ++i ) {
107         if ( defaultvalue )
108             o << "[0]";
109         else
110             o << "[]";
111     }
112 
113     if ( defaultvalue && sort > codemaker::UnoType::SORT_CHAR && rank == 0 ) {
114         if ( typeClass == RT_TYPE_ENUM )
115             o << ".getDefault()";
116         else
117             o << "()";
118     }
119 }
120 
printType(std::ostream & o,ProgramOptions const & options,TypeManager const & manager,OString const & type,bool referenceType,bool defaultvalue)121 void printType(std::ostream & o,
122     ProgramOptions const & options, TypeManager const & manager,
123     OString const & type, bool referenceType, bool defaultvalue)
124 {
125     RTTypeClass typeClass;
126     OString name;
127     sal_Int32 rank;
128     std::vector< OString > arguments;
129     codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve(
130         manager, type, true, true, true, &typeClass, &name, &rank, &arguments);
131     printType(o,
132         options, manager, sort, typeClass, name, rank, arguments,
133         referenceType, defaultvalue);
134 }
135 
printConstructorParameters(std::ostream & o,ProgramOptions const & options,TypeManager const & manager,typereg::Reader const & reader,typereg::Reader const & outerReader,std::vector<OString> const & arguments)136 bool printConstructorParameters(std::ostream & o,
137     ProgramOptions const & options, TypeManager const & manager,
138     typereg::Reader const & reader, typereg::Reader const & outerReader,
139     std::vector< OString > const & arguments)
140 {
141     bool previous = false;
142     if ( reader.getSuperTypeCount() != 0 ) {
143         OString super(
144             codemaker::convertString(reader.getSuperTypeName(0)));
145         typereg::Reader superReader(manager.getTypeReader(super));
146         if ( !superReader.isValid() ) {
147             throw CannotDumpException("Bad type library entity " + super);
148         }
149         previous = printConstructorParameters(o,
150             options, manager, superReader, outerReader, arguments);
151     }
152     for ( sal_uInt16 i = 0; i < reader.getFieldCount(); ++i ) {
153         if ( previous ) {
154             o << ", ";
155         }
156         previous = true;
157         if ( (reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) == 0  ) {
158             printType(o,
159                 options, manager,
160                 codemaker::convertString(reader.getFieldTypeName(i)),
161                 false);
162         } else if ( arguments.empty() ) {
163             o << "java.lang.Object";
164         } else {
165             sal_uInt16 tparam = 0;
166             while ( outerReader.getReferenceTypeName(tparam)
167                     != reader.getFieldTypeName(i) )
168             {
169                 ++tparam;
170                 OSL_ASSERT(tparam < outerReader.getReferenceCount());
171             }
172             // assume std::vector< OString >::size_type is at least as
173             // large as sal_uInt16:
174             printType(o, options, manager, arguments[tparam], true);
175         }
176         o
177             << ' '
178             << (codemaker::java::translateUnoToJavaIdentifier(
179                     codemaker::convertString(reader.getFieldName(i)),
180                     "param").
181                 getStr());
182     }
183     return previous;
184 }
185 
printConstructor(std::ostream & o,ProgramOptions const & options,TypeManager const & manager,typereg::Reader const & reader,std::vector<OString> const & arguments)186 void printConstructor(std::ostream & o,
187     ProgramOptions const & options, TypeManager const & manager,
188     typereg::Reader const & reader,
189     std::vector< OString > const & arguments)
190 {
191     OString type(codemaker::convertString(reader.getTypeName()));
192     o << "public " << type.copy(type.lastIndexOf('/') + 1) << '(';
193     printConstructorParameters(o, options, manager, reader, reader, arguments);
194     o << ");\n";
195 }
196 
printMethodParameters(std::ostream & o,ProgramOptions const & options,TypeManager const & manager,typereg::Reader const & reader,sal_uInt16 method,bool previous,bool withtype,bool)197 void printMethodParameters(std::ostream & o,
198     ProgramOptions const & options, TypeManager const & manager,
199     typereg::Reader const & reader, sal_uInt16 method, bool previous,
200     bool withtype, bool /*shortname*/)
201 {
202     for ( sal_uInt16 i = 0; i < reader.getMethodParameterCount(method); ++i ) {
203         if ( previous  )
204             o << ", ";
205         else
206             previous = true;
207 
208         if ( withtype ) {
209             printType(o, options, manager,
210                       codemaker::convertString(
211                           reader.getMethodParameterTypeName(method, i)),
212                       false);
213             if ( reader.getMethodParameterFlags(method, i) == RT_PARAM_OUT
214                  || reader.getMethodParameterFlags(method, i) == RT_PARAM_INOUT )
215             {
216                 o << "[]";
217             } else if ( (reader.getMethodParameterFlags(method, i) & RT_PARAM_REST )
218                        != 0)
219             {
220                 o << (options.java5 ? "..." : "[]");
221             }
222             o << ' ';
223         }
224         o << (codemaker::java::translateUnoToJavaIdentifier(
225                   codemaker::convertString(
226                       reader.getMethodParameterName(method, i)),
227                   "param").
228               getStr());
229     }
230 }
231 
printExceptionSpecification(std::ostream & o,ProgramOptions const & options,TypeManager const & manager,typereg::Reader const & reader,sal_uInt16 method)232 void printExceptionSpecification(std::ostream & o,
233     ProgramOptions const & options, TypeManager const & manager,
234     typereg::Reader const & reader, sal_uInt16 method)
235 {
236     if ( reader.getMethodExceptionCount(method) > 0 ) {
237         o << " throws ";
238         for ( sal_uInt16 i = 0; i < reader.getMethodExceptionCount(method); ++i )
239         {
240             if ( i != 0 ) {
241                 o << ", ";
242             }
243             printType(o,
244                 options, manager,
245                 codemaker::convertString(
246                     reader.getMethodExceptionTypeName(method, i)),
247                 false);
248         }
249     }
250 }
251 
252 
printSetPropertyMixinBody(std::ostream & o,typereg::Reader const & reader,sal_uInt16 field,sal_uInt16 method,OString const & indentation)253 void printSetPropertyMixinBody(std::ostream & o,
254                                typereg::Reader const & reader,
255                                sal_uInt16 field,
256                                sal_uInt16 method,
257                                OString const & indentation)
258 {
259     RTFieldAccess propFlags = checkAdditionalPropertyFlags(reader, field, method);
260     OString fieldname = codemaker::convertString(reader.getFieldName(field));
261     bool bound = (reader.getFieldFlags(field) & RT_ACCESS_BOUND ? true : false);
262 
263     o << "\n" << indentation << "{\n";
264 
265     if ( bound ) {
266         o << indentation << "    PropertySetMixin.BoundListeners l = "
267             "new PropertySetMixin.BoundListeners();\n\n";
268     }
269 
270     o << indentation << "    m_prophlp.prepareSet(\""
271       << fieldname << "\", ";
272     if ( propFlags & RT_ACCESS_CONSTRAINED ) {
273         OString fieldtype = codemaker::convertString(reader.getFieldTypeName(field));
274 
275         sal_Int32 index = fieldtype.lastIndexOf('<');
276         sal_Int32 nPos=0;
277 		bool single = true;
278 		bool optional = false;
279 		OStringBuffer buffer1(64);
280 		OStringBuffer buffer2(64);
281         do
282         {
283             OString s(fieldtype.getToken(0, '<', nPos));
284 			OStringBuffer buffer(16);
285             buffer.append("((");
286             buffer.append(s.copy(s.lastIndexOf('/')+1));
287             buffer.append(')');
288 			OString t = buffer.makeStringAndClear();
289 
290             if ( t.equals("((Optional)") ) {
291                 optional=true;
292                 if (single) {
293                     single=false;
294                     buffer1.append("the_value.IsPresent");
295                     buffer2.append("the_value.Value");
296                 } else {
297                     buffer1.insert(0, t);
298                     buffer1.append(").IsPresent");
299                     buffer2.insert(0, t);
300                     buffer2.append(").Value");
301                 }
302             } else {
303                 if ( single ) {
304                     single=false;
305                     if ( !optional ) {
306                         buffer1.append("the_value.Value");
307                     }
308                     buffer2.append("the_value.Value");
309                 } else {
310                     if ( !optional ) {
311                         buffer1.insert(0, t);
312                         buffer1.append(").Value");
313                     }
314                     buffer2.insert(0, t);
315                     buffer2.append(").Value");
316                 }
317             }
318         } while( nPos <= index );
319 
320         o << "Any.VOID,\n" << indentation << "        ";
321         if ( optional )
322             o << "(";
323         o << buffer1.makeStringAndClear();
324 		if ( optional )
325 			o << ") ? " << buffer2.makeStringAndClear() << " : Any.VOID,\n"
326               << indentation << "        ";
327         else
328             o << ", ";
329     }
330 
331     if ( bound )
332         o << "l";
333     else
334         o << "null";
335     o << ");\n";
336 
337     o << indentation << "    synchronized (this) {\n"
338       << indentation << "        m_" << fieldname
339       << " = the_value;\n" << indentation << "    }\n";
340 
341     if ( bound ) {
342         o << indentation << "    l.notifyListeners();\n";
343     }
344     o  << indentation << "}\n\n";
345 }
346 
347 void generateXPropertySetBodies(std::ostream& o);
348 void generateXFastPropertySetBodies(std::ostream& o);
349 void generateXPropertyAccessBodies(std::ostream& o);
350 
printMethods(std::ostream & o,ProgramOptions const & options,TypeManager const & manager,typereg::Reader const & reader,codemaker::GeneratedTypeSet & generated,OString const & delegate,OString const & indentation,bool defaultvalue,bool usepropertymixin)351 void printMethods(std::ostream & o,
352     ProgramOptions const & options, TypeManager const & manager,
353     typereg::Reader const & reader,
354     codemaker::GeneratedTypeSet & generated,
355     OString const & delegate, OString const & indentation,
356     bool defaultvalue, bool usepropertymixin)
357 {
358     OString type(codemaker::convertString(reader.getTypeName()));
359     if ( generated.contains(type) || type == "com/sun/star/uno/XInterface" ||
360          ( defaultvalue &&
361            ( type.equals("com/sun/star/lang/XComponent") ||
362              type.equals("com/sun/star/lang/XTypeProvider") ||
363              type.equals("com/sun/star/uno/XWeak") ) ) ) {
364         return;
365     }
366 
367     if ( usepropertymixin ) {
368         if ( type.equals("com/sun/star/beans/XPropertySet") ) {
369             generated.add(type);
370             generateXPropertySetBodies(o);
371             return;
372         } else if ( type.equals("com/sun/star/beans/XFastPropertySet") ) {
373             generated.add(type);
374             generateXFastPropertySetBodies(o);
375             return;
376         } else if ( type.equals("com/sun/star/beans/XPropertyAccess") ) {
377             generated.add(type);
378             generateXPropertyAccessBodies(o);
379             return;
380         }
381     }
382 
383     static OString sd(RTL_CONSTASCII_STRINGPARAM("_"));
384     bool body = ((delegate.getLength() > 0) ? true : false);
385     bool defaultbody = ((delegate.equals(sd)) ? true : false);
386 
387     generated.add(type);
388     if ( options.all || defaultvalue ) {
389         for (sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i) {
390             typereg::Reader super(
391                 manager.getTypeReader(
392                     codemaker::convertString(
393                         reader.getSuperTypeName(i))));
394             if ( !super.isValid() ) {
395                 throw CannotDumpException(
396                     "Bad type library entity "
397                     + codemaker::convertString(
398                         reader.getSuperTypeName(i)));
399             }
400             printMethods(o, options, manager, super, generated, delegate,
401                          indentation, defaultvalue, usepropertymixin);
402         }
403         if ( reader.getFieldCount() > 0 || reader.getMethodCount() > 0 ) {
404             o << indentation << "// ";
405             printType(o, options, manager, type, false);
406             o << ":\n";
407         }
408     }
409     sal_uInt16 method = 0;
410     for ( sal_uInt16 i = 0; i < reader.getFieldCount(); ++i ) {
411 //         OString fieldName(
412 //             codemaker::convertString(reader.getFieldName(i)).
413 //             replace('/', '.'));
414 //         OString fieldType(
415 //             codemaker::convertString(reader.getFieldTypeName(i)).
416 //             replace('/', '.'));
417 //         attributes.insert(StringPairHashMap::value_type(fieldName,
418 //                               std::pair<OString, sal_Int16>(
419 //                                   fieldType, reader.getFieldFlags(i))));
420 
421         o << indentation << "public ";
422         printType(o,
423             options, manager,
424             codemaker::convertString(reader.getFieldTypeName(i)), false);
425         o << " get"
426           << codemaker::convertString(reader.getFieldName(i)).getStr()
427           << "()";
428 
429         #if 0
430 		// DEBUG
431 		sal_uInt16 mc = reader.getMethodCount();
432 		RTMethodMode mm = reader.getMethodFlags(method);
433         #endif
434 		OUString mn = reader.getMethodName(method);
435 		OUString fn = reader.getFieldName(i);
436 
437         if ( method < reader.getMethodCount()
438              && reader.getMethodFlags(method) == RT_MODE_ATTRIBUTE_GET
439              && reader.getMethodName(method) == reader.getFieldName(i) )
440         {
441             printExceptionSpecification(o, options, manager, reader, method++);
442         }
443         if ( body ) {
444             if ( defaultbody ) {
445                 if ( usepropertymixin ) {
446                     o << "\n" << indentation << "{\n" << indentation
447                       << "    return m_"
448                       << codemaker::convertString(reader.getFieldName(i)).getStr()
449                       << ";\n" << indentation << "}\n\n";
450                 } else {
451                     o << "\n" << indentation << "{\n" << indentation
452                       << "    return ";
453                     printType(o,
454                               options, manager,
455                               codemaker::convertString(reader.getFieldTypeName(i)),
456                               false, true);
457                     o << ";\n" << indentation << "}\n\n";
458                 }
459             } else {
460                 o << "\n" << indentation << "{\n" << indentation <<
461                     "    return "
462                   << delegate.getStr() << "get"
463                   << codemaker::convertString(reader.getFieldName(i)).getStr()
464                   << "();\n" << indentation << "}\n\n";
465             }
466 		} else {
467             o << ";\n";
468 		}
469 
470 		// REMOVE next line
471 		OUString tmp = reader.getFieldName(i);
472 		bool setAttrMethod = false;
473         if ( (reader.getFieldFlags(i) & RT_ACCESS_READONLY) == 0 ) {
474             o << indentation << "public void set"
475               << (codemaker::convertString(reader.getFieldName(i)).
476                   getStr())
477               << '(';
478             printType(o,
479                 options, manager,
480                 codemaker::convertString(reader.getFieldTypeName(i)),
481                 false);
482             o << " the_value)";
483             if ( method < reader.getMethodCount()
484                  && reader.getMethodFlags(method) == RT_MODE_ATTRIBUTE_SET
485                  && reader.getMethodName(method) == reader.getFieldName(i) )
486             {
487 				setAttrMethod=true;
488                 printExceptionSpecification(o, options, manager, reader, method);
489             }
490             if ( body ) {
491                 if ( defaultbody ) {
492                     if ( usepropertymixin ) {
493                         printSetPropertyMixinBody(o, reader, i, method,
494                                                   indentation);
495                     } else {
496                         o << "\n" << indentation << "{\n\n" << indentation
497                           << "}\n\n";
498                     }
499                 } else {
500                     o << "\n" << indentation << "{\n" << indentation
501                       << "    " << delegate.getStr() << "set"
502                       << codemaker::convertString(reader.getFieldName(i)).getStr()
503                       << "(the_value);\n" << indentation << "}\n\n";
504                 }
505 			} else {
506                 o << ";\n";
507 			}
508 			if (setAttrMethod) ++method;
509         }
510     }
511     for ( ; method < reader.getMethodCount(); ++method ) {
512         o << indentation << "public ";
513         printType(o,
514             options, manager,
515             codemaker::convertString(
516                 reader.getMethodReturnTypeName(method)),
517             false);
518 
519         const OString methodName(codemaker::convertString(reader.getMethodName(method)));
520 
521         o << ' ' << methodName.getStr() << '(';
522         printMethodParameters(o, options, manager, reader, method, false, true);
523         o << ')';
524         printExceptionSpecification(o, options, manager, reader, method);
525         if ( body ) {
526             static OUString s(RTL_CONSTASCII_USTRINGPARAM("void"));
527             if ( defaultbody ) {
528                 o << "\n" << indentation << "{\n";
529                 if ( !reader.getMethodReturnTypeName(method).equals(s) ) {
530                     o << indentation << "    // TODO: Exchange the default return "
531                       << "implementation for \"" << methodName << "\" !!!\n";
532                     o << indentation << "    // NOTE: "
533                         "Default initialized polymorphic structs can cause problems"
534                         "\n" << indentation << "    // because of missing default "
535                         "initialization of primitive types of\n" << indentation
536                       << "    // some C++ compilers or different Any initialization"
537                         " in Java and C++\n" << indentation
538                       << "    // polymorphic structs.\n" << indentation
539                       << "    return ";
540                     printType(o,
541                         options, manager,
542                         codemaker::convertString(
543                             reader.getMethodReturnTypeName(method)),
544                         false, true);
545                     o << ";";
546                 } else {
547                     o << indentation << "    // TODO: Insert your implementation for \""
548                       << methodName << "\" here.";
549                 }
550                 o << "\n" << indentation << "}\n\n";
551             } else {
552                 o << "\n" << indentation << "{\n" << indentation << "    ";
553                 if ( !reader.getMethodReturnTypeName(method).equals(s) )
554                     o << "return ";
555                 o << delegate.getStr()
556                   << (codemaker::convertString(
557                           reader.getMethodName(method)).getStr())
558                   << '(';
559                 printMethodParameters(o, options, manager, reader, method,
560                                          false, false);
561                 o << ");\n" << indentation << "}\n\n";
562             }
563         } else {
564             o << ";\n";
565         }
566     }
567 }
568 
printConstructionMethods(std::ostream & o,ProgramOptions const & options,TypeManager const & manager,typereg::Reader const & reader)569 void printConstructionMethods(std::ostream & o,
570     ProgramOptions const & options, TypeManager const & manager,
571     typereg::Reader const & reader)
572 {
573     for ( sal_uInt16 i = 0; i < reader.getMethodCount(); ++i ) {
574         o << "public static ";
575         printType(o,
576             options, manager,
577             codemaker::convertString(reader.getSuperTypeName(0)), false);
578         o << ' ';
579         if ( reader.getMethodName(i).getLength() == 0 ) {
580             o << "create";
581         } else {
582             o << (codemaker::java::translateUnoToJavaIdentifier(
583                       codemaker::convertString(reader.getMethodName(i)),
584                       "method").getStr());
585         }
586         o << "(com.sun.star.uno.XComponentContext the_context";
587         printMethodParameters(o, options, manager, reader, i, true, true);
588         o << ')';
589         printExceptionSpecification(o, options, manager, reader, i);
590         o << ";\n";
591     }
592 }
593 
594 void generateDocumentation(std::ostream & o,
595     ProgramOptions const & options, TypeManager const & manager,
596     OString const & type);
597 
printServiceMembers(std::ostream & o,ProgramOptions const & options,TypeManager const & manager,typereg::Reader const & reader,OString const & type,OString const & delegate)598 void printServiceMembers(std::ostream & o,
599     ProgramOptions const & options, TypeManager const & manager,
600     typereg::Reader const & reader, OString const & type,
601     OString const & delegate)
602 {
603     for ( sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i ) {
604         OString referenceType(
605             codemaker::convertString(
606                 reader.getReferenceTypeName(i)).replace('/', '.'));
607 
608         if ( reader.getReferenceSort(i) == RT_REF_SUPPORTS ) {
609             o << "\n// supported interface " << referenceType.getStr() << "\n";
610             generateDocumentation(o, options, manager, referenceType, delegate);
611         } else if ( reader.getReferenceSort(i) == RT_REF_EXPORTS ) {
612             o << "\n// exported service " << referenceType.getStr() << "\n";
613             generateDocumentation(o, options, manager, referenceType, delegate);
614         }
615     }
616 
617     o << "\n// properties of service \""<< type.getStr() << "\"\n";
618     for ( sal_uInt16 i = 0; i < reader.getFieldCount(); ++i ) {
619         OString fieldName(
620             codemaker::convertString(reader.getFieldName(i)));
621         OString fieldType(
622             codemaker::convertString(reader.getFieldTypeName(i)));
623 
624         o << "// private ";
625         printType(o, options, manager, fieldType, false);
626         o << " "
627           << codemaker::java::translateUnoToJavaIdentifier(
628               fieldName, "property").getStr()
629           << ";\n";
630     }
631 }
632 
printMapsToJavaType(std::ostream & o,ProgramOptions const & options,TypeManager const & manager,codemaker::UnoType::Sort sort,RTTypeClass typeClass,OString const & name,sal_Int32 rank,std::vector<OString> const & arguments,const char * javaTypeSort)633 void printMapsToJavaType(std::ostream & o,
634     ProgramOptions const & options, TypeManager const & manager,
635     codemaker::UnoType::Sort sort, RTTypeClass typeClass,
636     OString const & name, sal_Int32 rank,
637     std::vector< OString > const & arguments, const char * javaTypeSort)
638 {
639     o << "maps to Java " << (options.java5 ? "1.5" : "1.4") << " ";
640     if ( javaTypeSort != 0 ) {
641         o << javaTypeSort << ' ';
642     }
643     o << "type \"";
644     if ( rank == 0 && name == "com/sun/star/uno/XInterface" ) {
645         o << "com.sun.star.uno.XInterface";
646     } else {
647         printType(o,
648             options, manager, sort, typeClass, name, rank, arguments, false);
649     }
650     o << '"';
651 }
652 
generateDocumentation(std::ostream & o,ProgramOptions const & options,TypeManager const & manager,OString const & type,OString const & delegate)653 void generateDocumentation(std::ostream & o,
654     ProgramOptions const & options, TypeManager const & manager,
655     OString const & type, OString const & delegate)
656 {
657     if ( type.indexOf('/') >= 0 ) {
658         throw CannotDumpException("Illegal type name " + type);
659     }
660     OString binType(type.replace('.', '/'));
661     RTTypeClass typeClass;
662     OString name;
663     sal_Int32 rank;
664     std::vector< OString > arguments;
665     codemaker::UnoType::Sort sort = decomposeResolveAndCheck(
666         manager, binType, false, true, true, &typeClass, &name, &rank,
667         &arguments);
668 
669     bool comment=true;
670     if ( delegate.getLength() > 0 ) {
671         if ( typeClass != RT_TYPE_INTERFACE && typeClass != RT_TYPE_SERVICE )
672             return;
673 
674         comment=false;
675     }
676 
677     if ( comment ) {
678         o << "\n// UNO";
679         if ( rank > 0 ) {
680             o << " sequence type";
681         } else if ( sort != codemaker::UnoType::SORT_COMPLEX ) {
682             o << " simple type";
683         } else {
684             typereg::Reader reader(manager.getTypeReader(name));
685             if ( !reader.isValid() ) {
686                 throw CannotDumpException("Bad type library entity " + name);
687             }
688             switch ( typeClass ) {
689             case RT_TYPE_INTERFACE:
690                 o << " interface type";
691                 break;
692 
693             case RT_TYPE_MODULE:
694                 o << "IDL module";
695                 break;
696 
697             case RT_TYPE_STRUCT:
698                 if ( reader.getReferenceCount() == 0 ) {
699                     o << " simple struct type";
700                 } else if ( arguments.empty() ) {
701                     o << " polymorphic struct type template";
702                 } else {
703                     o << " instantiated polymorphic struct type";
704                 }
705                 break;
706 
707             case RT_TYPE_ENUM:
708                 o << " enum type";
709                 break;
710 
711             case RT_TYPE_EXCEPTION:
712                 o << " exception type";
713                 break;
714 
715             case RT_TYPE_TYPEDEF:
716                 o << "IDL typedef";
717                 break;
718 
719             case RT_TYPE_SERVICE:
720                 if ( reader.getSuperTypeCount() > 0 ) {
721                     o << " single-inheritance--based service";
722                 } else {
723                     o << "IDL accumulation-based service";
724                 }
725                 break;
726 
727             case RT_TYPE_SINGLETON:
728                 if ( (manager.getTypeReader(
729                           codemaker::convertString(
730                               reader.getSuperTypeName(0))).getTypeClass())
731                      == RT_TYPE_INTERFACE )
732                 {
733                     o << " inheritance-based singleton";
734                 } else {
735                     o << "IDL service-based singleton";
736                 }
737                 break;
738 
739             case RT_TYPE_CONSTANTS:
740                 o << "IDL constant group";
741                 break;
742 
743             default:
744                 OSL_ASSERT(false);
745                 break;
746             }
747         }
748         o << " \"" << type.getStr() << "\" ";
749     }
750     sort = codemaker::decomposeAndResolve(
751         manager, binType, true, true, true, &typeClass, &name, &rank,
752         &arguments);
753     if ( rank > 0 ) {
754         printMapsToJavaType(o,
755             options, manager, sort, typeClass, name, rank, arguments, "array");
756         o << '\n';
757     } else if ( sort != codemaker::UnoType::SORT_COMPLEX ) {
758         printMapsToJavaType(o,
759             options, manager, sort, typeClass, name, rank, arguments, 0);
760         o << '\n';
761     } else {
762         typereg::Reader reader(manager.getTypeReader(name));
763         if ( !reader.isValid() ) {
764             throw CannotDumpException("Bad type library entity " + name);
765         }
766         switch ( typeClass ) {
767         case RT_TYPE_INTERFACE:
768             printMapsToJavaType(o,
769                 options, manager, sort, typeClass, name, rank, arguments,
770                 "interface");
771             if ( name == "com/sun/star/uno/XInterface" ) {
772                 o << '\n';
773             } else {
774                 o
775                     << "; " << (options.all ? "all" : "direct")
776                     << " methods:\n";
777                 codemaker::GeneratedTypeSet generated;
778                 printMethods(o, options, manager, reader, generated,
779                              delegate, "");
780             }
781             break;
782 
783         case RT_TYPE_MODULE:
784             printMapsToJavaType(o,
785                 options, manager, sort, typeClass, name, rank, arguments,
786                 "package");
787             o << '\n';
788             break;
789 
790         case RT_TYPE_STRUCT:
791             if ( reader.getReferenceCount() == 0 ) {
792                 printMapsToJavaType(o,
793                     options, manager, sort, typeClass, name, rank, arguments,
794                     "class");
795             } else if ( arguments.empty() ) {
796                 printMapsToJavaType(o,
797                     options, manager, sort, typeClass, name, rank, arguments,
798                     options.java5 ? "generic class" : "class");
799             } else {
800                 printMapsToJavaType(o,
801                     options, manager, sort, typeClass, name, rank, arguments,
802                     options.java5 ? "generic class instantiation" : "class");
803             }
804             o << "; full constructor:\n";
805             printConstructor(o, options, manager, reader, arguments);
806             break;
807 
808         case RT_TYPE_ENUM:
809         case RT_TYPE_CONSTANTS:
810             printMapsToJavaType(o,
811                 options, manager, sort, typeClass, name, rank, arguments,
812                 "class");
813             o << '\n';
814             break;
815 
816         case RT_TYPE_EXCEPTION:
817             printMapsToJavaType(o,
818                 options, manager, sort, typeClass, name, rank, arguments,
819                 "exception class");
820             o << "; full constructor:\n";
821             printConstructor(o, options, manager, reader, arguments);
822             break;
823 
824         case RT_TYPE_SERVICE:
825             if ( reader.getSuperTypeCount() > 0 ) {
826                 printMapsToJavaType(o,
827                     options, manager, sort, typeClass, name, rank, arguments,
828                     "class");
829                 o << "; construction methods:\n";
830                 printConstructionMethods(o, options, manager, reader);
831 
832                 OString super(
833                     codemaker::convertString(
834                         reader.getSuperTypeName(0)).replace('/', '.'));
835 
836                 generateDocumentation(o, options, manager, super, delegate);
837             } else {
838                 o << ("does not map to Java\n"
839                       "// the service members are generated instead\n");
840                 printServiceMembers(o, options, manager, reader, type, delegate);
841             }
842             break;
843 
844         case RT_TYPE_SINGLETON:
845             if ( reader.getSuperTypeCount() > 0 &&
846                  ((manager.getTypeReader(
847                        codemaker::convertString(
848                            reader.getSuperTypeName(0))).getTypeClass())
849                   == RT_TYPE_INTERFACE) ) {
850                 printMapsToJavaType(o, options, manager, sort, typeClass,
851                                     name, rank, arguments, "class");
852                 o << "; get method:\npublic static ";
853                 printType(o, options, manager,
854                           codemaker::convertString(reader.getSuperTypeName(0)),
855                           false);
856                 o
857                     << " get(com.sun.star.uno.XComponentContext context);\n";
858             } else {
859                 o << "does not map to Java\n";
860             }
861             break;
862 
863         default:
864             OSL_ASSERT(false);
865             break;
866         }
867     }
868 }
869 
870 } }
871 
872 
873