Sunday, March 29, 2009

Creating useful actions for the EMF Ecore Editor

When using the Ecore editor to produce models which can be used to generate code, it is often a tedious task to create some of the required artefacts.
Such as:
  • create an operation with ready made annotation for inclusion of an operation body in the generated code
  • create a validator constraint operation
  • create a derived, volatile attribute
  • ...
Create a new plugin project, e.g. org.softwarepoets.emf.ecore.editor.extensions

Open the manifest and add this to your plugin.xml file:
<extension
point="org.eclipse.ui.popupMenus">
<objectContribution id="org.eclipse.emf.ecore.editor.CreateEOperationWithAnnotation"
objectClass="org.eclipse.emf.ecore.EClass">
<action id="org.eclipse.emf.ecore.editor.CreateEOperationWithAnnotation"
label="Codegen Operation"
menubarPath="additions" class="org.softwarepoets.emf.ecore.editor.extensions.CreateEOperationWithAnnotation"
enablesFor="1"/>
</objectContribution>
</extension>

In the dependencies section of the manifest add org.eclipse.emf.ecore.

Create a new class org.softwarepoets.emf.ecore.editor.extensions.CreateEOperationWithAnnotation:

public class CreateEOperationWithAnnotation extends ActionDelegate implements
IActionDelegate {

protected EClass eClass;

public CreateEOperationWithAnnotation() {
super();
}

The run method:

@Override
public void run(IAction action) {
InputDialog dialog = new InputDialog(PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getShell(), "Enter Operation name",
"Enter the name of the operation without parameters using valid java naming conventions.", "", new JavaNamingValidator() );

if (dialog.open() == InputDialog.OK ) {
String name = dialog.getValue();
EOperation eOper = EcoreFactory.eINSTANCE.createEOperation();
eOper.setName(name);
eClass.getEOperations().add(eOper);
EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
eOper.getEAnnotations().add(eAnnotation);
eAnnotation.setSource(GenModelPackage.eNS_URI);
eAnnotation.getDetails().put("body","");
}
}


The implementation of the run method will also display a small dialog in order to ask the user for the operation name.




How to decide on which class the operation should be added and if the action should be enabled:
@Override
public void selectionChanged(IAction action, ISelection selection) {
if (selection instanceof IStructuredSelection) {
Object object = ((IStructuredSelection) selection)
.getFirstElement();
if (object instanceof EClass) {
eClass = (EClass) object;

action.setEnabled(true);
return;
}
}
eClass = null;
action.setEnabled(false);
}

The validator class, to validate the input of the user (draft version, can be improved a lot):
class JavaNamingValidator implements IInputValidator {
public String isValid(String newText) {
if (newText == null || newText.length() == 0)
return "You must enter an operation name.";
// maybe include an elaborate regular expression here...
// otherwise ok
return null;
}
}



After you are done, you can start a new runtime workspace, create an Ecore model, select an EClass and right click. You should see the additional action in the popup menu. After completing the dialog you should see something like this:

No comments:

Post a Comment