%\documentstyle{article}
\documentstyle[12pt]{article}

\makeatletter
\def\section{\@startsection {section}{1}{\z@}{-1.5ex plus -1ex minus -.2ex}{1.5ex plus .2ex}{\large\bf}}
\def\subsection{\@startsection{subsection}{2}{\z@}{-1.25ex plus -1ex minus -.2ex}{1.5ex plus .2ex}{\large\bf}}
\def\subsubsection{\@startsection{subsubsection}{3}{\z@}{-1.25ex plus -1ex minus -.2ex}{1.5ex plus .2ex}{\large\bf}}
\oddsidemargin 0cm
\textwidth 17cm
%\textwidth 20cm
\addtolength{\topmargin}{-2.5cm}
\raggedbottom
\textheight 22cm
%\textheight 27cm
\parskip 8pt plus 1pt minus 1pt
\parindent 0pt

\begin{document}
\bibliographystyle{alpha}
%\bibliographystyle{abbrv}

\title{Abstract Slicing: Case Study} \\ 
%{\normalsize Grammars = Datastructures}}
\author{Karl Lieberherr, Northeastern University}

\section{A Case Study: Abstract Slicing}

In this section we show by example how programming with abstract
slices works. 

The crosscutting described in this section is related to object slicing.
The object behavior is expressed in terms of a set of object slices.
A slice of an object is a subobject.
The problem
with object slices is that they are not robust under changes to the
class graph.  Therefore it is useful to program methods abstractly in
terms of object slices and to give the details of the slices succinctly
only when the method is called. This leads to more reusable methods.

A simple example where we can see the benefit of object slicing
is counting.  The following Java code counts \texttt{WhatToCount}
objects reachable through the \texttt{whereToCount} object slice (for
class \texttt{Utility}).

\begin{verbatim}
static public int count(ObjectGraphSlice whereToCount){
  Integer result = (Integer) whereToCount.traverse(
    new Visitor() {
      int c;
      public void start() { c=0; }
      public void before(WhatToCount o) { c++;}
      public Object getReturnValue() {return new Integer(c);}
  });
  return result.intValue();
}
\end{verbatim} 

The counting behavior is naturally formulated with two
participants: \texttt{Source} and \texttt{Target}.  When the counting
behavior is used, we can map \texttt{Source} to \texttt{BusRoute}
and \texttt{Target} to \texttt{Person}, for example.  We also need
method-valued variables. Consider a summing behavior (instead of just a
counting behavior). When we arrive at a target, we need to call a function
to return the value to be summed.  This function needs to be variable.

We show
how traversal strategies are planned to be used in adapters.
If we want to count the number of persons waiting at 
some bus stop in a bus simulation system, we would 
write the following Java code:
% [/course/com3362/sp99/DJ/bus-with-villages]:

\begin{verbatim}
ClassGraph cg = new ClassGraph(); // constructed using reflection
ObjectGraph og = new ObjectGraph(aBusRoute,cg);
int res = Utility.count(new ObjectGraphSlice(og,
            "from BusRoute through BusStop to Person"));
\end{verbatim} 

The above examples that we are using are written in Java using a library
called DJ that we have developed recently.  The string
\texttt{"from BusRoute through BusStop to Person"} is parsed by the
constructor.

The object slice is prepared depending on the structure 
of the current class graph. We assume that \texttt{Person} has been 
substituted for \texttt{WhatToCount} in method \texttt{count}. 
Notice that the implementation to object slicing shown
here is not type-safe because the compiler does not check 
whether the navigation is meaningful in the current class graph. 
To add type safety to this implementation is future work.


Using the terminology of AspectJ, an object slice is a 
pointcut consisting of all entry and exit events for the 
objects through which the slice  leads us. 
In AspectJ, the code that needs to be executed when 
the events happen is specified as advice. 
AspectJ also uses the notion of abstract pointcut. Pointcuts are 
refined through subclassing.

We notice the following correspondence between AspectJ
concepts and slicing concepts:

\begin{quote}
\begin{tabular}{|l|l|l|l|l|}
\hline
AspectJ & pointcut & advice & abstract pointcut & concrete pointcut \\
\hline
Slicing & object slice & visitor & formal object slice & actual object slice\\
\hline
\end{tabular}
\end{quote}

From a software architecture perspective, object slicing uses 
methods parameterized by object slices as components 
and the connectors are the actual object slice definitions 
that connect the
abstract behavior to an actual class graph. 
The connectors are expressed in terms of traversal strategies,
a central concept in adaptive programming.

The counting example is very simple and next we express the idea
of programming with object slices with a more complex example.
The terminal buffer rule (TBR) says that all terminal classes
should be ``buffered" by a class that has the terminal class as part
class.  TBR improves readability of class graphs.\footnote{The
complete terminal buffer rule example is in executable form at:
\texttt{http://www.ccs.neu.edu/research/demeter/DJ/annot-examples/TBR/TBR1-flexible}}
To implement the terminal buffer rule, we need to assume a structure for
representing classes, e.g., the UML meta model.  We assume that there
is a class \texttt{CdGraph} for which we write the following code
that demonstrates that
a severely crosscutting concern can still be 
expressible using a generalized procedure.
This is not too surprising because this example makes heavy use of 
reflective capabilities through the use of DJ.

Although the following code is not an aspect per se, it has the
characteristics of an aspect in AspectJ: The two traversal definitions
are pointcuts and the visitors are the advice.

\begin{verbatim}
public void TBRchecker(
  TraversalGraph defineClassNameTraversal,
  TraversalGraph allPartsTraversal) {
    // defineClassNameTraversal defines the part of the object graph
    // that is relevant for finding all defined classes.
    // allPartsTraversal defines the part of the object graph
    // that is relevant for checking the TerminalBufferRule

    // find defined classes
    DefinedClassVisitor v1 = new DefinedClassVisitor();
    Vector definedClasses = 
      (Vector) defineClassNameTraversal.traverse( this, v1);

    // check for violations
    TBRVisitor v2 = new TBRVisitor(definedClasses);
    allPartsTraversal.traverse(this, v2);
}
\end{verbatim} 


We have chosen to parameterize the  \texttt{TBRchecker} method
with two \texttt{TraversalGraph}-objects instead of with 
\texttt{ObjectGraphSlice}-objects.
The reason is that it is more natural to compute the slices
internal to the method from the \texttt{TraversalGraph}-objects.
This happens implicitly when the traverse method is executed.
Method \texttt{TBRchecker} makes very few assumptions about 
the class graph structure. 
Those assumptions are (1) there exists one slice to find all 
defined classes and (2) there exists one slice to find all 
part classes. In addition, there are assumptions encoded into the visitors. 
We need two visitors, one of which is shown here:

\begin{verbatim}
public class DefinedClassVisitor extends Visitor {       
  private Vector vNonTerminals = new Vector();    
  public void before(Adj o) {
    idCurrentAdj = o.vertex.name;                   
    vNonTerminals.addElement(idCurrentAdj);}
  public Object getReturnValue() {
    return vNonTerminals;
  }
}
\end{verbatim} 

Visitor \texttt{DefineClassVisitor} expects that the slice 
\texttt{defineClassNameSlice} goes through class \texttt{Adj}
that must have a part \texttt{vertex}.

For a concrete use of \texttt{TBRchecker} we get: 

\begin{verbatim}
ClassGraph cg = new ClassGraph(); // constructed by reflection
// The purpose of traversal tg1 is to collect all the class names that
// are defined in the model
TraversalGraph tg1 = new TraversalGraph( "from Cd_graph to Adj", cg);

// The purpose of traversal tg2 is to visit all parts of all classes
TraversalGraph tg2 = new TraversalGraph(
  "from Cd_graph via Construct to Vertex", cg);

CdGraph cdGraph = new CdGraph(...);
cd_graph.TBRchecker(tg1,tg2);
\end{verbatim}

The above code is adaptation code that  defines two concrete traversal
graph objects
for the current class graph and object graph. 

Notice that \texttt{TBRchecker} is a very generic checker that 
can be applied to many class graphs that satisfy 
certain constraints. Analyzing this constraint space 
is reserved for future research.

It is important to mention that there is a subtle difference between the
slice-based programming style shown here and the adaptive programming
styles used in Demeter/C++ or in DemeterJ. In DemeterJ
we consider
the traversal strategies as an integral part of the generic program.  This
``tradition" also lives on in AP\&PC where the participant
graph is an integral part of the program.  With the slice-based approach,
the traversal strategies are delegated outside the generic behavior which
is formulated in terms of ``abstract" slices. The slice-based approach
has the important advantage of simplicity and more genericity.
It is clear that collaborations written using abstract slicing will
have import methods that return object slices or traversal graphs.
But it is not yet completely clear how to express the requirements
 that the actual slices or traversal graphs need to fulfill.

After exposition by example of the abstract slicing programming style and its
relationship to AspectJ, we give a more complete definition of the
concepts involved.  We need the concepts of \textsf{ClassGraph},
\textsf{ObjectGraph}, \textsf{Strategy}, \textsf{TraversalGraph},
\textsf{ObjectGraphSlice} and \textsf{Visitor}.  \textsf{ClassGraph}
and \textsf{ObjectGraph} are familiar concepts, e.g. also used in UML.
\textsf{Objectgraph} contains both an object called root and a class
graph.  A \textsf{Strategy} is basically a subgraph of the transitive
closure of the class graph decorated with negative information about which
nodes and edges to bypass. A \textsf{Strategy}
also defines a set of source and target classes where traversals start
and stop.  A\textsf{TraversalGraph} is basically the crossproduct
of a \textsf{ClassGraph} and a \textsf{Strategy}. Traversal graphs
are used to guide a traversal efficiently through an object following
the rules of a strategy.  An \textsf{ObjectGraphSlice} consists of an
\textsf{ObjectGraph} and a \textsf{Strategy}.
\end{document}

