Hallo !
Hab mir mittels ArgoUML ein minimales Testmodell erstellt; dessen XMI - Export steht am Schluss des Beitrags.
In C++ wuerde das wohl so aussehen
[code lang=c++] #include <string>
/* abstract / class Bar { protected: / abstract */ virtual void doit() = 0; };
class Baz : public Bar { protected: /virtual/ void doit(){}; public: std::string really() { return std::string(""); }; };
class Foo { public: Bar* m_pBar; // Schon klar, das sollte private sein }; [/code]
Zur Erlaeuterung : "virtual void ... = 0;" entspricht "abstract" bei Java.
Also eine Klasse Foo, die eine Referenz ( hier eien Zeiger ) auf die abstrakte Klasse Bar eignet ( Aggregation ), eine Klasse Bar mit einer abstrakten Methode doit() und eine Klasse Baz, abgeleitet von Bar, die die Methode doit() implementiert und eine eigene oeffentliche Methode really() hat .
Jetzt moechte ich mir mittels UMMF Perl-Prototypen generieren lassen. ( Der ArgoUML-Generator unterstuetzt Perl-Generation nicht )
Zu UMMF :
Installiert als root via perl -MCPAN -e shell.
Das schlug erst mal fehl;
#ein Aufruf mit
ummf -e Perl ~/projects/cont2wiki/vhost/home/project/c2w_argo.zargo
# stieg aus wegen einer fehlenden "Perl.txt".
# Die gab's aber in meinem .cpan wd:
# ~/.cpan/build/UMMF-1.02/data/ummf/template/Perl.txt,
# also in ~/.cpan/build/UMMF-1.02/:
tar -cvf - data | tar -xf - -C /usr/local/share/perl/5.8.4/UMMF
# ( ich hasse rekursives Kopieren mit cp; nehme immer tar dafuer )
Ab da generiert ummf. Aber halt keine Methoden:
ummf -e Perl -o perltest ~/projects/cont2wiki/vhost/home/project/c2w_argo.zargo
#oder
ummf -e Perl -o perltest ~/projects/cont2wiki/vhost/home/project/c2w_argo.xmi
# mit dem aus Argo exportierten XMI
erzeugt mir wunderschoene Klassendekarationen, und Attributierungen und einen ganzen Bulk von Helper-Funktionen, aber weder die Funktionen doit() noch really tauchen irgendwo auf.
Erste Hypothese:
Works as designed, damit vorhandene Implementierungen nicht ueberschriben werden. Von Hand eine Funktion eingefuegt, neu generiert. Funktion weg :-(
Zweite Hypothese:
UMMF benutzt ein Java-centric profil; viellicht liegt's dort. Das Profil bezieht sich aber auf den UML-Generator ( ArgoUML ist eine Java-Anwendung )
Dritte Hypothese :
UMMF kennt die Rueckgabetypen aus Perl nicht. Aber die aus Java wird er ja wohl kennen - also :
Gegentest
ummf -e Java -o javatest ~/projects/cont2wiki/vhost/home/project/c2w_argo.zargo
dto., es werden sogar pro Klasse Interfaces deklariert. Aber auch die sind wieder leer.
=> Hat jemand eine Idee ? Vielleicht eigene Erfahrungen mit UMMF ? <= => Oder kennt ein anderes Tool das Perl-Code aux XMIs generiert ? <=
Das kann doch nicht so gemeint sein - Codegenerierung die die Interfaces nicht umfasst ????
Das sind so die Softwareprobleme, die ich besonders nervig finde - wenn nicht mal den Fuss in die Tuer kriegt. Etwa wie ein C-Compiler, der "Hello World" nicht packt...
Ein paar Versionsnummer zum Abschluss
Linux 2.6.8-3-686 ( Debian sarge 3.1r1 ) libxml2.so.2.6.16 ArgoUML v0.22 ( jre 1.5.0_09-b03 ) perl 5.8.4 UMMF 1.02
Sorry fuer die Laenge des Beitrags und danke fuer's Lesen
Gruss
Holger
<?xml version = '1.0' encoding = 'UTF-8' ?> <XMI xmi.version = '1.2' xmlns:UML = 'org.omg.xmi.namespace.UML' timestamp = 'Wed Nov 29 15:23:16 CET 2006'> <XMI.header> <XMI.documentation> <XMI.exporter>ArgoUML (using Netbeans XMI Writer version 1.0)</XMI.exporter> <XMI.exporterVersion>0.20.x</XMI.exporterVersion> </XMI.documentation> <XMI.metamodel xmi.name="UML" xmi.version="1.4"/></XMI.header> <XMI.content> <UML:Model xmi.id = '-64--88-1-2-9dbbd02:10f22425394:-8000:000000000000077B' name = 'cont2wiki' isSpecification = 'false' isRoot = 'false' isLeaf = 'false' isAbstract = 'false'> UML:Namespace.ownedElement <UML:Class xmi.id = '-64--88-1-2-9dbbd02:10f22425394:-8000:000000000000077C' name = 'Foo' visibility = 'public' isSpecification = 'false' isRoot = 'false' isLeaf = 'false' isAbstract = 'false' isActive = 'false'/> <UML:Class xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007DD' name = 'Bar' visibility = 'public' isSpecification = 'false' isRoot = 'false' isLeaf = 'false' isAbstract = 'true' isActive = 'false'> UML:Classifier.feature <UML:Operation xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007F3' name = 'doit' visibility = 'public' isSpecification = 'false' ownerScope = 'instance' isQuery = 'false' concurrency = 'sequential' isRoot = 'false' isLeaf = 'false' isAbstract = 'true'> UML:BehavioralFeature.parameter <UML:Parameter xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007F4' name = 'return' isSpecification = 'false' kind = 'return'> UML:Parameter.type <UML:DataType xmi.idref = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007F2'/> </UML:Parameter.type> </UML:Parameter> </UML:BehavioralFeature.parameter> </UML:Operation> </UML:Classifier.feature> </UML:Class> <UML:Class xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007DF' name = 'Baz' visibility = 'public' isSpecification = 'false' isRoot = 'false' isLeaf = 'false' isAbstract = 'false' isActive = 'false'> UML:GeneralizableElement.generalization <UML:Generalization xmi.idref = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007E1'/> </UML:GeneralizableElement.generalization> UML:Classifier.feature <UML:Operation xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007F5' name = 'doit' visibility = 'protected' isSpecification = 'false' ownerScope = 'instance' isQuery = 'false' concurrency = 'sequential' isRoot = 'false' isLeaf = 'false' isAbstract = 'false'> UML:BehavioralFeature.parameter <UML:Parameter xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007F6' name = 'return' isSpecification = 'false' kind = 'return'> UML:Parameter.type <UML:DataType xmi.idref = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007F2'/> </UML:Parameter.type> </UML:Parameter> </UML:BehavioralFeature.parameter> </UML:Operation> <UML:Operation xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007F7' name = 'really' visibility = 'public' isSpecification = 'false' ownerScope = 'instance' isQuery = 'false' concurrency = 'sequential' isRoot = 'false' isLeaf = 'false' isAbstract = 'false'> UML:BehavioralFeature.parameter <UML:Parameter xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007F8' name = 'return' isSpecification = 'false' kind = 'return'> UML:Parameter.type <UML:Class xmi.idref = '-64--88-1-2-72715727:10f33f091a6:-8000:00000000000007F3'/> </UML:Parameter.type> </UML:Parameter> </UML:BehavioralFeature.parameter> </UML:Operation> </UML:Classifier.feature> </UML:Class> <UML:Generalization xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007E1' isSpecification = 'false'> UML:Generalization.child <UML:Class xmi.idref = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007DF'/> </UML:Generalization.child> UML:Generalization.parent <UML:Class xmi.idref = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007DD'/> </UML:Generalization.parent> </UML:Generalization> <UML:Association xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007E9' name = '' isSpecification = 'false' isRoot = 'false' isLeaf = 'false' isAbstract = 'false'> UML:Association.connection <UML:AssociationEnd xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007EA' visibility = 'public' isSpecification = 'false' isNavigable = 'false' ordering = 'unordered' aggregation = 'aggregate' targetScope = 'instance' changeability = 'changeable'> UML:AssociationEnd.multiplicity <UML:Multiplicity xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007EB'> UML:Multiplicity.range <UML:MultiplicityRange xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007EC' lower = '1' upper = '1'/> </UML:Multiplicity.range> </UML:Multiplicity> </UML:AssociationEnd.multiplicity> UML:AssociationEnd.participant <UML:Class xmi.idref = '-64--88-1-2-9dbbd02:10f22425394:-8000:000000000000077C'/> </UML:AssociationEnd.participant> </UML:AssociationEnd> <UML:AssociationEnd xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007ED' visibility = 'public' isSpecification = 'false' isNavigable = 'true' ordering = 'unordered' aggregation = 'none' targetScope = 'instance' changeability = 'changeable'> UML:AssociationEnd.multiplicity <UML:Multiplicity xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007F1'> UML:Multiplicity.range <UML:MultiplicityRange xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007F0' lower = '1' upper = '-1'/> </UML:Multiplicity.range> </UML:Multiplicity> </UML:AssociationEnd.multiplicity> UML:AssociationEnd.participant <UML:Class xmi.idref = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007DD'/> </UML:AssociationEnd.participant> </UML:AssociationEnd> </UML:Association.connection> </UML:Association> <UML:DataType xmi.id = '-64--88-1-2-25d8ea0d:10f2d318756:-8000:00000000000007F2' name = 'void' isSpecification = 'false' isRoot = 'false' isLeaf = 'false' isAbstract = 'false'/> <UML:DataType xmi.id = '-64--88-1-2-72715727:10f33f091a6:-8000:00000000000007F0' name = 'int' isSpecification = 'false' isRoot = 'false' isLeaf = 'false' isAbstract = 'false'/> <UML:Package xmi.id = '-64--88-1-2-72715727:10f33f091a6:-8000:00000000000007F1' name = 'java' isSpecification = 'false' isRoot = 'false' isLeaf = 'false' isAbstract = 'false'> UML:Namespace.ownedElement <UML:Package xmi.id = '-64--88-1-2-72715727:10f33f091a6:-8000:00000000000007F2' name = 'lang' isSpecification = 'false' isRoot = 'false' isLeaf = 'false' isAbstract = 'false'> UML:Namespace.ownedElement <UML:Class xmi.id = '-64--88-1-2-72715727:10f33f091a6:-8000:00000000000007F3' name = 'String' isSpecification = 'false' isRoot = 'false' isLeaf = 'false' isAbstract = 'false' isActive = 'false'/> </UML:Namespace.ownedElement> </UML:Package> </UML:Namespace.ownedElement> </UML:Package> </UML:Namespace.ownedElement> </UML:Model> </XMI.content> </XMI>
Aus dem Perl Styleguide: "Choose mnemonic identifiers. If you can't remember what mnemonic means, you've got a problem."