Also known as Aspect Oriented Programming, GMF allows you to specify a location for custom dynamic templates, which are compiled and added to your plugin when the .gmfgen is being used to generate the diagram code.

This is based on two references: A really good presentation (see page 17), and a news posting. This example is based on GMF 2.0.1, but it should work fine with GMF 2.2 as well.

In this example, we want to change our getDestroyElementCommand() in my.diagram.edit.policies.PageItemSemanticEditPolicy:

/**
 * @generated
 */
protected Command getDestroyElementCommand(DestroyElementRequest req) {
  CompoundCommand cc = getDestroyEdgesCommand();
  addDestroyShortcutsCommand(cc);
  cc.add(getGEFWrapper(new DestroyElementCommand(req)));
  return cc.unwrap();
}

To:

/**
 * @generated
 */
protected Command getDestroyElementCommand(DestroyElementRequest req) {
  CompoundCommand cc = getDestroyEdgesCommand();
  addDestroyShortcutsCommand(cc);
  cc.add(getGEFWrapper(new DestroyElementCommand(req)));
  System.out.println("hello, world!");
  return cc.unwrap();
}
  1. Get the GMF Codegen source (includes the actual templates used to generate your plugin) and extract it somewhere.
  2. Search through the templates for getDestroyElementCommand
  3. Hunt around until you find a template that looks useful: in my case, I found xpt/diagram/editpolicies/NodeItemSemanticEditPolicy.xpt.
  4. Look in this template to find the DEFINE that make up this command: in my case, I decided to modify destroySemanticElement which was part of the code used to create getDestroyElementCommand:
«DEFINE destroySemanticElement FOR gmfgen::GenNode-»
	«EXPAND fixElementToDeleteIfShortcut-»
cc.add(getGEFWrapper(new org.eclipse.gmf.runtime.emf.type.core.commands.DestroyElementCommand(req)));
«ENDDEFINE»
  1. Create a new .xpt file like so (note: the IMPORT statement is for GMF 2.2):
«IMPORT 'http://www.eclipse.org/gmf/2009/GenModel'»
«EXTENSION xpt::diagram::Utils»
«EXTENSION xpt::GenModelUtils»

«AROUND destroySemanticElement FOR gmfgen::GenNode-»
   «targetDef.proceed()»
   System.out.println("hello, world!");
«ENDAROUND»
  1. You will notice above: AROUND is used to specify that we don’t want to replace the original element, we want to modify it.
  2. Also, «targetDef.proceed()» is the terminology to include the original template code (so we don’t lose functionality).
  3. Save this file into templates/aspects/xpt/diagram/editpolicies/NodeItemSemanticEditPolicy.xpt. This is a copy of the original template location, but notice the aspects part of the directory!
  4. Go into your .gmfgen
  5. Change Gen Editor Generator > Dynamic Templates to true
  6. Change Gen Editor Generator > Template Directory to /my.model/templates/
  7. You can now generate modified templates!

I did all of this in my own project, which you can view the diff on Google Code to see what I did