Skip to content

Commit cdd327e

Browse files
committed
Merge branch 'master' of github.com:Kiskae/Java-Source-Metrics
2 parents 4da0080 + bd28100 commit cdd327e

2 files changed

Lines changed: 117 additions & 2 deletions

File tree

EXTENDING.md

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,46 @@
1-
TODO
1+
Extending JSM
2+
===============
3+
4+
JSM can be extended in two ways:
5+
* Custom metrics, using the built-in data to calculate custom metrics and report the results.
6+
* Modified class visitor, expand the set of data available within the default frame.
7+
8+
Custom Metrics
9+
--------------
10+
11+
JSM uses a system of 3 metric-types that work to create a directional graph of dependencies to calculate their results.
12+
13+
* The first metric-type is the [IsolatedMetric](src/main/java/nl/rug/jbi/jsm/core/calculator/IsolatedMetric.java). This type is meant for metrics that can be calculated with just the information provided by the source. (The source being class/package/collection-specific sets of data)
14+
* The second metric-type is the [SharedMetric](src/main/java/nl/rug/jbi/jsm/core/calculator/SharedMetric.java). The shared metric is a metric where information from sources other than the assigned source are required, an example being a metric that requires reverse-mapping of relations. These metrics recieve the full dataset from all individual sources and process that dataset into a set of results.
15+
* The final metric-type is the [ProducerMetric](src/main/java/nl/rug/jbi/jsm/core/calculator/ProducerMetric.java). This type serves to both act as a common data-source for a set of metrics as well as bridge data between scopes. Producers expand the available data-set that is available to Isolated and Shared Metrics.
16+
17+
The actual definition of each metric consists of two parts. First of all the metric needs to define a set of listeners with the signature:
18+
```java
19+
@Subscribe
20+
public void <name>(MetricState state, <ObjectType> obj) {
21+
...
22+
}
23+
```
24+
The [Subscribe](src/main/java/nl/rug/jbi/jsm/core/event/Subscribe.java) annotation marks the method as a listener method, when the system encounters an object of type `<ObjectType>`, it will invoke that method with a system-managed State object. A list of objects that are available in the system by default can be found in [nl.rug.jbi.jsm.bcel](src/main/java/nl/rug/jbi/jsm/bcel).
25+
26+
A method can also listen for a Producer-produced Object, this is done with the following signature:
27+
```java
28+
@Subscribe
29+
@UsingProducer(<ProducerClass>.class)
30+
public void <name>(MetricState state, <Produce> obj) {
31+
...
32+
}
33+
```
34+
35+
The second part of the metric definition is the results/produce calculation, this is implemented as an abstract method in each of the metric-type classes. Shared/Producer-Metrics in general shouldn't return null, but an empty List if there are no results. Please refer to the javadocs for more information. Example implementations of metrics can be found in the [nl.rug.jbi.jsm.metrics](src/main/java/nl/rug/jbi/jsm/metrics) package.
36+
37+
38+
Modifying the Class Visitor
39+
-----------------
40+
41+
Using a modified class visitor is a three-part process:
42+
43+
1. Create a subclass of the default Class Visitor, if methods are overridden to add more data to broadcast, the super-method needs to be called to ensure the class-visitor completes. Objects can be broadcast using the [EventBus](src/main/java/nl/rug/jbi/jsm/core/event/EventBus.java) object that is available in the class visitor.
44+
2. Any new base data-types added by the modified class visitor need to be registered using [nl.rug.jbi.jsm.core.pipeline.Pipeline.registerNewBaseData(Class)](src/main/java/nl/rug/jbi/jsm/core/pipeline/Pipeline.java#L75). This needs to happen before any instances of the [Pipeline](src/main/java/nl/rug/jbi/jsm/core/pipeline/Pipeline.java) class are created. (JSMCore creates an instance of Pipeline)
45+
3. After creating a [PipelineExecutor](src/main/java/nl/rug/jbi/jsm/core/execution/PipelineExecutor.java), invoke the `setClassVisitorFactory(ClassVisitorFactory)` method on the instance using a new Factory for the custom ClassVisitor.
46+
4. Execute the executor, it will now calculate all the metrics using the new class-visitor as basic data-source.

HOWTOUSE.md

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,71 @@
1-
TODO
1+
How to use
2+
============
3+
4+
Building JSM produces an executable .jar file, this file can be executed in two different ways:
5+
* The first is GUI mode, which gets started if there are no additional parameters given when the application is started.
6+
* The second is Script mode, which gets started if there is at least 1 parameters given when the application starts, the parsing of these parameters will be described below in the *Script Mode* section.
7+
8+
To use the application, the following things need to be kept in mind regardless of what mode is used:
9+
* JSM considers the set of all inputs (and the classes they contain) to be a single full application. This has consequences for the results because inter-collection usage and extending is allowed. If the results for just 1 .jar is required then the other .jars should be provided as libraries.
10+
* The application will output detailed logs and exceptions to the `logs` folder in the working directory, if calculation of a unit fails due to an exception, these logs will contain the entire stacktrace.
11+
* When exporting the results to CSV, there are two things that need to be set:
12+
* Choose whether the metrics get exported by scope (so all CLASS/PACKAGE/COLLECTION datasets go in their own files) or by metric (Each metric/scope combination gets its own file).
13+
* The export path needs to contain the token `%s`, this token will get replaced by unique identifiers for each metric/scope.
14+
15+
The application comes packaged with two collections of metrics implemented, a brief description of these metrics and their definitions can be found at the bottom of this file. If a custom metric is required please refer to [EXTENDING.md](EXTENDING.md)
16+
17+
GUI Mode
18+
------------
19+
20+
![GUI Legend](imgs/gui-legend.png)
21+
22+
1. `Scope Tabs` switches between the tables displaying the results for the various scopes.
23+
2. `Input Sources` sources of class files that will be subject to calculation.
24+
3. `Library Sources` sources of class files that will not be subject to calculation, but used for class resolving.
25+
4. `Results Table` will display the results from the last execution, given the scope that the `Scope Tabs` is set to.
26+
5. `Execute` begin calculation of metrics on the current input.
27+
6. `Export` export the results to .csv files.
28+
7. `Console` will show information about failures during execution, as well as any messages sent out by the metrics.
29+
30+
31+
Script Mode
32+
------------
33+
34+
Script mode is meant as a way to automatically process an input set, to give JSM the information it needs to execute the following syntax is used:
35+
36+
* Argument context is controlled through a series of flags, initially the application will ignore any input until the first switching flag is encountered.
37+
* Flags:
38+
* `--in` signifies the following arguments are treated as input, the arguments have to be a path to either a .jar or a directory tree containing .class files. (The directory tree is required to have a package-structure)
39+
* `--out` signifies the following arguments are treated as possible targets for the .csv export, these targets will be linearly searched for an unused target where the .csv files can be exported to.
40+
* `--lib` signifies the following arguments are treated as libraries, he arguments have to be a path to either a .jar or a directory tree containing .class files. (The directory tree is required to have a package-structure)
41+
* The script mode defaults to export by metric, use `--group-scopes` to set it to export by scope.
42+
43+
Example input for script mode:
44+
```bash
45+
java -jar jsm-1.2.jar --in app.part1.jar app.part2.jar --lib lib1.jar --out results/%s.csv --group-scopes
46+
```
47+
48+
49+
Implemented Metrics
50+
------------
51+
52+
*CKJM*: Class-based metrics based on the paper by [Chidamber and Kemerer](http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=295895) and the implementation by [Diomidis Spinellis](/dspinellis/ckjm). Please note that the implementation differs in a few places due to errors in the CKJM implementation.
53+
* `Weighted Methods per Class (WMC)` In this implementation, this reflects the total number of methods in a class, including (static) initializers.
54+
* `Depth of Inheritance Tree (DIT)` Number of superclasses that the inspected class has, in Java this is always at least 1 due to Object.
55+
* `Number of Children (NOC)` Reverse of DIT, this tells how many of the inspected classes are subclasses of the inspected class.
56+
* `Coupling between Object Classes (CBO)` This represents the number of classes used within the inspected class.
57+
* `Response for a Class (RFC)` Number of unique methods used within a class, includes all declared methods in that class.
58+
* `Lack of Cohesion in Methods (LCOM)` Represents the degree to which methods share the use of variables in a class.
59+
* `Afferent Couplings (CA)` Reverse-mapping of CBO, represents the number of classes using the inspected class in some way.
60+
* `Number of Public Methods (NPM)` Simple metric that reflects the number of public methods in the inspected class.
61+
62+
*Package Metrics* Package-based metrics based on the paper by [Abdeen, Ducasse and Sahraoui](http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=6079866). The main way in which metrics are calculated is by defining a `Uses` and `Extends` set for each class. `Uses` is defined as using a class in a method invocation or field access that is not a superclass of the inspected class. `Extends` is the set of classes directly extended or implemented by the class. All results are defined as being between [0..1]
63+
* `Index of Inter-Package Usage (IIPU)` describes how much of the usage within a package is hidden from the outside. A low number of classes used from the outside results in a higher result.
64+
* `Index of Inter-Package Extending (IIPE)` describes how much of the extending within a package is hidden from the outside. A low number of classes extended from the outside results in a higher result.
65+
* `Index of Package Changing Impact (IPCI)` defines how many packages within a collection depend on the specified package, a low number indicates a lot of the other packages depend on its functionality.
66+
* `Index of Inter-Package Usage Diversion (IIPUD)` describes the usage of other packages, a high value indicates use is limited to a small number of packages and a high number of classes in those packages.
67+
* `Index of Inter-Package Extending Diversion (IIPED)` describes the extending of other packages, a high value indicates extending is limited to a small number of packages and a high number of classes in those packages.
68+
* `Index of Package Goal Focus (PF)` describes the way a package is used, it lowers depending on the divergence in sets of classes used by other packages, with cases where the same set of packages is used raises the value.
69+
* `Index of Package Services Cohesion (IPSC)` is an addition to PF, it calculates the cross-over between different sets of used packages, lowering the result if a class is reused for different purposes within a package.
70+
71+
If you want to extend the application with custom metrics, please see [EXTENDING.md](EXTENDING.md)

0 commit comments

Comments
 (0)