Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Texo/Design Concepts"

(Change generated code)
Line 10: Line 10:
 
== Runtime Model ==
 
== Runtime Model ==
  
Texo differs from other code generation approaches outside of EMF in that specific attention is paid to support of a runtime representation of the domain model. The domain model is expressed in ecore or XSD and with the model annotations drives the code generation. At runtime it is critical to also have the possibility to work with the domain model and to access the generated code using model constructs.  
+
Texo differs from other code generation approaches (except for EMF itself) in that specific attention is paid to support of a runtime representation of the domain model. The domain model is expressed in ecore or XSD and with the model annotations drives the code generation. At runtime it is important to also have the possibility to work with the domain model and to access the generated code using model constructs.  
  
 
=== Model-driven functionality (at runtime) ===
 
=== Model-driven functionality (at runtime) ===
Many applications have one or more functions which really make sense to implement at model level instead of at specific instance/type level. A runtime model is makes it very easy to implement functions at runtime such as:
+
Many applications have one or more functions which really make sense to implement at model level instead of at specific instance/type level. A runtime model makes it very easy to implement functions at runtime such as:
 
* archiving: implement a generic archiving model which uses the runtime model to interrogate objects and retrieve changed and new property values.
 
* archiving: implement a generic archiving model which uses the runtime model to interrogate objects and retrieve changed and new property values.
 
* security: it makes sense to define security also using entities from the domain model. To support security definition changes at runtime it must be possible to address the model at runtime. To check security at runtime one needs access to the runtime model also.
 
* security: it makes sense to define security also using entities from the domain model. To support security definition changes at runtime it must be possible to address the model at runtime. To check security at runtime one needs access to the runtime model also.
Line 22: Line 22:
 
=== Runtime Model in Texo ===
 
=== Runtime Model in Texo ===
  
The Texo runtime model is an ecore model. The ecore model can be reached through the generated ModelPackage class of a
+
The Texo runtime model functionality makes it possible to:
 +
* access the available EPackages which have been loaded/initialized and iterate over its EClassifiers and EFeatures.
 +
* (at runtime) determine the domain type (the EClass) represented by a pojo.
 +
* access the values of EFeatures for a pojo at runtime, both get and set features.
 +
 
 +
Texo takes a different approach than EMF in making the runtime model available. In EMF each object always implements the EMF EObject interface or extends the EMF BasicEObjectImpl. Texo implements the runtime model outside of the pojo in a separate generated class which acts as a wrapper of the pojo to give it a 'Model-Face'.
 +
 
 +
The Texo runtime model is an ecore model. The ecore model can be reached through the generated ModelPackage class.
 +
 
 +
=== Different approaches for linking pojo's and the runtime model ===
 +
 
 +
While designing and developing Texo different approaches have been tried to integrate pojo's and the runtime model:
 +
* generate model annotations in the pojo: this fits very nicely in the Java annotation concept (use an annotation to attach metadata to a class) it has two :
 +
compile time dependency of the pojo
 +
* use class enhancement at runtime: so at runtime add the implementation of a Model interface to each pojo. The reason that this approach was not chosen:
 +
** this means that at runtime the
 +
** when developing against the Model api you need to cast to the Model interface, so you loose a bit of compile time checking
 +
** the implementation of the model interface can not be changed by the user (currently the Model wrapper is also generated and can be adapted by a user, the manual changes are maintained when re-generating).
 +
* enhance classes at build time: (see the very interesting [http://projectlombok.org/slideshow.html Lombok] project), the reason that this approach was not chosen:
 +
we would force the user to change the build setup (although simple it still has to be done)
 +
the class file is not insync with the source code, so debugging is more difficult
 +
 
  
 
== Work with generated code ==
 
== Work with generated code ==

Revision as of 05:50, 31 January 2010

Introduction

This page gives an overview of the main design ideas which are the basis for the Texo project.

Annotated Models, Annotation generation with manual overrides

Runtime Model

Texo differs from other code generation approaches (except for EMF itself) in that specific attention is paid to support of a runtime representation of the domain model. The domain model is expressed in ecore or XSD and with the model annotations drives the code generation. At runtime it is important to also have the possibility to work with the domain model and to access the generated code using model constructs.

Model-driven functionality (at runtime)

Many applications have one or more functions which really make sense to implement at model level instead of at specific instance/type level. A runtime model makes it very easy to implement functions at runtime such as:

  • archiving: implement a generic archiving model which uses the runtime model to interrogate objects and retrieve changed and new property values.
  • security: it makes sense to define security also using entities from the domain model. To support security definition changes at runtime it must be possible to address the model at runtime. To check security at runtime one needs access to the runtime model also.
  • export/import: export and import functions in an application can benefit from generic model-based logic. Implementing export/import using the runtime model is very efficient compared to writing a specific export/import per type in a system.

Another usage scenario for having the model available at runtime is that the model elements can be used to define other system components. An example of this is a system which allows users/consultants to define the user interface themselves through a user interface. To support the user/consultant in defining a user interface he/she must be able to select elements from the runtime model to define fields in a form or columns in a grid.

Runtime Model in Texo

The Texo runtime model functionality makes it possible to:

  • access the available EPackages which have been loaded/initialized and iterate over its EClassifiers and EFeatures.
  • (at runtime) determine the domain type (the EClass) represented by a pojo.
  • access the values of EFeatures for a pojo at runtime, both get and set features.

Texo takes a different approach than EMF in making the runtime model available. In EMF each object always implements the EMF EObject interface or extends the EMF BasicEObjectImpl. Texo implements the runtime model outside of the pojo in a separate generated class which acts as a wrapper of the pojo to give it a 'Model-Face'.

The Texo runtime model is an ecore model. The ecore model can be reached through the generated ModelPackage class.

Different approaches for linking pojo's and the runtime model

While designing and developing Texo different approaches have been tried to integrate pojo's and the runtime model:

  • generate model annotations in the pojo: this fits very nicely in the Java annotation concept (use an annotation to attach metadata to a class) it has two :

compile time dependency of the pojo

  • use class enhancement at runtime: so at runtime add the implementation of a Model interface to each pojo. The reason that this approach was not chosen:
    • this means that at runtime the
    • when developing against the Model api you need to cast to the Model interface, so you loose a bit of compile time checking
    • the implementation of the model interface can not be changed by the user (currently the Model wrapper is also generated and can be adapted by a user, the manual changes are maintained when re-generating).
  • enhance classes at build time: (see the very interesting Lombok project), the reason that this approach was not chosen:

we would force the user to change the build setup (although simple it still has to be done) the class file is not insync with the source code, so debugging is more difficult


Work with generated code

There are roughly two schools of thought regarding how to handle and work with generated code.

One school of thought states that generated code should never be changed manually. Generated code should not be committed to a CVS. It should be possible to remove all the generated code, regenerate and then have the same situation as before. In this approach any manual/custom logic should be implemented in subclasses of the generated code. These subclasses can also be generated. This school of thought is what is propagated by developers from the [1] project.

The other school of thought states that it should be possible to change generated code. manual changes in the code should remain even if the code is re-generated. Generated code should be checked in to a CVS. This approach is followed by the [2] project.

Both groups consist of experienced, very knowledgeable developers, architects and experts on the field of model-to-text transformation and code generation.

Texo follows the EMF approach (the second school of though) because:

  • it feels more natural to change/add behavior to the generated class than to a subclass.
  • manual code can easily be identified inside of generated classes.
  • the code generation does not update the file on the file system if it has not changed by code generation. This results in minimal changesets in a CVS, and much better, if something changes it is directly visible in CVS diffs etc.
  • by checking in the generated code to cvs it is much easier for others to work with the development project as no generation step is needed after getting the project or updates from a CVS. The same applies to re-distribution of regenerated code, by checking in the generated code (and the changes) it is much clearer what has changed and when people update from the CVS they will receive a consistent state directly.
  • Texo will re-organize imports and remove files which related to model elements which have been removed. As the code is checked in these removal actions are tracked in a CVS.

Back to the top