Bug 75925 - [Plan Item] Generator Extensibility
Summary: [Plan Item] Generator Extensibility
Status: VERIFIED FIXED
Alias: None
Product: EMF
Classification: Modeling
Component: Tools (show other bugs)
Version: 2.1   Edit
Hardware: PC Windows XP
: P1 enhancement (vote)
Target Milestone: Past   Edit
Assignee: Dave Steinberg CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 76205 (view as bug list)
Depends on:
Blocks: 104727 125469 126892 129223 131078
  Show dependency tree
 
Reported: 2004-10-08 13:00 EDT by Marcelo Paternostro CLA
Modified: 2008-01-28 16:48 EST (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Marcelo Paternostro CLA 2004-10-08 13:00:06 EDT
 
Comment 1 Ed Merks CLA 2004-10-14 07:43:00 EDT
*** Bug 76205 has been marked as a duplicate of this bug. ***
Comment 2 Kenn Hussey CLA 2004-10-16 16:21:44 EDT
Enhancements to generator extensibility should make it possible to:

- customize existing parsers (e.g. the Rose parser) and Ecore "builders"
- add new Ecore builders (importers)
- customize existing generator model wrappers (i.e. GenFeatureImpl, etc.)
- add new templates

Validation of Ecore models that are built/imported should be extracted (e.g. 
into an EValidator) and shared by all existing/new builders/importers.

Ideally there would be an orthogonal way to plug in exporters as well.
Comment 3 Baybora Aksoy CLA 2004-11-15 20:23:40 EST
I customized the "codegen templates" and put them under my project . I 
can see all the the converted templates in the project .JETEmitters without 
errors. However, when I try to generate code from a genmodel using these 
templates , I am getting 'NoClassDefFound' error, for the packages that I 
have imported in the templates.
 
It seems we need to update the class loader of the GenModel's JetEmitters. 
The issue is that GenModel's JetEmitters are not settable from outside.
Ed Merks suggested overriding following method as a work around for now:
 
I think for right now you'd need to override this GenModelImpl method:
 
  protected JETEmitter createJETEmitter(String relativeTemplateURI)
  {
    JETEmitter jetEmitter =
      new JETEmitter(getTemplatePath(), relativeTemplateURI)
      {
        public void initialize(IProgressMonitor progressMonitor) throws JETException
        {
          addVariable("EMF_CODEGEN", "org.eclipse.emf.codegen");
          addVariable("EMF_CODEGEN_ECORE", "org.eclipse.emf.codegen.ecore");
          addVariable("EMF_COMMON", "org.eclipse.emf.common");
          addVariable("EMF_ECORE", "org.eclipse.emf.ecore");
          super.initialize(progressMonitor);
        }
      };
    return jetEmitter;
  }
 
We'd really appreciate if we could have access to JetEmitters from outside of
GenModel, as there is a number of dependent projects that need to be rebuilt and
customized just to override one method.
 
Comment 4 Joël Cheuoua CLA 2004-12-04 11:17:28 EST
I also used to work with a derived GenModel and a customized editor for JET 
templates to be able to have a more flexible generator and ease the process of 
writting my own templates. It was quite ugly because it implies deriving / 
rewriting parts of the GenModel GUI to be able to use the existing wizards, 
editors etc. With that derived GenModel structure, I was also doing some very 
nasty hacks to be able to reference other GenModels that were not deriving 
from the same custom structure.

This leads me to build a set of plugins to be able to do some fancier and 
slightly more flexible code generation without being much intrusive on the 
GenModel architecture itself.

One of the biggest interest of the tool is that it makes use of the Mapping 
framework and of a JET Template Model (JTM), that alow smooth selection 
of "what-is-going-to-be-generated-how-and-where". The generation is dynamic 
and you can easilly change templates between two generations. You didn't need 
to have an "hidden" .JETTemplate project. The steps are quite simple :
1 - create a Java JET Project with the templates
2 - create a JET Template Model (JTM) from the Java JET Project
3 - customize the JET Template model according to your wishes
4 - create a GenModel2JETMapping and associate the GenBase element to their 
JET templates
5 - generate and you're done :)

Actually, my point was to push even a little further and allow other inputs 
than GenModel instances for the templates (UML2 for instance).

I'll try to make the tool available on sourceforge soon, but if you need it 
quickly, contact me at jcheuoua@wanadoo.fr or jcheuoua@ilog.fr.

Cheers.

Joel.
Comment 5 Kenn Hussey CLA 2005-01-20 13:39:48 EST
There also needs to be a way to set the basePackage on an Ecore model (e.g. 
using an annotation or extended metadata) so that the basePackage is set 
correctly in the generator model when it is created. Currently, the 
basePackage is obtained and set in a different way for each import source 
(i.e. XSD vs. Rose, etc.).
Comment 6 Ed Merks CLA 2005-02-18 07:31:18 EST
[plan pri=1 est=12w/]
Comment 7 Ed Merks CLA 2006-02-21 12:10:24 EST
This feature will be late.
Comment 8 Dave Steinberg CLA 2006-05-01 10:52:41 EDT
The enhancement has been committed to CVS.

The approach I took to providing generator extensibility was to move all of the functional, code generation code out of the GenModel into adapters.  Code generation is done via a new Generator class, which delegates via GeneratorAdapterFactories to GeneratorAdapters, which are actually responsible for collecting the objects relevant to the code generation and generating artifacts for them.  This approach is not tied directly to the GenModel: you could reuse the Generator to produce code for another Ecore model (such as UML2 or Ecore itself) or even for arbitrary Java objects.  The generic interfaces and base classes are found in the new org.eclipse.emf.codegen.ecore.generator package.

A set of generator adapters and an adapter factory are provided for GenModel, which should provide exactly the same behaviour as the old mechanism for code generation (invoking the generateXYZ() methods directly on the GenModel elements).  They're in org.eclipse.emf.codegen.ecore.genmodel.generator.  

Additional generator adapters can be contributed via an extension point, and they will be invoked during code generation so that they can produce additional artifacts.  As is typical with extension point-based designs, this limits us to giving and does not allow taking away.  If the latter is necessary, it's still possible to subclass the default adapter factory to produce the subclassed adapters which don't generate everything.  The adapters are written using one method per artifact, making it easy to skip and/or replace some.  Then, it's code to the rescue!  The new adapter factory can be registered in place of the default one in the global generator adapter factory descriptor registry (Generator.AdapterFactory.Descriptor.Registry.INSTANCE) or as a local override in the Generator's registry (generator.getAdaterFactoryDescriptorRegistry()).

The Descriptor is just a factory for GeneratorAdapterFactorys, allowing a single global registry to be shared among Generators and providing for delayed class loading under Eclipse.

All the methods involved in the old code generation mechanism have been deprecated.

Along the way, I've addressed a number of smaller issues, some of which already had open Bugzillas:
 - Enable access to the GenModel's import manager from outside (bug 129223)
 - JavaFormatter should respect project settings (bug 131078)
 - Allow generation for just a single object, without its children (bug 125469)
 - Don't cache JETEmitters when using dynamic templates
 - Enable the cancel button during code generation.

In addition, error reporting is improved, contributing to bug 104727.
Comment 9 Nick Boldt CLA 2006-05-02 10:39:09 EDT
Fixed in 2.2.0RC2 (S200605020900)
Comment 10 Jörg von Frantzius CLA 2006-07-28 09:04:15 EDT
Assuming that GeneratorAdapter is supposed to be API, it would be nice if there was some javadoc elaborating on what those untyped Object arguments to several methods are exactly!

Following the usual Eclipse coding conventions, I guess it should also be called IGeneratorAdapter instead?
Comment 11 Dave Steinberg CLA 2006-07-31 09:03:49 EDT
Yes, some decent documentation is still required.

Unfortunately, EMF has a long history of not using the I convention for interfaces, except for Eclipse-dependent UI components, so the name won't be changing.
Comment 12 Dave Steinberg CLA 2006-11-08 17:05:27 EST
I've added documentation as part of bug 163845 (bug 163871 for the maintenance stream).
Comment 13 Nick Boldt CLA 2008-01-28 16:48:12 EST
Move to verified as per bug 206558.