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.
Difference between revisions of "Temporality"
(→Introduction) |
(→Background) |
||
Line 7: | Line 7: | ||
− | + | ||
+ | '''How to hook in | ||
+ | Temporality''' | ||
− | The | + | |
+ | <![if !supportEmptyParas]> <![endif]> | ||
+ | |||
+ | |||
+ | <![if !supportEmptyParas]> <![endif]> | ||
+ | |||
+ | |||
+ | The best approach to hook in the temporality feature | ||
+ | is to hook ourselves into the EStore. Doing so has many benefits like begging | ||
+ | able to turn the feature on or off. This will make development easier since we | ||
+ | will each be able to concentrate on the temporality feature without being | ||
+ | affecting other ones like the persistence feature. We can then compose them to | ||
+ | get the complete set of features. We could do this through an inheritance | ||
+ | structure but doing it using delegation is more flexible. Here’s the idea. | ||
+ | |||
+ | |||
+ | <![if !supportEmptyParas]> <![endif]> | ||
+ | |||
+ | |||
+ | Using a simple chain of responsibility similar to the | ||
+ | io package in Java would do the trick. Here’s an example: | ||
+ | |||
+ | |||
+ | <![if !supportEmptyParas]> <![endif]> | ||
+ | |||
+ | |||
+ | '''public''' MyDynamicEStoreEObjectImpl() { | ||
+ | |||
+ | |||
+ | eSetStore( | ||
+ | |||
+ | |||
+ | '''new''' MySecurityEStoreImpl( | ||
+ | |||
+ | |||
+ | '''new''' MyTemporalityEStoreImpl( | ||
+ | |||
+ | |||
+ | '''new''' MyMemoryEStoreImpl()))); | ||
+ | |||
+ | |||
+ | <![if !supportEmptyParas]> <![endif] | ||
+ | |||
+ | > | ||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | <![if !supportEmptyParas]> <![endif]> | ||
+ | |||
+ | |||
+ | However using this simple approach might lead to lots | ||
+ | of objects created needlessly. If this is found to be true we could also use | ||
+ | this approach and have a single EStoreImpl keeping state information and | ||
+ | delegate the processing to stateless EStoreImpl. | ||
+ | |||
+ | |||
+ | <![if !supportEmptyParas]> <![endif]> | ||
+ | |||
+ | |||
+ | '''public''' MyDynamicEStoreEObjectImpl() { | ||
+ | |||
+ | |||
+ | EStore store = '''new''' MyEStoreStateHolderImpl(); | ||
+ | |||
+ | |||
+ | store.add(MySecurityEStoreImpl.INSTANCE); | ||
+ | |||
+ | |||
+ | store.add(MyTemporalityEStoreImpl.INSTANCE); | ||
+ | |||
+ | |||
+ | store.add(MyMemoryEStoreImpl.INSTANCE); | ||
+ | |||
+ | |||
+ | eSetStore(store); | ||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | <![if !supportEmptyParas]> <![endif] | ||
+ | |||
+ | > | ||
+ | |||
+ | |||
+ | When the data | ||
+ | holder delegates to the processor it adds an extra parameter to the call | ||
+ | eSet(eObject, feature, value, '''MyContextualData'''). | ||
+ | |||
+ | |||
+ | <![if !supportEmptyParas]> <![endif]> | ||
+ | |||
+ | |||
+ | <![if !supportEmptyParas]> <![endif]> | ||
+ | |||
+ | |||
+ | It is possible to use this same base class in a | ||
+ | dynamically created EClass (an EClass created using the programmatic API). All | ||
+ | you have to do is write your own factory that implement the EFactory interface | ||
+ | to instantiate your EObjects using your own base class. To hook this factory | ||
+ | into EMF you get the package you defined for your dynamic EClasses and set your | ||
+ | custom factory on it. | ||
+ | |||
+ | |||
+ | <![if !supportEmptyParas]> <![endif]> | ||
+ | |||
+ | |||
+ | Here’s an example of overriding the basicCreate | ||
+ | method. All we have to do is replace the instantiation of the base class the | ||
+ | EFactoryImpl uses by the instantiation of our own base class. | ||
+ | |||
+ | |||
+ | <![if !supportEmptyParas]> <![endif]> | ||
+ | |||
+ | |||
+ | // Register my | ||
+ | own factory to create EStore backed DynamicEObjects | ||
+ | |||
+ | |||
+ | companyPackage.setEFactoryInstance('''new''' EFactoryImpl() { | ||
+ | |||
+ | |||
+ | <![if !supportEmptyParas]> <![endif]> | ||
+ | |||
+ | |||
+ | @Override | ||
+ | |||
+ | |||
+ | '''protected''' EObject basicCreate(EClass eClass) { | ||
+ | |||
+ | |||
+ | '''return''' | ||
+ | |||
+ | |||
+ | |||
+ | eClass.getInstanceClassName() == "java.util.Map$Entry" ? | ||
+ | |||
+ | |||
+ | '''new''' MyEStoreEObjectImpl.BasicEMapEntry(eClass) : | ||
+ | |||
+ | |||
+ | '''new''' MyEStoreEObjectImpl(eClass); | ||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | }); | ||
+ | |||
+ | |||
+ | <![if !supportEmptyParas]> <![endif]> | ||
+ | |||
+ | |||
+ | With the constructor of this base class written like | ||
+ | this | ||
+ | |||
+ | |||
+ | '''public''' MyDynamicEStoreEObjectImpl() { | ||
+ | |||
+ | |||
+ | eSetStore('''new''' MyMemoryEStoreImpl()); | ||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | <![if !supportEmptyParas]> <![endif]> | ||
+ | |||
+ | |||
+ | <![if !supportEmptyParas]> <![endif]> | ||
+ | |||
+ | |||
+ | So the base class can be specified both in generated | ||
+ | code as well as dynamically created EClasses. | ||
+ | |||
+ | |||
+ | <![if !supportEmptyParas]> <![endif]> |
Revision as of 16:56, 6 November 2007
Introduction
Mint is a proposed open source component in the Eclipse Modeling Framework Technology (EMFT) project whose goal is to improve out-of-the-box user experience when developing EMF-based solutions. For the most part, this is accomplished by extending Java Development Tools (JDT) with EMF-specific enhancements.
This proposal is in the Project Proposal Phase (as defined in the Eclipse Development Process document) and is written to declare its intent and scope. This proposal is written to solicit additional participation and input from the Eclipse community. You are invited to comment on and/or join the component. Please send all feedback to the eclipse.technology.emft newsgroup (please prefix the subject with [mint]).
How to hook in
Temporality
<![if !supportEmptyParas]> <![endif]>
<![if !supportEmptyParas]> <![endif]>
The best approach to hook in the temporality feature
is to hook ourselves into the EStore. Doing so has many benefits like begging
able to turn the feature on or off. This will make development easier since we
will each be able to concentrate on the temporality feature without being
affecting other ones like the persistence feature. We can then compose them to
get the complete set of features. We could do this through an inheritance
structure but doing it using delegation is more flexible. Here’s the idea.
<![if !supportEmptyParas]> <![endif]>
Using a simple chain of responsibility similar to the
io package in Java would do the trick. Here’s an example:
<![if !supportEmptyParas]> <![endif]>
public MyDynamicEStoreEObjectImpl() {
eSetStore(
new MySecurityEStoreImpl(
new MyTemporalityEStoreImpl(
new MyMemoryEStoreImpl())));
<![if !supportEmptyParas]> <![endif]
>
}
<![if !supportEmptyParas]> <![endif]>
However using this simple approach might lead to lots
of objects created needlessly. If this is found to be true we could also use
this approach and have a single EStoreImpl keeping state information and
delegate the processing to stateless EStoreImpl.
<![if !supportEmptyParas]> <![endif]>
public MyDynamicEStoreEObjectImpl() {
EStore store = new MyEStoreStateHolderImpl();
store.add(MySecurityEStoreImpl.INSTANCE);
store.add(MyTemporalityEStoreImpl.INSTANCE);
store.add(MyMemoryEStoreImpl.INSTANCE);
eSetStore(store);
}
<![if !supportEmptyParas]> <![endif]
>
When the data
holder delegates to the processor it adds an extra parameter to the call
eSet(eObject, feature, value, MyContextualData).
<![if !supportEmptyParas]> <![endif]>
<![if !supportEmptyParas]> <![endif]>
It is possible to use this same base class in a
dynamically created EClass (an EClass created using the programmatic API). All
you have to do is write your own factory that implement the EFactory interface
to instantiate your EObjects using your own base class. To hook this factory
into EMF you get the package you defined for your dynamic EClasses and set your
custom factory on it.
<![if !supportEmptyParas]> <![endif]>
Here’s an example of overriding the basicCreate
method. All we have to do is replace the instantiation of the base class the
EFactoryImpl uses by the instantiation of our own base class.
<![if !supportEmptyParas]> <![endif]>
// Register my
own factory to create EStore backed DynamicEObjects
companyPackage.setEFactoryInstance(new EFactoryImpl() {
<![if !supportEmptyParas]> <![endif]>
@Override
protected EObject basicCreate(EClass eClass) {
return
eClass.getInstanceClassName() == "java.util.Map$Entry" ?
new MyEStoreEObjectImpl.BasicEMapEntry(eClass) :
new MyEStoreEObjectImpl(eClass);
}
});
<![if !supportEmptyParas]> <![endif]>
With the constructor of this base class written like
this
public MyDynamicEStoreEObjectImpl() {
eSetStore(new MyMemoryEStoreImpl());
}
<![if !supportEmptyParas]> <![endif]>
<![if !supportEmptyParas]> <![endif]>
So the base class can be specified both in generated
code as well as dynamically created EClasses.
<![if !supportEmptyParas]> <![endif]>