Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 330988 - Provide a generic ODA driver implementation for EMF models
Summary: Provide a generic ODA driver implementation for EMF models
Status: VERIFIED FIXED
Alias: None
Product: EMF
Classification: Modeling
Component: Core (show other bugs)
Version: 2.7.0   Edit
Hardware: PC Mac OS X - Carbon (unsup.)
: P3 enhancement (vote)
Target Milestone: M4   Edit
Assignee: Kenn Hussey CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 331143
  Show dependency tree
 
Reported: 2010-11-23 23:47 EST by Kenn Hussey CLA
Modified: 2011-06-10 11:46 EDT (History)
10 users (show)

See Also:
Kenn.Hussey: indigo+
Ed.Merks: review+
Kenn.Hussey: review? (ed)


Attachments
patch for EMF Core (14.98 KB, patch)
2010-11-23 23:51 EST, Kenn Hussey CLA
no flags Details | Diff
patch for MDT OCL (5.64 KB, patch)
2010-11-23 23:52 EST, Kenn Hussey CLA
no flags Details | Diff
initial driver (75.94 KB, application/zip)
2010-11-24 00:16 EST, Kenn Hussey CLA
no flags Details
updated driver (86.20 KB, application/zip)
2010-11-24 22:58 EST, Kenn Hussey CLA
no flags Details
updated patch for EMF Core (15.15 KB, patch)
2010-11-30 21:16 EST, Kenn Hussey CLA
no flags Details | Diff
updated patch for MDT OCL (12.71 KB, patch)
2010-11-30 21:30 EST, Kenn Hussey CLA
no flags Details | Diff
updated driver (103.39 KB, application/zip)
2010-11-30 23:15 EST, Kenn Hussey CLA
no flags Details
updated driver (254.02 KB, application/zip)
2010-12-02 21:39 EST, Kenn Hussey CLA
no flags Details
patch for EMF All feature (791 bytes, patch)
2010-12-02 21:40 EST, Kenn Hussey CLA
no flags Details | Diff
patch for EMF releng (1.33 KB, patch)
2010-12-02 21:45 EST, Kenn Hussey CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Kenn Hussey CLA 2010-11-23 23:47:12 EST
Please provide an "official" ODA driver that can be used to create BIRT reports (for example) based on EMF models. The driver should support user-specified input parameters and ideally be pluggable so that different query languages can be "plugged in".
Comment 1 Kenn Hussey CLA 2010-11-23 23:51:16 EST
Created attachment 183724 [details]
patch for EMF Core

Here is a patch which introduces the concept of a "query delegate" similar to the validation, setting, and invocation delegates which were recently introduced. The idea is that this can be used as a generic interface for creating and executing queries within a given context on target objects without creating a (direct) dependency on the query engine (e.g., MDT OCL) which provide the implementation.
Comment 2 Kenn Hussey CLA 2010-11-23 23:52:02 EST
Created attachment 183725 [details]
patch for MDT OCL

Here's an implementation of a query delegate for OCL queries.
Comment 3 Kenn Hussey CLA 2010-11-24 00:16:20 EST
Created attachment 183726 [details]
initial driver

Here's an initial ODA driver implementation. It is by no means complete, but I am posting is now to give folks a chance to try it out and provide feedback.

This driver leverages the concept of "query delegates" to provide generic data source and data sets that can be used with EMF-based models.

The data source is currently configured with a "delegate" property to specify the query delegate to be used; its value corresponds to the URI used to declare a query delegate implementation. See, for example, the attached MDT OCL patch which provides such an implementation; it is in fact currently used as the default delegate but longer term I'd like to inspect the registry and offer the user a list of choices.

The data set is configured with "context", "type", and "resource" properties to identify its context type, result type, and resource URI, respectively. The first two (along with the query text) are actually enough to drive the data set but specifying a resource provides a way to preview the results (for queries against objects at the root of the resource).

A built in column is provided for data sets (called "@self" for objects and "@value" for data values) so that the current row can be accessed as a whole. The other columns in the result set are based on the features (attributes AND references) of the specified result type.

Note that a "Java Object" wrapper has been used to wrap objects which do not map directly to built-in Ecore data types. To access such values in Javascript, they must first be de-referenced by calling getObject().

Note also that, due to the way BIRT caches report data, reference values (or the value for any column of type Java Object, actually) should not be used directly in reports; instead, computed columns should be defined to contain the desired values. This approach should also be taken to reference values for features that may be defined on subtypes of the specified result type for the data set.

Two built-in query parameters are currently supported, namely @uri and @target. Specifying a value (a string URI) for @uri will result in the corresponding resource being used at runtime instead of the one configured in the data set. Similarly, specifying a value (an object) for @target will cause the query to be executed on that object instead of the default roots of the resource.

The following tasks remain in order to consider this driver minimally complete:

- The target and result values should be checked for conformance against the context and result types defined in the data set.

- Expressions should perhaps be parsed when the query delegate is created instead of at time of execution.

- The result type should perhaps be determined based on the result of parsing the expression rather than having to be specified by the designer.

- Support for user-specified input parameters needs to be more thoroughly tested.

- Better error handling (and messages) needs to be introduced for invalid user input.

- All instances of the result type should be used instead of resource roots when a target object is not passed as a parameter.

- Support should be added for previewing parameterized data sets (e.g., by using expressions to specify default/preview values).
Comment 4 Kenn Hussey CLA 2010-11-24 22:58:18 EST
Created attachment 183818 [details]
updated driver

Here's an updated driver which moves the resource property to the data source (where it more appropriately belongs) and the query delegate property to the data set (where it more appropriately belongs). The data set UI has also been updated with a combo box listing the available query delegates (currently only one, for OCL).

This new version also ensure that target and result objects match the context and result types; in case they don't the objects are excluded (e.g., the result set may be empty). Also, if the @target parameter is not specified, all objects of the specified context type (from all resources) are used as targets. This means that previews are now supported for parameterized data sets.

To try out the changes, check the org.eclipse.emf.ecore and org.eclipse.ocl.ecore projects out of CVS and apply the patches, import the driver projects into your workspace, and launch a runtime workspace to create a data source, data set, and report. Of course, you'll need to have DTP and BIRT installed. I'll try to attach sample reports when time allows.
Comment 5 Ed Willink CLA 2010-11-25 12:35:12 EST
The MDT/OCL additions seem very simple and clearly benign, so I see no problem in incorporating the patch once the EMF patch is committed.

Minor query; the signatures of execute use EList; might not List be better?
Comment 6 Kenn Hussey CLA 2010-11-25 14:25:24 EST
(In reply to comment #5)
> Minor query; the signatures of execute use EList; might not List be better?

Yes, perhaps it would. The only reason I use EList was for consistency with the signature for operation invocation delegates.

Question for you: do you see a problem with moving the expression parsing to the constructor in the interest of "failing fast"? The motivation here is so that queries could be prepared (and validated) in the data set wizard without having to actually execute them (i.e., without having to preview the result set).
Comment 7 Ed Willink CLA 2010-11-25 17:21:48 EST
(In reply to comment #6)
> Question for you: do you see a problem with moving the expression parsing to
> the constructor in the interest of "failing fast"? The motivation here is so
> that queries could be prepared (and validated) in the data set wizard without
> having to actually execute them (i.e., without having to preview the result
> set).

I've not studied the invocation context.

Parsing throws exceptions which seems poor practice for constructors.

Perhaps you want:

construct
prepare-to-execute
can-execute
execute

phases similar to commands.

Random thought: would an OCLCommand be useful?
Comment 8 Kenn Hussey CLA 2010-11-30 21:16:40 EST
Created attachment 184208 [details]
updated patch for EMF Core

This patch applies to the org.eclipse.emf.ecore project.

Updates include the introduction of variables and variable bindings instead of parameter arguments. The idea is that variables can be declared for an expression when the query delegate is created by passing a map of names to types; then, when the query is executed, those variables are bound to values based on the specified map of names to objects.
Comment 9 Kenn Hussey CLA 2010-11-30 21:30:11 EST
Created attachment 184211 [details]
updated patch for MDT OCL

This patch applies to the org.eclipse.ocl.ecore and org.eclipse.ocl.ecore.tests projects.

Updates include changes that correspond to the introduction of variables (declarations and bindings) in the API and the addition of unit tests. Creation of variables and parsing of the expression is done when the delegate is created so that errors are encountered as early as possible in the data set definition process (i.e., when the query is prepared).
Comment 10 Kenn Hussey CLA 2010-11-30 23:15:34 EST
Created attachment 184218 [details]
updated driver

Here's an updated version of the driver implementation which I consider more or less complete, at least for the upcoming M4 milestone.

The data source and data set wizard/property pages have been improved for usability and comments have been added throughout. Changes have been made to leverage the expression variables (declarations and bindings) that are now supported by the query delegate in EMF and OCL; these surface as parameters in the data set.
 
Expressions (and their variables) are now parsed by the query delegate when the query is prepared so that syntax errors, etc., show up immediately in the wizard as the query text is being edited.

I've decided that it's probably best NOT to determine the result type based on the parsed expression since doing so may result in loss of precision, at least in the case of OCL. This is because there are only four primitive types in OCL (String, Integer, Real, and Boolean) whereas Ecore has several more (as does Java).

Requiring that the user specify the result type explicitly actually helps ensure that the expected results are being obtained (otherwise the results set would be empty) and can in fact be used as an additional way to filter results, e.g., if the query returns objects of a more general type and you want to retrieve only objects of a particular subtype, you can specify the more specific subtype as the result type and the result set will only contain objects of that subtype.

User-specified input parameters are automatically defined based on expression variables that have been defined (on the Query page in the wizard). Data sets with such parameters can be previewed if/when such parameters have default values defined.

Error handling is now done in a consistent way; messages are displayed at the top of the wizard page when the user fails to specify a property value (or provides an invalid one).
Comment 11 Ed Merks CLA 2010-12-02 14:21:03 EST
The core parts look good.
Comment 12 Kenn Hussey CLA 2010-12-02 20:25:08 EST
I've committed the changes to EMF Core (i.e., the support for query delegates), after addressing some minor issues identified by Ed (Merks).
Comment 13 Kenn Hussey CLA 2010-12-02 20:30:34 EST
Comment on attachment 184211 [details]
updated patch for MDT OCL

I've attached an updated version of the patch for MDT OCL to bug 331143. Discussions related to support for OCL query delegates should take place there from now on.
Comment 14 Kenn Hussey CLA 2010-12-02 21:39:27 EST
Created attachment 184432 [details]
updated driver

Here's an updated version of the driver which addresses some minor usability issues but which also includes a branding plug-in and feature bundles (in preparation for adding this new functionality to the EMF build).
Comment 15 Kenn Hussey CLA 2010-12-02 21:40:56 EST
Created attachment 184433 [details]
patch for EMF All feature

This patch includes the new ODA SDK feature in the EMF "All" feature (alongside the existing SDKs for EMF and XSD).
Comment 16 Kenn Hussey CLA 2010-12-02 21:45:00 EST
Created attachment 184434 [details]
patch for EMF releng

Here's a patch for the Buckminster releng project, in preparation for adding the new functionality to the EMF build.
Comment 17 Ed Willink CLA 2010-12-03 02:17:08 EST
(In reply to comment #7)
> Perhaps you want:
> 
> construct
> prepare-to-execute
> can-execute
> execute
> 
> phases similar to commands.

This doesn't seem to have been considered. Now that I've had a chance to review the OCL JUnit test, the current structure seems inflexible and unusual.

The OCLQueryDelegate constructor performs parsing and so may have a variety of semantic errors and I/O errors from loading referenced models. These are all hidden in a WrappedException. Surely QueryDelegate.Factory.createQueryDelegate must return these as non-RuntimeExceptions? This could be cured by a throws InvocationTargetException. But...

The OCL parsing costs are unavoidably incurred up front. If a user has many query delegates, there is no opportunity for making these costs lazy; they would have to create their own lazy query delegate delegates. This could be cured by introducing a QueryDelegate.compile() method that could be explicitly called by the user for eager compilation, or lazily called by execute. In either case the exception comes from compile rather than construct.

Please add:

QueryDelegate.compile() throws InvocationTargetException
Comment 18 Kenn Hussey CLA 2010-12-03 09:00:01 EST
(In reply to comment #17)
> This doesn't seem to have been considered. Now that I've had a chance to review
> the OCL JUnit test, the current structure seems inflexible and unusual.

It was considered, but I wanted to remain consistent with the other delegates.

> Please add:
> 
> QueryDelegate.compile() throws InvocationTargetException

OK, but I'd like to call it prepare(). Is that OK with you? Should we also consider moving the parameters and expression arguments to this method, i.e., prepare(Map<String, EClassifier>, String)?
Comment 19 Kenn Hussey CLA 2010-12-03 10:51:46 EST
(In reply to comment #18)
> OK, but I'd like to call it prepare(). Is that OK with you? Should we also
> consider moving the parameters and expression arguments to this method, i.e.,
> prepare(Map<String, EClassifier>, String)?

I've committed changes to EMF core which include the addition of a prepare() method to query delegates which can be used prepare (e.g., parse) a query in advance of execution.
Comment 20 Kenn Hussey CLA 2010-12-06 11:41:33 EST
The changes have been committed to CVS. Further changes will be made against other bugs in future milestones.
Comment 21 Kenn Hussey CLA 2010-12-06 11:42:52 EST
The changes are available in integration build I201012061026.
Comment 22 Miles Parker CLA 2010-12-23 22:29:39 EST
Hi guys,

I'm guessing the dependencies on org.eclipse.emf.common.ui 2.7.0 and of that on org.eclipse.ui 3.7.0 are necessary? I ask because the dependency situation for Indigo is still not that great and I'd like to be able to use the ODA driver w/ 3.6.1..

cheers,

Miles
Comment 23 Ed Willink CLA 2010-12-27 06:55:33 EST
(In reply to comment #22)
> Hi guys,
> 
> I'm guessing the dependencies on org.eclipse.emf.common.ui 2.7.0 and of that on
> org.eclipse.ui 3.7.0 are necessary? I ask because the dependency situation for
> Indigo is still not that great and I'd like to be able to use the ODA driver w/
> 3.6.1..

Sorry. The basic query delegate uses an extension point introduced in EMF 2.7.0M4. The viewer delegate is new in EMF 2.7.0M5. There is nothing else in MDT/OCL that has post Helios dependency. Since the incompatibility is via an extension point you can ignore it, but then you won't get ODA support...
Comment 24 Kenn Hussey CLA 2010-12-29 09:04:13 EST
(In reply to comment #22)
> I'm guessing the dependencies on org.eclipse.emf.common.ui 2.7.0 and of that on
> org.eclipse.ui 3.7.0 are necessary? I ask because the dependency situation for
> Indigo is still not that great and I'd like to be able to use the ODA driver w/
> 3.6.1..

EMF always depends on the versions of things it was built against (even if that requirement is really necessary or not).

Cloudsmith produces a build of EMF against Helios which you might find useful, the latest of which is at http://download.cloudsmith.com/emf4gwt/sdk/I201012222039. Its original purpose was to provide a build of the EMF for GWT tooling which could be used in conjunction with Google's GDT (which doesn't support Indigo), but it happens to contain the ODA stuff too...