Extensions How To

One important feature of XWeaver is its extensibility. This page discusses various possibilities to extend XWeaver. It is assumed that you are familiar with the Extensible Stylesheet Language (XSL).

Dollar variables

The dollar variables can be used in a codeModifier element to access the context of the basecode. An example of a dollar variable is ${className} which holds the name of the currently woven class. It is very easy to add new dollar variables. Declarations for new new dollar variables are defined in several XSL stylesheets in the directory variableDeclarations which itself is a subdirectory of src/xsl/compilerRules. Each XSL file in this directory defines the variable declarations for a certain pointcut type. The file class.xsl, for instance, defines all dollar variables which are defined for code modifiers inside an advice, which uses a pointcut of type 'src:class'. XSL files can be extended or new files can be created to support new pointcut types. New XLS files must be included in the main compiler XSL stylesheet src/xsl/main/compiler/main.xsl. The following template can be used to create a new XSL file for a new pointcut type:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:src="http://www.sdml.info/srcML/src"
                xmlns:cpp="http://www.sdml.info/srcML/cpp"
                xmlns:ax="http://control.ee.ethz.ch/XWeaver/AspectX"
                xmlns:xd="http://www.pnp-software.com/XSLTdoc"
                xmlns:xslt="http://xslt">

  <!--
    The result of the transformation with this stylesheet is again a stylesheet. Whenever
    an element in this stylesheet is used with the prefix 'xslt', it is copied to the
    resulting document as an xsl element.
  -->
  <xsl:namespace-alias stylesheet-prefix="xslt" result-prefix="xsl"/>
  
  <xsl:template match="The pointcut type" mode="variableDeclarations">
    Add <xsl:variable select="..."/> elements here
  </xsl:template>

</xsl:stylesheet>

Variable declarations are expressed by standard XSL variable elements. Therefore any xpath expression can be used in the select attribute. The current node (current() or .) is always a srcML element of the type of the pointcut. Hence, for a pointcut type src:class the current node is a srcML src:class element. See the code below for an example of an xsl:variable element:

<xslt:variable name="className" select="src:name"/>

This variable contains the name of the class and can be used as ${className} inside a codeModifier element. A more complicated variable declaration may look like this:

<xslt:variable name="nrOfSetterMethods" select="count(.//src:function_decl[starts-with(name, 'set')])"/>

This variable contains the number of setter methods in the current class and can be used as ${nrOfSetterMethods} inside a codeModifier element. Variables cannot only hold a single value (string, integer), they also can contain a node set. Consider the following example:

<xslt:variable name="setterMethodNames" select=".//src:function_decl[starts-with(src:name, 'set')]/src:name"/>

This variable contains a node set of the names of all setter methods in the class. and can be used as ${setterMethodNames[i]} inside a codeModifier element.

Restrictions

Restrictions are used to constrain a pointcut in addition to the constraint of the type and constraint attributes. A restriction normally is based on another pointcut, but can also stand alone. The compiler generates an XPath expression for each restriction, which is sinmply added to the XPath expression of the constraint attribute using an 'and' combination. The rule how this expression is generated is implemented in a modular way. For each restriction there is an XSL stylesheet which generates the XPath expression. These XSL stylesheets can be found in the src/xsl/compilerRules/restrictions directory. To add a new restriction, a new XSL stylesheet must be created that generates the XPath expression. New XLS files must be included in the main compiler XSL stylesheet src/xsl/main/compiler/main.xsl. The following template can be used as a starting point.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:ax="http://control.ee.ethz.ch/XWeaver/AspectX"
                xmlns:xd="http://www.pnp-software.com/XSLTdoc"
                version="2.0">
  <xsl:template match="ax:restriction[@type='contain']" mode="pointcutXPath">
    XXX: Create text node with XPath expression here
    
    <xsl:apply-templates select="*" mode="pointcutXPath"/>
  </xsl:template>    
</xsl:stylesheet>

The last line in the template above evaluates the XPath expression of a potential child pointcut:

<xsl:apply-templates select="*" mode="pointcutXPath"/> 

See the already defined restrictions for examples.

Weaver Rules

The weaver component of the XWeaver implements the actual weaving that is done on the annotated code. After annotating the base code, the actual weaving of the code around the annotated srcML elements has to be done. An annotation is is an advice element, which is added directly after the element to be annotated. For all possible annotations a rule is defined how the advice should be woven at the current position. Such a rule depends on the srcML element (pointcut type) plus the type of the advice and the code modifier. For example there is a weaver rule for a pointcut of type src:class, an advice of type add and a code modifier of type declaration. The currently implemented triplets can be found here.

Weaver rules are in general saved in the directory src/xsl/weaverRules. The subdirectory common contains the weaver rules not specific to a particular base language. Then for each base language supported by XWeaver (or srcML respectively) a directory exists containing the language specific weaver rules.

The filename of a weaver rule is standardized as follows:

pointcutType_adviceType_codeModifierType.xsl

An XSL template of the following form defines the rule for a triplet:

<xsl:template match="POINTCUT TYPE[ax:advice[@type='ADVICE TYPE' and position() = 1]/ax:codeModifier[@type='CODE MODIFIER TYPE']]" mode="weaving">

A weaver rule is also responsible for deleting the advice (annotation) it has processed. There is always only one advice (annotation) processed at a time (Note that this is implemented with the and position() = 1 XPath expression in the template), although there can be more than one annotation for one srcML element. Concretely, the first advice is processed and then deleted after the processing. The weaver makes sure that all advices are processed, therefore if an advice is not deleted after processing it, the weaver will run forever (infinite loop)! The deletion of the advice can be done very easely with the folling XSL statement:

 <xsl:apply-templates select="advice[position() != 1]" mode="weaving"/> 

This preserves all except the first advice. Note the mode of the apply-templates expression must be weaving. Because the annotated element normally does contain other elements these elements have to be preserves as well. In fact they not only need to be preserved but should be searched for annotations as well. That's why elements should be preserved by apply-templates with the mode weaving.

Newly created XLS files must be included in the appropriate main weaver XSL stylesheet. You'll find stylesheets for each base language supported in src/xsl/main/weaver/. If you write a weaver rule which works with all base languages add the include in the src/xsl/main/weaver/common.xsl file (which itself is included in all language specific main stylesheets). Make yourself familiar with the srcML language before implementing a new rule and look at the already definded rules for examples. Make sure that you whenever plain text is added to the base code to enclose this text inside an xml element inserted. There are some helper templates defined in the core weaver stylesheet (src/xsl/axw.xsl), they can be used in the weaveRules stylesheets. See the XSLTdoc documentation of the core weaver stylesheet for more information. In most cases you'll need the functions getCodeModifierText and addIndentation. Note that it is also possible to write a rule that covers more than one combination of a triplet.