<
aspect xmlns:src="
http://www.sdml.info/srcML/src"
xmlns:xsl="
http://www.w3.org/1999/XSL/Transform"
xmlns:cpp="
http://www.sdml.info/srcML/cpp"
xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
xmlns="
http://control.ee.ethz.ch/XWeaver/AspectX"
xsi:schemaLocation="
http://control.ee.ethz.ch/XWeaver/AspectX ../../../../src/xsd/aspectX.xsd"
name="
CarPreCondition">
<
description>
The base code does not perform any range checks on the values of
parameters being passed to methods (for instance, there is no check that
object pointers are not <
code>
NULL</
code>
). We want to modify this base code to do two
things:
<
ol>
<
li>
to perform validity checks on the parameters passed to a method</
li>
<
li>
to execute a recovery action in case the parameters are found to be
invalid.
</
li>
</
ol>
A "recovery action" in our context is an instance of a class derived
from class <
code>
RecoveryAction</
code>
. The recovery action should be a plug-in component
for the class where the parameter valildity check is performed.
<
author>
I. Birrer, O. Rohlik</
author>
<
see>
CarBeginEnd</
see>
<
see>
CarPostCondition</
see>
<
see>
CarSynchronizeWindows</
see>
</
description>
<
pointcut type="
src:function"
name="
checkedMethods">
<
description>
Points to all methods which ranges should be checked. These methods are <
code>
setPower</
code>
and
<
code>
setLoadLevel</
code>
.
</
description>
<
or>
<
pointcut type="
src:function"
constraint="
src:name='Engine::setPower'" />
<
pointcut type="
src:function"
constraint="
src:name='Battery::setLoadLevel'" />
</
or>
</
pointcut>
<
pointcut type="
src:class"
name="
checkedMethodsClasses">
<
description>
Points to all classes that have methods which ranges should be checked. These classes
are <
code>
Engine</
code>
and <
code>
Battery</
code>
.
</
description>
<
or>
<
pointcut type="
src:class"
constraint="
src:name='Engine'" />
<
pointcut type="
src:class"
constraint="
src:name='Battery'" />
</
or>
</
pointcut>
<
advice name="
addRecoverySupportMethodDeclaration"
type="
add">
<
description>
Adds a method <
code>
setRecoveryAction()</
code>
to the classes that supports recovery.</
description>
<
pointcutRef ref="
checkedMethodsClasses"
type="
src:class" />
<
codeModifier type="
declaration">
<
accessModifier type="
public" />
<
text />
<
text>
/**
* Sets the recovery action to be taken, if a method returns a NULL pointer
* @param RecoveryAction The recoveryAction to be taken, if a method returns a NULL pointer
*/
void setRecoveryAction( RecoveryAction aRecoveryAction );</
text>
</
codeModifier>
</
advice>
<
advice name="
addRecoverySupportFieldDeclaration"
type="
add">
<
description>
Adds a declaration of field variable <
code>
recoveryAction</
code>
to classes that support recovery.</
description>
<
pointcutRef ref="
checkedMethodsClasses"
type="
src:class" />
<
codeModifier type="
declaration">
<
accessModifier type="
private" />
<
text>
/** The recovery action to be taken, if a method returns a NULL pointer"/> */</
text>
<
text>
RecoveryAction recoveryAction;</
text>
</
codeModifier>
</
advice>
<
advice name="
addRecoverySupportDefinition"
type="
add">
<
description>
Adds definition of method <
code>
setRecoveryAction()</
code>
to units (files) that contain definition of class that that have methods which ranges should be checked.</
description>
<
pointcut type="
src:unit">
<
restriction type="
isDefinitionOf">
<
pointcutRef ref="
checkedMethodsClasses"
type="
src:class" />
</
restriction>
</
pointcut>
<
codeModifier type="
definition">
<
text>
void ${className}::setRecoveryAction( RecoveryAction aRecoveryAction ) {</
text>
<
text>
recoveryAction = aRecoveryAction;</
text>
<
text>
}</
text>
</
codeModifier>
</
advice>
<
advice name="
checkedMethods"
type="
begin">
<
description>
Adds code that validates the precondition. It checks the value of the first parameter. It it is less than 10 the recovery action is performed.</
description>
<
pointcutRef type="
src:function"
ref="
checkedMethods" />
<
codeModifier type="
codeFragment">
<
text>
if( ${paramNames[1]} < 10 ) {
recoveryAction.recover();
}</
text>
</
codeModifier>
</
advice>
<
advice type="
add"
name="
addIncludeDecl">
<
description>
Adds <
code>
#include "RecoveryAction.h"</
code>
to all units where classes with functions returning pointers are defined.</
description>
<
pointcut type="
src:unit">
<
restriction type="
isDefinitionOf">
<
pointcutRef ref="
checkedMethodsClasses"
type="
src:class" />
</
restriction>
</
pointcut>
<
codeModifier type="
include">
<
text>
#include "RecoveryAction.h"</
text>
</
codeModifier>
</
advice>
<
advice type="
add"
name="
addIncludeDef">
<
description>
Adds <
code>
#include "RecoveryAction.h"</
code>
to all units where functions returning pointer are defined.</
description>
<
pointcut type="
src:unit">
<
restriction type="
contain">
<
pointcutRef ref="
checkedMethodsClasses"
type="
src:class" />
</
restriction>
</
pointcut>
<
codeModifier type="
include">
<
text>
#include "RecoveryAction.h"</
text>
</
codeModifier>
</
advice>
</
aspect>
v