Skip to content

Commit

Permalink
#2 CAMC works
Browse files Browse the repository at this point in the history
  • Loading branch information
yegor256 committed Oct 17, 2017
1 parent a0b6ed2 commit bc5bc36
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 10 deletions.
88 changes: 80 additions & 8 deletions src/main/java/org/jpeek/metrics/cohesion/CAMC.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,16 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtMethod;
import javassist.NotFoundException;
import org.cactoos.iterable.Filtered;
import org.cactoos.iterable.Joined;
import org.cactoos.iterable.Mapped;
Expand All @@ -50,7 +56,9 @@
* @see <a href="https://pdfs.semanticscholar.org/2709/1005bacefaee0242cf2643ba5efa20fa7c47.pdf">A class cohesion metric for object-oriented designs</a>
* @since 0.1
* @checkstyle AbbreviationAsWordInNameCheck (5 lines)
* @checkstyle ClassDataAbstractionCouplingCheck (500 lines)
*/
@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
public final class CAMC implements Metric {

/**
Expand Down Expand Up @@ -96,7 +104,6 @@ public Iterable<Directive> xembly() throws IOException {
* @return Metrics
* @throws IOException If fails
*/
@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
private Iterable<Map.Entry<String, Directives>> metrics()
throws IOException {
final Map<String, Directives> map = new HashMap<>(0);
Expand Down Expand Up @@ -126,13 +133,78 @@ private Map.Entry<String, Directives> metric(
final CtClass ctc = this.pool.makeClass(
new FileInputStream(file.toFile())
);
return new MapEntry<>(
ctc.getPackageName(),
new Directives()
.add("class")
.attr("id", ctc.getSimpleName())
.attr("value", "0")
.up()
try {
return new MapEntry<>(
ctc.getPackageName(),
new Directives()
.add("class")
.attr("id", ctc.getSimpleName())
.attr("value", String.format("%.4f", CAMC.cohesion(ctc)))
.up()
);
} catch (final NotFoundException ex) {
throw new IllegalStateException(ex);
}
}

/**
* Calculate CAMC metric for a single Java class.
* @param ctc The .class file
* @return Metrics
* @throws NotFoundException If fails
*/
private static double cohesion(final CtClass ctc) throws NotFoundException {
final Collection<Collection<String>> methods = CAMC.methods(ctc);
final Collection<String> types = new HashSet<>(
new org.cactoos.collection.Joined<String>(
() -> new org.cactoos.iterator.Mapped<>(
methods.iterator(),
strings -> strings
)
)
);
int sum = 0;
for (final Collection<String> mtd : methods) {
int mine = 0;
for (final String arg : mtd) {
if (types.contains(arg)) {
++mine;
}
}
sum += mine;
}
final double cohesion;
if (types.isEmpty() || methods.isEmpty()) {
cohesion = 1.0d;
} else {
cohesion = (double) sum / (double) (types.size() * methods.size());
}
return cohesion;
}

/**
* Get all method signatures.
* @param ctc The .class file
* @return Method signatures
* @throws NotFoundException If fails
*/
private static Collection<Collection<String>> methods(final CtClass ctc)
throws NotFoundException {
final Collection<Collection<String>> methods = new LinkedList<>();
for (final CtMethod mtd : ctc.getDeclaredMethods()) {
final Collection<String> args = new LinkedList<>();
for (final CtClass arg : mtd.getParameterTypes()) {
args.add(arg.getName());
}
methods.add(args);
}
for (final CtConstructor ctor : ctc.getConstructors()) {
final Collection<String> args = new LinkedList<>();
for (final CtClass arg : ctor.getParameterTypes()) {
args.add(arg.getName());
}
methods.add(args);
}
return methods;
}
}
7 changes: 5 additions & 2 deletions src/test/java/org/jpeek/metrics/cohesion/CAMCTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
public final class CAMCTest {

@Test
public void createsXmlReport() throws IOException {
public void createsBigXmlReport() throws IOException {
MatcherAssert.assertThat(
XhtmlMatchers.xhtml(
new Xembler(
Expand All @@ -51,7 +51,10 @@ public void createsXmlReport() throws IOException {
).xembly()
).xmlQuietly()
),
XhtmlMatchers.hasXPaths("/app/package/class[@id = 'CAMCTest']")
XhtmlMatchers.hasXPaths(
"/app/package/class[@id='CAMCTest']",
"//class[@id='Base' and @value='1.0000']"
)
);
}

Expand Down

0 comments on commit bc5bc36

Please sign in to comment.