Skip to main content

Notice: This Wiki is now read only and edits are no longer 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/Runtime Model"

Line 21: Line 21:
 
* eGet(EStructuralFeature): to get the value of an EStructuralFeature
 
* eGet(EStructuralFeature): to get the value of an EStructuralFeature
 
* eSet(EStructuralFeature, Object): to set the value of an EStructuralFeature
 
* eSet(EStructuralFeature, Object): to set the value of an EStructuralFeature
 +
 +
The approach with generated ModelObject wrappers has been chosen because:
 +
it performs much better than reflective access (about 100 times faster)
 +
it does not require runtime class enhancements, i.e. no complex class loader configurations which can interfere with other frameworks.
 +
 +
The only 'price' is an extra class (the ModelFactory) which contains an inner-class for each EClass. '''Note the generation of the runtime model layer will be made optional. So if you don't need runtime model access then the ModelFactory and ModelPackage classes will not be generated.'''
 +
 +
== Model-driven access to Pojo's ==
 +
The ModelObject (eClass, eGet, eSet) interface makes it possible to access generated pojo's at generic model level. Then how do you create or wrap a generated pojo into a ModelObject? This is where the org.eclipse.emf.texo.model.ModelResolver can be used. The ModelResolver provides global access to all registered/initialized ModelPackages. It also makes it easy to access pojo's in a 'model-drive'n way. The ModelResolver.getModelObject(Object) is used for this. Let's show an example. This example creates a pojo (Book), sets some values and then accesses this same pojo in a model-driven way:
 +
<source lang="java">
 +
final LibraryModelFactory factory = LibraryModelPackage.MODELFACTORY;
 +
final Book book = factory.createBook(); // or just do new Book();
 +
book.setTitle(TITLE);
 +
book.setCategory(BOOK_CATEGORY);
 +
book.setPages(PAGES);
 +
 +
final ModelObject<?> modelObject = ModelResolver.getInstance().getModelObject(book);
 +
for (EStructuralFeature eFeature : modelObject.eClass().getEAllStructuralFeatures()) {
 +
    System.err.println(eFeature.getName() + ": " + modelObject.eGet(eFeature)); //$NON-NLS-1$
 +
}
 +
</source>
 +
The for loop walks through all the EStructuralFeatures of the EClass. The following is printed:
 +
<source lang="javascript">
 +
title: title
 +
pages: 27
 +
category: ScienceFiction
 +
author: null
 +
</source>
  
 
== Access to the ModelFactory and ModelPackage ==
 
== Access to the ModelFactory and ModelPackage ==
Line 30: Line 58:
 
</source>
 
</source>
  
The other method is to use the ModelResolver. The ModelResolver roughly has the same meaning as the EMF EPackageRegistry. All initialized ModelPackage instances are present in the global ModelResolver instance.
+
The other method is to use the org.eclipse.emf.texo.model.ModelResolver. The ModelResolver roughly has the same meaning as the EMF EPackageRegistry. All initialized ModelPackage instances are present in the global ModelResolver instance (which can be retrieved using ModelResolver.getInstance()). The following code snippet for example returns the LibraryModelPackage:
 
+
<source lang="java">
 
+
ModelPackage modelPackage = ModelResolver.getInstance().getModelPackage(LibraryModelPackage.NS_URI);
 
+
</source>
 
+
 
+
 
+
Texo generates two types of java files:
+
* pojo's without explicit model information
+
* two Model* classes which provide runtime model access
+
 
+
Runtime mo
+

Revision as of 06:56, 7 March 2010

Introduction

Runtime model access is very useful when trying to implement generic functions like export/import, security, archiving etc. Also when the model is explicitly used in the application then it can make sense to access model objects (entities) in a model-driven way.

To support a model-driven approach at runtime, Texo generates two extra java class files for each EPackage. These can be normally be found in the same package as the generated entities:

  • ModelPackage: provides access to the EPackage and its content
  • ModelFactory: contains factory methods to create instances of an EClassifier and for String conversion. In addition this class provides access to the model wrappers.

Model Wrappers: the ModelObject

As noted in the previous section, the ModelFactory class contains so-called ModelWrappers. The model wrappers provides a 'model-face' on top of a pojo.

To illustrate this with the EMF library example. For the EMF Library EClass, the following is generated:

  • a Library java class (a true pojo)
  • a LibraryModelObject which can be found inside the generated LibraryModelFactory class

The Library java class will have methods like getName, getBooks, etc. The LibraryModelObject has three methods:

  • eClass(): returning the Library EClass
  • eGet(EStructuralFeature): to get the value of an EStructuralFeature
  • eSet(EStructuralFeature, Object): to set the value of an EStructuralFeature

The approach with generated ModelObject wrappers has been chosen because: it performs much better than reflective access (about 100 times faster) it does not require runtime class enhancements, i.e. no complex class loader configurations which can interfere with other frameworks.

The only 'price' is an extra class (the ModelFactory) which contains an inner-class for each EClass. Note the generation of the runtime model layer will be made optional. So if you don't need runtime model access then the ModelFactory and ModelPackage classes will not be generated.

Model-driven access to Pojo's

The ModelObject (eClass, eGet, eSet) interface makes it possible to access generated pojo's at generic model level. Then how do you create or wrap a generated pojo into a ModelObject? This is where the org.eclipse.emf.texo.model.ModelResolver can be used. The ModelResolver provides global access to all registered/initialized ModelPackages. It also makes it easy to access pojo's in a 'model-drive'n way. The ModelResolver.getModelObject(Object) is used for this. Let's show an example. This example creates a pojo (Book), sets some values and then accesses this same pojo in a model-driven way:

final LibraryModelFactory factory = LibraryModelPackage.MODELFACTORY;
final Book book = factory.createBook(); // or just do new Book();
book.setTitle(TITLE);
book.setCategory(BOOK_CATEGORY);
book.setPages(PAGES);
 
final ModelObject<?> modelObject = ModelResolver.getInstance().getModelObject(book);
for (EStructuralFeature eFeature : modelObject.eClass().getEAllStructuralFeatures()) {
    System.err.println(eFeature.getName() + ": " + modelObject.eGet(eFeature)); //$NON-NLS-1$
}

The for loop walks through all the EStructuralFeatures of the EClass. The following is printed:

title: title
pages: 27
category: ScienceFiction
author: null

Access to the ModelFactory and ModelPackage

There are several ways to get to the ModelFactory or ModelPackage instance. The first method is to use the generated statics:

final LibraryModelFactory modelFactory = LibraryModelPackage.MODELFACTORY;
final LibraryModelPackage modelPackage = LibraryModelPackage.INSTANCE;

The other method is to use the org.eclipse.emf.texo.model.ModelResolver. The ModelResolver roughly has the same meaning as the EMF EPackageRegistry. All initialized ModelPackage instances are present in the global ModelResolver instance (which can be retrieved using ModelResolver.getInstance()). The following code snippet for example returns the LibraryModelPackage:

ModelPackage modelPackage = ModelResolver.getInstance().getModelPackage(LibraryModelPackage.NS_URI);

Back to the top