Closed eclipse-ocl-bot closed 1 month ago
By Ed Willink on Apr 23, 2011 05:57
(In reply to comment #0)
Proposed solution: look for a detail on the delegate annotation that turns "hidden opposites" on.
Presuming you mean an EPackage annotation detail.\
For a holistic solution, this should also be settable by the OCLinEcore editors.
There already is default capability for any EAnnotation.
However OCL annotations deserve a first class syntax. Possibly
package xxx\ {\ options {\ environmentFactory = '...';\ }
The options should perhaps support any Parsing/Evaluation option.
It is probably worth considering how options are communicated to the CDO server as part of this activity. The same solution may suit both requirements.
We need to be clear that there are three levels of options resolution.
a) the default built-in settings\ b) the overrides embedded within EPackage EAnnotations\ c) the overrides programmatically inserted in an Environment
By Axel Uhl on Apr 23, 2011 11:04
Created attachment 193957 (attachment deleted)\
Introduces hiddenOpposites detail on OCL package annotation
Allows the use of hiddenOpposites=true annotation detail in the OCL package annotation. This is now evaluated by the OCLDelegateDomain constructor, and the EcoreEnvironmentFactoryWithHiddenOpposites is used if it's set.
Contains corresponding test case, required extension of the HiddenOpposites test model as well as a bit of documentation.
It currently only supports the use of the DefaultOppositeEndFinder as the opposite end finder can't be configured. The issue is that even if we'd allow for the specification of a fully-qualified class name, class path issues could thwart the easy creation of the opposite end finder class if outside of the OCL bundle (which it usually would be if it isn't the DefaultOppositeEndFinder). I'll open a bugzilla for that, depending on this one.
By Ed Willink on Apr 23, 2011 11:46
(In reply to comment #2)
It currently only supports the use of the DefaultOppositeEndFinder as the opposite end finder can't be configured. The issue is that even if we'd allow for the specification of a fully-qualified class name, class path issues could thwart the easy creation of the opposite end finder class if outside of the OCL bundle (which it usually would be if it isn't the DefaultOppositeEndFinder). I'll open a bugzilla for that, depending on this one.
grep the EMF code, particularly the validation delegate dispatcher for ClassLoader. There's some strange code that makes sure that the user's class loader is in use. This may be what's needed to use the plugin of the Ecore.
(Not a separate Bugzilla; a necessary part of this one.)
By Axel Uhl on Apr 23, 2011 15:22
Do you mean
./org.eclipse.emf.ecore.xmi/src/org/eclipse/emf/ecore/xmi/impl/XMLHandler.java:2502: Class<?> javaClass = Class.forName(className, true, Thread.currentThread().getContextClassLoader());
? This looks as if it depended on the thread currently invoking some piece of code. How can we know that the desired OppositeEndFinder is in scope for any of the class loaders "accidentally" triggering the delegate domain constructor?
By Ed Willink on Apr 24, 2011 01:36
No. I was thinking of EObjectValidator line 334
return\
new DynamicEClassValidator()\
{\
// Ensure that the class loader for this class will be used downstream.\
//\
}.validate(eClass, eObject, diagnostics, context);
Both snippets may help solve the following:
The annotation will reference a class from an Ecore file, that, in an Eclipse environment, forms part of a plugin that has a class path. That class path can be required to include the target path, so it is just necessary to access the class from a class loader for the plugin.
For standalone usage, the standalone application must provide access to the class on its own class path.
By Axel Uhl on Apr 24, 2011 04:45
(In reply to comment #5)\ We may be able to determine the class loader that loads classes for an Ecore model. It is certainly ok that an Ecore model that makes use of hidden opposites specifies so in its OCL annotation. However, it feels wrong to fix the OppositeEndFinder class by an annotation in the package. This choice should be "injected" by the using environment.
Ideally, the client of the Ecore that uses hidden opposites would be able to specify the OppositeEndFinder to use. However, other than by a heavy-weight and global extension point (which would also cleanly solve the class loading issue) I'm not aware of a good, reliable way for performing such an injection. Having the client explicitly invoke some setter for the OppositeEndFinder raises the question of synchronization and the right point in time for calling such a setter.
Ideas?
By Ed Willink on Apr 24, 2011 15:36
My initial instinct was to allow the user environment to influence the use of a model, but for different reasons I observed a very similar problem with the pivot model.
EMF delegates are a service required by and declared by an Ecore model. Using an editing domain, the Ecore model may be shared by many applications, therefore the shared service should be independent of each application, else one application can disrupt the behaviour of another.
So since the Ecore model declares the service, only the Ecore model can parameterize that declaration and the Ecore model provides the context for resolution of that parameterization.
By Axel Uhl on Apr 24, 2011 17:18
(In reply to comment #7)
So since the Ecore model declares the service, only the Ecore model can parameterize that declaration and the Ecore model provides the context for resolution of that parameterization.
Another way to view it is this: an Ecore model provides the structural declarations. It depends on a specific application how these declarations are rendered in a persistence service (CDO, file system storage as XMI, ...), and the Ecore model/plugin doesn't and shouldn't know. The Ecore model does not specify from where its instance models can be loaded. Also, query2 scope definitions are independent of what the Ecore model specifies. I see the opposite end finder as a related mechanism that should be independent of the Ecore model's definitions. The Ecore model should only have to specify that it does use hidden opposites, not how they have to be resolved scope-wise.
By Ed Willink on Apr 25, 2011 03:26
Yes. Every interesting problem in software engineeering can be solved by an extra level of indirection.
But exactly what is the intermediate? Call it a "key" that identifies a "handler" for now.
Keys are defined:
Handlers are requested by an Ecore model by listing required keys.
Applications may specifically override the key response by programmatically specifying a higher priority handler.
Tool suites may generically override the key response by specifying an extension point with a higher priority handler.
So what is a key? Do we need this new terminology or is an extension point id directly reusable as a key?
Prioritised extension points seem the solution. So the Ecore model just specifies to activate the highest priority registration for a facility identified by an extension point, that can have a facility-specific schema to define whatever is appropriate.
This is now nothing to do with OCL; just an ability for an Ecore model to trigger extension points during loading. Check the existing EMF load capabilities; there are a lot of facilities already that few users are aware of. Perhaps there's something similar.
By Axel Uhl on Apr 25, 2011 04:50
(In reply to comment #9)\ Extension points are one way. They are global in the sense that they require the participating bundles to be singletons. A pretty heavy-weight approach and not really context-sensitive.
How about using DefaultOppositeEndFinder by default unless a specific ThreadLocal has been set by the thread calling the delegate? Not completely thought through. One problem seems to be that currently the OppositeEndFinder is fixed by a triple of EcoreEnvironmentFactory/EcoreEvaluationEnvironment/EcoreEnvironment. And this in turn is attached to one OCL which is attached to one OCLDelegateDomain which for one delegate URI is probably unique for the EMF/Ecore bundle and hence presumably even unique for the VM (singleton). If a ThreadLocal is only used for initializing the OCLDelegateDomain, this could again cause trouble due to unclear timing and multiple clients.
With this, there currently doesn't seem any better way than setting an opposite end finder for the OCLDelegateDomain for all clients of the respective Ecore. Not nice, but I currently don't see a better way. I sure could add an extension point for this, but I'm scared by
If we attach the OppositeEndFinder implementation class to use to the Ecore model then I think it's just fair to demand a bundle dependency from the this Ecore bundle to the bundle holding the OppositeEndFinder implementation specified. So it should suffice using the Ecore model bundle's class loader for loading the OppositeEndFinder class. I'll look at this option tomorrow.
By Axel Uhl on May 02, 2011 06:01
Created attachment 194473 (attachment deleted)\
Allows clients to choose opposite end finder class
As discussed, choosing an opposite end finder implementation is necessary. With this patch, any opposite end finder class in scope for the using Ecore package can be loaded by providing an additional key in the annotation.
By Ed Willink on May 03, 2011 15:40
Since you're 'editing' this can you prepare a 'test' for DocumentationExamples to validate the Java source text.
Your extra paragraph would look better with a Sample Ecore Editor snapshot showing the result, with text that provides clarifying detail, probably in 'bullet' form:
I see no need for yet another constructor, particularly one that should be deprecated. 3 was already too many.
I think a custom EnvironmentFactory class is much more useful than a custom OppositeEndFinder class.
Seems to me the algorithm should be
Choose either EPackage.Registry.INSTANCE or resourceSet.getPackageRegistry() as the package registry.\ Then call createEnvironmentFactory(ePackage, packageRegistry) where
if there is a custom environment factory annotation use it to create a custom environment factory\ (which can process standard and/or custom annotations)\ otherwise if there is a hidden opposites annotation create a EcoreEnvironmentFactoryWithHiddenOpposites\ otherwise create a EcoreEnvironmentFactory
I think EMF has a WrappedException that is slightly better than RuntimeException.
By Axel Uhl on May 03, 2011 16:53
Created attachment 194650 (attachment deleted)\
Configurable environment factory, too
Better?
By Ed Willink on May 06, 2011 09:24
Created attachment 194930 (attachment deleted)\
Simplified patch without opposite finder class
I've simplified the logic.
It seems enough to have three cases:\ a) environmentFactoryClass - user gets substantial conrtrol to change all sorts of things including opposites\ b) hiddenOpposites - declarative behaviour change\ c) traditional default
the extra opposite class is unnecessary. If opposites need customisation then use the factory.
I've also fixed an NPE on a null resource that I'm sure I'd fixed, but maybe only on the pivot.
I've tweaked the docunmentation, and deleted an obsolete test; you might want to check it.
By Ed Willink on May 06, 2011 09:25
Created attachment 194932 additional binary file for 194930
put this in same directory as abstractSyntax.html
abstractSyntax_hiddenOpposites.png
By Axel Uhl on May 10, 2011 12:03
Created attachment 195238 Removed commented test case
Remove the commented test case; use a LocalDefaultOppositeEndFinder to ensure and document that / how it is possible to use a specific OppositeEndFinder implementation by providing an own factory. Tweaked existing test case to ensure that this opposite end finder is actually used.
:notepad_spiral: 343684.patch
By Ed Willink on May 10, 2011 13:43
+1
By Axel Uhl on May 10, 2011 17:20
Committed to CVS HEAD for RC1
By Ed Willink on May 29, 2012 13:23
Closing all bugs resolved in Indigo.
| --- | --- | | Bugzilla Link | 343684 | | Status | CLOSED FIXED | | Importance | P3 normal | | Reported | Apr 23, 2011 05:41 EDT | | Modified | May 29, 2012 13:23 EDT | | Version | 3.1.0 | | Reporter | Axel Uhl |
Description
Currently, OCLDelegateDomain's constructor fixes the factory class used to EcoreEnvironmentFactory. This makes it impossible to use the new hidden opposites functionality in any delegate.
Proposed solution: look for a detail on the delegate annotation that turns "hidden opposites" on.
For a holistic solution, this should also be settable by the OCLinEcore editors.