Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipse-incubator-e4-dev] YAMI (Yet Another Model Interface)

Michael,

Comments below.


Ed Merks/Toronto/IBM@IBMCA
mailto: merks@xxxxxxxxxx
905-413-3265 (t/l 313)



eclipse-incubator-e4-dev-bounces@xxxxxxxxxxx wrote on 05/02/2008 01:21:29 PM:

> Hi Ed,
>
> I look forward to meet you at the summit...
>
> Comments below...
>
> Ed Merks wrote:
> >  > have you looked at the openArchitectureWare MetaModel [1][2]? It is
> > similar
> >  > to IObservableModel [3] but it seems to be more complete. It is
> >  > missing notifications though.
> >
> > I think the intent is a quite a different though...
>
> This is a good point! There are clearly different uses of meta-models.
> Maybe we should differentiate between the uses.
>
> In modeling you need a metamodel that is a model as well, especially,
> you need a modifiable metamodel to build your metamodel. EMF is very
> good for that and I think that was its primary intend of use.


It's definitely focused on inspection and update to support the full life cycle...

>
> There are cases when you need meta information about the objects
> at hand. In that case the metamodel is essentially read-only (at
> least for the consumer). Often additional meta information about
> the meta-model artifacts might be useful. Those are often a kind of
> annotations. But annotations can come from anywhere. If you look
> at persistence systems like Hibernate and EclipseLink, the "annotations"
> can either come from the metamodel directly or from an external XML
> file that associates the annotations with the model. Ideally, the
> annotation itself has a metamodel.....


Yes, the whole issue of having embedded annotations (easy to maintain) and external annotations (more flexible).

>
> Typical examples for the need of read-only metamodels
> - database persistence
> - data-binding


I'm not so sure abut these two.  You want might want to store into the data base, or update the data based on changes in the GUI

> - annotation driven UI
> - model validation
> - serialization


And what good is serialization without deserialization? :-P

> - scripting language binding (expose java objects to the scripting language)
> - access to objects from scripting languages (access scripting
> objects in java)


If the scripts will only view them...

>
> Ok, here's an example where you need a modifiable metamodel:


Probably in every case you've used the word meta model, you really just mean model.  Most often meta models are quite rigid and not likely to change so much.  It's often hard to change a meta model once instances exists.

> ad-hoc data-structures like IMemento. But with something like
> my MagicInterfaces or generated code, the user is not exposed
> too the fact that the metamodel is modifiable.
>
> I think in the realm of UI there is a lot you can do if you have
> a strong metamodel. The EMF tools show quite nicely what you can do
> with a good metamodel.
>
> But unfortunately, EMF is viral like GPL. If you want to use it you
> have to make your objects EObject. The oaw metamodel is similar
> to ecore but it is not viral (because you can use it for non
> openArchitectureWare and non EMF objects).


True enough.  Though if you want your model to produce notifications, which is a key thing for most of the things we've been talking about, the notification generating code itself is viral in nature.  Only Aspects provide a kind of non-viral approach, but even then, it's because the virus is hidden...

>
>
> >  >
> >  > - it does the indirection (model.value(object, attrId))
> >  > - it is tuned for model access
> >  > - there are implementations for EMF, java beans, JDT etc
> >
> > I'm not sure of the specifics, but I expect the need for it is much like
> > in JET where you want to write templates that traverse a data string in
> > a uniform way.  I.e., it's effectively a requirement to write scripts
> > against arbitrary data structures all of which you want to view as being
> > typed objects with properties...
>
> It is used for more I think -- (I don't know the oaw code in detail).
> But the metamodel is also used in the editors for code completion and
> validation. The oaw language family (xTend, xPand etc) is strongly
> typed and they rely on a strong metamodel. I don't know about their
> dynamic UI. I don't know they are using EMF (that would prove the
> viral nature of EMF ;-) or if they base it on their metamodel.


Hehehe.  I was asking Bernd about this...  I think they drank the koolaide.  :-P

>
> >  > This would then have the benefits of the IObservableModel and
> >  > openArchitectureWare metamodel with the power of EMF....
> >
> > Again, I think the intent is a little different and I'm not sure those
> > differences unimportant.
> >
> >  >
> >  >
> >  > interface IObservableModel {
> >  >    // ask an object for what type it is
> >  >    EClassifier getClassifier(Object obj);
> >  >    EClass getClass(Object obj);
> >  >    EDataType getDataType(Object obj);
> >
> > Note that in general, given a Java object, there isn't necessarily only
> > one EDataType to represent that type of object.
>
> true!
>
> >
> >  >    // setting attributes
> >  >    void set(Object obj, EStructuralFeature feature, Object value);
> >  >    void unset(Object obj, EStructuralFeature feature);
> >
> > This is where I think one of the big differences lie.  When seen as a
> > way of inducing/deducing a view from an underlying model, many if not
> > all of the properties are likely to be derived and hence not editable.
>
> and therefore there is EStructuralFeature.isChangeable()
>
> > Imagine the label of the tree node for a person being the first name and
> > the last name without there being a full name feature in the model...
> >  In that sense, the "model" of the view, is very different from the
> > underlying data model itself.  Things like fonts and colors typically
> > have no meaning in a data model.
>
> ... and with a flexible metamodel it should be possible to add
> "volatile" attributes. The openArchitectureWare metamodel adds
> some artificial attributes to all objects. At the moment, there
> is no way in EMF to access volatile attributes for dynamic models.


Objects either carry data directly or they have associated data.  It's always possible to associate data...

> For example, you have to write your own helper to interpret CQL
> statements that are associated with volatile attributes (at least
> that is what I remember you told me at eclipsecon). But like
> in openArchitectureWare it should be possible to allow extensions
> to weave in additional attributes. Code that might get generated
> but is not available in dynamic models. Like the OAW team, and
> many others, I have created my own engine to deal with dynamically
> calculated attributes. I wish there was a general mechanism...


This is precisely how simple things become complex over time.  Java provides maps for such things...

>
> This weaving could either be done by a dynamic IAdaptable mechanism
> or in a aspect oriented way by changing the metamodel...


EMF's adapters can be used to carry additional state on each instance.

>
> But having a strong annotation model would be key here. As I
> said before annotations don't have to be "physical" annotations
> associated directly with the source of the metamodel. There could
> be an extension point to contribute "annotations" like hybernate
> and eclipselink allow the meta information to come from
> different sources.
>
> Here again, the annotations could also be accessed in the eclipse
> adpter way:
>     AdapterManager.adapt(eStructuralFeature, MyAnnotation.class);


I'm quite sure that EMF Adapter and AdapterFactory would make sense for this.

>
>
>
> >  >    boolean isSet(Object obj, EStructuralFeature feature);
> >
> > If data binding an things like the properties view considered this
> > aspect a little better, stuff like the restore button in the properties
> > view could be disabled when the feature is already in the unset/default
> > state...
>
> ... in my annotation driven UI the EMF implementation of default values
> annoyed me, because unsetting a value does not get back the default
> value (or something strange like this).


Yes, it does. :-P  If eIsSet is false, it should return the default value, and calling eUnset should cause eIsSet to return false.

>
> >  >    
> >  >    // some convenience methods using strings instead of features
> >  >    Object value(Object obj, String feature);
> >  >    void set(Object obj, String feature,Object value);
> >  >    void unset(Object obj, String feature);
> >  >    boolean isSet(Object obj, String feature);
> >
> > Yes, looking up the feature by name.  I can also imagine useful
> > coercions being involved, must like the SDOUtil help methods that would
> > let you set an integer property from a string value...
>
> Yes, and I created my own utility class, like everybody does.
>
> >  >    
> >  >    // methods to needed to create objects
> >  >    EClass getClassByName(String name);
> >
> > Often many different models will use the same name...
>
> I did not specify how the name looks like ;-) Could be
> a full uri... Or there might be multiple IObservableModel
> "Realms" with different name resolutions.


Touche.

>
> >
> >  >    EDataType getDataTypeByName(String name);
> >  >    Object createInstance(EClassifier cl);
> >
> > Typically data type values are not created in this way.  For example,
> > you couldn't just create java.lang.String this way since you can't
> > change it once it exists.
>
> yes therefore there is the EFactory.createFromString(EDataType
> eDataType, String literalValue);
> method:
>     Object createInstance(EClassifier eDataType, String literalValue);
>
> >  >    
> >  >    Object callWithException(Object obj, EOperation operation,
> >  > Object[] args) throws Exception;
> >
> > Ooo.  Like the eInvoke I've always wanted but have never had time to
> > support.  It would be so cool if models could describe behavior in any
> > extensible scripting language...
>
> ...which goes back to the dynamic weaving of features into objects.
>
> >  >
> >  >    Object call(Object obj, EOperation operation, Object[] args);
> >  >    
> >  >    // borrowed from IObservableModel
> >  >     /** Returns the length of the given array */
> >  >    int length(Object array);
> >  >
> >  >    /** Returns the element at the given index of
> >  >    the given array */
> >  >    Object element(Object array, int index);
> >
> > I never did quite understand these...  Multi-vaued features in EMF are
> > lists and can be manipulated directly. Of course that doesn't fit well
> > with this design where observable model controls all data access.
>
> This is a tricky business. And I just copied it from Boris model.
>
>
> >  >
> >  >    // TODO some way to manipulate arrays/lists and maps
> >  >    
> >  >    /** Adds a listener */
> >  >    void addModelChangeListener(IModelChangeListener listener);
> >  >
> >  >    /** Removes a listener */
> >  >    void removeModelChangeListener(IModelChangeListener listener);
> >  > }
> >  >
> >  > Essentially, this class should cover the self manipulation methods
> >  > of EObject (including EList and EMap).
> >
> > You'd have to add effectively the full set of methods you can use with
> > lists, like add, remove, contains...
>
> yes....
>
> >  >  But it would allow to have
> >  > models that do not have a IsA relationship to EObject. As Ed points
> >  > out all the time: we will end up with a metamodel like ecore anyway.
> >  > So, why not starting with ecore as metamodel (instead of Attr)....
> >
> > Hehehehe.  I don't see what Boris is proposing as a general purpose meta
> > model for general purpose data models though...  It's easy to see it
> > that way though...
>
> Neither am I proposing a general purpose metamodel. All I want is a
> unified metamodel that can be used for
> - databinding
> - scripting
> - validation
> - "annotation driven" UI


Of course EMF does all those things, but you want something that unifies all the things not unified by EMF already...  Models that doesn't notify are difficult to unify fully though...

>
> If you look at the example, I don't think it is impossible
> to come up with a good practical solution. The same way
> EMF is a good practical solution for modeling (I am sure
> theoreticians don't like it).


Actually the theoreticians like to call it EMOF and will tend to fret about the lack of CMOF.

>
> >  >
> >  > Obviously, modifications of the ecore (meta)model cannot supported for
> >  > all underlying type systems. I'd like to have a clear separation
> >  > between accessing a metamodel (a kind of read-only access) and
> >  > metamodel manipulation (read-write access). But maybe that's my
> >  > personal opinion (I also hate that there are no interfaces for
> >  > read-only collections, and that java supports them by decorating
> >  > them and then throwing runtime exceptions.....).
> >
> > Architecture always seems to be a comprimise...  Imagine the impact on
> > the class hiearchies to have such a split...
>
> yes that is true... In C++ you can declare methods as const and if
> you get a const object you can only access const methods. This
> essentially splits a class into a read-only and a modifiable
> interface. This has advantages, if you want to maintain integrity
> of objects you give to clients. In java you have to either decorate
> the objects (like the java.util.Collections.unmodifiableXXX methods
> which do a runtime protection of your classes but do not help
> at compile time) or you create two interfaces (one for modifications
> and one for read-only access). But creating those two interfaces is
> pretty tricky (especially in java 1.4). In java 5 you can override
> return types:
>
>     public interface UnmodifiableIterator<E> {
>          boolean hasNext();
>          E next();
>          // no remove method
>      }
>      interface UnmodifiableCollection<E> {
>          int size();
>          // the client cannot remove anything from the list!
>          UnmodifiableIterator<E> iterator();
>      }
>      interface Iterator<E> extends UnmodifiableIterator<E> {
>          // this modifies the inderlyinglist
>          void remove();
>      }
>      interface Collection<E> extends UnmodifiableCollection<E> {
>          boolean add(E o);
>          boolean remove(Object o);
>          // and a modifiable list overrides the iterator
>          // returning a modifiable iterator
>          Iterator<E> iterator();
>      }
>
> This is actually better than the C++ solution, because depending
> on the kind of collection you get, the unmodifiable list or
> the unmodifiable list. To be really on the safe side, you'd
> still have to use unmodifiable decorators, because else a
> user could cast you class
>      UnmodifiableCollection ucoll=...;
>      if(ucoll instanceof Collection)
>           Collection coll=(Collection)ucoll;


YOu really should have had a long chat with the Java folks.  of course at the time, they did the initial, convariant return types weren't supported.  As always, the things that start out simple become more complex...  I still remember the excellent reasons (simplicity being key) for not including enumerations in Java...

>
> >  >
> >  > In a world like this it also makes no sense that the ecore classes
> >  > (EModelElement, EClass, EFeature etc) extend EObject.... If you
> >  > want to introspect EClass you'd use IObservableModel...
> >
> > An Ecore model is just a model as well as being the meta model for other
> > models. so a world where it's not sensible is an odd world for me.
>
> ...well because in your world *everything* is a model. I mean
> it *IsA* model (the GPL like viral aspect). In my
> world it can be seen as a model even it it is not a EMF model....


I have more of a Borg world model. :-P  Someone resists, I just I inject their data with EMF nanobots to help assimilate it.

> I am a big fan of minimal interfaces. Don't expose implementation
> details to your client.


There's a lot to be said for that.  Of course the extent to which I've enabled EMF's clients to have their way with EMF often limits me, but I suspect that's also been one of the keys to success.

> Making models IsA EObject exposes
> implementation details to the client that are really hard
> to change later.


True.  It's good to have gotten it right the first time.

> And for most clients it does not matter if
> the object IsA EObject.


Not really true.  You can make unifying assumptions as a result.  A how whack of infrastructure has been built on being able to have this unifying assumption.

> The users of a ecore metamodel don't
> need to know that it IsA EObject. Like what is the meaning
> of eResource() in case of a java-reflection based metamodel?


Now we're getting into REST...  EMF definitely helps to impose a Borg-like world view where everything functions as a part of the collective...

>
>
> Michael
> _______________________________________________
> eclipse-incubator-e4-dev mailing list
> eclipse-incubator-e4-dev@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/eclipse-incubator-e4-dev


Back to the top