Cl a ss Calen d a r i m p l e m e nts Tim e A n d D a t e {
lab e ls ( int ) ho urMar ker , minute M a rker ,
secondM a r k e r ;
lab e ls d e f a u l tT i m e Z on e ;
fi n al int HO U R _ O F _ D A Y + ho u r M a r k e r = 1 1;
/* etc . */
Calend a r ()
res u lt : + d e f a ul t T i m eZ o n e { ... }
int get ( int selector )
th is : de f a u l t TimeZone ,
( se l e c t o r : hou r Marke r ,
res u lt : + nowHour )? ,
( se l e c t o r : minut e M arker ,
res u lt : + nowMinute )? { ... }
}
Figure 2. TimeAndDate annotations for Java 1.5. Here the
+ sign indicates an invariant.
need to have a Date object with the currentTime label. We
repeat the search and find that there is a constructor that takes
no arguments and that produces such an object. This yields
a complete solution, and thus, after the code has been gener-
ated and the substitution has taken place, the client class will
look like the following:
cl a ss TimeUtils implements TimeA n d D a t e {
vo id pr i n t H o u r () {
Da te v1 = new Date () ;
int h our = v1 . getHou r ();
Sys t em . out . println (" The curr e n t hour is : " +
ho ur );
}
}
In addition, the solver will remove non-Java elements
from the code, such as the label declarations from the various
classes, so that the result is valid Java source code.
2.2 Upgrading to Java 1.5
Let us now consider how we could adapt this client to the
Java 1.5 version. In this case, the service component would
resemble the one shown in Figure 2.
In this case, all the values are accessed through one
method, which takes a selector argument. We have given
the field HOUR_OF_DAY an explicit label hourMarker, which
links it to its possible use as an argument for the get(int)
method. We group invariants and postconditions using the
(a, b, ...)? syntax, which makes the pre- and postcon-
ditions inside the group optional. This is mainly a syntactic
shorthand to avoid having to repeat the defaultTimeZone
requirement for the this object. In this case, however, clearly
minuteMarker, hourMarker and so on will be mutually ex-
clusive labels. The plan search now takes the same query as
a starting point, but the APIs supplied as input are different
(and perhaps the 1.5 API is marked as taking precedence
over the 1.4 one if both are available) and after substituting
a solution for the query we end up with:
new Calendar()
get(int)
(Calendar,
defaultTimeZone)
(int, nowHour)
Start
Finish
Calendar.HOUR_OF_DAY
(int, hourMarker)
new Date()
getHour()
(Date, currentTime)
(int, nowHour)
Start
Finish
Java 1.4 Java 1.5
Figure 3. Visual representations of the plans generated in
the case of producing the current hour of the day in Java 1.4
and 1.5, respectively.
cl a ss TimeUtils implements TimeA n d D a t e {
vo id pr i n t H o u r () {
Da te v1 = new C a l e n d a r () ;
int v2 = C alendar . HO U R_OF _ D A Y ;
int h our = v1 . get (v2 );
Sys t em . out . println (" The curr e n t hour is : " +
ho ur );
}
}
We show the plans visually in Figure 3. The resulting
code is extracted directly from the plans. Rounded boxes are
pre- and postconditions (the existence of a variable with a
given label), and square boxes are actions such as method
invocation and field access. Dashed lines represent sequen-
tial constraints, which impose an ordering on the actions.
These constraints will be at least as strong as the dataflow
dependencies of the solution, and possibly stronger due to
possible conflicts.
These examples demonstrate how clients can automati-
cally be reconfigured to use a new version of an API, or
even a different API, given that the necessary annotations
are present on both the client and the service side. In this
case it would simply be a matter of re-running the integra-
tion tool with the newest service components added to the
classpath.
4 2011/6/10