| Summary: | Allow lookup of all subclasses of an EClass on EPackage.Registry | ||
|---|---|---|---|
| Product: | [Modeling] EMF | Reporter: | Axel Uhl <eclipse> |
| Component: | Core | Assignee: | Ed Merks <Ed.Merks> |
| Status: | CLOSED DUPLICATE | QA Contact: | |
| Severity: | enhancement | ||
| Priority: | P3 | CC: | eclipse, stepper |
| Version: | 2.6.0 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Windows XP | ||
| Whiteboard: | |||
|
Description
Axel Uhl
This is brutal stuff. It forces all packages to be initialized. That's just not acceptable behavior in an Eclipse IDE. We do related stuff for child creation extenders, but in this case, packages register their intent to be considered as an extender. Better would be something where a package declares the packages of the classes that its classes extends so that one could limit the packages being considered. This is clearly an enhancement request. I'm curious the use case for this. To the use cases: we're working on an event manager that can be registered with a ResourceSet and manages event filter tree registrations efficiently. This requires some up-front effort when registering a filter in lieu for good performance when a Notification is being processed. In particular, we support one filter type that registers for events on notifiers of a specific EClass or any subclass thereof. Now you could argue that it is possible to ascend the superclass graph when a Notification reaches the event manager and then "explode" the original Notification into one for all superclasses. However, this would put the performance penalty into the performance-critical phase of Notification processing.
Another use case is the ExtentMap used for the OCL allInstances() expression. It needs to figure out for which subclasses to retrieve their instance elements. The current implementation in LazyExtentMap seems pretty broken as it looks only in a single resource (the one containing the context element of the expression under evaluation) and then iterates them to check for type conformance:
for (Iterator<Notifier> iter = EcoreUtil.getAllContents(roots); iter.hasNext();) {
@SuppressWarnings("unchecked")
E next = (E) iter.next();
if (isInstance(cls, next)) {
result.add(next);
}
}
with roots being initialized by
if (context.eResource() != null) {
// the extent is in the resource
roots = context.eResource().getContents();
} else {
// can only search this object tree
roots = Collections.singleton(context);
}
In our implementation of an extent map we use visibility declarations between projects containing EMF content and use a query which retrieves all instances of the class and all its subclasses within the visible scope starting from the context object. The query mechanism we use to implement this (the query2 contribution) requires that we expand the list of subclasses at the moment the query is defined.
The first use case seems to call for something that's demand based. You get a notification, you look at the object, you get its class, then ask the question, does some filter apply. If that question is expensive to answer, you create some type of cache to store the answer for fast lookup. The second use case I don't understand well, but it seems to me you know all the instances and know all the classes of those instances and ought to restrict your sublcass query to those rather than pawing through all things registered in the JVM, including things that might never be part of your OCL context, e.g., you'll pull in every model from WTP. ALso, given things like dynamic packages that could be loaded into the resource set, you're going to need to take more into account than just a static global set of subclasses. I see the point. For the event manager use case we should be able to find a solution along the lines of what you proposed, probably caching superclass hierarchies as classes are seen by the event manager. For the query2 support I've found out that there's also a way to query for subclasses. One additional tricky use-case that I forgot to mention we're still wrestling with. For our OCL impact analysis we're doing all kinds of up-front static analysis of OCL expressions. During one of these analyses we're computing whether two classes have overlapping subclass trees. If not, we can cut of large branches of a computation tree. In our case we now would have to trade the additional cost of loading registered EPackages for the cost of worse up-front analysis or runtime cost during handling individual Notifications which we're really trying to avoid. Is there any way to get notified when an EPackage is loaded so that we at least can invalidate and repeat our up-front analysis at this point? Is there a way to find out which EPackages have already been loaded so as to at least scan those without triggering the load of additional bundles? Is there any way to get a notification when in the dynamic case that you mentioned a new subclass to an existing class is introduced? Probably not. Thanks and best, -- Axel Hi Axel, I thought that I submitted a request for "package loaded notification" long ago but I could not find it. May have been a private discussion with Ed. I see one solution to this problem, but it only works if running in OSGi, and I'm sure it's not ideal in all situations: Listen to the extension registry for new contributions to the org.eclipse.emf.ecore.generated_package extension point (be prepared that the package registry can be modified after your listener is called, depending on the order of listeners that you can not influence). If the new contribution is still represented by a package descriptor, replace this descriptor with one that emits the desired notification. And save me from Ed's revenge for poisoning one more fountain :P Cheers /Eike I'll mark this as a duplicate of the registry listener request to which Eike refers. *** This bug has been marked as a duplicate of bug 273989 *** |