Version: 1.4.2 (using KDE KDE 3.4.2) Installed from: SuSE RPMs Bodys of methods defined by an interface should be automatically written in the generated code of an class, which implements the Interface. This should happen in the generated file, not in the UML diagram. With that system, implementation of the methods in the class are not forgoten and done easily by hand.
Created attachment 19756 [details] java class diagram with interface That's an exemple of a class diagram with few interfaces and classes
Created attachment 19757 [details] java generated code With the patch in the next attachment, here comes the generated code. You can notice: the method kde4ever is not generated in class_1 because it exists in class_2 the method doStuff is not generated in class_1 because it should be implemented first in class_2 the method beSmart is only implemented once
Created attachment 19758 [details] patch for #111593 The difficult part was to not generate methods that exist in super classes and not to generate twice methods that exist in two super interfaces Thanks
SVN commit 635782 by okellogg: Apply attachment 19758 [details] from Antoine Dopffer. > The difficult part was to not generate methods that exist in super classes > and not to generate twice methods that exist in two super interfaces Many thanks Antoine for your work! BUG:111593 M +2 -0 ChangeLog M +74 -1 umbrello/codegenerators/javawriter.cpp M +31 -0 umbrello/codegenerators/javawriter.h --- branches/KDE/3.5/kdesdk/umbrello/ChangeLog #635781:635782 @@ -5,6 +5,8 @@ * Java interface inheritance, abstract classes and generics in code generation (53376) * %date% and %time% not being parsed (96612) +* Operations of the Interface are not implemented in the class automatically + (111593) * Relationships for entities do not live outside of the diagram (125146) * Javascript wrong Code Generation (135527) * Javascript Code Generation creates bad format methods (135540) --- branches/KDE/3.5/kdesdk/umbrello/umbrello/codegenerators/javawriter.cpp #635781:635782 @@ -704,6 +704,76 @@ return l; } + +bool JavaWriter::compareJavaMethod(UMLOperation *op1, UMLOperation *op2) +{ + if (op1 == NULL || op2 == NULL) + return false; + if (op1 == op2) + return true; + if (op1->getName() != op2->getName()) + return false; + UMLAttributeList atl1 = op1->getParmList(); + UMLAttributeList atl2 = op2->getParmList(); + if (atl1.count() != atl2.count()) + return false; + UMLAttribute *at1; + UMLAttribute *at2; + for (at1 = atl1.first(), at2 = atl2.first(); at1 && at2 ; at1 = atl1.next(),at2 = atl2.next()) + { + if (at1->getTypeName() != at2->getTypeName()) + return false; + } + return true; + +} + +bool JavaWriter::javaMethodInList(UMLOperation *umlOp, UMLOperationList &opl) +{ + for (UMLOperation *op = opl.first(); op; op = opl.next()) { + if (JavaWriter::compareJavaMethod(op, umlOp)) { + return true; + } + } + return false; +} + +void JavaWriter::getSuperImplementedOperations(UMLClassifier *c, UMLOperationList &yetImplementedOpList ,UMLOperationList &toBeImplementedOpList, bool noClassInPath) +{ + UMLClassifierList superClasses = c->findSuperClassConcepts(); + + for (UMLClassifier *concept= superClasses.first(); concept; concept = superClasses.next()) + { + getSuperImplementedOperations(concept, yetImplementedOpList, toBeImplementedOpList, (concept->isInterface() && noClassInPath)); + UMLOperationList opl = concept->getOpList(); + for (UMLOperation *op = opl.first(); op; op = opl.next()) { + if (concept->isInterface() && noClassInPath) { + if (!JavaWriter::javaMethodInList(op,toBeImplementedOpList)) + toBeImplementedOpList.append(op); + } + else + { + if (!JavaWriter::javaMethodInList(op, yetImplementedOpList)) + yetImplementedOpList.append(op); + } + } + } + +} + +void JavaWriter::getInterfacesOperationsToBeImplemented(UMLClassifier *c, UMLOperationList &opList ) +{ + UMLOperationList yetImplementedOpList; + UMLOperationList toBeImplementedOpList; + + getSuperImplementedOperations(c,yetImplementedOpList, toBeImplementedOpList); + for (UMLOperation *op = toBeImplementedOpList.first(); op; op = toBeImplementedOpList.next()) + { + if ( ! JavaWriter::javaMethodInList(op, yetImplementedOpList) && ! JavaWriter::javaMethodInList(op, opList) ) + opList.append(op); + } +} + void JavaWriter::writeOperations(UMLClassifier *c, QTextStream &java) { UMLOperationList opl; UMLOperationList oppub,opprot,oppriv; @@ -711,8 +781,11 @@ opprot.setAutoDelete(false); oppriv.setAutoDelete(false); - //sort operations by scope first and see if there are abstrat methods + //sort operations by scope first and see if there are abstract methods opl = c->getOpList(); + if (! c->isInterface()) { + getInterfacesOperationsToBeImplemented(c, opl); + } for (UMLOperation *op = opl.first(); op; op = opl.next()) { switch(op->getVisibility()) { case Uml::Visibility::Public: --- branches/KDE/3.5/kdesdk/umbrello/umbrello/codegenerators/javawriter.h #635781:635782 @@ -76,6 +76,37 @@ void writeConstructor(UMLClassifier *c, QTextStream &java); /** + * return true if the two operations have the same name and the same parameters + * @param op1 first operation to be compared + * @param op2 second operation to be compared + */ + static bool compareJavaMethod(UMLOperation *op1, UMLOperation *op2); + + /** + * return true if the operation is in the list + * @param umlOp operation to be searched + * @param opl list of operations + */ + static bool javaMethodInList(UMLOperation *umlOp, UMLOperationList &opl); + + /** + * get all operations which a given class inherit from all its super interfaces and get all operations + * which this given class inherit from all its super classes + * @param c the class for which we are generating code + * @param yetImplementedOpList the list of yet implemented operations + * @param toBeImplementedOpList the list of to be implemented operations + * @param noClassInPath tells if there is a class between the base class and the current interface + */ + void getSuperImplementedOperations(UMLClassifier *c, UMLOperationList &yetImplementedOpList ,UMLOperationList &toBeImplementedOpList, bool noClassInPath = true); + + /** + * get all operations which a given class inherit from all its super interfaces and that should be implemented + * @param c the class for which we are generating code + * @param opl the list of operations used to append the operations + */ + void getInterfacesOperationsToBeImplemented(UMLClassifier *c, UMLOperationList &opl); + + /** * write all operations for a given class * @param c the class for which we are generating code * @param j the stream associated with the output file