[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[news.eclipse.tools.emf] Re: dynamic extension of model

Prasad,

You can actually do eGet and eSet directly with open content features (features from a document root and not actually from the class itself) and that will end up using the underlying feature map. So it's more like you want to create normal properties just like what's in the document root, but applied to your actual object being edited and thereby getting and setting them will access the underlying feature map corresponding to the anyAttribute; I've never tried to do this, so I don't know what if any problems you'll encounter.


exquisitus wrote:
hi Ed,

I have gotten to this point ..
>From each of the external model I have, I retrieve the global properties and
adding them to the base model's element's properties.
for(ModelInfo mi: externalModels.getModels()){
    ItemProviderAdapter ipa = mi.getDocumentRoot();
    List<IItemPropertyDescriptor> pds = ipa.getPropertyDescriptors("Dummy
String");
    base_model_properties.addAll(pds);
}

but, my problem is, doing this way, I am not using the "AnyAttribute"
feature. In case of elements, I am adding the extra elements to the Any
feature as feature map entries.

My question is, how do use the AnyAttribute feature of my base models
elements ?


Thank you
Prasad




"Ed Merks" <merks@xxxxxxxxxx> wrote in message
news:f7jml4$8l6$1@xxxxxxxxxxxxxxxxx...
Prasad,

This is the trickiest issue of all I think.  You'd need to create property
descriptors for all the properties that correspond to attribute-based
features of the document root of the "extending" packages, i.e., packages
with namespace that match the anyAttribute wildcards namespace.   If you
look at the DocumentRoot's item provider, it will have
addAbcPropertyDescriptor for the global attributes of that namespace, so
you'll want item property descriptors much like these, but for the object
with the wildcard that supports these.  (It's late, so I haven't given this
much thought.)


exquisitus wrote:
Hi Ed,
If you can recall, this is what I am trying to achieve.
My base_model allows for Any and AnyAttributes at various points in my base
schema.
At runtime, we know if there are other models available.
If there are other models available, at a given point in the base model, we
need to say, "add these elements from this model A, B etc" and "add these
attributes from model A, B etc" . To The end user it should be transparent.
Ie, when the user right clicks on the tree node, the children should be the
collection of what came from the basemodel and those that got added later.
Same case with the attributes.
To this end, I did the following code [ to add the extrernal model elements
to the base model ].
CommandParameter cmdParam = new
CommandParameter(null,any,FeatureMapUtil.createEntry(other_model_elements_ES
tructuralFeature, other_model_elements_instance_object));
Here, any is got from:
EStructuralFeature any = eObj.eClass().getEStructuralFeature("any");
And, I add this param to the list of cmdParams of the base model's ...
... newChildDescriptors.add(cmdParam);

Doing this and some other supporting code, got me to the point that, I am
able to see the other model element listed as One of the children for the
base models element.
Is this the right thing to do ?
But, when it comes to the properties, I don't know how to achieve similar
thing .
Can you provide any hints ?
Thanks
Prasad





"Ed Merks" <merks@xxxxxxxxxx> wrote in message
news:<f73pve$unp$1@xxxxxxxxxxxxxxxxx>...
  
Prasad,

Ah, I didn't pay attention to the @cisco.com... More comments below...


exquisitus wrote:
    
Thanks for the reply.

yes, we are using the
new
ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.IN
STANCE) That is helping to the extent of reaching out to the correct
edit-model for getting text strings ..

But, during a call to the 'getCreateChildText(Object, Object,
Object, Collection<?>)' on the base model's provider with an object
representing the other model's entity [ because it was bundled into
the base models featuremap ..] , the base model's resource locator [
the edit plugin ] is asked to get the child text. And, it fails to
get it and the call goes into the EMFPlugin's
delegatedGetString(String,
boolean) method.
      
I see. We haven't had time to address
https://bugs.eclipse.org/bugs/show_bug.cgi?id=109472 so we've not
encountered this yet.
    
That is the reason we changed the generated edit plugin to add the
other models' edit plug ins as the other resource locators ...
In a diffrent thread you hinted to my colleague that such a thing is
better achevied as an extension point.. We will figure out how to do
it, but , in the meantime , I have the following hack in my base
model's edit plugin ...

public void addResourceLocator(ResourceLocator rl){
for(int i=0; i<delegateResourceLocators.length;i++){
ResourceLocator resLoc = delegateResourceLocators[i];
if(resLoc == null){
delegateResourceLocators[i] = rl;
break;
}
}
}

And, after the intial startup of the tool, there will be calls to
this method for each of those other models. .....

During this work I have the following technical issues. Appreciate
any help.

1) I have a plug-in , let us call it, 'ExtensionsHandler' which
takes care of maintaining the model extension mapping [ which model
elemnet wants which other elements .. etc ].
This code needs to be able to do the following:
A) figure out what other [apart from my base model] emf models are
available in the installation.
[This I figured out by using the following code]
Platform.getExtensionRegistry().getExtensionPoint("org.eclipse.emf.e
core.generated_package").getExtensions();
      
This information is effectively available void
EPackage.Registry.INSTANCE. Given an EPackage's nsURI, you'll be able
to fetch the EPackage from this map. Be careful that you don't just
iterate over the map and fetch everything, this that would effectively
activate every plugin with an EMF model which in a large installation
with many extensions could be expensive.
    
edits =
Platform.getExtensionRegistry().getExtensionPoint("org.eclipse.emf.e
dit.itemProviderAdapterFactories").getExtensions();
      
This information is used to populated
ComposedAdapterFactory.Descriptor.Registry.INSTANCE. It's probably
useful to set a breakpoint in the getDescriptor method and watch how
it gets called.
    
B) somehow Load each of those packages and edit plug ins knowing
them only by their [ uris, names]
      
EPackage.Registry.INSTANCE.getEPackage(<nsURI>) should do the trick.
    
C) get a handle to the edit plugins and register them with the base
models 'delegeatedResourceLocators' ..
      
Hmmm... If you can adapt an instance of a class from that package
using the composed adapter factory that adapter will be a
ResourceLocator; this seems kind of kludgy but is the first thing that
pops to mind at this late hour.
    
etc ..

I tried the Class.forName("genearated_package_class_name') , but it
failed with ClassNotFound ...

so, how does my plug-in get to access classes it does not know at
compile time ? I am sure this is a classpath issue, but, how do I
add the external models to my tool's classpath ?
      
Generally you'd need to use
    
Platform.getBundle("a.b.c").loadClass("x.y.Z").
  
If my plug-in exposes an extension and if I get the other model's
extend this extension, then, at runtime, can my plug-in say, '''' I
know there are some models out there extending my extension point,
load all of them ''' or something to that effect ??

In general what is the solution for this scenario ?
      
Hopefully these hints will help. Sorry that we've not been able to
address these kinds of issues in the base framework to date. :-(
    
Thanks
Prasad


"Ed Merks" <merks@xxxxxxxxxx> wrote in message
news:f73crh$e85$1@xxxxxxxxxxxxxxxxx...
Prasad,

The information I gave in the last answer is pretty much all I can
provide at this point. Additional comments below.


exquisitus wrote:
hi,
we have a similar need in my tool..

We have a base model (based on xml schema) which has "any" and
"anyattributes" at various places in the model.
Such things, unless namespace constrained, effectively allow any
element or any attribute to appear, i.e., any feature of any
DocumentRoot of any other model. So it's awfully open ended to
provide a good API for such things.

We have a tool using the generated emf code from this schema and the
new dynamic forms, data binding etc .....

The extension use case is this:
The tool is given to various clients. A client may have other emf
models, let us say, model A, model B etc.
The user expresses what extenison he needs at what point. For
example,
BaseModel.Element1 ---> modelA.elemnt1, modelB.element3,
BaseModel.Element2 ---> modelA.AttributeB, modelA.elemnt3,
modelB.element10 etc ....

so, the tool has the base model , other emf models and the knowledge
of what extension is needed at what place.
I see. That provides better constraints...


The tool now needs to reach out to the other models and pull in the
other entities into the base model. For example, when we need to
show the children of an element A in the base model, it should also
show the children from other models. The forms that are generated
should also present the elements and attributes from the other models
      
too.
  
What is the right way to solve this problem ? I did some
implementation with the following logic:
/** in the item providers of my model entities */ protected void
collectNewChildDescriptors(Collection<Object>
newChildDescriptors, Object object) {
ExtensionsManager.instance().collectNewChildDescriptors(newChildDesc
riptors,
object);
..... the generated code goes here
}
The ExtensionsManager will figure out what other model elements are
set to contribute to this item and adds CommandParameters to the Any
feature map of this item.
Currently I am adding the plugin instances of the other models to my
base edit plugins delegatedResourceLocators ..
Have you tried the approach of using "new

      
ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE)"
  
to create the adapter factory. This should automatically make the
item providers for the derived class available in the editor.

Is this whole thing on the right path ?
Yes, it sounds like a good path you are on.

Appreciate any pointers.
thanks
Prasad



"Ed Merks" <merks@xxxxxxxxxx> wrote in message
news:f72h89$pst$1@xxxxxxxxxxxxxxxxx...
Niclas,

Doesn't that imply building a new Ecore model whose EClass extends
your Ecore model?

In EMF 2.3, every editor is structured like this, which means that
registered item providers for derived classes not know at the time
the editor was generated will automatically be picked up.


protected void initializeEditingDomain()
{
// Create an adapter factory that yields item providers.
//
adapterFactory = new
ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.IN
STANCE);

What we still don't have is the ability to extend the child creation
menu dynamically:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=109472


Niclas wrote:
Thanks for your answer.
No my problem is a bit different.
I have an editor which was generated from my ecore model, I want to
be able to extend this model without generating new code from the
genmodel. My tought was to define a new extension point in the edit
plugin and load new extensions dynamicaly. Is this possible if I
have mechanism to load new "extension plugins" ?