1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <algorithm>
23 #include <cstring>
24 
25 #include <codemaker/codemaker.hxx>
26 #include <codemaker/commonjava.hxx>
27 #include <codemaker/global.hxx>
28 
29 #include "skeletoncommon.hxx"
30 #include "skeletonjava.hxx"
31 
32 namespace skeletonmaker { namespace java {
33 
printType(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,codemaker::UnoType::Sort sort,OUString const & nucleus,sal_Int32 rank,std::vector<OUString> const & arguments,bool referenceType,bool defaultvalue)34 static void printType(
35     std::ostream & o, ProgramOptions const & options,
36     rtl::Reference< TypeManager > const & manager,
37     codemaker::UnoType::Sort sort, OUString const & nucleus, sal_Int32 rank,
38     std::vector< OUString > const & arguments, bool referenceType,
39     bool defaultvalue)
40 {
41     if (defaultvalue && rank == 0 && sort <= codemaker::UnoType::Sort::Char) {
42         switch (sort) {
43         case codemaker::UnoType::Sort::Boolean:
44             o << "false";
45             return;
46         case codemaker::UnoType::Sort::Char:
47         case codemaker::UnoType::Sort::Byte:
48         case codemaker::UnoType::Sort::Short:
49         case codemaker::UnoType::Sort::UnsignedShort:
50         case codemaker::UnoType::Sort::Long:
51         case codemaker::UnoType::Sort::UnsignedLong:
52         case codemaker::UnoType::Sort::Hyper:
53         case codemaker::UnoType::Sort::UnsignedHyper:
54         case codemaker::UnoType::Sort::Float:
55         case codemaker::UnoType::Sort::Double:
56             o << "0";
57             return;
58         default:
59             break;
60         }
61     }
62 
63     if (defaultvalue) {
64         if (sort == codemaker::UnoType::Sort::Interface) {
65             o << "null";
66             return;
67         } else if (sort == codemaker::UnoType::Sort::Any && rank == 0) {
68             o << "com.sun.star.uno.Any.VOID";
69             return;
70         } else if (sort == codemaker::UnoType::Sort::Type && rank == 0) {
71             o << "com.sun.star.uno.Type.VOID";
72             return;
73         } else if (sort != codemaker::UnoType::Sort::Enum || rank != 0) {
74             o << "new ";
75         }
76     }
77 
78     OString sType(
79         codemaker::java::translateUnoToJavaType(
80             sort, u2b(nucleus), referenceType && rank == 0));
81     if (sType.startsWith("java.lang.")) {
82         sType = sType.copy(std::strlen("java.lang."));
83     }
84     o << sType;
85     if (!arguments.empty()) {
86         o << '<';
87         for (std::vector< OUString >::const_iterator i(arguments.begin());
88              i != arguments.end(); ++i)
89         {
90             if (i != arguments.begin()) {
91                 o << ", ";
92             }
93             printType(o, options, manager, *i, true);
94         }
95         o << '>';
96     }
97     for (sal_Int32 i = 0; i != rank; ++i) {
98         if (defaultvalue)
99             o << "[0]";
100         else
101             o << "[]";
102     }
103 
104     if (defaultvalue && sort > codemaker::UnoType::Sort::Char && rank == 0) {
105         if (sort == codemaker::UnoType::Sort::Enum)
106             o << ".getDefault()";
107         else
108             o << "()";
109     }
110 }
111 
printType(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,OUString const & name,bool referenceType,bool defaultvalue)112 void printType(
113     std::ostream & o, ProgramOptions const & options,
114     rtl::Reference< TypeManager > const & manager, OUString const & name,
115     bool referenceType, bool defaultvalue)
116 {
117     OUString nucleus;
118     sal_Int32 rank;
119     std::vector< OUString > arguments;
120     codemaker::UnoType::Sort sort = manager->decompose(
121         name, true, &nucleus, &rank, &arguments, nullptr);
122     printType(
123         o, options, manager, sort, nucleus, rank, arguments, referenceType,
124         defaultvalue);
125 }
126 
printConstructorParameters(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,codemaker::UnoType::Sort sort,rtl::Reference<unoidl::Entity> const & entity,OUString const & name,std::vector<OUString> const & arguments)127 static bool printConstructorParameters(
128     std::ostream & o, ProgramOptions const & options,
129     rtl::Reference< TypeManager > const & manager,
130     codemaker::UnoType::Sort sort,
131     rtl::Reference< unoidl::Entity > const & entity, OUString const & name,
132     std::vector< OUString > const & arguments)
133 {
134     bool previous = false;
135     switch (sort) {
136     case codemaker::UnoType::Sort::PlainStruct:
137         {
138             rtl::Reference< unoidl::PlainStructTypeEntity > ent2(
139                 dynamic_cast< unoidl::PlainStructTypeEntity * >(entity.get()));
140             assert(ent2.is());
141             if (!ent2->getDirectBase().isEmpty()) {
142                 rtl::Reference< unoidl::Entity > baseEnt;
143                 codemaker::UnoType::Sort baseSort = manager->getSort(
144                     ent2->getDirectBase(), &baseEnt);
145                 previous = printConstructorParameters(
146                     o, options, manager, baseSort, baseEnt,
147                     ent2->getDirectBase(), std::vector< OUString >());
148             }
149             for (const auto& rMember : ent2->getDirectMembers())
150             {
151                 if (previous) {
152                     o << ", ";
153                 }
154                 previous = true;
155                 printType(o, options, manager, rMember.type, false);
156                 o << ' '
157                   << codemaker::java::translateUnoToJavaIdentifier(
158                       u2b(rMember.name), "param");
159             }
160             break;
161         }
162     case codemaker::UnoType::Sort::PolymorphicStructTemplate:
163         {
164             rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > ent2(
165                 dynamic_cast< unoidl::PolymorphicStructTypeTemplateEntity * >(
166                     entity.get()));
167             assert(ent2.is());
168             for (const auto& rMember : ent2->getMembers())
169             {
170                 if (previous) {
171                     o << ", ";
172                 }
173                 previous = true;
174                 if (rMember.parameterized) {
175                     o << rMember.type;
176                 } else {
177                     printType(o, options, manager, rMember.type, false);
178                 }
179                 o << ' '
180                   << codemaker::java::translateUnoToJavaIdentifier(
181                       u2b(rMember.name), "param");
182             }
183             break;
184         }
185     case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
186         {
187             rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > ent2(
188                 dynamic_cast< unoidl::PolymorphicStructTypeTemplateEntity * >(
189                     entity.get()));
190             assert(ent2.is());
191             for (const auto& rMember : ent2->getMembers())
192             {
193                 if (previous) {
194                     o << ", ";
195                 }
196                 previous = true;
197                 if (rMember.parameterized) {
198                     auto j = std::find(ent2->getTypeParameters().begin(),
199                         ent2->getTypeParameters().end(), rMember.type);
200                     if (j != ent2->getTypeParameters().end()) {
201                         o << arguments[j - ent2->getTypeParameters().begin()];
202                     }
203                 } else {
204                     printType(o, options, manager, rMember.type, false);
205                 }
206                 o << ' '
207                   << codemaker::java::translateUnoToJavaIdentifier(
208                       u2b(rMember.name), "param");
209             }
210             break;
211         }
212     case codemaker::UnoType::Sort::Exception:
213         {
214             rtl::Reference< unoidl::ExceptionTypeEntity > ent2(
215                 dynamic_cast< unoidl::ExceptionTypeEntity * >(entity.get()));
216             assert(ent2.is());
217             if (!ent2->getDirectBase().isEmpty()) {
218                 rtl::Reference< unoidl::Entity > baseEnt;
219                 codemaker::UnoType::Sort baseSort = manager->getSort(
220                     ent2->getDirectBase(), &baseEnt);
221                 previous = printConstructorParameters(
222                     o, options, manager, baseSort, baseEnt,
223                     ent2->getDirectBase(), std::vector< OUString >());
224             }
225             for (const auto& rMember : ent2->getDirectMembers())
226             {
227                 if (previous) {
228                     o << ", ";
229                 }
230                 previous = true;
231                 printType(o, options, manager, rMember.type, false);
232                 o << ' '
233                   << codemaker::java::translateUnoToJavaIdentifier(
234                       u2b(rMember.name), "param");
235             }
236             break;
237         }
238     default:
239         throw CannotDumpException(
240             "unexpected entity \"" + name
241             + "\" in call to skeletonmaker::cpp::printConstructorParameters");
242     }
243     return previous;
244 }
245 
printConstructor(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,codemaker::UnoType::Sort sort,rtl::Reference<unoidl::Entity> const & entity,OUString const & name,std::vector<OUString> const & arguments)246 static void printConstructor(
247     std::ostream & o, ProgramOptions const & options,
248     rtl::Reference< TypeManager > const & manager,
249     codemaker::UnoType::Sort sort,
250     rtl::Reference< unoidl::Entity > const & entity, OUString const & name,
251     std::vector< OUString > const & arguments)
252 {
253     o << "public " << name.copy(name.lastIndexOf('.') + 1) << '(';
254     printConstructorParameters(
255         o, options, manager, sort, entity, name, arguments);
256     o << ");\n";
257 }
258 
printMethodParameters(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,std::vector<unoidl::InterfaceTypeEntity::Method::Parameter> const & parameters,bool withType)259 static void printMethodParameters(
260     std::ostream & o, ProgramOptions const & options,
261     rtl::Reference< TypeManager > const & manager,
262     std::vector< unoidl::InterfaceTypeEntity::Method::Parameter > const &
263         parameters,
264     bool withType)
265 {
266     for (std::vector< unoidl::InterfaceTypeEntity::Method::Parameter >::
267              const_iterator i(parameters.begin());
268          i != parameters.end(); ++i)
269     {
270         if (i != parameters.begin()) {
271             o << ", ";
272         }
273         if (withType) {
274             printType(o, options, manager, i->type, false);
275             if (i->direction
276                 != unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN)
277             {
278                 o << "[]";
279             }
280             o << ' ';
281         }
282         o << codemaker::java::translateUnoToJavaIdentifier(
283             u2b(i->name), "param");
284     }
285 }
286 
printExceptionSpecification(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,std::vector<OUString> const & exceptions)287 static void printExceptionSpecification(
288     std::ostream & o, ProgramOptions const & options,
289     rtl::Reference< TypeManager > const & manager,
290     std::vector< OUString > const & exceptions)
291 {
292     if (!exceptions.empty()) {
293         o << " throws ";
294         for (std::vector< OUString >::const_iterator i(exceptions.begin());
295              i != exceptions.end(); ++i)
296         {
297             if (i !=exceptions.begin() ) {
298                 o << ", ";
299             }
300             printType(o, options, manager, *i, false);
301         }
302     }
303 }
304 
305 
printSetPropertyMixinBody(std::ostream & o,unoidl::InterfaceTypeEntity::Attribute const & attribute,OString const & indentation)306 static void printSetPropertyMixinBody(
307     std::ostream & o, unoidl::InterfaceTypeEntity::Attribute const & attribute,
308     OString const & indentation)
309 {
310     unoidl::AccumulationBasedServiceEntity::Property::Attributes propFlags
311         = checkAdditionalPropertyFlags(attribute);
312 
313     o << "\n" << indentation << "{\n";
314 
315     if ( attribute.bound ) {
316         o << indentation << "    PropertySetMixin.BoundListeners l = "
317             "new PropertySetMixin.BoundListeners();\n\n";
318     }
319 
320     o << indentation << "    m_prophlp.prepareSet(\""
321       << attribute.name << "\", ";
322     if ( propFlags & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_CONSTRAINED ) {
323         OString fieldtype = codemaker::convertString(attribute.type);
324 
325         sal_Int32 index = fieldtype.lastIndexOf('<');
326         sal_Int32 nPos=0;
327         bool single = true;
328         bool optional = false;
329         OStringBuffer buffer1(64);
330         OStringBuffer buffer2(64);
331         do
332         {
333             OString s(fieldtype.getToken(0, '<', nPos));
334             OString t{ "((" + s.copy(s.lastIndexOf('/')+1) + ")" };
335 
336             if ( t == "((Optional)" ) {
337                 optional=true;
338                 if (single) {
339                     single=false;
340                     buffer1.append("the_value.IsPresent");
341                     buffer2.append("the_value.Value");
342                 } else {
343                     buffer1.insert(0, t);
344                     buffer1.append(").IsPresent");
345                     buffer2.insert(0, t);
346                     buffer2.append(").Value");
347                 }
348             } else {
349                 if ( single ) {
350                     single=false;
351                     if ( !optional ) {
352                         buffer1.append("the_value.Value");
353                     }
354                     buffer2.append("the_value.Value");
355                 } else {
356                     if ( !optional ) {
357                         buffer1.insert(0, t);
358                         buffer1.append(").Value");
359                     }
360                     buffer2.insert(0, t);
361                     buffer2.append(").Value");
362                 }
363             }
364         } while( nPos <= index );
365 
366         o << "Any.VOID,\n" << indentation << "        ";
367         if ( optional )
368             o << "(";
369         o << buffer1.makeStringAndClear();
370         if ( optional )
371             o << ") ? " << buffer2.makeStringAndClear() << " : Any.VOID,\n"
372               << indentation << "        ";
373         else
374             o << ", ";
375     }
376 
377     if ( attribute.bound )
378         o << "l";
379     else
380         o << "null";
381     o << ");\n";
382 
383     o << indentation << "    synchronized (this) {\n"
384       << indentation << "        m_" << attribute.name
385       << " = the_value;\n" << indentation << "    }\n";
386 
387     if ( attribute.bound ) {
388         o << indentation << "    l.notifyListeners();\n";
389     }
390     o  << indentation << "}\n\n";
391 }
392 
printMethods(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,OUString const & name,codemaker::GeneratedTypeSet & generated,OString const & delegate,OString const & indentation,bool defaultvalue,bool usepropertymixin)393 void printMethods(std::ostream & o,
394     ProgramOptions const & options, rtl::Reference< TypeManager > const & manager,
395     OUString const & name,
396     codemaker::GeneratedTypeSet & generated,
397     OString const & delegate, OString const & indentation,
398     bool defaultvalue, bool usepropertymixin)
399 {
400     if ( generated.contains(u2b(name)) || name == "com.sun.star.uno.XInterface" ||
401          ( defaultvalue &&
402            ( name == "com.sun.star.lang.XComponent" ||
403              name == "com.sun.star.lang.XTypeProvider" ||
404              name == "com.sun.star.uno.XWeak" ) ) ) {
405         return;
406     }
407 
408     if ( usepropertymixin ) {
409         if (name == "com.sun.star.beans.XPropertySet") {
410             generated.add(u2b(name));
411             generateXPropertySetBodies(o);
412             return;
413         } else if (name == "com.sun.star.beans.XFastPropertySet") {
414             generated.add(u2b(name));
415             generateXFastPropertySetBodies(o);
416             return;
417         } else if (name == "com.sun.star.beans.XPropertyAccess") {
418             generated.add(u2b(name));
419             generateXPropertyAccessBodies(o);
420             return;
421         }
422     }
423 
424     static OString sd("_");
425     bool body = !delegate.isEmpty();
426     bool defaultbody = delegate == sd;
427 
428     generated.add(u2b(name));
429     rtl::Reference< unoidl::Entity > ent;
430     if (manager->getSort(name, &ent) != codemaker::UnoType::Sort::Interface)
431     {
432         throw CannotDumpException(
433             "unexpected entity \"" + name
434             + "\" in call to skeletonmaker::java::printMethods");
435     }
436     rtl::Reference< unoidl::InterfaceTypeEntity > ent2(
437         dynamic_cast< unoidl::InterfaceTypeEntity * >(ent.get()));
438     assert(ent2.is());
439     if ( options.all || defaultvalue ) {
440         for (const auto& rBase : ent2->getDirectMandatoryBases())
441         {
442             printMethods(
443                 o, options, manager, rBase.name, generated, delegate, indentation,
444                 defaultvalue, usepropertymixin);
445         }
446         if (!(ent2->getDirectAttributes().empty()
447               && ent2->getDirectMethods().empty()))
448         {
449             o << indentation << "// ";
450             printType(o, options, manager, name, false);
451             o << ":\n";
452         }
453     }
454     for (const auto& rAttr : ent2->getDirectAttributes())
455     {
456         o << indentation << "public ";
457         printType(o, options, manager, rAttr.type, false);
458         o << " get" << rAttr.name << "()";
459         printExceptionSpecification(o, options, manager, rAttr.getExceptions);
460         if ( body ) {
461             if ( defaultbody ) {
462                 if ( usepropertymixin ) {
463                     o << "\n" << indentation << "{\n" << indentation
464                       << "    return m_" << rAttr.name << ";\n" << indentation
465                       << "}\n\n";
466                 } else {
467                     o << "\n" << indentation << "{\n" << indentation
468                       << "    return ";
469                     printType(o, options, manager, rAttr.type, false, true);
470                     o << ";\n" << indentation << "}\n\n";
471                 }
472             } else {
473                 o << "\n" << indentation << "{\n" << indentation
474                   << "    return " << delegate << "get" << rAttr.name
475                   << "();\n" << indentation << "}\n\n";
476             }
477         } else {
478             o << ";\n";
479         }
480 
481         // REMOVE next line
482         if (!rAttr.readOnly) {
483             o << indentation << "public void set" << rAttr.name << '(';
484             printType(o, options, manager, rAttr.type, false);
485             o << " the_value)";
486             printExceptionSpecification(o, options, manager, rAttr.setExceptions);
487             if ( body ) {
488                 if ( defaultbody ) {
489                     if ( usepropertymixin ) {
490                         printSetPropertyMixinBody(o, rAttr, indentation);
491                     } else {
492                         o << "\n" << indentation << "{\n\n" << indentation
493                           << "}\n\n";
494                     }
495                 } else {
496                     o << "\n" << indentation << "{\n" << indentation
497                       << "    " << delegate << "set" << rAttr.name
498                       << "(the_value);\n" << indentation << "}\n\n";
499                 }
500             } else {
501                 o << ";\n";
502             }
503         }
504     }
505     for (const auto& rMethod : ent2->getDirectMethods())
506     {
507         o << indentation << "public ";
508         printType(o, options, manager, rMethod.returnType, false);
509         o << ' ' << rMethod.name << '(';
510         printMethodParameters(o, options, manager, rMethod.parameters, true);
511         o << ')';
512         printExceptionSpecification(o, options, manager, rMethod.exceptions);
513         if ( body ) {
514             if ( defaultbody ) {
515                 o << "\n" << indentation << "{\n";
516                 if (rMethod.returnType != "void") {
517                     o << indentation << "    // TODO: Exchange the default return implementation for \"" << rMethod.name << "\" !!!\n";
518                     o << indentation << "    // NOTE: "
519                         "Default initialized polymorphic structs can cause problems"
520                         "\n" << indentation << "    // because of missing default "
521                         "initialization of primitive types of\n" << indentation
522                       << "    // some C++ compilers or different Any initialization"
523                         " in Java and C++\n" << indentation
524                       << "    // polymorphic structs.\n" << indentation
525                       << "    return ";
526                     printType(o, options, manager, rMethod.returnType, false, true);
527                     o << ";";
528                 } else {
529                     o << indentation << "    // TODO: Insert your implementation for \""
530                       << rMethod.name << "\" here.";
531                 }
532                 o << "\n" << indentation << "}\n\n";
533             } else {
534                 o << "\n" << indentation << "{\n" << indentation << "    ";
535                 if (rMethod.returnType != "void") {
536                     o << "return ";
537                 }
538                 o << delegate << rMethod.name << '(';
539                 printMethodParameters(
540                     o, options, manager, rMethod.parameters, false);
541                 o << ");\n" << indentation << "}\n\n";
542             }
543         } else {
544             o << ";\n";
545         }
546     }
547 }
548 
printConstructors(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,OUString const & name)549 static void printConstructors(
550     std::ostream & o, ProgramOptions const & options,
551     rtl::Reference< TypeManager > const & manager, OUString const & name)
552 {
553     rtl::Reference< unoidl::Entity > ent;
554     if (manager->getSort(name, &ent)
555         != codemaker::UnoType::Sort::SingleInterfaceBasedService)
556     {
557         throw CannotDumpException(
558             "unexpected entity \"" + name
559             + "\" in call to skeletonmaker::java::printConstructors");
560     }
561     rtl::Reference< unoidl::SingleInterfaceBasedServiceEntity > ent2(
562         dynamic_cast< unoidl::SingleInterfaceBasedServiceEntity * >(ent.get()));
563     assert(ent2.is());
564     for (const auto& rConstructor : ent2->getConstructors())
565     {
566         o << "public static ";
567         printType(o, options, manager, ent2->getBase(), false);
568         o << ' ';
569         if (rConstructor.defaultConstructor) {
570             o << "create";
571         } else {
572             o << codemaker::java::translateUnoToJavaIdentifier(
573                 u2b(rConstructor.name), "method");
574         }
575         o << "(com.sun.star.uno.XComponentContext the_context";
576         for (const auto& rParam : rConstructor.parameters)
577         {
578             o << ", ";
579             printType(o, options, manager, rParam.type, false);
580             if (rParam.rest) {
581                 o << "...";
582             }
583             o << ' '
584               << codemaker::java::translateUnoToJavaIdentifier(
585                   u2b(rParam.name), "param");
586         }
587         o << ')';
588         printExceptionSpecification(o, options, manager, rConstructor.exceptions);
589         o << ";\n";
590     }
591 }
592 
printServiceMembers(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,OUString const & name,rtl::Reference<unoidl::AccumulationBasedServiceEntity> const & entity,OString const & delegate)593 static void printServiceMembers(
594     std::ostream & o, ProgramOptions const & options,
595     rtl::Reference< TypeManager > const & manager,
596     OUString const & name,
597     rtl::Reference< unoidl::AccumulationBasedServiceEntity > const & entity,
598     OString const & delegate)
599 {
600     assert(entity.is());
601     for (const auto& rService : entity->getDirectMandatoryBaseServices())
602     {
603         o << "\n// exported service " << rService.name << "\n";
604         generateDocumentation(o, options, manager, u2b(rService.name), delegate);
605     }
606     for (const auto& rIface : entity->getDirectMandatoryBaseInterfaces())
607     {
608         o << "\n// supported interface " << rIface.name << "\n";
609         generateDocumentation(o, options, manager, u2b(rIface.name), delegate);
610     }
611     o << "\n// properties of service \""<< name << "\"\n";
612     for (const auto& rProp : entity->getDirectProperties())
613     {
614         o << "// private ";
615         printType(o, options, manager, rProp.type, false);
616         o << " "
617           << codemaker::java::translateUnoToJavaIdentifier(
618               u2b(rProp.name), "property")
619           << ";\n";
620     }
621 }
622 
printMapsToJavaType(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,codemaker::UnoType::Sort sort,OUString const & nucleus,sal_Int32 rank,std::vector<OUString> const & arguments,const char * javaTypeSort)623 static void printMapsToJavaType(
624     std::ostream & o, ProgramOptions const & options,
625     rtl::Reference< TypeManager > const & manager,
626     codemaker::UnoType::Sort sort, OUString const & nucleus, sal_Int32 rank,
627     std::vector< OUString > const & arguments, const char * javaTypeSort)
628 {
629     o << "maps to Java 1.5 ";
630     if (javaTypeSort != nullptr) {
631         o << javaTypeSort << ' ';
632     }
633     o << "type \"";
634     if (rank == 0 && nucleus == "com.sun.star.uno.XInterface") {
635         o << "com.sun.star.uno.XInterface";
636     } else {
637         printType(
638             o, options, manager, sort, nucleus, rank, arguments, false, false);
639     }
640     o << '"';
641 }
642 
generateDocumentation(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,OString const & type,OString const & delegate)643 void generateDocumentation(std::ostream & o,
644     ProgramOptions const & options, rtl::Reference< TypeManager > const & manager,
645     OString const & type, OString const & delegate)
646 {
647     OUString nucleus;
648     sal_Int32 rank;
649     codemaker::UnoType::Sort sort = manager->decompose(
650         b2u(type), false, &nucleus, &rank, nullptr, nullptr);
651 
652     bool comment = true;
653     if (!delegate.isEmpty()) {
654         if (sort != codemaker::UnoType::Sort::Interface &&
655             sort != codemaker::UnoType::Sort::SingleInterfaceBasedService &&
656             sort != codemaker::UnoType::Sort::AccumulationBasedService )
657         {
658             return;
659         }
660         comment = false;
661     }
662 
663     if (comment) {
664         o << "\n// UNO";
665         if (rank != 0) {
666             o << " sequence type";
667         } else if (sort <= codemaker::UnoType::Sort::Any) {
668             o << " simple type";
669         } else {
670             switch (sort) {
671             case codemaker::UnoType::Sort::Interface:
672                 o << " interface type";
673                 break;
674 
675             case codemaker::UnoType::Sort::Module:
676                 o << "IDL module";
677                 break;
678 
679             case codemaker::UnoType::Sort::PlainStruct:
680                 o << " simple struct type";
681                 break;
682 
683             case codemaker::UnoType::Sort::PolymorphicStructTemplate:
684                 o << " polymorphic struct type template";
685                 break;
686 
687             case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
688                 o << " instantiated polymorphic struct type";
689                 break;
690 
691             case codemaker::UnoType::Sort::Enum:
692                 o << " enum type";
693                 break;
694 
695             case codemaker::UnoType::Sort::Exception:
696                 o << " exception type";
697                 break;
698 
699             case codemaker::UnoType::Sort::Typedef:
700                 o << "IDL typedef";
701                 break;
702 
703             case codemaker::UnoType::Sort::SingleInterfaceBasedService:
704                 o << " single-inheritance--based service";
705                 break;
706 
707             case codemaker::UnoType::Sort::AccumulationBasedService:
708                 o << "IDL accumulation-based service";
709                 break;
710 
711             case codemaker::UnoType::Sort::InterfaceBasedSingleton:
712                 o << " inheritance-based singleton";
713                 break;
714 
715             case codemaker::UnoType::Sort::ServiceBasedSingleton:
716                 o << "IDL service-based singleton";
717                 break;
718 
719             case codemaker::UnoType::Sort::ConstantGroup:
720                 o << "IDL constant group";
721                 break;
722 
723             default:
724                 OSL_ASSERT(false);
725                 break;
726             }
727         }
728         o << " \"" << type << "\" ";
729     }
730     std::vector< OUString > arguments;
731     rtl::Reference< unoidl::Entity > entity;
732     sort = manager->decompose(
733         b2u(type), true, &nucleus, &rank, &arguments, &entity);
734     if (rank != 0) {
735         printMapsToJavaType(
736             o, options, manager, sort, nucleus, rank, arguments, "array");
737         o << '\n';
738     } else if (sort <= codemaker::UnoType::Sort::Any) {
739         printMapsToJavaType(
740             o, options, manager, sort, nucleus, rank, arguments, nullptr);
741         o << '\n';
742     } else {
743         switch (sort) {
744         case codemaker::UnoType::Sort::Interface:
745             printMapsToJavaType(
746                 o, options, manager, sort, nucleus, rank, arguments,
747                 "interface");
748             if (nucleus == "com.sun.star.uno.XInterface") {
749                 o << '\n';
750             } else {
751                 o << "; " << (options.all ? "all" : "direct") << " methods:\n";
752                 codemaker::GeneratedTypeSet generated;
753                 printMethods(
754                     o, options, manager, nucleus, generated, delegate, "");
755             }
756             break;
757 
758         case codemaker::UnoType::Sort::Module:
759             printMapsToJavaType(
760                 o, options, manager, sort, nucleus, rank, arguments, "package");
761             o << '\n';
762             break;
763 
764         case codemaker::UnoType::Sort::PlainStruct:
765             printMapsToJavaType(
766                 o, options, manager, sort, nucleus, rank, arguments, "class");
767             o << "; full constructor:\n";
768             printConstructor(
769                 o, options, manager, codemaker::UnoType::Sort::PlainStruct,
770                 entity, nucleus, arguments);
771             break;
772 
773         case codemaker::UnoType::Sort::PolymorphicStructTemplate:
774             printMapsToJavaType(
775                 o, options, manager, sort, nucleus, rank, arguments,
776                 "generic class");
777             o << "; full constructor:\n";
778             printConstructor(
779                 o, options, manager,
780                 codemaker::UnoType::Sort::PolymorphicStructTemplate,
781                 entity, nucleus, arguments);
782             break;
783 
784         case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
785             printMapsToJavaType(
786                 o, options, manager, sort, nucleus, rank, arguments,
787                 "generic class instantiation");
788             o << "; full constructor:\n";
789             printConstructor(
790                 o, options, manager,
791                 codemaker::UnoType::Sort::InstantiatedPolymorphicStruct,
792                 entity, nucleus, arguments);
793             break;
794 
795         case codemaker::UnoType::Sort::Enum:
796         case codemaker::UnoType::Sort::ConstantGroup:
797             printMapsToJavaType(
798                 o, options, manager, sort, nucleus, rank, arguments, "class");
799             o << '\n';
800             break;
801 
802         case codemaker::UnoType::Sort::Exception:
803             printMapsToJavaType(
804                 o, options, manager, sort, nucleus, rank, arguments,
805                 "exception class");
806             o << "; full constructor:\n";
807             printConstructor(
808                 o, options, manager, codemaker::UnoType::Sort::Exception,
809                 entity, nucleus, arguments);
810             break;
811 
812         case codemaker::UnoType::Sort::SingleInterfaceBasedService:
813             printMapsToJavaType(
814                 o, options, manager, sort, nucleus, rank, arguments, "class");
815             o << "; construction methods:\n";
816             printConstructors(o, options, manager, nucleus);
817             generateDocumentation(
818                 o, options, manager,
819                 u2b(dynamic_cast< unoidl::SingleInterfaceBasedServiceEntity * >(
820                         entity.get())->getBase()),
821                 delegate);
822             break;
823 
824         case codemaker::UnoType::Sort::AccumulationBasedService:
825             o << ("does not map to Java\n"
826                   "// the service members are generated instead\n");
827             printServiceMembers(
828                 o, options, manager, nucleus,
829                 dynamic_cast< unoidl::AccumulationBasedServiceEntity * >(
830                     entity.get()),
831                 delegate);
832             break;
833 
834         case codemaker::UnoType::Sort::InterfaceBasedSingleton:
835             printMapsToJavaType(
836                 o, options, manager, sort, nucleus, rank, arguments, "class");
837             o << "; get method:\npublic static ";
838             printType(
839                 o, options, manager,
840                 dynamic_cast< unoidl::InterfaceBasedSingletonEntity * >(
841                     entity.get())->getBase(),
842                 false);
843             o << " get(com.sun.star.uno.XComponentContext context);\n";
844             break;
845 
846         case codemaker::UnoType::Sort::ServiceBasedSingleton:
847             o << "does not map to Java\n";
848             break;
849 
850         default:
851             OSL_ASSERT(false);
852             break;
853         }
854     }
855 }
856 
857 } }
858 
859 
860 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
861