How to Write Java/CVS Metrics Using JCVSReport

JCVSReport supports two types of metrics: Metrics that operate on the raw source code, and metrics that operate on a compiled Java syntax tree. Both types of metrics are easy to setup. We'll show you examples of both, below.

Raw Source Code

We define two classes of metrics that operate on raw source code:

What's the difference between the above two? Well, let's say you're looking for comments in the source code. Do you want to count the number of comments, or the number of lines of comments? It's all up to you -- take your pick!

Now for an example. Let's say you're tired of your teammates putting tabs in your source code, and you'd like to make a new metric that will pin down exactly who put those annoying tabs in your source code. JCVSReport supports this out of the box with the LinesOfTabs metric. Let's see how it's implemented, under the hood, so that you can implement your own new metrics too.

class=ca.utoronto.JCVSReport.metric.RegexLineCounter
title=Lines With Tabs
regex=\t.*\n

It's that easy to define a metric! Now let's say you wanted to define something more complicated, like the number of lines of JavaDoc comments. JavaDoc comments are delimited by /** and */ characters, so you'll need to write a regular expression that does this. We do this below.

class=ca.utoronto.JCVSReport.metric.RegexLineCounter
title=Lines of JavaDoc
regex=/\\*\\*(?s:.*?)\\*/.*\n

RegexLineCounter takes that regular expression and then counts the number of newlines that are matched by that regular expression.

Now let's say you changed your mind, and you instead wanted to count the number of JavaDoc comments, rather than the number of lines. That's as easy as changing the above .properties file to reference "RegexMatchCounter" instead of "RegexLineCounter"!

If you'd like to see docs on how regular expressions work in Java, please see the java.util.regex.Pattern JavaDoc

Java Syntax Tree

It's even easier to define Java Syntax tree metrics than it is to define raw source code metrics. For example, here's a properties file that counts the number of methods and constructors in a piece of code:

class=ca.utoronto.JCVSReport.metric.SyntaxTreeRegexMatchCounter
title=Number of Methods
regex=MethodDeclarator|ConstructorDeclaration

Imagine, for Phase D, that Karen asks us to count the 'cyclomatic complexity' of a piece of code. 'Cyclomatic complexity' is defined as the number of possible paths through a particular piece of code. It sounds complex, and it is. But thanks to our careful design, it's not too difficult to implement with JCVSReport. Here's how we did it.

First, we figured out exactly what we need to count with Cyclomatic Complexity. We need to count: (the number of constuctors) + (the number of functions without return statements) + (the number of if, while, do, for, return or throw statements) + (the number of case labels in switch statements) + (the number of catch statements)

The following regular expressions count each of the above concepts

Putting those patterns all into a single .properties file, we get the following:

class=ca.utoronto.JCVSReport.metric.SyntaxTreeRegexMatchCounter
title=Cyclomatic Complexity
regex=\
ConstructorDeclaration\
|MethodDeclaration\\S+\\s+ResultType\\s+MethodDeclarator\
|(If|While|Do|For|Return|Throw)Statement\
|SwitchLabel\
|TryStatement:\\(has catch\\)


Back to the JCVSReport page