eclipse / epsilon

Epsilon is a family of Java-based scripting languages for automating common model-based software engineering tasks, such as code generation, model-to-model transformation and model validation, that work out of the box with EMF (including Xtext and Sirius), UML (including Cameo/MagicDraw), Simulink, XML and other types of models.
https://eclipse.org/epsilon
Eclipse Public License 2.0
55 stars 11 forks source link

Adds PlainXMLOperationContributor to access to internal XM methods #9

Closed arcanefoam closed 1 year ago

arcanefoam commented 1 year ago

The issue with tagName access(#5) was a sign of a bigger issue as reported in #6.

I propose the following fix, which applies specifically to the XML diver, but perhaps can be extended to the JavaPropertyGetter and ReflectionUtil:

  1. Find the method as currently done via ReflectionUtil.
  2. If the method is accesible, execute it.
  3. If not, try to find the method declaration in an implemented interface. This assumes that the interface will be public and not internal.
  4. If the method is accesible, execute it.
  5. If still not accesible, throw exception.

Some of the methods in ReflectionUtil that are private where copied into PlainXMLOperationContributor, we could reduce duplication by making them public+static (was not sure about any restrictions).

Adds tests for accessing a method via this way (and for the tagName attribute from #5).

kolovos commented 1 year ago

Thanks Horacio. The proposed fix looks reasonable to me at first glance. It would also be worth trying @jgsuess's suggestion, in case [Statement.execute()](https://docs.oracle.com/javase/7/docs/api/java/beans/Statement.html#execute()) is already smart enough to do this.

arcanefoam commented 1 year ago

Since I am using the latest interim version I guess the changes for fixing the varargs issue does not resolve the access problem. Finding the method for the correct arguments assumes the list of available methods has already been computed. What his fix does is change how the list of methods is found: class.getMethods()/getDeclaredMethods() vs. looking for the methods in the interfaces. The fundamental difference is that, hopefully, the interface class is not internal and the method would be accessible.

arcanefoam commented 1 year ago

I also have a branch for the website that updates the PlainXML EMC page: PlainXML-page

jgsuess commented 1 year ago

[Statement.execute()](https://docs.oracle.com/javase/7/docs/api/java/beans/Statement.html#execute())

should choose the most specific method using the algorithm specified in the Java Language Specification (15.11).

as per it's own spec. If the Java team does not get dynamic dispatch resolution right, who would?

Stand on the shoulders of giants. Best view.

arcanefoam commented 1 year ago

As I understand, dynamic dispatch is about selecting which implementation of a polymorphic operation to call based on the runtime parameter's types. This assumes that for a method with a given name, there exist different implementations.

The issue with the XML driver is what happens after the appropriate method is found. In particular, the list of candidate methods (i.e. name matches) are found by using the XML runtime class of the model elements. In my tests, this is com.sun.org.apache.xerces.internal.dom.DeferredElementImpl. Hence, the dynamic dispatch founds a method that belongs to the DeferredElementImpl, which is internal and is not accesible.

What my fix does is change how the list of candidate methods is found. Specifically, the methods are found against the model element type's interfaces. In short, DeferredElementImpl exends ElementImpl (still internal), which implements Element, Element, ElementTraversal, TypeInfo. Now, we have org.w3c.dom.Element, which is not internal and hence the candidate methods will be accessible and the specific method will too.

Note that my fix does not change how the dynamic dispatch works.

arcanefoam commented 1 year ago

A fix based on this but with Java 8 support was added by @kolovos with 14d2a3