Java Interface

Contents

Overview

XMF provides an interface to Java that allows Java values to be manipulated alongside XCore elements. Java classes can be referenced by name, instantiated in XMF and the Java fields and methods can be referenced and invoked using the standard XOCL '.' notation. XMF invisibly translates between an XMF representation for data and a Java representation. In addition, XMF allows Java classes to be wrapped with XOCL class definitions. This allows Java classes to be extended with XOCL operation definitions, constraints etc. Finally, XMF implements a meta-object protocol for Java objects that allows you to define what XOCL '.' means on a class-by-class basis. This document provides an overview of the Java interface.

To top.

Referencing a Java Class

You can reference a Java class by name using the xmf operation javaClass:
[1] XMF> xmf.javaClass("java.util.Date");
class java.util.Date
[1] XMF>
The result is an instance of ForeignObject. A foreign object is a wrapper for Java objects. In this case the Java object is the class java.util.Date. The path supplied as the argument should be relative to the Java class path. You can augment the Java class path dynamically using a second argument to javaClass. The second argument is a sequence of directories and JAR files that are added to the class path. For example, if the following class is defined in c:/tmp:
public class Example {

public int i = 100;

public boolean b = true;

public double d = 3.14;

public String s = "a string";

public Example(int i,String s) {
this.i = i;
this.s = s;
}

public int getInt() {
return i;
}

public void setInt(int i) {
this.i = i;
}

public void setInts(int[] is) {
for(int j = 0; j < is.length; j++)
i = i + is[j];
}

public String toString() {
return "Example(" + i + "," + b + "," + d + "," + s + ")";
}

}
Then it can be loaded using:
[1] XMF> xmf.javaClass("Example",Seq{"c:/tmp"});
class Example
[1] XMF>
To top.

Class Instantiation

Once you have a Java class you can instantiate it by applying it to some constructor arguments. So long as the class has a constructor whose argument types match those you supply then the constructor is used to instantiate the class:
[1] XMF> Date := xmf.javaClass("java.util.Date");
<Root>
[1] XMF> Date();
Tue Dec 11 12:29:31 GMT 2007
[1] XMF>
The example above shows the class Data instantiated and returning an instance of Date. If you ask for the type of the new instance it will be an instance of ForeignObject (although see Extending a Java Class below). The Example constructor can be used to create a new object:
[1] XMF> Example := xmf.javaClass("Example",Seq{"c:/tmp"});
<Root>
[1] XMF> Example(-4,"example");
Example(-4,true,3.14,example)
[1] XMF>
To top.

Field Reference

The public fields of a foreign object can be accessed and updated using '.' in the same way as normal XMF objects.

To top.

Method Invocation

Public methods of foreign objects can be called in the same way as normal XMF objects. For example:
[1] XMF> o := Example(-4,"example");
<Root>
[1] XMF> o.getInt();
-4
[1] XMF> o.setInts(Seq{1,2,3});
null
[1] XMF> o;
Example(2,true,3.14,example)
[1] XMF>
To top.

Extending a Java Class

Java classes can be extended by defining an XMF class that wraps them. The XMF class should be an instance of the meta-class JavaClass and should define a JavaDescriptor that links the XMF class with the Java class. Any operations defined by the XMF class are used in preference to the methods defined by the Java class with the same name. Otherwise, the operations augment the interface of the Java class. For example, support we want to extend the class java.util.Date with an operation less(other) that returns a boolean if the receiver is an earlier date than the argument. Defining this operation has the advantage of allowing us to write expressions date1 < date2 between objects. This can be achieve as follows:
import Java;

context Root

// A class that wraps a Java class must be an instance of
// JavaClass...

@Class Date metaclass JavaClass

// A JavaClass must have a Java descriptor that
// defines the Java class it wraps...

JavaDescriptor("java.util.Date")

// Any operations augment the Java methods. The
// Operations can make use of the Java fields and
// Java methods...

@Operation less(other)
if other.isKindOf(Date)
then self.compareTo(other) < 0
else false
end
end
end
To top.

A Java MOP

To top.