Home | History | Annotate | Download | only in etc
      1 <?xml version="1.0"?>
      2 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
      3   xmlns:lxslt="http://xml.apache.org/xslt"
      4   xmlns:xalan="http://xml.apache.org/xalan"
      5   xmlns:redirect="org.apache.xalan.lib.Redirect"
      6   exclude-result-prefixes="xalan"
      7   extension-element-prefixes="redirect">
      8 <xsl:output method="html" indent="yes" encoding="US-ASCII"/>
      9 <xsl:decimal-format decimal-separator="." grouping-separator="," />
     10 <!--
     11    Licensed to the Apache Software Foundation (ASF) under one or more
     12    contributor license agreements.  See the NOTICE file distributed with
     13    this work for additional information regarding copyright ownership.
     14    The ASF licenses this file to You under the Apache License, Version 2.0
     15    (the "License"); you may not use this file except in compliance with
     16    the License.  You may obtain a copy of the License at
     17 
     18        http://www.apache.org/licenses/LICENSE-2.0
     19 
     20    Unless required by applicable law or agreed to in writing, software
     21    distributed under the License is distributed on an "AS IS" BASIS,
     22    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     23    See the License for the specific language governing permissions and
     24    limitations under the License.
     25 -->
     26 <!--
     27   @author Stephane Bailliez <a href="mailto:sbailliez (a] apache.org"/>
     28   -->
     29 <xsl:param name="output.dir" select="'.'"/>
     30 
     31 <!-- default max value for the metrics -->
     32 <xsl:param name="vg.max" select="10"/>
     33 <xsl:param name="loc.max" select="1000"/>
     34 <xsl:param name="dit.max" select="10"/>
     35 <xsl:param name="noa.max" select="250"/>
     36 <xsl:param name="nrm.max" select="50"/>
     37 <xsl:param name="nlm.max" select="250"/>
     38 <xsl:param name="wmc.max" select="250"/>
     39 <xsl:param name="rfc.max" select="50"/>
     40 <xsl:param name="dac.max" select="10"/>
     41 <xsl:param name="fanout.max" select="10"/>
     42 <xsl:param name="cbo.max" select="15"/>
     43 <xsl:param name="lcom.max" select="10"/>
     44 <xsl:param name="nocl.max" select="10"/>
     45 
     46 
     47 <!-- create a tree fragment to speed up processing -->
     48 <xsl:variable name="doctree.var">
     49   <xsl:element name="classes">
     50     <xsl:for-each select=".//class">
     51       <xsl:element name="class">
     52         <xsl:attribute name="package">
     53           <xsl:value-of select="(ancestor::package)[last()]/@name"/>
     54         </xsl:attribute>
     55         <xsl:copy-of select="@*"/>
     56         <xsl:attribute name="name">
     57           <xsl:apply-templates select="." mode="class.name"/>
     58         </xsl:attribute>
     59         <xsl:copy-of select="method"/>
     60       </xsl:element>
     61     </xsl:for-each>
     62   </xsl:element>
     63 </xsl:variable>
     64 
     65 <xsl:variable name="doctree" select="xalan:nodeset($doctree.var)"/>
     66 
     67 <xsl:template match="metrics">
     68 
     69   <!-- create the index.html -->
     70   <redirect:write file="{$output.dir}/index.html">
     71     <xsl:call-template name="index.html"/>
     72   </redirect:write>
     73 
     74   <!-- create the stylesheet.css -->
     75   <redirect:write file="{$output.dir}/stylesheet.css">
     76     <xsl:call-template name="stylesheet.css"/>
     77   </redirect:write>
     78 
     79   <redirect:write file="{$output.dir}/metrics-reference.html">
     80     <xsl:call-template name="metrics-reference.html"/>
     81   </redirect:write>
     82 
     83   <!-- create the overview-packages.html at the root -->
     84   <redirect:write file="{$output.dir}/overview-summary.html">
     85     <xsl:apply-templates select="." mode="overview.packages"/>
     86   </redirect:write>
     87 
     88   <!-- create the all-packages.html at the root -->
     89   <redirect:write file="{$output.dir}/overview-frame.html">
     90     <xsl:apply-templates select="." mode="all.packages"/>
     91   </redirect:write>
     92 
     93   <!-- create the all-classes.html at the root -->
     94   <redirect:write file="{$output.dir}/allclasses-frame.html">
     95     <xsl:apply-templates select="." mode="all.classes"/>
     96   </redirect:write>
     97 
     98   <!-- process all packages -->
     99   <xsl:apply-templates select=".//package"/>
    100 </xsl:template>
    101 
    102 
    103 <xsl:template match="package">
    104   <xsl:variable name="package.name" select="@name"/>
    105   <xsl:variable name="package.dir">
    106     <xsl:if test="not($package.name = 'unnamed package')"><xsl:value-of select="translate($package.name,'.','/')"/></xsl:if>
    107     <xsl:if test="$package.name = 'unnamed package'">.</xsl:if>
    108   </xsl:variable>
    109   <!-- create a classes-list.html in the package directory -->
    110   <redirect:write file="{$output.dir}/{$package.dir}/package-frame.html">
    111     <xsl:apply-templates select="." mode="classes.list"/>
    112   </redirect:write>
    113 
    114   <!-- create a package-summary.html in the package directory -->
    115   <redirect:write file="{$output.dir}/{$package.dir}/package-summary.html">
    116     <xsl:apply-templates select="." mode="package.summary"/>
    117   </redirect:write>
    118 
    119   <!-- for each class, creates a @name.html -->
    120   <!-- @bug there will be a problem with inner classes having the same name, it will be overwritten -->
    121   <xsl:for-each select="$doctree/classes/class[@package = current()/@name]">
    122       <!--Processing <xsl:value-of select="$class.name"/><xsl:text>&#10;</xsl:text> -->
    123     <redirect:write file="{$output.dir}/{$package.dir}/{@name}.html">
    124       <xsl:apply-templates select="." mode="class.details"/>
    125     </redirect:write>
    126   </xsl:for-each>
    127 </xsl:template>
    128 
    129 <!-- little trick to compute the classname for inner and non inner classes -->
    130 <!-- this is all in one line to avoid CRLF in the name -->
    131 <xsl:template match="class" mode="class.name">
    132     <xsl:if test="parent::class"><xsl:apply-templates select="parent::class" mode="class.name"/>.<xsl:value-of select="@name"/></xsl:if><xsl:if test="not(parent::class)"><xsl:value-of select="@name"/></xsl:if>
    133 </xsl:template>
    134 
    135 
    136 <xsl:template name="index.html">
    137 <HTML>
    138   <HEAD><TITLE>Metrics Results.</TITLE></HEAD>
    139   <FRAMESET cols="20%,80%">
    140     <FRAMESET rows="30%,70%">
    141       <FRAME src="overview-frame.html" name="packageListFrame"/>
    142       <FRAME src="allclasses-frame.html" name="classListFrame"/>
    143     </FRAMESET>
    144     <FRAME src="overview-summary.html" name="classFrame"/>
    145   </FRAMESET>
    146   <noframes>
    147     <H2>Frame Alert</H2>
    148     <P>
    149     This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
    150     </P>
    151   </noframes>
    152 </HTML>
    153 </xsl:template>
    154 
    155 <!-- this is the stylesheet css to use for nearly everything -->
    156 <xsl:template name="metrics-reference.html">
    157 <html>
    158 <head>
    159 <link title="Style" type="text/css" rel="stylesheet" href="stylesheet.css"/>
    160 </head>
    161 <body style="text-align:justify;">
    162 <h2>Metrics Reference</h2>
    163 <a href="#V(G)">V(G)</a> |
    164 <a href="#LOC">LOC</a> |
    165 <a href="#DIT">DIT</a> |
    166 <a href="#NOA">NOA</a> |
    167 <a href="#NRM">NRM</a> |
    168 <a href="#NLM">NLM</a> |
    169 <a href="#WMC">WMC</a> |
    170 <a href="#RFC">RFC</a> |
    171 <a href="#DAC">DAC</a> |
    172 <a href="#FANOUT">FANOUT</a> |
    173 <a href="#CBO">CBO</a> |
    174 <a href="#LCOM">LCOM</a> |
    175 <a href="#NOC">NOC</a>
    176 
    177 <a name="V(G)"/>
    178 <h3>Cyclomatic Complexity - V(G)</h3>
    179 This metric was introduced in the 1970s to measure the amount of control
    180 flow complexity or branching complexity in a module such as a
    181 subroutine. It gives the number of paths that may be taken through the
    182 code, and was initially developed to give some measure of the cost of
    183 producing a test case for the module by executing each path.
    184 <p/>
    185 Methods with a high cyclomatic complexity tend to be more difficult to
    186 understand and maintain. In general the more complex the methods of an
    187 application, the more difficult it will be to test it, and this will adversely
    188 affect its reliability.
    189 <p/>
    190 V(G) is a measure of the control flow complexity of a method or
    191 constructor.  It counts the number of branches in the body of the method,
    192 defined as:
    193 <ul>
    194 <li>while statements;</li>
    195 <li>if statements;</li>
    196 <li>for statements.</li>
    197 </ul>
    198 
    199 The metric can also be configured to count each case of a switch
    200 statement as well.
    201 
    202 <a name="LOC"/>
    203 <h3>Lines of Code - LOC</h3>
    204 
    205 This is perhaps the simplest of all the metrics to define and compute.
    206 Counting lines has a long history as a software metric dating from before
    207 the rise of structured programming, and it is still in widespread use today.
    208 The size of a method affects the ease with which it can be understood, its
    209 reusability and its maintainability. There are a variety of ways that the size
    210 can be calculated. These include counting all the lines of code, the number
    211 of statements, the blank lines of code, the lines of commentary, and the
    212 lines consisting only of syntax such as block delimiters.
    213 <p/>
    214 This metric can also be used for sizing other constructs as well, for
    215 example, the overall size of a Java class or package can be measured by
    216 counting the number of source lines it consists of.
    217 <p/>
    218 LOC can be used to determine the size of a compilation unit (source file),
    219 class or interface, method, constructor, or field.  It can be configured to
    220 ignore:
    221 <ul>
    222 <li>blank lines;</li>
    223 <li>lines consisting only of comments;</li>
    224 <li>lines consisting only of opening and closing braces.</li>
    225 </ul>
    226 
    227 <a name="DIT"/>
    228 <h3>Depth of Inheritance Hierarchy - DIT</h3>
    229 
    230 This metric calculates how far down the inheritance hierarchy a class is
    231 declared. In Java all classes have java.lang.Object as their ultimate
    232 superclass, which is defined to have a depth of 1. So a class that
    233 immediately extends java.lang.Object has a metric value of 2; any of its
    234 subclasses will have a value of 3, and so on.
    235 <p/>
    236 A class that is deep within the tree inherits more methods and state
    237 variables, thereby increasing its complexity and making it difficult to
    238 predict its behavior. It can be harder to understand a system with many
    239 inheritance layers.
    240 <p/>
    241 DIT is defined for classes and interfaces:
    242 <ul>
    243 <li>all interface types have a depth of 1;</li>
    244 <li>the class java.lang.Object has a depth of 1;</li>
    245 <li>all other classes have a depth of 1 + the depth of their super class.</li>
    246 </ul>
    247 
    248 <a name="NOA"/>
    249 <h3>Number of Attributes - NOA</h3>
    250 
    251 The number of distinct state variables in a class serves as one measure of
    252 its complexity. The more state a class represents the more difficult it is to
    253 maintain invariants for it. It also hinders comprehensibility and reuse.
    254 <p/>
    255 In Java, state can be exposed to subclasses through protected fields, which
    256 entails that the subclass also be aware of and maintain any invariants. This
    257 interference with the class's data encapsulation can be a source of defects
    258 and hidden dependencies between the state variables.
    259 <p/>
    260 NOA is defined for classes and interfaces.  It counts the number of fields
    261 declared in the class or interface.
    262 
    263 <a name="NRM"/>
    264 <h3>Number of Remote Methods - NRM</h3>
    265 
    266 NRM is defined for classes.  A remote method call is defined as an
    267 invocation of a method that is not declared in any of:
    268 <ul>
    269 <li>the class itself;</li>
    270 <li>a class or interface that the class extends or implements;</li>
    271 <li>a class or method that extends the class.</li>
    272 </ul>
    273 
    274 The value is the count of all the remote method calls in all of the methods
    275 and constructors of the class.
    276 
    277 <a name="NLM"/>
    278 <h3>Number of Local Methods - NLM</h3>
    279 
    280 NLM is defined for classes and interfaces.  A local method is defined as a
    281 method that is declared in the class or interface. NLM can be configured to
    282 include the local methods of all of the class's superclasses.  Methods with
    283 public, protected, package and private visibility can be independently
    284 counted by setting configuration parameters.
    285 
    286 <a name="WMC"/>
    287 <h3>Weighted Methods per Class - WMC</h3>
    288 
    289 If the number of methods in a class can be determined during the design
    290 and modeling phase of a project, it can be used as a predictor of how
    291 much time and effort is needed to develop, debug and maintain it. This
    292 metric can be further refined by incorporating a weighting for the
    293 complexity of each method. The usual weighting is given by the cyclomatic
    294 complexity of the method.
    295 <p/>
    296 The subclasses of a class inherit all of its public and protected methods,
    297 and possibly its package methods as well, so the number of methods a
    298 class has directly impacts the complexity of its subclasses. Classes with
    299 large numbers of methods are often specific to a particular application,
    300 reducing the ability to reuse them.
    301 <p/>
    302 The definition of WMC is based upon NLM, and it provides the same
    303 configuration parameters for counting inherited methods and of varying
    304 visibility. The main difference is that NLM always counts each method as 1,
    305 whereas WMC will weight each method. There are two weighting schemes:
    306 <ul>
    307 <li>V(G) the cyclomatic complexity of the method is used as its weight.
    308    Methods from class files are given a V(G) of 1.</li>
    309 <li>the arity, or the number of parameters of the method are used to
    310    determine the weight.</li>
    311 </ul>
    312 
    313 <a name="RFC"/>
    314 <h3>Response For Class - RFC</h3>
    315 
    316 The response set of a class is the set of all methods that can be invoked as
    317 a result of a message sent to an object of the class. This includes methods
    318 in the class's inheritance hierarchy and methods that can be invoked on
    319 other objects. The Response For Class metric is defined to be size of the
    320 response set for the class. A class which provides a larger response set is
    321 considered to be more complex than one with a smaller response set.
    322 <p/>
    323 One reason for this is that if a method call on a class can result in a large
    324 number of different method calls on the target and other classes, then it
    325 can be harder to test the behavior of the class and debug problems. It will
    326 typically require a deeper understanding of the potential interactions that
    327 objects of the class can have with the rest of the system.
    328 <p/>
    329 RFC is defined as the sum of NLM and NRM for the class.  The local methods
    330 include all of the public, protected, package and private methods, but not
    331 methods declared only in a superclass.
    332 
    333 <a name="DAC"/>
    334 <h3>Data Abstraction Coupling - DAC</h3>
    335 
    336 DAC is defined for classes and interfaces.  It counts the number of reference
    337 types that are used in the field declarations of the class or interface.  The
    338 component types of arrays are also counted.  Any field with a type that is
    339 either a supertype or a subtype of the class is not counted.
    340 
    341 <a name="FANOUT"/>
    342 <h3>Fan Out - FANOUT</h3>
    343 
    344 FANOUT is defined for classes and interfaces, constructors and methods. It
    345 counts the number of reference types that are used in:
    346 <ul>
    347 <li>field declarations;</li>
    348 <li>formal parameters and return types;</li>
    349 <li>throws declarations;</li>
    350 <li>local variables.</li>
    351 </ul>
    352 
    353 The component types of arrays are also counted. Any type that is either a
    354 supertype or a subtype of the class is not counted.
    355 
    356 <a name="CBO"/>
    357 <h3>Coupling Between Objects - CBO</h3>
    358 
    359 When one object or class uses another object or class they are said to be
    360 coupled. One major source of coupling is that between a superclass and a
    361 subclass. A coupling is also introduced when a method or field in another
    362 class is accessed, or when an object of another class is passed into or out
    363 of a method invocation. Coupling Between Objects is a measure of the
    364 non-inheritance coupling between two objects.
    365 <p/>
    366 A high value of coupling reduces the modularity of the class and makes
    367 reuse more difficult. The more independent a class is the more likely it is
    368 that it will be possible to reuse it in another part of the system. When a
    369 class is coupled to another class it becomes sensitive to changes in that
    370 class, thereby making maintenance for difficult. In addition, a class that is
    371 overly dependent on other classes can be difficult to understand and test in
    372 isolation.
    373 <p/>
    374 CBO is defined for classes and interfaces, constructors and methods. It
    375 counts the number of reference types that are used in:
    376 <ul>
    377 <li>field declarations</li>
    378 <li>formal parameters and return types</li>
    379 <li>throws declarations</li>
    380 <li>local variables</li>
    381 </ul>
    382 
    383 It also counts:
    384 <ul>
    385 <li>types from which field and method selections are made</li>
    386 </ul>
    387 
    388 The component types of arrays are also counted. Any type that is either a
    389 supertype or a subtype of the class is not counted.
    390 
    391 <a name="LCOM"/>
    392 <h3>Lack of Cohesion Of Methods - LCOM</h3>
    393 
    394 The cohesion of a class is the degree to which its methods are related to
    395 each other. It is determined by examining the pattern of state variable
    396 accesses within the set of methods. If all the methods access the same state
    397 variables then they have high cohesion; if they access disjoint sets of
    398 variables then the cohesion is low. An extreme example of low cohesion
    399 would be if none of the methods accessed any of the state variables.
    400 
    401 If a class exhibits low method cohesion it indicates that the design of the
    402 class has probably been partitioned incorrectly, and could benefit by being
    403 split into more classes with individually higher cohesion. On the other
    404 hand, a high value of cohesion (a low lack of cohesion) implies that the
    405 class is well designed. A cohesive class will tend to provide a high degree
    406 of encapsulation, whereas a lack of cohesion decreases encapsulation and
    407 increases complexity.
    408 <p/>
    409 Another form of cohesion that is useful for Java programs is cohesion
    410 between nested and enclosing classes. A nested class that has very low
    411 cohesion with its enclosing class would probably better designed as a peer
    412 class rather than a nested class.
    413 <p/>
    414 LCOM is defined for classes. Operationally, LCOM takes each pair of
    415 methods in the class and determines the set of fields they each access. If
    416 they have disjoint sets of field accesses increase the count P by one. If they
    417 share at least one field access then increase Q by one. After considering
    418 each pair of methods,
    419 LCOM = (P > Q) ? (P - Q) : 0
    420 <p/>
    421 Indirect access to fields via local methods can be considered by setting a
    422 metric configuration parameter.
    423 
    424 <a name="NOC"/>
    425 <h3>Number Of Classes - NOC</h3>
    426 
    427 The overall size of the system can be estimated by calculating the number
    428 of classes it contains. A large system with more classes is more complex
    429 than a smaller one because the number of potential interactions between
    430 objects is higher. This reduces the comprehensibility of the system which
    431 in turn makes it harder to test, debug and maintain.
    432 <p/>
    433 If the number of classes in the system can be projected during the initial
    434 design phase of the project it can serve as a base for estimating the total
    435 effort and cost of developing, debugging and maintaining the system.
    436 <p/>
    437 The NOC metric can also usefully be applied at the package and class level
    438 as well as the total system.
    439 <p/>
    440 NOCL is defined for class and interfaces. It counts the number of classes or
    441 interfaces that are declared. This is usually 1, but nested class declarations
    442 will increase this number.
    443 </body>
    444 </html>
    445 </xsl:template>
    446 
    447 <!-- this is the stylesheet css to use for nearly everything -->
    448 <xsl:template name="stylesheet.css">
    449     .bannercell {
    450       border: 0px;
    451       padding: 0px;
    452     }
    453     body {
    454       margin-left: 10;
    455       margin-right: 10;
    456       font:normal 80% arial,helvetica,sanserif;
    457       background-color:#FFFFFF;
    458       color:#000000;
    459     }
    460     .a td {
    461       background: #efefef;
    462     }
    463     .b td {
    464       background: #fff;
    465     }
    466     th, td {
    467       text-align: left;
    468       vertical-align: top;
    469     }
    470     th {
    471       font-weight:bold;
    472       background: #ccc;
    473       color: black;
    474     }
    475     table, th, td {
    476       font-size:100%;
    477       border: none
    478     }
    479     table.log tr td, tr th {
    480 
    481     }
    482     h2 {
    483       font-weight:bold;
    484       font-size:140%;
    485       margin-bottom: 5;
    486     }
    487     h3 {
    488       font-size:100%;
    489       font-weight:bold;
    490       background: #525D76;
    491       color: white;
    492       text-decoration: none;
    493       padding: 5px;
    494       margin-right: 2px;
    495       margin-left: 2px;
    496       margin-bottom: 0;
    497     }
    498     .Error {
    499       font-weight:bold; color:red;
    500     }
    501 
    502 </xsl:template>
    503 
    504 <!-- print the metrics of the class -->
    505 <xsl:template match="class" mode="class.details">
    506   <!--xsl:variable name="package.name" select="(ancestor::package)[last()]/@name"/-->
    507   <xsl:variable name="package.name" select="@package"/>
    508   <HTML>
    509     <HEAD>
    510       <xsl:call-template name="create.stylesheet.link">
    511         <xsl:with-param name="package.name" select="$package.name"/>
    512       </xsl:call-template>
    513     </HEAD>
    514     <BODY>
    515       <xsl:call-template name="pageHeader"/>
    516 
    517       <H3>Class <xsl:if test="not($package.name = 'unnamed package')"><xsl:value-of select="$package.name"/>.</xsl:if><xsl:value-of select="@name"/></H3>
    518       <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
    519         <xsl:call-template name="all.metrics.header"/>
    520         <xsl:apply-templates select="." mode="print.metrics"/>
    521       </table>
    522 
    523       <H3>Methods</H3>
    524       <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
    525         <xsl:call-template name="method.metrics.header"/>
    526         <xsl:apply-templates select="method" mode="print.metrics"/>
    527       </table>
    528 
    529       <xsl:call-template name="pageFooter"/>
    530     </BODY>
    531   </HTML>
    532 </xsl:template>
    533 
    534 
    535 <!-- list of classes in a package -->
    536 <xsl:template match="package" mode="classes.list">
    537   <HTML>
    538     <HEAD>
    539       <xsl:call-template name="create.stylesheet.link">
    540         <xsl:with-param name="package.name" select="@name"/>
    541       </xsl:call-template>
    542     </HEAD>
    543     <BODY>
    544       <table width="100%">
    545         <tr>
    546           <td nowrap="nowrap">
    547             <H2><a href="package-summary.html" target="classFrame"><xsl:value-of select="@name"/></a></H2>
    548           </td>
    549         </tr>
    550       </table>
    551 
    552       <H2>Classes</H2>
    553       <TABLE WIDTH="100%">
    554         <!-- xalan-nodeset:nodeset for Xalan 1.2.2 -->
    555             <xsl:for-each select="$doctree/classes/class[@package = current()/@name]">
    556                 <xsl:sort select="@name"/>
    557           <tr>
    558             <td nowrap="nowrap">
    559               <a href="{@name}.html" target="classFrame"><xsl:value-of select="@name"/></a>
    560             </td>
    561           </tr>
    562             </xsl:for-each>
    563       </TABLE>
    564     </BODY>
    565   </HTML>
    566 </xsl:template>
    567 
    568 
    569 <!--
    570   Creates an all-classes.html file that contains a link to all package-summary.html
    571   on each class.
    572 -->
    573 <xsl:template match="metrics" mode="all.classes">
    574   <html>
    575     <head>
    576       <xsl:call-template name="create.stylesheet.link">
    577         <xsl:with-param name="package.name" select="''"/>
    578       </xsl:call-template>
    579     </head>
    580     <body>
    581       <h2>Classes</h2>
    582       <table width="100%">
    583           <xsl:for-each select="$doctree/classes/class">
    584               <xsl:sort select="@name"/>
    585               <xsl:apply-templates select="." mode="all.classes"/>
    586           </xsl:for-each>
    587       </table>
    588     </body>
    589   </html>
    590 </xsl:template>
    591 
    592 <xsl:template match="class" mode="all.classes">
    593     <xsl:variable name="package.name" select="@package"/>
    594     <xsl:variable name="class.name" select="@name"/>
    595   <tr>
    596     <td nowrap="nowrap">
    597       <a target="classFrame">
    598         <xsl:attribute name="href">
    599           <xsl:if test="not($package.name='unnamed package')">
    600             <xsl:value-of select="translate($package.name,'.','/')"/><xsl:text>/</xsl:text>
    601           </xsl:if>
    602           <xsl:value-of select="$class.name"/><xsl:text>.html</xsl:text>
    603         </xsl:attribute>
    604         <xsl:value-of select="$class.name"/>
    605       </a>
    606     </td>
    607   </tr>
    608 </xsl:template>
    609 
    610 <!--
    611   Creates an html file that contains a link to all package-summary.html files on
    612   each package existing on testsuites.
    613   @bug there will be a problem here, I don't know yet how to handle unnamed package :(
    614 -->
    615 <xsl:template match="metrics" mode="all.packages">
    616   <html>
    617     <head>
    618       <xsl:call-template name="create.stylesheet.link">
    619         <xsl:with-param name="package.name" select="./package/@name"/>
    620       </xsl:call-template>
    621     </head>
    622     <body>
    623       <h2><a href="overview-summary.html" target="classFrame">Home</a></h2>
    624       <h2>Packages</h2>
    625         <table width="100%">
    626           <xsl:apply-templates select=".//package[not(./@name = 'unnamed package')]" mode="all.packages">
    627             <xsl:sort select="@name"/>
    628           </xsl:apply-templates>
    629         </table>
    630     </body>
    631   </html>
    632 </xsl:template>
    633 
    634 <xsl:template match="package" mode="all.packages">
    635   <tr>
    636     <td nowrap="nowrap">
    637       <a href="{translate(@name,'.','/')}/package-summary.html" target="classFrame">
    638         <xsl:value-of select="@name"/>
    639       </a>
    640     </td>
    641   </tr>
    642 </xsl:template>
    643 
    644 
    645 <xsl:template match="metrics" mode="overview.packages">
    646   <html>
    647     <head>
    648       <xsl:call-template name="create.stylesheet.link">
    649         <xsl:with-param name="package.name" select="''"/>
    650       </xsl:call-template>
    651     </head>
    652     <body onload="open('allclasses-frame.html','classListFrame')">
    653     <xsl:call-template name="pageHeader"/>
    654     <h3>Summary</h3>
    655     <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
    656     <tr>
    657       <th><a href="metrics-reference.html#V(G)">V(G)</a></th>
    658       <th><a href="metrics-reference.html#LOC">LOC</a></th>
    659       <th><a href="metrics-reference.html#DIT">DIT</a></th>
    660       <th><a href="metrics-reference.html#NOA">NOA</a></th>
    661       <th><a href="metrics-reference.html#NRM">NRM</a></th>
    662       <th><a href="metrics-reference.html#NLM">NLM</a></th>
    663       <th><a href="metrics-reference.html#WMC">WMC</a></th>
    664       <th><a href="metrics-reference.html#RFC">RFC</a></th>
    665       <th><a href="metrics-reference.html#DAC">DAC</a></th>
    666       <th><a href="metrics-reference.html#FANOUT">FANOUT</a></th>
    667       <th><a href="metrics-reference.html#CBO">CBO</a></th>
    668       <th><a href="metrics-reference.html#LCOM">LCOM</a></th>
    669       <th><a href="metrics-reference.html#NOCL">NOCL</a></th>
    670     </tr>
    671     <xsl:apply-templates select="." mode="print.metrics"/>
    672     </table>
    673     <table border="0" width="100%">
    674     <tr>
    675     <td style="text-align: justify;">
    676     Note: Metrics evaluate the quality of software by analyzing the program source and quantifying
    677     various kind of complexity. Complexity is a common source of problems and defects in software.
    678     High complexity makes it more difficult to develop, understand, maintain, extend, test and debug
    679     a program.
    680     <p/>
    681     The primary use of metrics is to focus your attention on those parts of code that potentially are
    682     complexity hot spots. Once the complex areas your program have been uncovered, you can take remedial
    683     actions.
    684     For additional information about metrics and their meaning, please consult
    685     Metamata Metrics manual.
    686     </td>
    687     </tr>
    688     </table>
    689 
    690     <h3>Packages</h3>
    691     <table border="0" cellpadding="5" cellspacing="2" width="100%">
    692       <xsl:call-template name="all.metrics.header"/>
    693       <xsl:for-each select=".//package[not(@name = 'unnamed package')]">
    694         <xsl:sort select="@name" order="ascending"/>
    695         <xsl:apply-templates select="." mode="print.metrics"/>
    696       </xsl:for-each>
    697     </table>
    698     <!-- @bug there could some classes at this level (classes in unnamed package) -->
    699     <xsl:call-template name="pageFooter"/>
    700     </body>
    701     </html>
    702 </xsl:template>
    703 
    704 <xsl:template match="package" mode="package.summary">
    705   <HTML>
    706     <HEAD>
    707       <xsl:call-template name="create.stylesheet.link">
    708         <xsl:with-param name="package.name" select="@name"/>
    709       </xsl:call-template>
    710     </HEAD>
    711     <body onload="open('package-frame.html','classListFrame')">
    712       <xsl:call-template name="pageHeader"/>
    713       <!-- create an anchor to this package name -->
    714       <h3>Package <xsl:value-of select="@name"/></h3>
    715 
    716       <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
    717         <xsl:call-template name="all.metrics.header"/>
    718         <xsl:apply-templates select="." mode="print.metrics"/>
    719       </table>
    720 
    721       <table border="0" width="100%">
    722       <tr>
    723       <td style="text-align: justify;">
    724       Note: Metrics evaluate the quality of software by analyzing the program source and quantifying
    725       various kind of complexity. Complexity is a common source of problems and defects in software.
    726       High complexity makes it more difficult to develop, understand, maintain, extend, test and debug
    727       a program.
    728       <p/>
    729       The primary use of metrics is to focus your attention on those parts of code that potentially are
    730       complexity hot spots. Once the complex areas your program have been uncovered, you can take remedial
    731       actions.
    732       For additional information about metrics and their meaning, please consult
    733       Metamata Metrics manual.
    734       </td>
    735       </tr>
    736       </table>
    737 
    738       <xsl:variable name="classes-in-package" select="$doctree/classes/class[@package = current()/@name]"/>
    739       <xsl:if test="count($classes-in-package) &gt; 0">
    740         <H3>Classes</H3>
    741         <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
    742           <xsl:call-template name="all.metrics.header"/>
    743           <xsl:for-each select="$classes-in-package">
    744                 <xsl:sort select="@name"/>
    745                 <xsl:apply-templates select="." mode="print.metrics"/>
    746           </xsl:for-each>
    747         </table>
    748       </xsl:if>
    749 
    750       <xsl:call-template name="pageFooter"/>
    751     </body>
    752   </HTML>
    753 </xsl:template>
    754 
    755 
    756 <!--
    757     transform string like a.b.c to ../../../
    758     @param path the path to transform into a descending directory path
    759 -->
    760 <xsl:template name="path">
    761   <xsl:param name="path"/>
    762   <xsl:if test="contains($path,'.')">
    763     <xsl:text>../</xsl:text>
    764     <xsl:call-template name="path">
    765       <xsl:with-param name="path"><xsl:value-of select="substring-after($path,'.')"/></xsl:with-param>
    766     </xsl:call-template>
    767   </xsl:if>
    768   <xsl:if test="not(contains($path,'.')) and not($path = '')">
    769     <xsl:text>../</xsl:text>
    770   </xsl:if>
    771 </xsl:template>
    772 
    773 
    774 <!-- create the link to the stylesheet based on the package name -->
    775 <xsl:template name="create.stylesheet.link">
    776   <xsl:param name="package.name"/>
    777   <LINK REL ="stylesheet" TYPE="text/css" TITLE="Style"><xsl:attribute name="href"><xsl:if test="not($package.name = 'unnamed package')"><xsl:call-template name="path"><xsl:with-param name="path" select="$package.name"/></xsl:call-template></xsl:if>stylesheet.css</xsl:attribute></LINK>
    778 </xsl:template>
    779 
    780 
    781 <!-- Page Header -->
    782 <xsl:template name="pageHeader">
    783 
    784   <!-- jakarta logo -->
    785   <table border="0" cellpadding="0" cellspacing="0" width="100%">
    786   <tr>
    787     <td class="bannercell" rowspan="2">
    788       <a href="http://jakarta.apache.org/">
    789       <img src="http://jakarta.apache.org/images/jakarta-logo.gif" alt="http://jakarta.apache.org" align="left" border="0"/>
    790       </a>
    791     </td>
    792     <td style="text-align:right"><h2>Source Code Metrics</h2></td>
    793     </tr>
    794     <tr>
    795     <td style="text-align:right">Designed for use with <a href='http://www.webgain.com/products/quality_analyzer/'>Webgain QA/Metamata Metrics</a> and <a href='http://jakarta.apache.org'>Ant</a>.</td>
    796     </tr>
    797   </table>
    798   <hr size="1"/>
    799 </xsl:template>
    800 
    801 <!-- Page Footer -->
    802 <xsl:template name="pageFooter">
    803 </xsl:template>
    804 
    805 <!-- class header -->
    806 <xsl:template name="all.metrics.header">
    807   <tr>
    808     <th width="80%">Name</th>
    809     <th nowrap="nowrap">V(G)</th>
    810     <th>LOC</th>
    811     <th>DIT</th>
    812     <th>NOA</th>
    813     <th>NRM</th>
    814     <th>NLM</th>
    815     <th>WMC</th>
    816     <th>RFC</th>
    817     <th>DAC</th>
    818     <th>FANOUT</th>
    819     <th>CBO</th>
    820     <th>LCOM</th>
    821     <th>NOCL</th>
    822   </tr>
    823 </xsl:template>
    824 
    825 <!-- method header -->
    826 <xsl:template name="method.metrics.header">
    827   <tr>
    828     <th width="80%">Name</th>
    829     <th nowrap="nowrap">V(G)</th>
    830     <th>LOC</th>
    831     <th>FANOUT</th>
    832     <th>CBO</th>
    833   </tr>
    834 </xsl:template>
    835 
    836 <!-- method information -->
    837 <xsl:template match="method" mode="print.metrics">
    838   <tr>
    839     <xsl:call-template name="alternate-row"/>
    840     <td><xsl:apply-templates select="@name"/></td>
    841     <td><xsl:apply-templates select="@vg"/></td>
    842     <td><xsl:apply-templates select="@loc"/></td>
    843     <td><xsl:apply-templates select="@fanout"/></td>
    844     <td><xsl:apply-templates select="@cbo"/></td>
    845   </tr>
    846 </xsl:template>
    847 
    848 <!-- class information -->
    849 <xsl:template match="class" mode="print.metrics">
    850   <tr>
    851     <xsl:call-template name="alternate-row"/>
    852     <td><a href="{@name}.html"><xsl:value-of select="@name"/></a></td>
    853     <td><xsl:apply-templates select="@vg"/></td>
    854     <td><xsl:apply-templates select="@loc"/></td>
    855     <td><xsl:apply-templates select="@dit"/></td>
    856     <td><xsl:apply-templates select="@noa"/></td>
    857     <td><xsl:apply-templates select="@nrm"/></td>
    858     <td><xsl:apply-templates select="@nlm"/></td>
    859     <td><xsl:apply-templates select="@wmc"/></td>
    860     <td><xsl:apply-templates select="@rfc"/></td>
    861     <td><xsl:apply-templates select="@dac"/></td>
    862     <td><xsl:apply-templates select="@fanout"/></td>
    863     <td><xsl:apply-templates select="@cbo"/></td>
    864     <td><xsl:apply-templates select="@lcom"/></td>
    865     <td><xsl:apply-templates select="@nocl"/></td>
    866   </tr>
    867 </xsl:template>
    868 
    869 <xsl:template match="file|package" mode="print.metrics">
    870   <tr>
    871     <xsl:call-template name="alternate-row"/>
    872     <td>
    873     <a href="{translate(@name,'.','/')}/package-summary.html" target="classFrame">
    874     <xsl:value-of select="@name"/>
    875     </a>
    876     </td>
    877     <td><xsl:apply-templates select="@vg"/></td>
    878     <td><xsl:apply-templates select="@loc"/></td>
    879     <td><xsl:apply-templates select="@dit"/></td>
    880     <td><xsl:apply-templates select="@noa"/></td>
    881     <td><xsl:apply-templates select="@nrm"/></td>
    882     <td><xsl:apply-templates select="@nlm"/></td>
    883     <td><xsl:apply-templates select="@wmc"/></td>
    884     <td><xsl:apply-templates select="@rfc"/></td>
    885     <td><xsl:apply-templates select="@dac"/></td>
    886     <td><xsl:apply-templates select="@fanout"/></td>
    887     <td><xsl:apply-templates select="@cbo"/></td>
    888     <td><xsl:apply-templates select="@lcom"/></td>
    889     <td><xsl:apply-templates select="@nocl"/></td>
    890   </tr>
    891 </xsl:template>
    892 
    893 <xsl:template match="metrics" mode="print.metrics">
    894   <tr>
    895     <xsl:call-template name="alternate-row"/>
    896       <!-- the global metrics is the top package metrics -->
    897     <td><xsl:apply-templates select="./package/@vg"/></td>
    898     <td><xsl:apply-templates select="./package/@loc"/></td>
    899     <td><xsl:apply-templates select="./package/@dit"/></td>
    900     <td><xsl:apply-templates select="./package/@noa"/></td>
    901     <td><xsl:apply-templates select="./package/@nrm"/></td>
    902     <td><xsl:apply-templates select="./package/@nlm"/></td>
    903     <td><xsl:apply-templates select="./package/@wmc"/></td>
    904     <td><xsl:apply-templates select="./package/@rfc"/></td>
    905     <td><xsl:apply-templates select="./package/@dac"/></td>
    906     <td><xsl:apply-templates select="./package/@fanout"/></td>
    907     <td><xsl:apply-templates select="./package/@cbo"/></td>
    908     <td><xsl:apply-templates select="./package/@lcom"/></td>
    909     <td><xsl:apply-templates select="./package/@nocl"/></td>
    910   </tr>
    911 </xsl:template>
    912 
    913 <!-- alternated row style -->
    914 <xsl:template name="alternate-row">
    915 <xsl:attribute name="class">
    916   <xsl:if test="position() mod 2 = 1">a</xsl:if>
    917   <xsl:if test="position() mod 2 = 0">b</xsl:if>
    918 </xsl:attribute>
    919 </xsl:template>
    920 
    921 
    922 <!-- how to display the metrics with their max value -->
    923 <!-- @todo the max values must be external to the xsl -->
    924 
    925   <xsl:template match="@vg">
    926     <xsl:call-template name="display-value">
    927       <xsl:with-param name="value" select="current()"/>
    928       <xsl:with-param name="max" select="$vg.max"/>
    929     </xsl:call-template>
    930   </xsl:template>
    931 
    932   <xsl:template match="@loc">
    933     <xsl:call-template name="display-value">
    934       <xsl:with-param name="value" select="current()"/>
    935       <xsl:with-param name="max" select="$loc.max"/>
    936     </xsl:call-template>
    937   </xsl:template>
    938 
    939   <xsl:template match="@dit">
    940     <xsl:call-template name="display-value">
    941       <xsl:with-param name="value" select="current()"/>
    942       <xsl:with-param name="max" select="$dit.max"/>
    943     </xsl:call-template>
    944   </xsl:template>
    945 
    946   <xsl:template match="@noa">
    947     <xsl:call-template name="display-value">
    948       <xsl:with-param name="value" select="current()"/>
    949       <xsl:with-param name="max" select="$noa.max"/>
    950     </xsl:call-template>
    951   </xsl:template>
    952 
    953   <xsl:template match="@nrm">
    954     <xsl:call-template name="display-value">
    955       <xsl:with-param name="value" select="current()"/>
    956       <xsl:with-param name="max" select="$nrm.max"/>
    957     </xsl:call-template>
    958   </xsl:template>
    959 
    960   <xsl:template match="@nlm">
    961     <xsl:call-template name="display-value">
    962       <xsl:with-param name="value" select="current()"/>
    963       <xsl:with-param name="max" select="$nlm.max"/>
    964     </xsl:call-template>
    965   </xsl:template>
    966 
    967   <xsl:template match="@wmc">
    968     <xsl:call-template name="display-value">
    969       <xsl:with-param name="value" select="current()"/>
    970       <xsl:with-param name="max" select="$wmc.max"/>
    971     </xsl:call-template>
    972   </xsl:template>
    973 
    974   <xsl:template match="@rfc">
    975     <xsl:call-template name="display-value">
    976       <xsl:with-param name="value" select="current()"/>
    977       <xsl:with-param name="max" select="$rfc.max"/>
    978     </xsl:call-template>
    979   </xsl:template>
    980 
    981   <xsl:template match="@dac">
    982     <xsl:call-template name="display-value">
    983       <xsl:with-param name="value" select="current()"/>
    984       <xsl:with-param name="max" select="$dac.max"/>
    985     </xsl:call-template>
    986   </xsl:template>
    987 
    988   <xsl:template match="@fanout">
    989     <xsl:call-template name="display-value">
    990       <xsl:with-param name="value" select="current()"/>
    991       <xsl:with-param name="max" select="$fanout.max"/>
    992     </xsl:call-template>
    993   </xsl:template>
    994 
    995   <xsl:template match="@cbo">
    996     <xsl:call-template name="display-value">
    997       <xsl:with-param name="value" select="current()"/>
    998       <xsl:with-param name="max" select="$cbo.max"/>
    999     </xsl:call-template>
   1000   </xsl:template>
   1001 
   1002   <xsl:template match="@lcom">
   1003     <xsl:call-template name="display-value">
   1004       <xsl:with-param name="value" select="current()"/>
   1005       <xsl:with-param name="max" select="$lcom.max"/>
   1006     </xsl:call-template>
   1007   </xsl:template>
   1008 
   1009   <xsl:template match="@nocl">
   1010     <xsl:call-template name="display-value">
   1011       <xsl:with-param name="value" select="current()"/>
   1012       <xsl:with-param name="max" select="$nocl.max"/>
   1013     </xsl:call-template>
   1014   </xsl:template>
   1015 
   1016   <xsl:template name="display-value">
   1017     <xsl:param name="value"/>
   1018     <xsl:param name="max"/>
   1019     <xsl:if test="$value > $max">
   1020       <xsl:attribute name="class">Error</xsl:attribute>
   1021     </xsl:if>
   1022     <xsl:value-of select="$value"/>
   1023   </xsl:template>
   1024 
   1025 </xsl:stylesheet>
   1026 
   1027