Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 318489 - Interface in EPackage with Classes with validation produces uncompilable ValidationClass
Summary: Interface in EPackage with Classes with validation produces uncompilable Vali...
Status: RESOLVED WORKSFORME
Alias: None
Product: EMF
Classification: Modeling
Component: Core (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Ed Merks CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-06-30 11:43 EDT by Axel Uhl CLA
Modified: 2010-07-05 09:11 EDT (History)
1 user (show)

See Also:


Attachments
Project reproducing the problem (26.89 KB, application/x-zip)
2010-07-04 11:50 EDT, Axel Uhl CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Axel Uhl CLA 2010-06-30 11:43:03 EDT
Build Identifier: 20100527-0614

For an EPackage, a ValidationClass is generated when there is at least one class inside that has a validation rule specified. However, when a validation class is generated, all classifiers including interfaces are used to generate validation methods for each of them. For interfaces this produces uncompilable code because the interfaces don't extend EObject but a call to EObjectValidator.validate_EveryDefaultConstraint is generated.

Workaround: put interfaces in a separate package that does not contain any classes with validation methods

Reproducible: Always

Steps to Reproduce:
1. create an Ecore model with an EPackage with an interface and a class
2. add an operation to the class, with an EBoolean operation taking an EDiagnosticChain and an EMap<EJavaObject, EJavaObject> argument
3. generate model code and try to compile the generated validator class
Comment 1 Ed Merks CLA 2010-07-01 10:20:51 EDT
I'm getting

  public boolean validateA(Serializable a, DiagnosticChain diagnostics, Map<Object, Object> context)
  {
    return validate_EveryDefaultConstraint((EObject)a, diagnostics, context);
  }

I.e., the instance is cast to EObject.

Please attach a test case rather than a description of how to produce one.

Note that I'm testing with EMF 2.6.
Comment 2 Axel Uhl CLA 2010-07-04 11:50:10 EDT
Created attachment 173374 [details]
Project reproducing the problem

I assume the problem originates from a specific set-up of a class in the OCL.ecore model: Visitor. It is configured as an interface, its generated version does for some reason not extend EObject.
Comment 3 Ed Merks CLA 2010-07-04 12:05:19 EDT
The generator expects Visitor to extend EObject (it's a generated interface and it's GenModel specifies EObject as the Root Extends Interface) but the actual source code blocks merging so that's not actually the case.
Comment 4 Ed Merks CLA 2010-07-04 12:56:01 EDT
Of course a simple workaround is to specialize the generated code like this.

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated not
     */
    public boolean validateB(B<?, ?, ?, ?, ?, ?, ?, ?, ?, ?> b, DiagnosticChain diagnostics, Map<Object, Object> context) {
        return validate_EveryDefaultConstraint((EObject)b, diagnostics, context);
    }
Comment 5 Axel Uhl CLA 2010-07-04 16:15:48 EDT
When a package only contains interfaces, no validator seems to be generated at all. I was wondering why validation code is generated into the validator for interfaces if they appear in a package also containing non-interface classes.
Comment 6 Ed Merks CLA 2010-07-05 09:11:01 EDT
When there is at least one constraint on at least one of the classes (even pure interfaces can have constraints) a validator that covers all classes in the package is generated. This generated validator "overrides" the default validator (EObjectValidator) that's otherwise used and otherwise covers all classes in the package.