Create CodeStyle for different List subclasses
I tried to create my own CodeStyle to make UML Lab recognize my LinkedList and ArrayList attributes as one to many referenced (I prefer not to use List attributes because different implementations have different running times for the same methods (e.g. O(n) for access in LinkedList vs. O(1) for ArrayList)).
But your examples did not help me to do that. I tried to override toManyDeclaration in Association.xpt:
But that does not work and - to be honest - I do not really understand it. What else could I do?
Moritz
But your examples did not help me to do that. I tried to override toManyDeclaration in Association.xpt:
«DEFINE toManyDeclaration (ListsStyledElement style, Property partnerRole, Classifier parent) FOR Property»
«IF !parent.isInterface()»
private «IF isStatic»static «ENDIF»LinkedList «pluralizeIfNeeded()»;
«ENDIF»
«ENDDEFINE»
But that does not work and - to be honest - I do not really understand it. What else could I do?
Moritz
Comments
Your template is ok! If you're using Java5/6/7 I'd suggest adding type parameters. You should also add an import to java.util.LinkedList.
Additionally, you can overwrite the getter template.
This template works well for your purpose:
«IMPORT uml»
«IMPORT UMLLabProfile»
«IMPORT ListsStyle»
«IMPORT java::standard::classDiag::assoc»
«EXTENSION Utility»
«EXTENSION java::standard::classDiag::assoc::AssociationExtensions»
«EXTENSION java::standard::classDiag::property::AttributeExtensions»
«EXTENSION java::standard::classDiag::classifier::ClassifierExtensions»
«DEFINE toManyDeclaration (ListsStyledElement style, Property partnerRole, Classifier parent) FOR Property»
«IF !parent.isInterface()»
private «IF isStatic»static «ENDIF»LinkedList<«EXPAND AssociationContainer::containeeType(type) FOR this»> «pluralizeIfNeeded()»;
«addImport("java.util.LinkedList")»
«ENDIF»
«ENDDEFINE»
«DEFINE toManyGetter (ListsStyledElement style, Property partnerRole, Classifier parent) FOR Property»
«visibilityString()» «IF isStatic»static «ENDIF»LinkedList<«EXPAND AssociationContainer::containeeType(type) FOR this»> get«methodSuffix()»()«""»
«addImport("java.util.LinkedList")»
«IF parent.isInterface()»
;
«ELSE»
{
«LET getOtherEnd().hasKeyword("pluralized") AS pluralized»
if («thisName(parent, pluralized)» == null) {
«" "»«thisName(parent, pluralized)» = new LinkedList<«EXPAND AssociationContainer::containeeType(type) FOR this»>();
}
return «thisName(parent, pluralized)»;
«ENDLET»
}
«ENDIF»
«ENDDEFINE»
After creating the template, just select the affected roles in the Class Diagram and choose "Lists" in the Code Style section of the Eclipse Properties view. You can also apply the Code Style on any parent element of your model (i.e. on a Class or on a Package) and all contained elements (including the roles) will inherit the Code Style then.
Later you can refine your template to control which List implementation should be used by using a UML keyword in the model:
«IF hasKeyword("ConcurrentLinkedList")»ConcurrentLinkedList«ELSE»LinkedList«ENDIF»
Please let me know if this fullfills your requirements.
Best regards
Manuel
yes, no it works! Thank you.
So there is the next question :):
I want to add support for HashMap, so I need an unordered reference. What it the correct code to check whether the to many reference is ordered in the template? And how do I get the Key class (
HashMap<Key class, Reference class>
)?Is there anywhere a list of functions that are available for template coding?
Moritz
Nice to see that the template works for you.
You can access the key class by using getQualifier(). I adapted your existing template.
«DEFINE toManyDeclaration (ListsStyledElement style, Property partnerRole, Classifier parent) FOR Property»
«IF !parent.isInterface()»
private «IF isStatic»static «ENDIF»
«IF isQualified()»
HashMap<«""-»
«IF isMultivalued()»
«EXPAND AssociationContainer::containeeType(getQualifier().type) FOR getQualifier()», Set<«EXPAND AssociationContainer::containeeType(type)»>>«""-»
«addImport("java.util.Set")»
«ELSE»
«EXPAND AssociationContainer::containeeType(getQualifier().type) FOR getQualifier()», «EXPAND AssociationContainer::containeeType(type)»>«""-»
«ENDIF»
«addImport("java.util.HashMap")»
«ELSE»
LinkedList
<«EXPAND AssociationContainer::containeeType(type) FOR this»>«""-»
«addImport("java.util.LinkedList")»
«ENDIF»
«pluralizeIfNeeded()»;
«ENDIF»
«ENDDEFINE»
Adapt the getter template accordingly, et voila - that's it.
Manuel
UML Lab's templates are written in Xpand. You find the Xpand reference in the Eclipse help or on the web, for example http://www.openarchitectureware.org/pub/documentation/4.3.1/html/contents/core_reference.html#xpand_reference_introduction
In addition, we enhanced Xpand to Xpand++. The new Xpand++ language constructs are documented in the Eclipse help ("Help->Help Contents->UML Lab User Guide->Reference->Xpand++").
Within templates you can use all classes, attributes and methods of the UML2 meta-model. Be aware, the UML2 meta-model is very large and hard to understand.
In UML Lab's current templates we basically use the UML2 classes Class, Interface, Property, Operation, Parameter, Type and Association (including their corresponding parent classes and interfaces). The template editor offers code completion of course. So you can just type ctrl+space and see a list of possible methods and attributes.
We cover almost all aspects of the UML2 model for class diagrams in our templates. Often only small adaptions to our templates are required - like in your case, exchanging List by LinkedList or Map by HashMap. So the best way to start writing and adapting templates is to have a closer look on the templates that we ship with UML Lab.
Did you know that you can navigate from each model element into the templates that are involved in generating code for that element? In your case, just draw an association between two classes, generate code, right-click on one of the roles and choose "Navigate To->Template". An editor containing our Association::roleDeclaration template shows up. Have a look to the Search view: There are seven templates listened (depends on the Code Style). There should be an entry with the AssociationContainer::container template (double click on the entry to open it). Have a closer look at it: You can see under which circumstances a Map is generated into the source code. This helps you create your own template - I used this information to adapt your template in my previous post.
You could also directly overwrite the AssociationContainer template (by creating a template file in your Code Style project with the same fully qualified name ("java/standard/classDiag/assoc/AssociationContainer.xpt"). But I would advise against it because this is an important internal template for UML Lab's Java code generator and overwriting it will likely break reverse engineering of Java legacy code.
Manuel
Maybe my understanding of UML is wrong, but why do you use the Set in the template when the association should be multivalued? I can store in a hash map different values. If I only want to use a hash map without a set I have to create a to 1 association and add a qualifier, but then I can store different values. Does the meaning of the multiplicity change when I add a qualifier? Multiplicity 1: One qualifier for one value, Multiplicity *: one qualifier for many values? It just confused me.
EDIT: Ignore that, It does not seem to be a problem of UML Lab but of Eclipse (happens with non UML Lab views too)
And there is a complete other thing I noticed, some UI problem (see attached files). I was not sure whether I should create a bug report or not, the problem gets solved when switching to another view (e.g. Problems) and than switch back. I am not able to reproduce the problem.
I add a new qualifier save the model, generate the file, parse the file and the qualifier is lost, something seems to be corrupt because every time when I try to modify the problematic association I get an error.
Example:
java.lang.IllegalStateException
at com.yattasolutions.obf.mc.i.cg(SourceFile:135)
at com.yattasolutions.obf.mc.f.c(SourceFile:46)
at com.yattasolutions.obf.mc.i.a(SourceFile:62)
at com.yattasolutions.obf.mc.k.a(SourceFile:138)
at com.yattasolutions.obf.mc.k.e(SourceFile:154)
at com.yattasolutions.obf.mc.k.b(SourceFile:217)
at com.yattasolutions.obf.fz.e$d$4.widgetSelected(SourceFile:544)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:240)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4128)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1457)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1480)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1465)
at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1270)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3974)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3613)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
java.lang.IllegalStateException
at com.yattasolutions.obf.mc.i.cg(SourceFile:135)
at com.yattasolutions.obf.mc.g.c(SourceFile:44)
at com.yattasolutions.obf.mc.i.a(SourceFile:62)
at com.yattasolutions.obf.mc.k.a(SourceFile:138)
at com.yattasolutions.obf.mc.k.e(SourceFile:154)
at com.yattasolutions.obf.mc.k.b(SourceFile:217)
at com.yattasolutions.obf.fz.e$d$4.widgetSelected(SourceFile:544)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:240)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4128)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1457)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1480)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1465)
at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1270)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3974)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3613)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
java.lang.IllegalStateException
at com.yattasolutions.obf.mc.i.cg(SourceFile:135)
at com.yattasolutions.obf.mc.g.c(SourceFile:44)
at com.yattasolutions.obf.mc.i.a(SourceFile:62)
at com.yattasolutions.obf.mc.k.a(SourceFile:138)
at com.yattasolutions.obf.mc.k.e(SourceFile:154)
at com.yattasolutions.obf.mc.k.b(SourceFile:217)
at com.yattasolutions.obf.fz.e$d$4.widgetSelected(SourceFile:544)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:240)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4128)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1457)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1480)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1465)
at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1270)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3974)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3613)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
many elements are reachable when traversing the association. In our templates we distinguish between to-1 and to-many. The qualifier doesn't change semantics, it adds semantics: It defines that one or many elements are reachable by a single key.
So you're right, in the Java source code both situations are kind of "to-many" because there is a Map which contains many elements - both times. The qualifier makes the difference.
By the way, it's also possible to set the multiplicities upper bound to some other value, i.e. 4. Then one could generate a addToXXX()-method that assures that max 4 elements at a time are contained in the collection.
Regarding your UI problem - unfortunatly the attachement seems to be lost. Could you please file a bug report for it, even though its not UML Lab specific? Maybe we can solve the issue in Eclipse itself and contribute the patch back. I and some coworkers are also Eclipse committers ;).
You can find the archive with the CodeStyle project and the uml model here:
http://moritzsoftware.bplaced.net/Private/UML_Collections.zip
When you told me how to use different containers (by using key words) I deleted the Lists Project and created a new Collections project (so it is not ListsStyledElement but CollectionsStyledELement). Do you need my source code?
Here is another archive with the Screenshots I tried to add before:
http://moritzsoftware.bplaced.net/Private/Screenshots.zip
Edit: Uploaded the files with Firefox and the links above are now not valid anymore.
unfortunatly I'm not able to reproduce your bug. Round-Trip-Engineering works quite nice with your Code Style. I need to know which Association is affected. In this case, I think I also need the source code of both associated Classes... ;)
You're right, the stack trace indicates, that your model is corrupt. I already filed a bug for this issue, but this will only fix the symptom and not the problem itself. Perhaps I can tell more after I know which Association is affected.
Have a nice weekend,
Manuel
I marked the affected association in the attached screenshot (works with Firefox well). There is also the source of "Update.java" and "UpdateDescription.java". I failed to model the
private HashMap<Locale, UpdateDescription> updateDescriptions;
.Would it be the best to create a new model? Of course, that would take some time, but with reverse engineering it should not take too much time, but I hope that I can avoid the problems then.
Moritz
java.lang.IllegalStateException
at com.yattasolutions.obf.fz.aa.setInput(SourceFile:530)
at com.yattasolutions.obf.ll.a$7$1.run(SourceFile:259)
at com.yattasolutions.obf.ll.a.run(SourceFile:344)
at com.yattasolutions.obf.ll.a.a(SourceFile:341)
at com.yattasolutions.obf.ll.a$7.setInput(SourceFile:255)
at org.eclipse.ui.views.properties.tabbed.TabContents$5.run(TabContents.java:181)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:49)
at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:175)
at org.eclipse.ui.views.properties.tabbed.TabContents.setInput(TabContents.java:184)
at org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage$SelectionChangedListener.selectionChanged(TabbedPropertySheetPage.java:212)
at org.eclipse.jface.viewers.Viewer$2.run(Viewer.java:164)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:49)
at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:175)
at org.eclipse.jface.viewers.Viewer.fireSelectionChanged(Viewer.java:162)
at org.eclipse.jface.viewers.StructuredViewer.updateSelection(StructuredViewer.java:2188)
at org.eclipse.jface.viewers.StructuredViewer.handleSelect(StructuredViewer.java:1211)
at org.eclipse.jface.viewers.StructuredViewer$4.widgetSelected(StructuredViewer.java:1241)
at org.eclipse.jface.util.OpenStrategy.fireSelectionEvent(OpenStrategy.java:239)
at org.eclipse.jface.util.OpenStrategy.access$4(OpenStrategy.java:233)
at org.eclipse.jface.util.OpenStrategy$1.handleEvent(OpenStrategy.java:403)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4128)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1457)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1480)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1465)
at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1270)
at org.eclipse.ui.internal.views.properties.tabbed.view.TabbedPropertyList.select(TabbedPropertyList.java:664)
at org.eclipse.ui.internal.views.properties.tabbed.view.TabbedPropertyList$2.mouseUp(TabbedPropertyList.java:156)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:219)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4128)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1457)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1480)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1465)
at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1270)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3974)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3613)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
That seems to be the same exception as before, but ...
Maybe the following screenshot helps you. The properties view is quite empty :).
java.lang.NullPointerException
at com.yattasolutions.obf.fz.d$1.handleInputChanged(SourceFile:130)
at com.yattasolutions.obf.fz.ao.focusLost(SourceFile:42)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:143)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4128)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1457)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1480)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1461)
at org.eclipse.swt.widgets.Control.sendFocusEvent(Control.java:3285)
at org.eclipse.swt.widgets.Display.checkFocus(Display.java:642)
at org.eclipse.swt.widgets.Shell.makeFirstResponder(Shell.java:1234)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5581)
at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
at org.eclipse.swt.widgets.Widget.callSuper(Widget.java:220)
at org.eclipse.swt.widgets.Widget.textDidEndEditing(Widget.java:1954)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5549)
at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
at org.eclipse.swt.widgets.Widget.callSuperBoolean(Widget.java:287)
at org.eclipse.swt.widgets.Widget.makeFirstResponder(Widget.java:1165)
at org.eclipse.swt.widgets.Shell.makeFirstResponder(Shell.java:1233)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5581)
at org.eclipse.swt.internal.cocoa.OS.objc_msgSend_bool(Native Method)
at org.eclipse.swt.internal.cocoa.NSWindow.makeFirstResponder(NSWindow.java:194)
at org.eclipse.swt.widgets.Control.forceFocus(Control.java:1445)
at org.eclipse.swt.widgets.Control.forceFocus(Control.java:1425)
at org.eclipse.swt.widgets.Control.setTabItemFocus(Control.java:4087)
at org.eclipse.swt.widgets.Widget.setTabGroupFocus(Widget.java:1877)
at org.eclipse.swt.widgets.Control.traverseGroup(Control.java:4810)
at org.eclipse.swt.widgets.Control.traverse(Control.java:4775)
at org.eclipse.swt.widgets.Control.translateTraversal(Control.java:4552)
at org.eclipse.swt.widgets.Control.doCommandBySelector(Control.java:1058)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5563)
at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
at org.eclipse.swt.widgets.Widget.callSuper(Widget.java:220)
at org.eclipse.swt.widgets.Widget.superKeyDown(Widget.java:1898)
at org.eclipse.swt.widgets.Widget.keyDown(Widget.java:1076)
at org.eclipse.swt.widgets.Control.keyDown(Control.java:2367)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5473)
at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
at org.eclipse.swt.widgets.Widget.callSuper(Widget.java:220)
at org.eclipse.swt.widgets.Widget.windowSendEvent(Widget.java:2095)
at org.eclipse.swt.widgets.Shell.windowSendEvent(Shell.java:2253)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5535)
at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
at org.eclipse.swt.widgets.Display.applicationSendEvent(Display.java:4989)
at org.eclipse.swt.widgets.Display.applicationProc(Display.java:5138)
at org.eclipse.swt.internal.cocoa.OS.objc_msgSend(Native Method)
at org.eclipse.swt.internal.cocoa.NSApplication.sendEvent(NSApplication.java:128)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3610)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
The Association between Update and UpdateDescription is defect. That's why you're having troubles editing them. In order to repair your model, delete the Association and reverse engineer the affected files again (i.e. right-click on the affected classes and choose "Update from ClassPath").
The Association is not detected with your Code Style, because the getter is missing. If you add the code for the getter in the source file, your Code Style will match.
public HashMap getUpdateDescriptions() {
return updateDescriptions;
}
You can of course define in your template, that a Getter is not required.
Manuel
Thanks,
Moritz
Open your template with the default text editor (right click on the template file in the package explorer and choose "Open With"). Then you'll find something like this:
«DEFINE role (StyledElement style,Classifier parent,MemberFragmentTuple fragment) FOR Property»
«IF fragment.partId==0»
«EXPAND role_FRG_Declaration(style, parent) FOR this»
«ELSEIF fragment.partId==1»
«EXPAND role_FRG_Setter(style, parent) FOR this»
«ELSEIF fragment.partId==2»
«EXPAND role_FRG_Getter(style, parent) FOR this»
«ENDIF»
«ENDDEFINE»
This template dispatches to the fragment templates generating - in this case - declaration, getter and setter. So if you want to add or remove fragments, this is the right place to do so. If you keep on the syntax, UML Lab's template editor will hide it from you. Be aware, that this template must not generate code itself. It only dispatches to the corresponding fragment templates.
Manuel
Should I add it?