Internal builder for MetricOptions

This commit is contained in:
oowekyala
2017-08-17 18:36:05 +02:00
committed by Clément Fournier
parent 8bac632333
commit f747129e8c
5 changed files with 85 additions and 24 deletions

View File

@ -78,7 +78,18 @@ Some metrics define options that can be used to slightly modify the computation.
gathered inside an enum in the implementation class of the metric, for example `CycloMetric.CycloOptions`. They're
also documented on the [index of metrics](/pmd_java_metrics_index.html).
To use options with a metric, you must first bundle them into a `MetricOptions`.
To use options with a metric, you must first bundle them into a `MetricOptions` object. `MetricOptions` provides the
utility method `toOptions(Collection<? extends MetricOption>)` to get a `MetricOptions` bundle. You can then pass
this bundle as a parameter to `JavaMetrics.get`:
```java
public Object visit(ASTMethodDeclaration node, Object data) {
int cyclo = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, node, MetricOptions.toOptions());
if (cyclo > 10) {
// add violation
}
return data;
}
```

View File

@ -97,7 +97,7 @@ public abstract class AbstractApexMetricTestRule extends AbstractApexRule {
/**
* Mappings of labels to options for use in the options property.
*
* @return A map of labels to options
* @return A map of labels to options&
*/
protected Map<String, MetricOption> optionMappings() {
return new HashMap<>();

View File

@ -18,7 +18,7 @@ import java.util.Set;
*/
public class MetricOptions {
private static final Map<MetricOptions, MetricOptions> POOL = new HashMap<>();
static final Map<MetricOptions, MetricOptions> POOL = new HashMap<>();
private static final MetricOptions EMPTY_OPTIONS;
private Set<MetricOption> options;
@ -34,7 +34,7 @@ public class MetricOptions {
}
private MetricOptions(Set<MetricOption> opts) {
private MetricOptions(Set<? extends MetricOption> opts) {
switch (opts.size()) {
case 0:
@ -94,31 +94,81 @@ public class MetricOptions {
*
* @return An empty options bundle
*/
public static MetricOptions emptyOptions() {
return EMPTY_OPTIONS;
}
/**
* Gets an options bundle from a list of options.
* Gets an options bundle from a collection of options.
*
* @param opts The options to build the bundle from
* @param options The options to build the bundle from
*
* @return An options bundle
*/
public static MetricOptions ofOptions(Collection<MetricOption> opts) {
MetricOptions version;
if (opts instanceof Set) {
version = new MetricOptions((Set<MetricOption>) opts);
} else {
version = new MetricOptions(new HashSet<>(opts));
}
if (!POOL.containsKey(version)) {
POOL.put(version, version);
}
return POOL.get(version);
public static MetricOptions ofOptions(Collection<? extends MetricOption> options) {
MetricOptionsBuilder builder = new MetricOptionsBuilder();
builder.addAll(options);
return builder.build();
}
/**
* Gets an options bundle from options.
*
* @param option Mandatory first argument
* @param options Rest of the options
*
* @return An options bundle
*/
public static MetricOptions ofOptions(MetricOption option, MetricOption... options) {
MetricOptionsBuilder builder = new MetricOptionsBuilder();
builder.add(option);
for (MetricOption opt : options) {
builder.add(opt);
}
return builder.build();
}
private static class MetricOptionsBuilder {
private Set<MetricOption> opts = new HashSet<>();
void add(MetricOption option) {
if (option != null) {
opts.add(option);
}
}
void addAll(Collection<? extends MetricOption> options) {
if (options != null) {
this.opts.addAll(options);
opts.remove(null);
}
}
MetricOptions build() {
if (opts.size() == 0) {
return emptyOptions();
}
MetricOptions result = new MetricOptions(opts);
if (!POOL.containsKey(result)) {
POOL.put(result, result);
}
return POOL.get(result);
}
}
}

View File

@ -45,7 +45,7 @@ public class CyclomaticComplexityRule extends AbstractJavaMetricsRule {
}
private static final EnumeratedMultiProperty<MetricOption> CYCLO_VERSION_DESCRIPTOR = new EnumeratedMultiProperty<>(
private static final EnumeratedMultiProperty<MetricOption> CYCLO_OPTIONS_DESCRIPTOR = new EnumeratedMultiProperty<>(
"cycloOptions", "Choose options for the computation of Cyclo",
VERSION_MAP, Collections.<MetricOption>emptyList(), MetricOption.class, 3.0f);
@ -57,7 +57,7 @@ public class CyclomaticComplexityRule extends AbstractJavaMetricsRule {
public CyclomaticComplexityRule() {
definePropertyDescriptor(CLASS_LEVEL_DESCRIPTOR);
definePropertyDescriptor(METHOD_LEVEL_DESCRIPTOR);
definePropertyDescriptor(CYCLO_VERSION_DESCRIPTOR);
definePropertyDescriptor(CYCLO_OPTIONS_DESCRIPTOR);
}
@ -66,7 +66,7 @@ public class CyclomaticComplexityRule extends AbstractJavaMetricsRule {
methodReportLevel = getProperty(METHOD_LEVEL_DESCRIPTOR);
classReportLevel = getProperty(CLASS_LEVEL_DESCRIPTOR);
if (cycloOptions == null) {
cycloOptions = MetricOptions.ofOptions(getProperty(CYCLO_VERSION_DESCRIPTOR));
cycloOptions = MetricOptions.ofOptions(getProperty(CYCLO_OPTIONS_DESCRIPTOR));
}
super.visit(node, data);

View File

@ -29,8 +29,8 @@ import net.sourceforge.pmd.lang.metrics.ParameterizedMetricKey;
*/
public class ParameterizedMetricKeyTest {
private static final MetricOptions DUMMY_VERSION_1 = MetricOptions.ofOptions(Arrays.<MetricOption>asList(Options.DUMMY1, Options.DUMMY2));
private static final MetricOptions DUMMY_VERSION_2 = MetricOptions.ofOptions(Collections.<MetricOption>singleton(Options.DUMMY2));
private static final MetricOptions DUMMY_VERSION_1 = MetricOptions.ofOptions(Options.DUMMY1, Options.DUMMY2);
private static final MetricOptions DUMMY_VERSION_2 = MetricOptions.ofOptions(Options.DUMMY2);
@Test
public void testIdentity() {