EulerGUI Architecture

© Jean-Marc Vanel - $Date: 2012-09-01$ - under Creative Commons License



There is an N3 translation of the bytecode of EulerGUI, made with EulerGUI, that can be used with EulerGUI or other tools to make queries and statistics:



Project is the algorithmic facade. This UML diagram shows its structure:

            sources *
                n3Query |
            searches *

Project has a (partial) publish-subscribe pattern :

void addProjectListener(ProjectListener listener)

It is partial because other events like inference engine launch, add a sub-project, etc, are not published. PENDING Adding a sub-project or a post-processing project raises the issue that the Project object changes and is re-created as a different object and class, which is problematic with observers.

The class Project is too big. We should extract all inference engines bindings, and have an SPI and an API for that.

N3Source is the other central class; it has a sub-class per type of data converted to N3:


N3Source currently has no publish-subscribe pattern.

See below in Refactorings section.


ProjectGUI, the main GUI class, does a bit too much, but it mostly does GUI layout and delegates the application behavior to the XXXManagement classes.


Threads should be used for long operations, mainly inference runs. It also has the advantage to be able to break these operations.

Singleton for the EulerGUI application

We actually need a singleton for the EulerGUI application

EulerGUI <>---- * ProjectGUI<>----N3Source

N3 jEdit editor

TODO explain ?????????????

N3 to Drools translator

Implemented in class DroolsTripleHandler, it leverages on the N3 iterator, class RDFIterator . The Drools code that is generated is described here in the Manual: "Translating N3 into Drools language". The N3 triples that are interpretable as Java calls and instantiations are described below in N3 - Java mapping (embedded Java objects) .

Translation of N3 search into Drools query



N3 to GraphViz translator

It also leverages on the N3 iterator, class RDFIterator .

TODO explain more ?????????????

N3 to JavaScript+Java translator

It also leverages on the N3 iterator, class RDFIterator .

Implemented in class Instanciator class.

The code that is generated is described here in the Manual: "Generate Java code".

It is used in Generated Swing applications .

N3 - Java mapping (embedded Java objects)

This architecture replaced the JavaScript+Java translator used in versions up to 1.8 . It is used in Internal Knowledge Base (the ApplicationKB class), and in the generated Swing applications .

This is made to enable the N3 rule engine to trigger actions on pure Java implementation objects. The main flow of information goes in the direction N3 ==> Java, and consists of creating new Java objects and calling methods or properties on them. However, the reverse direction is possible :

The general idea (compatible with older N3 to JavaScript+Java translator ) is the following. A triple such as this in the antecedent of a rule stands for a test on existence of a Java object of class p.MyClass bound to name ?OBJ :

?OBJ a java:p-MyClass.

The same triple in the consequent of a rule, or as fact triple, stands for the instantiation of a Java object of class p.MyClass bound to ?OBJ , a name, blank node, or URI. In any case, the URI or blank node bound to ?OBJ can be involved in ordinary (non Java) RDF triples. So one has the power to annotate an URI as a Java object, or the converse.

Likewise, a triple like this is interpreted as a property call:

?OBJ javap:myProperty ?PROP .

which is a logical test on the antecedent side, and an actual call on the consequent side or outside of a rule. In the latter case, this actually associates an URI to the return value of the property call.

Here is a complete example outside of a rule (it shows a Swing JFrame with text "Papilio" ) :

_:obj a java:javax-swing-JFrame .
_:obj javap:contentPane _:PANE .
_:LAB a java:javax-swing-JLabel
      ; javam:setText "Papilio" .
_:PANE javam:add _:LAB .

which is equivalent to:

_:obj a java:javax-swing-JFrame .
_:obj javam:getContentPane _:PANE .
_:LAB a java:javax-swing-JLabel
      ; javam:setText "Papilio" .
_:PANE javam:add _:LAB .

where prefix javam: indicates a method call. Here only when the variable in object position is not already bound to a Java instance, and the method has no argument, the return value is assigned to the N3 term. Otherwise, in particular with methods having arguments, bound arguments are used for the method call, e.g. javam:setText just above.

These property or method call patterns also work on the consequent side of a rule . Examples are here: N3 rule javaMappingAccessFieldAsN3Variable.n3 ; project BloodPressure.n3p . See also this page for a commented example and good practices in mixing Java and N3: N3 rules triggering Java .

Deferred Java calls

A triple in a rule consequent like this is always interpreted as a Java method call :

?INST javam:myMethod ( ?ARG1 ?ARG2 ) .

But the nice thing is that you don't have to instantiate ?INST in the same rule.

In the course of the inference, the instantiation of ?INST can happen in another rule, before or after the method call. This is what we call deferred Java calls; it allows for greater flexibility in the way you design mixed Java+N3 rules.

Details of the N3 to Drools translation

We leverage on the capability of Drools engine to host any Java object in the Knowledge Base (called Object Oriented RETE) . So we insert Java application objects in the KB along with business objects, which are implemented by Triple objects). That is, we insert the Java objects in the Knowledge Base (KB) (without passing through a terminal stage of instantiation as in previous architecture N3 to JavaScript+Java translator ).

The Java objects are wrapped in a simple class Assignment, that adds a global name to the Java object. Assignment has two fields: name, a string, and reference, the object itself. The class Assignment is a simple Java bean with this constructor and corresponding properties:

Assignment( String name, Object reference )

The instances of Assignment in the Drools KB are a map of Java objects (the reference field) keyed by N3 terms (the name field).

Assignment objects are introduced into the KB in one of two ways. They can be inserted from the Java API, by method TripleStoreDrools.assign(). Or they can be inserted from an N3 rule, as is detailed below.

The N3 to Drools translation is implemented in class N3JavaMappingBuiltin .


In the following example, let MyClass be any class, in the package p. Below we give the N3 triple, and the Java translation in Drools DRL language in the antecedent and in the consequent.

Class membership:

?OBJ    a java:p-MyClass.
_:OBJ2  a java:p-MyClass.
pf:OBJ3 a java:p-MyClass. # 3
<> a java:p-MyClass. # 4

Translation in the antecedent:

Assignment( name == $OBJ,     reference.class == p.MyClass,
            $OBJ_reference :  reference )
Assignment( name == "_:OBJ2", reference.class == p.MyClass,
            $OBJ2_reference : reference )
Assignment( name == "<>",
            reference.class == p.MyClass,
            $OBJ3_reference :  reference )


Translation in the consequent or in plain triples :

$OBJ_reference = new p.MyClass();
insert(new Assignment($OBJ,     $OBJ_reference ));
insert(new Assignment("_:OBJ2", $OBJ_reference ));
insert(new Assignment("<>", $OBJ_reference ));

NOTE: we will implement OBJ2 first. We have no use case (yet?) for a Java object being associated to an URI; this object would be potentially visible from the Internet.

Method or property call:

?OBJ  java:myProperty ?PROP .

Translation in the antecedent

Assignment( $OBJ : name, reference.class == p.MyClass, $OBJ_reference : reference )
p.MyClass( $PROP : myProperty, this == $OBJ_reference )

Note that method call not recommended in the antecedent, because of potential side effects, but property is OK.

Translation in the consequent or in plain triples :

DeferredPropertyAssignment dpa_OBJ3 = new DeferredPropertyAssignment();
dpa_OBJ3.setSubject( OBJ.toString() );
dpa_OBJ3.setPredicate( "<>" );
dpa_OBJ3.setObject( $PROP );


- Casting will also occur on argument, even when it is of primitive type.

- The normal case is when been referred to as a Java object in the antecedent side. In this case the class name, e.g. p.MyClass , will be obtained from the method

DroolsTripleHandler.javaTypeFromN3Variable(String var)

Java object coming from another rule

The issue that this solves is this: in several occasions an RDF Id is assigned Java properties before it is assigned a Java type (see above "Java object coming from another rule" ).

A special case is when ?OBJ has not been referred to as a Java object in the antecedent or consequent side. In this case there are several designs.

The solution is a runtime mechanism. A new Java infrastructure class DeferredPropertyAssignment keeps track of the property assignments and method calls, in cases like this . Then, when later (or before as the rule firing order is unpredictable) the Java type gets known from an object creation triple, the Java call can actually be made.

There are a Drools rules that says: "when there is a deferred property assignment ?X ?P ?V , and ?X is a Java object, then apply the property assignment and delete the deferred property assignment". These rules allow to wait until calling object and arguments (if not literal) have all been assigned a Java object.


Here is the rule in Drools language (infrastructure-rules.drl); this could not be expressed in N3. This is an "under the hood rule", that will be added to every rule base.

rule "DeferredPropertyAssignment literal argument"
  $DPA : DeferredPropertyAssignment( $S : subject, $O : object )
  $A : Assignment( name == $S )
  eval( eulergui.util.N3TermHelper.isLiteral($O) ) )
  $DPA.assign( $A );
  retract( $DPA );

rule "DeferredPropertyAssignment object argument"
  $DPA : DeferredPropertyAssignment( $S : subject, $O : object )
  $A : Assignment( name == $S )
  $ARG : Assignment( name == $O )
  $DPA.assign( $A, $ARG );
  retract( $DPA );


The feature is implemented, and it is activated in the user Drools runs ( the Swing rules for form generation worked with very few modifications ).

In the API, the feature is activable with this method in class Project :

setJavaObjectsInDrools( boolean jod )

It is activated in the internal rule engine.

In know exactly what is implemented and works, look at the test class BasicRuntimeTest .

Related changes:

Wrap up: Java objects inserted in Drools/N3 engine

What Java objects are inserted in Drools/N3 engine :

  1. objects of class Triple
  2. any Java object necessary for inference, like an N3TableModel ( see example )
  3. Assignment objects, a simple class with 2 props: name and object
  4. DeferredMethodCall objects , allowing to create methods calls in N3 *before* the Java objects are ready

( you know that anything can be inserted in a Drools KB ).

Also, there are several singleton objects prefilled by the framework:

During the user session, these N3 events are inserted in the Internal Knowledge Base, con,foming to the concept of "Event Condition Action (ECA)".

eg:n3SourceChanged eg:uri <n3SourceUri> .
_:d eg:hasOpenedProject <projectUri> .

Internal Knowledge Base

Familiarly referred to as the "conscience of the application", it is work in progress, to be released after release 1.9 .

It is implemented in singleton class ApplicationKB , which contains a Drools RETE Knowledge Base, and subscribes to application and model (Project) events. It is populated by :

The details of the distribution of work between Java and rules are not carved in stone, but the general principle is "the software makes decisions based on formal rules, not on conventional procedural code".

During the current session, the Internal Knowledge Base will receive and accumulate events; it is how we are going to implement the Déductions project's vision of the "good servant".

Extension points with interfaces


Specifying Extension points

We need a lightweight Extension points architecture, allowing to minimize the number of places to modify when adding features.

Inspired by Spring and the eclipse Extension points, we thought of this declarative framework, where the extensions (a.k.a. plug-ins) are specified in N3 syntax, following the naming conventions for Java object instantiations, property and method call explained here: see Generate Java code , N3 - Java mapping .

Here is a first simple example of an extension specification in N3, where we add to EulerGUI an N3 Data Source:

# create an instance of N3SourceFromJavaByteCode
_:ds a java:eulergui-inputs-N3SourceFromJavaByteCode.
# add this instance to EulerGUI
_:EulerGUI javam:addDataSource ( _:ds ) .

The added instance of N3SourceFromJavaByteCode must implement the interface N3SourceFactory .

public interface N3SourceFactory {
  boolean canCreateFromURI(URI uri, URI baseUri);
  N3Source createFromURI(URI uri, URI baseUri) throws N3SourceException;

Then the facade method addDataSource() will add the instance of N3SourceFromJavaByteCode to a list of N3SourceFactory in the global factory SourceFactory .

Conceptually, the extension specification is similar to a Spring configuration file.

This N3 file is added to the Internal Knowledge Base. Prior to inference launch, the _:EulerGUI N3 blank node is associated to the EulerGUI Java singleton instance :

tripleStore.assign( "_:EulerGUI", eulerGUI );

For an infrastructure KB, this call must happen before any N3 source is added.

For Java extensions in N3, the chronological sequence is:

  1. the _:EulerGUI N3 blank node is associated to the EulerGUI Java singleton instance
  2. the extensions N3 file is added to the Internal Knowledge Base;

    due to the N3==>Java translations (see preceding paragraph "N3 - Java mapping"), the Java instantiations and calls happen at once

  3. later, when an event triggers a rule with Java application objects in the consequent, again the Java instantiations and calls happen at once

We will implement this for the Internal Knowledge Base first; see below "Include rules to extend EulerGUI behavior". Then we will refactor the generated Swing application to use this.

It is possible to write an N3 rule base that will check the type correctness of the Java calls made in an extension specification in N3.

Extension points machinery

Extension points need to be equiped with interfaces, extension points, and extensions. We need to find a lightweight architecture for that. With the current implementation in ProjectChangeSupport, adding a new extension point needs an intervention at 3 places:

Extension point need to be represented by a class :

class ExtensionPoint {
  void add( Extension extension );
  /** fire Event to all registered extensions */
  void fireEvent( Event e );
interface Extension {
  /** receive notification of Event */
  public void notify( Event e );

So the previous configuration example would be extended to this :

# create an instance of N3SourceFromJavaByteCode
_:ds a java:eulergui-inputs-N3SourceFromJavaByteCode.
# add this instance to EulerGUI
_:EulerGUI javam:addExtension
  ( _:ds java:eulergui-inputs-N3SourceFactoryExtensionPoint ) .

The method addExtension() in the application singleton EulerGUI will add the Extension in a Map of Sets keyed by the Extension points classes.

To most Extension points, an event type is associated, and most event types will extend this:

class ProjectEvent extends Event { private Project project; }

Or this for N3 source events:

class N3SourceEvent extends ProjectEvent { private N3Source n3; }

(getters and setters are implicit).

The name of the class will indicate the event type, e.g. :

class UserSaveEvent extends N3SourceEvent { }

List of Extension points in EulerGUI

Here is a list of the "event" extension points, related to the main EulerGUI window :

  1. File menu
  2. Project menu (import etc)
  3. Export menu
  4. Add N3 source
  5. Launch inference engine
  6. Launch search
  7. Display menu
  8. Tools (general)
  9. Tools (reasoners)
  10. Result action
  11. N3 source action
  12. N3 source décorations

There are also 2 events types, related to the editor window: Save and SaveAs.

There are also non event extension points, like the N3SourceFactoryExtensionPoint mentioned above.

New extensions to develop (many more in next paragraph):

Rules to extend EulerGUI behavior

Among the extension points, some are particularly interesting because they can be implemented partially or totally by a rule, in the Internal Knowledge Base .

Here is an example of a silly little rule that fires when an N3 Source From Java Class Tree is added, and changes its File Name to "tutu" and inactivates the N3 Source :

  ?x a java:eulergui-inputs-N3SourceFromClassesTree .
 => {
  ?x javam:setFileName "tutu".
  ?x javam:setActivated false .

In this simple example, there is no event, or one could say the object appearance is the event. In general, we need to have consequences of events that fire just once, like e.g. most most extension for "Save in editor". There are at least two designs for this:

  1. A small Java wrapper that will add the event , launch the inference (which will fire the rule), then remove the event
  2. A more rule based design: the Java wrapper will add the event, launch the inference, and then the rule will either remove the event or set it to "consumed" by this rule

Design 2. is the one enabling processing of the user past events. During the current session, the Internal Knowledge Base will receive and accumulate events; it is how we are going to implement the Déductions project's vision of the "good servant".

Anyway, the Java wrapper will add the event as e.g.

@prefix eg: <> .
_:ev a eg:UserSaveEvent;
     eg:about <mySource.n3> ;
     eq:timestamp "2010-..." .

And after the event processing by "rule1" this will be asserted:

_:ev eg:status ( "consumed" "rule1").

The Java wrapper will look like this :

class RuleExtensionSupport implements Extension {
  public void notify( Event e ) {
    insertEventInKB( e.getClass().getSimpleName(), e.getN3Source(), timestamp() );

The currently implemented rules are in application-rules.n3.

With the EulerGUI internal rule engine

Here is some work for the new embedded (a.k.a. internal) rule engine ( this engine is only aware of the user actions, the user configuration, and the projects ) :

With the "user data KB" rule engine

A KB is maintained which contains all the triples in the Project; this is the one that is already used for inferencing, and it is already resident in memory. Let's call it "user data KB". It can be accessed with Project.getWorkingMemory().

We need some application related queries to run on this "user data KB". But we are reluctant to alter this KB with non user rules. Of course, we can add a rule and remove it afterwards. To be thread safe, the operation of adding the temporary rule, and running the non user rule, must be synchronized. That is not needed if the rule is run through Euler.

Some features for the "user data KB" rule engine :

TODO Completion implementation in N3 editor

For plain N3 URI

In an N3 query, one can use substring-after ( tested in test/concatenationQ.n3 ) to get the list of possible completions . When substring-after returns an empty string, it is not a possible completion.

One would also like to have the details about the completed suggestions. To do that, one can combine this with implementation for ordinary tooltips.

For this a rule base can do all the job, returning e.g. triples like:

eg:completion <> "Foo Bar: the property FooBar means ..." .

The object could be formatted in HTML.

For prefixed N3 URI

It is more complicated, but one can get a map of prefix associations from


Then, if the string to complete does not begin with "<" , nor is a number, nor a blank node, and does not include a ":", the Known URI Prefixes can be used for completion.

If the string to complete does include a ":", then expand the prefix abbreviation, and use plain N3 URI algorithm.

Inactivated sources

Inactivated sources should also be searched by the N3 editor to provide labels and comments about the predicates and classes. To achieve that, one possible design is to have an extra KB containing all the inactivated sources. This extra KB will be serached the same way as the main user KB for labels and comments.

When we will integrate the rules to flag undeclared terms, the generated declarations will be added to Inactivated sources, as well as a list of classic ontologies like OWL, FOAF, etc , if they are effectively used.

Java bytecode to N3


TODO explain more <<<<<<<

EulerGUI as Protégé plugin


EulerGUI as a Protégé view.

EulerGUI will mostly stay as is, except for removals in the File menu of things (Open Project) that are already in Protégé. It seems that the largest task is to make an adaptor from the OWL API to the Project class.

Maybe we need first to have the N3 project file, see new N3 project file.

Official doc. on Protégé plugins :

Another question is : will Protégé Felix plugins work with Maven : see ?

TODO explain more <<<<<<<

EulerGUI as eclipse plugin


EulerGUI as an eclipse plugin.

This looks much more complex than the Protégé plugin. First there is the Swing-SWT affair. Then eclipse architecture is overly complex. Hopefully we can find another RDF or OWL plugin as starting point.

People will expect to find sub-projects and sources in a tree view, actions for N3 sources in a pull-down menu, etc.

TODO explain more <<<<<<<

RDBMS connector


We could integrate D2R into EuleGUI.

TODO explain more <<<<<<<

Web services connectors


We need connectors (i.e. servers and clients) for the most standard protocols: Soap, Rest with XML, ... what more ?

This will reuse the XML Schema translators that we already have .

This is an oportunity to advance in the vision of the "intelligent modularity".

TODO explain more <<<<<<<

Smart extraction from SPARQL databases


We should design the intelligent extraction of data compatible with a query ; ask Martin what he thinks ... One idea is to limit a priori the depth of the extraction , for example in the FaceBook example it is 2 .

Note that RDF stores like Virtuoso that handle rdfs:subClassOf and rdfs:subPropertyOf could potentially with the same algorithms handle other transitive properties.


Current issues

Good practices

Being started as an exploration tool, EulerGUI has several good practices not implemented:


Internet cache ==> unified API for data input.

Extension point

We defined an N3 based architecture for extension points, similar to Spring configuration files, but in N3.

Should we use another architecture like OSGi declarative services ?

Relations between Internal rule base and Java

We now have added in the ApplicationKB:

WORK IN PROGRESS : some architecture points to think about, like:

  1. - why and how to have the same thing both as Triple and Assignement
  2. - should we present a single facade to the rule engine or several objects like now ?

Data sources

In EulerGUI we need to add other data sources, like Java source code (and other programming languages), Javadoc, various databases (JDBC, XML-DB, no-SQL stores), AI sources (KIF, CLIPS, TPTP, ...). Right now we plan Javadoc, and recently did Java source code .

For that we have this interface, yet unused, to model a source factory for a specific file format :


Then we need to to track all places where , e.g. , N3SourceFromRDF is created, and replace the call to constructor with a loop on all the N3SourceFactories . Plus a piece of code to setup all the N3SourceFactories; use extension point mechanism .

Stuff to refactor


SimplifiedURI is a mess, it has so many implicit states. Maybe it should be re-implemented in Prolog.

It has improved, with many test cases. We implemented Simplified URI's like:


but we also want that SimplifiedURI are re-evaluated when saving the project in a different place. TODO.


Instanciator class is also a mess, TODO:

DroolsTripleHandler (N3 to Drools translator)

This class is too big. Work has begun to extract special features in separate plugins (see implementors of interface N3TranslationPlugin).

But we also have a more interesting project to make an N3 to Drools translator implemented as an N3 rule base.