<< Language Constructs | Contents | Mixin Composition >>
Overview of Language Constructs
This section gives a brief overview of the core of Caesar features.
Caesar Classes
Caesar classes are defined using the cclass keyword in order to separate them from plain Java class. Inheritance hierarchies of Caesar classes and Java classes are strictly separated in Caesar. A cclass may not inherit from a Java class and vice versa. However, object composition is allowed and interface implementation.
public interface AJavaInterface {
}
public class APlainJavaClass {
ACaesarClass aRefToACaesarClass;
}
public cclass ACaesarClass implements AJavaInterface {
APlainJavaClass aRefToAPlainJavaClass;
java.util.Vector aRefToAnotherPlainJavaClass;
}
Collaborations
Collaborations are used to group a set of collaborating classes. Each cclass containing at least one inner cclass is considered as a collaboration.
// collaboration Graph
public cclass Graph {
/*
* nested cclass-es
*/
public cclass Edge {...}
public cclass UEdge extends Edge {...}
public cclass Node {...}
}
Virtual Classes
All inner classes within a cclass are considered as virtual classes, because they are handles in a similar way as virtual methods. Differently from plain Java inner classes, Virtual classes can be redefined in any subclass of the enclosing class.
public cclass Graph {
public cclass Edge {
Node start, end;
}
public cclass UEdge extends Edge {...}
public cclass Node {...}
}
public cclass WeightedGraph extends Graph {
public cclass Edge {
float cost;
}
public cclass Node {
float cost;
}
}
In the example above we redefine in
WeightedGraph
the classes
Edge
and
Node
in order to add the
cost
attribute. Virtual classes allow us to incrementally refine a set of collaborating classes.
The interesting point here is that the references to virtual classes are always bound to the most specific redefinition known in the context of the enclosing
object. Hence, the super-class of
WeightedGraph.UEdge
is bound to
WeightedGraph.Edge
. Moreover, accessing the variables
start
and
end
in the context of
WeightedGraph
allows us to use the newly introduced properties of
WeightedGraph.Node
, although the declaration was made in
Graph.Edge
itself.
Composition Mechanism
Two or more Caesar classes can be composed using the
&
-operator.
public cclass ColoredGraph extends Graph {
public cclass Node {
Color color;
}
}
public cclass ColoredWeightedGraph extends ColorGraph & WeightedGraph {
...
}
In the example above, we use the
&
-operator to compose a new collaboration having the properties from
ColorGraph
and
WeightedGraph
.
The interesting point here is that the composition mechanism is propagated into the inner classes. All compatible members from both collaborations are also composed together, e.g., after the composition
ColoredWeightedGraph.Node
will have the
cost
and the
color
property.
Pointcuts & Advices
CaesarJ is a superset of AspectJ. This means it adopts the join point interception (JPI) model introduced in AspectJ as the basic corner stone for modularizing the crosscutting concerns.
Each
cclass
declaration can contain pointcuts and advices, e.g.:
public cclass AnAspect {
public pointcut APointcut() : .... ;
public around() : APointcut() {
// code to insert
}
}
If you are new to
AspectJ
please read the
AspectJ Programming Guide first.
Aspect Deployment
In addition to the compile-time activation of an aspect, in Caesar an aspect can be instantiated and activated at run-time. Caesar introduces a
deploy
statement, which is used to define the activation scope of an aspect, e.g.:
...
AnAspect a = new AnAspect();
// a not activated here
deploy( a ) {
// a is activated now
...
}
// a is deactivated again
...
The aspectj-like compile-time deployment of aspects is activated using the
deployed
cclass modifier.
public deployed cclass AnAtCompileTimeActivatedAspect {
// ...pointcuts...
// ...advices...
}
Wrapper Mechanism
Caesar introduces the language constructs for wrapper classes and automated wrapper recycling.
public class X {
// state
public int x1;
// methods
public int m1() {...}
}
public cclass ACollaboration {
public cclass XWrapper wraps X {
// additional state
int x2;
// additional methods
public int m2() {
return wrappee.m1() + x2;
}
}
public void doSomethingWith(ApplicationModel.X x) {
XWrapper(x).m2(); // wrapping x
}
}
In the example above, The class
XWrapper
wraps a plain Java class
X
. When a wrapper is created, it is bound to the specified wrappee object. It exists until the wrappee object is collected by the JVM garbage collector. In order to simplify the management of wrappers, Caesar provides a wrapper recycling method for each wrapper class (see
XWrapper(x).m2()
call), which has the following funtionality:
- create new wrapper if no wrapper exists for the wrappee object
- reuse existing wrapper if one has been already associated with the wrappee object.
<< Language Constructs | Contents | Mixin Composition >>