Luca Fossati, Raymond Hu (homepage), Nobuko Yoshida (homepage)
2014-04-28 If you downloaded the Java APIs some time in the last few days and had a compilation error due to a missing file, please re-download and try again. Apologies for any inconvenience.
This page and the linked resources (e.g. the tool implementation) will continue to be updated
Downloads:
These APIs allow the construction of global session graphs, well-formedness validation and endpoint type conformance checking. Java 7 or above is required. Please note: this is a preliminary working version that is still under development. See below for a tutorial. For any queries regarding the APIs, please contact Raymond Hu.
Examples To compile the packaged source and run all the examples of the above paper, from the parent directory of the extracted sessnet and test directories do the following. (Manually do mkdir bin first if required.)
The list of examples (as per the main method of the Examples class compiled above) and what it means to "run" them is as follows. All references to figures, pages, etc. are with respect to the above paper.
(1) Global session graph construction
Global session graphs are most conveniently constructed using the
We first create a new SessionGraphBuilder. We then create the Place, Output, Input and InternalTransition objects (from the sessnet.net package) for each role structure.
SessionGraphBuilder b = new SessionGraphBuilder();
// First A role structure
Place p1 = new Place("A");
Output oa = new Output("a");
// First B role structure
Input ia = new Input("a");
Input ic = new Input("c");
Place p2 = new Place("B");
InternalTransition t = new InternalTransition();
Place p3 = new Place("B");
Output ob = new Output("b");
// Second A role structure
Input ib = new Input("b");
Place p4 = new Place("A");
Output oc = new Output("c");
Output od = new Output("d");
// Final B role structure
Input id = new Input("d");
Place p5 = new Place("B");
After creating the various place and transition objects, the SessionGraphBuilder (b) is used to construct each role structure by declaring the nodes and edges via its role structure builder (b.rsb) and input/output role tree builder (b.rsb.ib and b.rsb.ob) helper subcomponents.
The first A role structure is constructed by:
// Construct the first A RS
b.rsb.addCorePlace(p1); // Set the core place (adds to both IRT and ORT)
// There are no further nodes in the IRT
b.rsb.ob.addLeaves(oa); // The ORT has one leaf..
b.rsb.ob.addEdge(p1, oa); // ..and one edge
b.addRoleStructure(); // Finalise the RS
The addRoleStructure method finalises the role structure being assembled (and checks that it has been correctly constructed) and resets the state of the role structure and input/output role tree builders.
The first B RS is constructed as follows.
// Construct the first B role structure
b.rsb.addCorePlace(p3); // Set the core place
b.rsb.ib.addLeaves(ia, ic); // The IRT has two leaves..
b.rsb.ib.addOtherNodes(p2, t); // ..and two additional nodes
b.rsb.ib.addEdge(ia, p2); // Connect the IRT nodes
b.rsb.ib.addEdge(p2, t);
b.rsb.ib.addEdge(t, p3);
b.rsb.ib.addEdge(ic, p3);
b.rsb.ob.addLeaves(ob); // The ORT has one leaf..
b.rsb.ob.addEdge(p3, ob); // ..and one edge
b.addRoleStructure(); // Finalise the RS
The other two role structures are constructed similarly. Finally, we add the communication places between the outputs and inputs to the graph, and finalise the whole graph with the role structures constructed so far.
// Add the communication places (the edges are added implicitly)
b.addCommunicationPlace(oa, ia);
b.addCommunicationPlace(ob, ib);
b.addCommunicationPlace(oc, ic);
b.addCommunicationPlace(od, id);
Session Graph g = b.makeSessionGraph(); // Finalise the whole graph
Finalising the graph checks resets the state of the builder object.
(2) Well-formedness validation
The makeSessionGraph method finalises the session graph and checks that it has been correctly constructed and is well-formed.
For example, consider the following modification of the graph from (1) above (corresponding to the Figure 3 (left) "bad entry" example):
This may be constructed by replacing the code for the first B role structure with the following. The remainder of the code for this new graph is the same as above.
// Modified B role structure
Place pp = new Place("B"); // An additional RS place is needed
b.rsb.addCorePlace(p3);
b.rsb.ib.addLeaves(ia, ic);
b.rsb.ib.addOtherNodes(p2, t, pp); // The IRT has the extra place
b.rsb.ib.addEdge(ia, p2);
b.rsb.ib.addEdge(p2, t);
b.rsb.ib.addEdge(t, p3);
b.rsb.ib.addEdge(ic, pp); // Connect ?c to t via pp
b.rsb.ib.addEdge(pp, t);
b.rsb.ob.addLeaves(ob);
b.rsb.ob.addEdge(p3, ob);
b.addRoleStructure();
This graph is badly-formed because there is cycle with a transition entry node: the cycle is t -> B -> !b -> ?b -> A -> !c -> ?c -> t (omitting the unlabelled places) with entry path A -> !a -> ?a -> t. As explained in the above paper, the well-formedness condition that has been violated is (C1) in Definition 2.3.
When the final makeSessionGraph method is called, the following exception will be raised (modulo the integer identifier for the offending transition):
Well-formedness error:
Entry node of cycle must be a place: Tau<87>
(3) Endpoint type conformance
Provided a graph has been correctly constructed and is well-formed, the makeSessionGraph builder method returns a sessnet.net.SessionGraph object.
To test an endpoint type for conformance, we first construct the sessnet.endpoint.EndpointType object that represents the syntactic type. Note: the API for constructing endpoint types in the following example is an intermediate interface intended as a parser target rather than a direct user interface.
Here we create an EndpointType for TAbad (!B<a>.?B<b>.!B<c>.?B<d>.end) for the role A from the Figure 5 example.
// Construct the endpoint type: !B<a>.?B<b>.!B<c>.?B<d>.end
EndpointType e;
Map<Message, EndpointType> cases;
//For convenience, we construct the type "backwards"
e = new EndType("A");
cases = new HashMap<>();
cases.put(new Message("B", "A", "d"), e);
e = new InputType("A", cases);
cases = new HashMap<>();
cases.put(new Message("A", "B", "c"), e);
e = new OutputType("A", cases);
cases = new HashMap<>();
cases.put(new Message("B", "A", "b"), e);
e = new InputType("A", cases);
cases = new HashMap<>();
cases.put(new Message("A", "B", "a"), e);
e = new OutputType("A", cases);
To test conformance, we then create an initial net from the session graph and pass the above EndpointType as an argument to the isConformant method of the net object.
// sg is a reference to the SessionGraph object for Figure 5
SessionNet net = sg.makeInitialNet();
System.out.println("Checking: " + e); // e is the EndpointType from above
System.out.println("Conformance: " + net.isConformant(e));
The above code generates the following output:
Checking: A!{B<a>.A?{B<b>.A!{B<c>.A?{B<d>.end}}}}
Conformance: false
2014-04-29.