Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 109472 - [Plan Item] Generated ItemProviderAdapter.collectNewChildDescriptors doesn't recognize dependent models
Summary: [Plan Item] Generated ItemProviderAdapter.collectNewChildDescriptors doesn't ...
Status: VERIFIED FIXED
Alias: None
Product: EMF
Classification: Modeling
Component: Edit (show other bugs)
Version: 2.2   Edit
Hardware: PC Windows XP
: P3 enhancement with 12 votes (vote)
Target Milestone: Past   Edit
Assignee: Dave Steinberg CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 204200
  Show dependency tree
 
Reported: 2005-09-14 02:26 EDT by Eike Stepper CLA
Modified: 2011-06-17 03:48 EDT (History)
16 users (show)

See Also:


Attachments
Changes to generate child creation extenders (223.40 KB, patch)
2008-01-25 11:16 EST, Ed Merks CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Eike Stepper CLA 2005-09-14 02:26:20 EDT
If you have models BASIC and EXTENDED and EXTENDED depends on and derives
classes from BASIC, these derived classes are not collected as children by
BASICs ItemProviderAdapters.

Since EXTENDEDs classes are not known at development time of BASIC there should
be some runtime magic to collect appropriate child classes also in EXTENDED-like
models.
Comment 1 Eike Stepper CLA 2005-09-15 02:56:02 EDT
In general I see two options:

a) Provide a registry (as you mentioned) and an ext-point to populate it.
   I'm not sure if really every class has to be registered. It'd also be
   fine if I could register certain classes that would cause trouble otherwise.

b) Use the local EPackage.Registry of the underlying ResourceSet to reflectively
   determine the set of derived child classes. I believe that all the needed
   things are in place except for the loop that augments the generated set
   of descriptors. 
Comment 2 Koen van Dijken CLA 2006-05-15 13:57:51 EDT
When this is solved, the template for the generated editor has to be adjusted to include something like

factories.add(new ComposedAdapterFactory(		ComposedAdapterFactory.Descriptor.Registry.INSTANCE));

, otherwise the editor will fall back on the ReflectiveItemProvider for children from EXTENDED models.
Comment 3 Ed Merks CLA 2008-01-25 11:16:09 EST
Created attachment 87876 [details]
Changes to generate child creation extenders

Quite a few tricky issues came up, including the need to be able to delegate resource loading to the extenders.  I think this quite complete now...
Comment 4 Dave Steinberg CLA 2008-01-26 18:12:09 EST
Hi Ed,

One thing that was really bothering me as I was looking over this: should we be restricting it to one set of extenders per package like this?  In general, you could define any number of different item provider adapter factories for a single package, in order to visualize the model in different ways.

But this patch allows you only to register an extender against a package URI.  If someone tries to use multiple adapter factories for a single package, they're all forced to pick up the same extenders. I believe this is the first 1-to-1 linkage we've forced between an adapter factory and a package. 

I wonder if it wouldn't be better to have extensible item provider adapter factories register an ID, and then have the extenders register against those IDs, instead. This would allow for more flexibility for people who want to write their own, additional adapter factories.  What do you think?
Comment 5 Dave Steinberg CLA 2008-01-28 10:24:40 EST
Wow. That was the opposite of insightful.

With the existing design, a user could easily write an item provider adapter factory that picks up extenders for an arbitrary ID, just by changing the second argument to the ChildCreationExtenderManager constructor.

So, my suggestion turns into a question: what would you think about changing some names (the "uri" attribute of extender in the extension point, the "namespace" attribute of ChildCreationExtenderManager) to make it sound as flexible as it actually is?  We could even still generate the code to use the URI, if that's the most reasonable default. But, a more Eclipse-like dot-separated ID might make sense, too.

I'm still doing a careful review.  I'll let you know if I find any actual problems. ;)
Comment 6 Dave Steinberg CLA 2008-01-29 13:44:41 EST
I've finished the review.  I found a few problems:

ItemProviderAdapterFactory.javajet
316: In Java 1.4 case, must return Collection, not List (to match what IChildCreationExtender declares). For simplicity, probably should return Collection<?> in Java 5.0, too?

GenPackageImpl.java:
4302: I'm not sure what the last condition is supposed to do, but it's always true since allUsedGenPackagesWithClassifiers will never contain a GenFeature.

plugin.xmljet
58: Generating the extensions should be conditional on GenPackage.isChildCreationExtenders(), but isn't.

childCreationExtenders.exsd 
60: I believe meta.attribute should have a basedOn=":org.eclipse.emf.edit.provider.IChildCreationExtender"
82: should be: &lt;extender (impressively, PDE caught the erroneous trailing &gt;)

Also, a few opportunities for improvement:

ChildCreationExtenderManager.java
139: could collapse two lines:
return getChildCreationExtenders().getDelegateResourceLocators();

ItemProviderAdapterFactory.javajet
402: Consider changing "affected" to "supported" or "extended" in the Javadoc.
407: CreationSwitch looks like an implementation detail to me. Why public?

GenClassImpl.java
1873: getAllCreateChildFeaturesIncludingDelegation() and getCreateChildFeaturesIncludingDelegation() could share a private, static GenFeatureFilter.

GenPackage.java
953: I thihnk getExtendedChildCreationData() really needs some Javadoc, as the return type is quite complicated. How about this:

Returns a nested map structure describing the child creation extensions that this package provides to other packages.
The result maps other packages to their classes that have child creation extension provided by this package.
Each inner map maps from the class to the list of child creation data for these extensions.
Comment 7 Ed Merks CLA 2008-01-29 14:56:35 EST
I changed the logic to

          // It belongs to this package if the delegate feature is from this package,
          // or the class is from this package and either there is no delegate feature or the delegate feature is from some used package.
          //
          if (childCreationData.delegatedFeature != null && childCreationData.delegatedFeature.getGenPackage() == this ||
                childCreationData.createClassifier.getGenPackage() == this && 
                  (childCreationData.delegatedFeature == null || allUsedGenPackagesWithClassifiers.contains(childCreationData.delegatedFeature.getGenPackage())))
          {

the plugin.xmljet logic also needs to be in the plugin.xmljet for the editor project (in case the edit and editor are the same project).

I can't change this:

    getChildCreationExtenders();
    return childCreationExtenders.getDelegateResourceLocators();

because the field actually has a different type (specialized list with extra methods) than the getter returns.

I made the creation switch protected.

For GenClassImpl, I created a private method to which both delegate.

Comment 8 Ed Merks CLA 2008-01-29 16:14:12 EST
The changes have been committed to CVS.
Comment 9 Nick Boldt CLA 2008-01-30 00:04:26 EST
Fix available in HEAD: 2.4.0.I200801292000.