Home » Language IDEs » Objectteams » Lifting and Roles - Graph Product Line example (Lifting and Roles - Graph Product Line example)
| Lifting and Roles - Graph Product Line example [message #1007183] |
Mon, 04 February 2013 14:58  |
Steve Mayer Messages: 9 Registered: December 2012 |
Junior Member |
|
|
Hello,
I have programmed part of the Graph Product Line (GPL) in Object-Teams. I have a question regarding my code, so I post here a simplified version of my example.
Background: The Graph Product Line (GPL) is a Software Product Line (SPL) about Graphs and features regarding different type of Graphs (weighted or unweighted edges, directed or undirected edges, colored or uncolored edges, etc.) and various graph algorithms.
Currently I am interested in the dynamic capabilities of Object Teams. Especially in adding roles to existing objects at runtime and managing the state of instance variables in that situation.
In my small example I have implemented a plain 'Graph' and also a 'WeightedGraph' (both team classes). It is setting, an edge is part of a graph and connects two nodes. This is implemented via the Role 'Graph.Edge' that consists of two instance variables 'from' and 'to', which are both of type 'Graph.Node'.
Here is a link to the full code example, a simplified version of the graph product line (GPL):
[h]ttps://gist.github.com/8cb1cd50bd5b832532c9
[h]ttp://wikisend.com/download/348874/simplified-gpl-example.zip
(Probably I am using object teams in a slightly different manner compared to the online code examples. If you know improvements to my code, please tell me.)
Information about the version of OT:
Eclipse SDK 4.3M4
Object Teams Development Tooling - 2.2.0.201212161846
Runtime - objectteams.runtime_2.1.0.201212161846.jar
Short information regarding the code example:
For a weighted edge a new instance variable 'weight' is needed, which is of type 'int'. The Role 'Weighted.Edge' that is part of 'WeightedGraph' and includes the instance variable 'weight'.
The goal for the example is:
How can I create an 'Edge' with the Role 'Graph.Edge' and how can I later lift this edge to also include the Role 'WeightedGraph.Edge'. After the lifting, I would like to access/print the instance variables defined in 'Graph.Edge', as well those defined in 'WeightedGraph.Edge'.
I have implemented the functionality using lifting, but unfortunately if I print the 'Edge' object, this result is a NullPointerException. (The call 'super.print()' within the method 'WeightedGraph.Edge.print()' of Role 'WeightedGraph.Edge' results in the exception.)
I am interested in:
a) Why does this exception happen?
b) Is there an alternative approach in object teams to solve the problem?
Best regards from Vienna,
Stephan
(aka Steve Mayer)
====== here is a copy of the source code (see also the linked zipfile above) ======
public class Edge { }
public class Node { }
public team class Graph {
// ArrayList<REdges> edges = new ArrayList<GEdge>();
// public void addEdge(Edge as REdge e) { edges.add(e); }
// (simplified example, this is commented out)
// new method
protected REdge newEdge(String name) {
return new REdge(name);
}
public class REdge playedBy Edge {
protected RNode from, to;
public REdge(Edge e) { System.out.println("Graph.REdge() -- custom lifting constructor"); }
public REdge(String name) {
base();
System.out.println("Graph.REdge() -- normal constructor");
from = new RNode("node-from -- name: "+name);
to = new RNode("node-to -- name: "+name);
}
public void print() {
System.out.println("Plain Edge with two nodes:");
from.print();
to.print();
}
}
public class RNode playedBy Node {
protected String name;
public RNode(String s) { base(); name = s;}
public void print() { System.out.println(name); }
}
}
public team class WeightedGraph extends Graph {
// lifting method
protected REdge liftDecorate(Edge as REdge e) { return e;}
public class REdge playedBy Edge {
int weight = -1;
public REdge(Edge e) { System.out.println("WeightedGraph.REdge() -- custom lifting constructor"); }
public void print() {
System.out.println("WeightedEdge with nodes:");
tsuper.print();
}
public int getWeight() { return weight; }
}
}
public class Main {
public static void main(String[] args) {
// note: simplified example, we don't do anything with the objects
// usually we would do 'g1.add( g1.newEdge() )' and so on
Graph g1 = new Graph();
g1.newEdge(" plain Edge A").print();
WeightedGraph g2 = new WeightedGraph();
System.out.println("======\n\n");
// we can lift the plain edge (i.e., it becomes a weighted edge) and get its weight:
int testWeight = g2.liftDecorate(g1.newEdge(" plain Edge B")).getWeight();
System.out.println("======\n\n");
// again lifting, but printing the edge results in a NullPointerException
// (i.e., the instance variables 'from' and 'to' are NullPointers!)
g2.liftDecorate(g1.newEdge(" plain Edge B")).print();
}
}
/**
* OUTPUT:
*
*
Graph.REdge() constructor
Plain Edge with nodes:
node-from -- name: plain Edge A
node-to -- name: plain Edge A
======
Graph.REdge() constructor
WeightedGraph.REdge() -- custom lifting constructor
======
Graph.REdge() constructor
WeightedGraph.REdge() -- custom lifting constructor
WeightedEdge with nodes:
Plain Edge with nodes:
Exception in thread "main" java.lang.NullPointerException
at WeightedGraph$__OT__REdge.print(WeightedGraph.java:35)
at WeightedGraph$__OT__REdge.print(WeightedGraph.java:22)
at Main.main(Main.java:25)
*/
|
|
|
Goto Forum:
Current Time: Tue May 28 07:20:26 EDT 2013
Powered by FUDForum. Page generated in 0.05184 seconds
|