Merge branch 'ruleset-f-builder-merger' into analysis-listener

This commit is contained in:
Clément Fournier 2020-10-27 00:48:47 +01:00
commit 8213596591
23 changed files with 488 additions and 374 deletions

View File

@ -23,6 +23,23 @@ This is a {{ site.pmd.release_type }} release.
### API Changes
#### Deprecated API
##### Around RuleSet parsing
* {% jdoc core::RuleSetFactory %} and {% jdoc core::RuleSetFactoryUtils %} have been deprecated in favor of {% jdoc core::RuleSetParser %}. This is easier to configure, and more maintainable than the multiple overloads of `RuleSetFactoryUtils`.
* Some static creation methods have been added to {% jdoc core::RuleSet %} for simple cases, eg {% jdoc core::RuleSet#forSingleRule(core::Rule) %}. These replace some counterparts in {% jdoc core::RuleSetFactory %}
* Since {% jdoc core::RuleSets %} is also deprecated, many APIs that require a RuleSets instance now are deprecated, and have a counterpart that expects a `List<RuleSet>`.
* {% jdoc core::RuleSetReferenceId %}, {% jdoc core::RuleSetReference %}, {% jdoc core::RuleSetFactoryCompatibility %} are deprecated. They are most likely not relevant outside of the implementation of pmd-core.
##### Around the `PMD` class
Many APIs around PMD's entry point ({% jdoc core::PMD %}) have been deprecated, including:
* The contents of the packages {% jdoc_package core::cli %}, {% jdoc_package core::processor %}
* {% jdoc core::SourceCodeProcessor %}
* The constructors of {% jdoc core::PMD %} (the class will be made a utility class)
### External Contributions
{% endtocmaker %}

View File

@ -14,16 +14,15 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.SystemErrRule;
import net.sourceforge.pmd.RulePriority;
import net.sourceforge.pmd.RuleSet;
import net.sourceforge.pmd.RuleSetFactory;
import net.sourceforge.pmd.RulesetsFactoryUtils;
import net.sourceforge.pmd.RuleSetParser;
public class DefaultRulesetTest {
@Rule
public final SystemErrRule systemErrRule = new SystemErrRule().enableLog().muteForSuccessfulTests();
private RuleSetFactory factory = RulesetsFactoryUtils.createFactory(RulePriority.LOW, true, false);
private RuleSetFactory factory = new RuleSetParser().enableCompatibility(false).toFactory();
@Test
public void loadDefaultRuleset() throws Exception {

View File

@ -14,6 +14,8 @@ import java.io.Writer;
import java.net.URISyntaxException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@ -22,6 +24,7 @@ import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.benchmark.TextTimingReportRenderer;
import net.sourceforge.pmd.benchmark.TimeTracker;
import net.sourceforge.pmd.benchmark.TimedOperation;
@ -42,7 +45,6 @@ import net.sourceforge.pmd.reporting.GlobalAnalysisListener.ViolationCounterList
import net.sourceforge.pmd.util.ClasspathClassLoader;
import net.sourceforge.pmd.util.FileUtil;
import net.sourceforge.pmd.util.IOUtil;
import net.sourceforge.pmd.util.ResourceLoader;
import net.sourceforge.pmd.util.database.DBMSMetadata;
import net.sourceforge.pmd.util.database.DBURI;
import net.sourceforge.pmd.util.database.SourceObject;
@ -83,7 +85,10 @@ public final class PMD {
*
* @throws IOException if the URI couldn't be parsed
* @see DBURI
*
* @deprecated Will be hidden as part of the parsing of {@link PMD#getApplicableFiles(PMDConfiguration, Set)}
*/
@Deprecated
public static List<DataSource> getURIDataSources(String uriString) throws IOException {
List<DataSource> dataSources = new ArrayList<>();
@ -188,6 +193,7 @@ public final class PMD {
* @throws Exception If an exception occurs while closing the data sources
* Todo wrap that into a known exception type
*/
@Deprecated
public static void processFiles(PMDConfiguration configuration,
List<RuleSet> ruleSets,
List<DataSource> files,
@ -379,7 +385,7 @@ public final class PMD {
}
/**
* Entry to invoke PMD as command line tool
* Entry to invoke PMD as command line tool. Note that this will invoke {@link System#exit(int)}.
*
* @param args
* command line arguments
@ -389,7 +395,8 @@ public final class PMD {
}
/**
* Parses the command line arguments and executes PMD.
* Parses the command line arguments and executes PMD. Returns the
* exit code without exiting the VM.
*
* @param args
* command line arguments

View File

@ -24,6 +24,7 @@ import net.sourceforge.pmd.cache.ChecksumAware;
import net.sourceforge.pmd.internal.util.PredicateUtil;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.rule.RuleReference;
import net.sourceforge.pmd.lang.rule.XPathRule;
/**
* This class represents a collection of rules along with some optional filter
@ -90,6 +91,89 @@ public class RuleSet implements ChecksumAware {
filter = rs.filter; // filters are immutable, can be shared
}
/**
* Creates a new ruleset containing a single rule. The ruleset will
* have default description, name, and null file name.
*
* @param rule The rule being created
*
* @return The newly created RuleSet
*/
public static RuleSet forSingleRule(final Rule rule) {
final long checksum;
if (rule instanceof XPathRule) {
checksum = ((XPathRule) rule).getXPathExpression().hashCode();
} else {
// TODO : Is this good enough? all properties' values + rule name
checksum = rule.getPropertiesByPropertyDescriptor().values().hashCode() * 31 + rule.getName().hashCode();
}
final RuleSetBuilder builder =
new RuleSetBuilder(checksum)
.withName(rule.getName())
.withDescription("RuleSet for " + rule.getName());
builder.addRule(rule);
return builder.build();
}
/**
* Creates a new ruleset with the given metadata such as name, description,
* fileName, exclude/include patterns are used. The rules are taken from the given
* collection.
*
* <p><strong>Note:</strong> The rule instances are shared between the collection
* and the new ruleset (copy-by-reference). This might lead to concurrency issues,
* if the rules of the collection are also referenced by other rulesets and used
* in different threads.
* </p>
*
* @param name the name of the ruleset
* @param description the description
* @param fileName the filename
* @param excludePatterns list of exclude patterns
* @param includePatterns list of include patterns, that override the exclude patterns
* @param rules the collection with the rules to add to the new ruleset
*
* @return the new ruleset
*
* @throws NullPointerException If any parameter is null, or the collections contain null elements
*/
public static RuleSet create(String name,
String description,
String fileName,
Collection<Pattern> excludePatterns,
Collection<Pattern> includePatterns,
Iterable<? extends Rule> rules) {
RuleSetBuilder builder = new RuleSetBuilder(0L); // TODO: checksum missing
builder.withName(name)
.withDescription(description)
.withFileName(fileName)
.replaceFileExclusions(excludePatterns)
.replaceFileInclusions(includePatterns);
for (Rule rule : rules) {
builder.addRule(rule);
}
return builder.build();
}
/**
* Creates a copy of the given ruleset. All properties like name, description, fileName
* and exclude/include patterns are copied.
*
* <p><strong>Note:</strong> The rule instances are shared between the original
* and the new ruleset (copy-by-reference). This might lead to concurrency issues,
* if the original ruleset and the new ruleset are used in different threads.
* </p>
*
* @param original the original rule set to copy from
*
* @return the copy
*/
public static RuleSet copy(RuleSet original) {
return new RuleSet(original);
}
/* package */ static class RuleSetBuilder {
public String description;

View File

@ -37,18 +37,18 @@ import net.sourceforge.pmd.RuleSet.RuleSetBuilder;
import net.sourceforge.pmd.lang.Language;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.rule.RuleReference;
import net.sourceforge.pmd.lang.rule.XPathRule;
import net.sourceforge.pmd.rules.RuleFactory;
import net.sourceforge.pmd.util.ResourceLoader;
/**
* RuleSetFactory is responsible for creating RuleSet instances from XML
* content. By default Rules will be loaded using the {@link RulePriority#LOW} priority,
* with Rule deprecation warnings off;
* the ruleset compatibility filter is active, too (see {@link RuleSetFactoryCompatibility});
* if the ruleset contains rule references (e.g. for renamed or moved rules), these
* are ignored by default.
* content. See {@link RuleSetParser} for configuration options and
* their defaults.
*
* @deprecated Use a {@link RuleSetParser} instead. This will be hidden in PMD 7
* (it's the implementation, while {@link RuleSetParser} is the API).
*/
@Deprecated
public class RuleSetFactory {
private static final Logger LOG = Logger.getLogger(RuleSetFactory.class.getName());
@ -66,7 +66,7 @@ public class RuleSetFactory {
private final Map<RuleSetReferenceId, RuleSet> parsedRulesets = new HashMap<>();
/**
* @deprecated Use {@link RulesetsFactoryUtils#defaultFactory()}
* @deprecated Use a {@link RuleSetParser} to build a new factory
*/
@Deprecated // to be removed with PMD 7.0.0.
public RuleSetFactory() {
@ -74,8 +74,7 @@ public class RuleSetFactory {
}
/**
* @deprecated Use {@link RulesetsFactoryUtils#createFactory(ClassLoader, RulePriority, boolean, boolean)}
* or {@link RulesetsFactoryUtils#createFactory(RulePriority, boolean, boolean)}
* @deprecated Use a {@link RuleSetParser} to build a new factory
*/
@Deprecated // to be removed with PMD 7.0.0.
public RuleSetFactory(final ClassLoader classLoader, final RulePriority minimumPriority,
@ -84,8 +83,7 @@ public class RuleSetFactory {
}
/**
* @deprecated Use {@link RulesetsFactoryUtils#createFactory(ClassLoader, RulePriority, boolean, boolean)}
* or {@link RulesetsFactoryUtils#createFactory(RulePriority, boolean, boolean)}
* @deprecated Use a {@link RuleSetParser} to build a new factory
*/
@Deprecated // to be hidden with PMD 7.0.0.
public RuleSetFactory(final ResourceLoader resourceLoader, final RulePriority minimumPriority,
@ -114,12 +112,20 @@ public class RuleSetFactory {
* The factory whose configuration to copy.
* @param warnDeprecated
* Whether deprecation warnings are to be produced by this
* factory.
* factory
*
* @deprecated Use {@link #toParser()} to rebuild a factory from a configuration
*/
@Deprecated
public RuleSetFactory(final RuleSetFactory factory, final boolean warnDeprecated) {
this(factory.resourceLoader, factory.minimumPriority, warnDeprecated, factory.compatibilityFilter != null);
}
RuleSetFactory(RuleSetParser config) {
this(config.resourceLoader, config.minimumPriority, config.warnDeprecated, config.enableCompatibility, config.includeDeprecatedRuleReferences);
}
/**
* Gets the compatibility filter in order to adjust it, e.g. add additional
* filters.
@ -137,7 +143,10 @@ public class RuleSetFactory {
* @return An Iterator of RuleSet objects.
*
* @throws RuleSetNotFoundException if the ruleset file could not be found
*
* @deprecated This is apparently only used in code deprecated for removal
*/
@Deprecated
public Iterator<RuleSet> getRegisteredRuleSets() throws RuleSetNotFoundException {
String rulesetsProperties = null;
List<RuleSetReferenceId> ruleSetReferenceIds = new ArrayList<>();
@ -173,7 +182,11 @@ public class RuleSetFactory {
* @return The new RuleSets.
* @throws RuleSetNotFoundException
* if unable to find a resource.
*
* @deprecated Use {@link RuleSetParser#parseFromResource(String)},
* but note that that method does not split on commas
*/
@Deprecated
public List<RuleSet> createRuleSets(String referenceString) throws RuleSetNotFoundException {
return createRuleSets(RuleSetReferenceId.parse(referenceString));
}
@ -187,7 +200,10 @@ public class RuleSetFactory {
* @return The new RuleSets.
* @throws RuleSetNotFoundException
* if unable to find a resource.
*
* @deprecated Will not be replaced
*/
@Deprecated
public List<RuleSet> createRuleSets(List<RuleSetReferenceId> ruleSetReferenceIds) throws RuleSetNotFoundException {
List<RuleSet> ruleSets = new ArrayList<>();
for (RuleSetReferenceId ruleSetReferenceId : ruleSetReferenceIds) {
@ -209,7 +225,10 @@ public class RuleSetFactory {
* @return A new RuleSet.
* @throws RuleSetNotFoundException
* if unable to find a resource.
*
* @deprecated Use {@link RuleSetParser#parseFromResource(String)} and discard the rest of the list.
*/
@Deprecated
public RuleSet createRuleSet(String referenceString) throws RuleSetNotFoundException {
List<RuleSetReferenceId> references = RuleSetReferenceId.parse(referenceString);
if (references.isEmpty()) {
@ -228,7 +247,10 @@ public class RuleSetFactory {
* @return A new RuleSet.
* @throws RuleSetNotFoundException
* if unable to find a resource.
*
* @deprecated Will not be replaced
*/
@Deprecated
public RuleSet createRuleSet(RuleSetReferenceId ruleSetReferenceId) throws RuleSetNotFoundException {
return createRuleSet(ruleSetReferenceId, includeDeprecatedRuleReferences);
}
@ -249,7 +271,10 @@ public class RuleSetFactory {
*
* @param original the original rule set to copy from
* @return the copy
*
* @deprecated Use {@link RuleSet#copy(RuleSet)}
*/
@Deprecated
public RuleSet createRuleSetCopy(RuleSet original) {
RuleSetBuilder builder = new RuleSetBuilder(original);
return builder.build();
@ -273,23 +298,17 @@ public class RuleSetFactory {
* @param includePatterns list of include patterns, if any is not a valid regular expression, it will be ignored
* @param rules the collection with the rules to add to the new ruleset
* @return the new ruleset
*
* @deprecated Use {@link RuleSet#create(String, String, String, Collection, Collection, Iterable)}
*/
@Deprecated
public RuleSet createNewRuleSet(String name,
String description,
String fileName,
Collection<String> excludePatterns,
Collection<String> includePatterns,
Collection<Rule> rules) {
RuleSetBuilder builder = new RuleSetBuilder(0L); // TODO: checksum missing
builder.withName(name)
.withDescription(description)
.withFileName(fileName)
.replaceFileExclusions(toPatterns(excludePatterns))
.replaceFileInclusions(toPatterns(includePatterns));
for (Rule rule : rules) {
builder.addRule(rule);
}
return builder.build();
return RuleSet.create(name, description, fileName, toPatterns(excludePatterns), toPatterns(includePatterns), rules);
}
private Collection<Pattern> toPatterns(Collection<String> sources) {
@ -307,24 +326,15 @@ public class RuleSetFactory {
/**
* Creates a new RuleSet containing a single rule.
*
* @param rule
* The rule being created
* @param rule The rule being created
*
* @return The newly created RuleSet
*
* @deprecated Use {@link RuleSet#forSingleRule(Rule)}
*/
public RuleSet createSingleRuleRuleSet(final Rule rule) { // TODO make static?
final long checksum;
if (rule instanceof XPathRule) {
checksum = ((XPathRule) rule).getXPathExpression().hashCode();
} else {
// TODO : Is this good enough? all properties' values + rule name
checksum = rule.getPropertiesByPropertyDescriptor().values().hashCode() * 31 + rule.getName().hashCode();
}
final RuleSetBuilder builder = new RuleSetBuilder(checksum)
.withName(rule.getName())
.withDescription("RuleSet for " + rule.getName());
builder.addRule(rule);
return builder.build();
@Deprecated
public RuleSet createSingleRuleRuleSet(final Rule rule) {
return RuleSet.forSingleRule(rule);
}
/**
@ -347,7 +357,8 @@ public class RuleSetFactory {
private Rule createRule(RuleSetReferenceId ruleSetReferenceId, boolean withDeprecatedRuleReferences)
throws RuleSetNotFoundException {
if (ruleSetReferenceId.isAllRules()) {
throw new IllegalArgumentException("Cannot parse a single Rule from an all Rule RuleSet reference: <" + ruleSetReferenceId + ">.");
throw new IllegalArgumentException(
"Cannot parse a single Rule from an all Rule RuleSet reference: <" + ruleSetReferenceId + ">.");
}
RuleSet ruleSet;
// java8: computeIfAbsent
@ -556,7 +567,7 @@ public class RuleSetFactory {
// load the ruleset with minimum priority low, so that we get all rules, to be able to exclude any rule
// minimum priority will be applied again, before constructing the final ruleset
RuleSetFactory ruleSetFactory = new RuleSetFactory(resourceLoader, RulePriority.LOW, false, this.compatibilityFilter != null);
RuleSetFactory ruleSetFactory = toParser().filterAbovePriority(RulePriority.LOW).warnDeprecated(false).toFactory();
RuleSet otherRuleSet = ruleSetFactory.createRuleSet(RuleSetReferenceId.parse(ref).get(0));
List<RuleReference> potentialRules = new ArrayList<>();
int countDeprecated = 0;
@ -671,7 +682,7 @@ public class RuleSetFactory {
// load the ruleset with minimum priority low, so that we get all rules, to be able to exclude any rule
// minimum priority will be applied again, before constructing the final ruleset
RuleSetFactory ruleSetFactory = new RuleSetFactory(resourceLoader, RulePriority.LOW, false, this.compatibilityFilter != null);
RuleSetFactory ruleSetFactory = toParser().filterAbovePriority(RulePriority.LOW).warnDeprecated(false).toFactory();
boolean isSameRuleSet = false;
RuleSetReferenceId otherRuleSetReferenceId = RuleSetReferenceId.parse(ref).get(0);
@ -824,4 +835,19 @@ public class RuleSetFactory {
return false;
}
}
/**
* Create a new {@link RuleSetParser} with the same config as this
* factory. This is a transitional API.
*/
public RuleSetParser toParser() {
return new RuleSetParser().loadResourcesWith(resourceLoader)
.filterAbovePriority(minimumPriority)
.warnDeprecated(warnDeprecated)
.enableCompatibility(compatibilityFilter != null)
.includeDeprecatedRuleReferences(includeDeprecatedRuleReferences);
}
}

View File

@ -18,13 +18,20 @@ import java.util.regex.Pattern;
import org.apache.commons.io.IOUtils;
import net.sourceforge.pmd.annotation.InternalApi;
/**
* Provides a simple filter mechanism to avoid failing to parse an old ruleset,
* which references rules, that have either been removed from PMD already or
* renamed or moved to another ruleset.
*
* @see <a href="https://sourceforge.net/p/pmd/bugs/1360/">issue 1360</a>
*
* @deprecated Use {@link RuleSetParser#enableCompatibility(boolean)} to enable this feature.
* This implementation is internal API.
*/
@InternalApi
@Deprecated
public class RuleSetFactoryCompatibility {
private static final Logger LOG = Logger.getLogger(RuleSetFactoryCompatibility.class.getName());

View File

@ -0,0 +1,156 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import net.sourceforge.pmd.util.ResourceLoader;
/**
* Configurable ruleset parser. Note that this replaces the API of {@link RulesetsFactoryUtils}
* and {@link RuleSetFactory}. This can be configured using a fluent
* API, see eg {@link #warnDeprecated(boolean)}. To create a list of
* rulesets, use {@link #parseFromResource(String)}.
*/
public final class RuleSetParser {
ResourceLoader resourceLoader = new ResourceLoader(RuleSetParser.class.getClassLoader());
RulePriority minimumPriority = RulePriority.LOW;
boolean warnDeprecated = true;
boolean enableCompatibility = true;
boolean includeDeprecatedRuleReferences = false;
/**
* Specify that the given classloader should be used to resolve
* paths to external ruleset references. The default uses PMD's
* own classpath.
*/
public RuleSetParser loadResourcesWith(ClassLoader classLoader) {
this.resourceLoader = new ResourceLoader(classLoader);
return this;
}
// internal
RuleSetParser loadResourcesWith(ResourceLoader loader) {
this.resourceLoader = loader;
return this;
}
/**
* Filter loaded rules to only those that match or are above
* the given priority. The default is {@link RulePriority#LOW},
* ie, no filtering occurs.
* @return This instance, modified
*/
public RuleSetParser filterAbovePriority(RulePriority minimumPriority) {
this.minimumPriority = minimumPriority;
return this;
}
/**
* Log a warning when referencing a deprecated rule.
* This is enabled by default.
* @return This instance, modified
*/
public RuleSetParser warnDeprecated(boolean warn) {
this.warnDeprecated = warn;
return this;
}
/**
* Enable translating old rule references to newer ones, if they have
* been moved or renamed. This is enabled by default, if disabled,
* unresolved references will not be translated and will produce an
* error.
* @return This instance, modified
*/
public RuleSetParser enableCompatibility(boolean enable) {
this.enableCompatibility = enable;
return this;
}
/**
* Follow deprecated rule references. By default this is off,
* and those references will be ignored (with a warning depending
* on {@link #enableCompatibility(boolean)}).
*
* @return This instance, modified
*/
public RuleSetParser includeDeprecatedRuleReferences(boolean enable) {
this.includeDeprecatedRuleReferences = enable;
return this;
}
/**
* Create a new rule set factory, if you have to (that class is deprecated).
* That factory will use the configuration that was set using the setters of this.
*/
@Deprecated
public RuleSetFactory toFactory() {
return new RuleSetFactory(this);
}
/**
* Parses and returns a ruleset from its location. The location may
* be a file system path, or a resource path (see {@link #loadResourcesWith(ClassLoader)}).
*
* <p>This replaces {@link RuleSetFactory#createRuleSet(String)},
* but does not split commas.
*
* @param rulesetPath A reference to a single ruleset
*
* @throws RuleSetNotFoundException If the path does not correspond to a resource
*/
public RuleSet parseFromResource(String rulesetPath) throws RuleSetNotFoundException {
return parseFromResource(new RuleSetReferenceId(rulesetPath));
}
/**
* Parses several resources into a list of rulesets.
*
* @param paths Paths
*
* @throws RuleSetNotFoundException If any resource throws
* @throws NullPointerException If the parameter, or any component is null
*/
public List<RuleSet> parseFromResources(Collection<String> paths) throws RuleSetNotFoundException {
List<RuleSet> ruleSets = new ArrayList<>(paths.size());
for (String path : paths) {
ruleSets.add(parseFromResource(path));
}
return ruleSets;
}
/**
* Parses several resources into a list of rulesets.
*
* @param paths Paths
*
* @throws RuleSetNotFoundException If any resource throws
* @throws NullPointerException If the parameter, or any component is null
*/
public List<RuleSet> parseFromResources(String... paths) throws RuleSetNotFoundException {
return parseFromResources(Arrays.asList(paths));
}
// package private
RuleSet parseFromResource(RuleSetReferenceId ruleSetReferenceId) throws RuleSetNotFoundException {
return new RuleSetFactory(this).createRuleSet(ruleSetReferenceId);
}
/**
* Configure a new ruleset factory builder according to the parameters
* of the given PMD configuration.
*/
public static RuleSetParser fromPmdConfig(PMDConfiguration configuration) {
return new RuleSetParser().filterAbovePriority(configuration.getMinimumPriority())
.enableCompatibility(configuration.isRuleSetFactoryCompatibilityEnabled());
}
}

View File

@ -8,9 +8,15 @@ import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import net.sourceforge.pmd.annotation.InternalApi;
/**
* This class represents a reference to RuleSet.
*
* @deprecated This is part of the internals of the {@link RuleSetParser}.
*/
@Deprecated
@InternalApi
public class RuleSetReference {
private final String ruleSetFileName;
private final boolean allRules;

View File

@ -14,6 +14,7 @@ import java.util.List;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.util.ResourceLoader;
/**
@ -78,7 +79,11 @@ import net.sourceforge.pmd.util.ResourceLoader;
* </tr>
* </tbody>
* </table>
*
* @deprecated This is part of the internals of the {@link RuleSetParser}.
*/
@Deprecated
@InternalApi
public class RuleSetReferenceId {
private final boolean external;
private final String ruleSetFileName;

View File

@ -9,11 +9,12 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.benchmark.TimeTracker;
import net.sourceforge.pmd.benchmark.TimedOperation;
import net.sourceforge.pmd.benchmark.TimedOperationCategory;
import net.sourceforge.pmd.util.ResourceLoader;
/**
* @deprecated Use a {@link RuleSetParser} instead
*/
@Deprecated
public final class RulesetsFactoryUtils {
private static final Logger LOG = Logger.getLogger(RulesetsFactoryUtils.class.getName());
@ -37,10 +38,10 @@ public final class RulesetsFactoryUtils {
*/
@InternalApi
@Deprecated
public static List<RuleSet> getRuleSets(String rulesets, RuleSetFactory factory) {
public static List<RuleSet> getRuleSets(String rulesets, RuleSetParser factory) {
List<RuleSet> ruleSets;
try {
ruleSets = factory.createRuleSets(rulesets);
ruleSets = factory.parseFromResources(rulesets.split(","));
printRuleNamesInDebug(ruleSets);
if (ruleSets.stream().mapToInt(RuleSet::size).sum() == 0) {
String msg = "No rules found. Maybe you misspelled a rule name? (" + rulesets + ')';
@ -51,33 +52,11 @@ public final class RulesetsFactoryUtils {
LOG.log(Level.SEVERE, "Ruleset not found", rsnfe);
throw new IllegalArgumentException(rsnfe);
}
return ruleSets;
return new RuleSets(ruleSets);
}
/**
* See {@link #getRuleSets(String, RuleSetFactory)}. In addition, the
* loading of the rules is benchmarked.
*
* @param rulesets
* the string with the rulesets to load
* @param factory
* the ruleset factory
* @return the rulesets
* @throws IllegalArgumentException
* if rulesets is empty (means, no rules have been found) or if
* a ruleset couldn't be found.
* @deprecated Is internal API
*/
@InternalApi
@Deprecated
public static List<RuleSet> getRuleSetsWithBenchmark(String rulesets, RuleSetFactory factory) {
try (TimedOperation to = TimeTracker.startOperation(TimedOperationCategory.LOAD_RULES)) {
return getRuleSets(rulesets, factory);
}
}
/**
* @deprecated Use {@link #createFactory(PMDConfiguration)} or {@link #createFactory(PMDConfiguration, ClassLoader)}
* @deprecated Use a {@link RuleSetParser}
*/
@InternalApi
@Deprecated
@ -97,7 +76,10 @@ public final class RulesetsFactoryUtils {
* @return A ruleset factory
*
* @see #createFactory(PMDConfiguration, ClassLoader)
*
* @deprecated Use {@link RuleSetParser#fromPmdConfig(PMDConfiguration)}
*/
@Deprecated
public static RuleSetFactory createFactory(final PMDConfiguration configuration) {
return createFactory(configuration, RulesetsFactoryUtils.class.getClassLoader());
}
@ -108,7 +90,7 @@ public final class RulesetsFactoryUtils {
*
* @return A ruleset factory
*
* @see #createFactory(PMDConfiguration, ClassLoader)
* @see RuleSetParser
*/
public static RuleSetFactory defaultFactory() {
return new RuleSetFactory();
@ -125,7 +107,10 @@ public final class RulesetsFactoryUtils {
* @return A ruleset factory
*
* @see #createFactory(PMDConfiguration)
*
* @deprecated Use a {@link RuleSetParser}
*/
@Deprecated
public static RuleSetFactory createFactory(final PMDConfiguration configuration, ClassLoader classLoader) {
return createFactory(classLoader,
configuration.getMinimumPriority(),
@ -146,7 +131,10 @@ public final class RulesetsFactoryUtils {
* @return A ruleset factory
*
* @see #createFactory(PMDConfiguration)
*
* @deprecated Use a {@link RuleSetParser}
*/
@Deprecated
public static RuleSetFactory createFactory(ClassLoader classLoader,
RulePriority minimumPriority,
boolean warnDeprecated,
@ -167,11 +155,13 @@ public final class RulesetsFactoryUtils {
* @return A ruleset factory
*
* @see #createFactory(PMDConfiguration)
*
* @deprecated Use a {@link RuleSetParser}
*/
@Deprecated
public static RuleSetFactory createFactory(RulePriority minimumPriority,
boolean warnDeprecated,
boolean enableCompatibility) {
return new RuleSetFactory(new ResourceLoader(), minimumPriority, warnDeprecated, enableCompatibility);
}
@ -191,14 +181,16 @@ public final class RulesetsFactoryUtils {
* @return A ruleset factory
*
* @see #createFactory(PMDConfiguration)
* @deprecated Use a {@link RuleSetParser}
*/
@Deprecated
public static RuleSetFactory createFactory(RulePriority minimumPriority,
boolean warnDeprecated,
boolean enableCompatibility,
boolean includeDeprecatedRuleReferences) {
return new RuleSetFactory(new ResourceLoader(), minimumPriority, warnDeprecated, enableCompatibility,
includeDeprecatedRuleReferences);
includeDeprecatedRuleReferences);
}
/**
@ -209,8 +201,8 @@ public final class RulesetsFactoryUtils {
private static void printRuleNamesInDebug(List<RuleSet> rulesets) {
if (LOG.isLoggable(Level.FINER)) {
for (RuleSet rset : rulesets) {
for (Rule rule : rset.getRules()) {
LOG.finer("Loaded rule " + rule.getName());
for (Rule r : rset.getRules()) {
LOG.finer("Loaded rule " + r.getName());
}
}
}

View File

@ -9,6 +9,7 @@ import java.util.stream.Collectors;
import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.PMDVersion;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.Language;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.properties.PropertyDescriptor;
@ -21,7 +22,10 @@ import com.beust.jcommander.ParameterException;
/**
* @author Romain Pelisse &lt;belaran@gmail.com&gt;
*
* @deprecated Internal API. Use {@link PMD#run(String[])} or {@link PMD#main(String[])}
*/
@Deprecated
@InternalApi
public final class PMDCommandLineInterface {
public static final String PROG_NAME = "pmd";

View File

@ -11,8 +11,10 @@ import java.util.Properties;
import org.checkerframework.checker.nullness.qual.Nullable;
import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.PMDConfiguration;
import net.sourceforge.pmd.RulePriority;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.Language;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.LanguageVersion;
@ -23,6 +25,11 @@ import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import com.beust.jcommander.validators.PositiveInteger;
/**
* @deprecated Internal API. Use {@link PMD#run(String[])} or {@link PMD#main(String[])}
*/
@Deprecated
@InternalApi
public class PMDParameters {
@Parameter(names = { "-rulesets", "-R" }, description = "Comma separated list of ruleset names to use.",

View File

@ -1,73 +0,0 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.util;
import java.util.Iterator;
import java.util.NoSuchElementException;
import net.sourceforge.pmd.annotation.InternalApi;
/**
* Creates a single compound Iterator from an array of Iterators.
*
* @param <T>
* The type returned by the Iterator.
*
* @see Iterator
*/
@InternalApi
@Deprecated
public class CompoundIterator<T> implements Iterator<T> {
private final Iterator<T>[] iterators;
private int index;
/**
*
* @param iterators
* The iterators use.
*/
public CompoundIterator(Iterator<T>... iterators) {
this.iterators = iterators;
this.index = 0;
}
@Override
public boolean hasNext() {
return getNextIterator() != null;
}
@Override
public T next() {
Iterator<T> iterator = getNextIterator();
if (iterator != null) {
return iterator.next();
} else {
throw new NoSuchElementException();
}
}
@Override
public void remove() {
Iterator<T> iterator = getNextIterator();
if (iterator != null) {
iterator.remove();
} else {
throw new IllegalStateException();
}
}
// Get the next iterator with values, returns null if there is no such
// iterator
private Iterator<T> getNextIterator() {
while (index < iterators.length) {
if (iterators[index].hasNext()) {
return iterators[index];
} else {
index++;
}
}
return null;
}
}

View File

@ -16,7 +16,6 @@ import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
@ -46,8 +45,7 @@ public class RuleSetFactoryTest {
RuleSet rs = loadRuleSet(EMPTY_RULESET);
assertNull("RuleSet file name not expected", rs.getFileName());
RuleSetFactory rsf = RulesetsFactoryUtils.defaultFactory();
rs = rsf.createRuleSet("net/sourceforge/pmd/TestRuleset1.xml");
rs = new RuleSetParser().parseFromResource("net/sourceforge/pmd/TestRuleset1.xml");
assertEquals("wrong RuleSet file name", rs.getFileName(), "net/sourceforge/pmd/TestRuleset1.xml");
}
@ -59,8 +57,7 @@ public class RuleSetFactoryTest {
@Test
public void testRefs() throws Exception {
RuleSetFactory rsf = RulesetsFactoryUtils.defaultFactory();
RuleSet rs = rsf.createRuleSet("net/sourceforge/pmd/TestRuleset1.xml");
RuleSet rs = new RuleSetParser().parseFromResource("net/sourceforge/pmd/TestRuleset1.xml");
assertNotNull(rs.getRuleByName("TestRuleRef"));
}
@ -70,8 +67,7 @@ public class RuleSetFactoryTest {
assertNotNull("Test ruleset not found - can't continue with test!", in);
in.close();
RuleSetFactory rsf = RulesetsFactoryUtils.defaultFactory();
RuleSets rs = new RuleSets(rsf.createRuleSets("net/sourceforge/pmd/rulesets/reference-ruleset.xml"));
RuleSets rs = new RuleSets(new RuleSetParser().parseFromResource("net/sourceforge/pmd/rulesets/reference-ruleset.xml"));
// added by referencing a complete ruleset (TestRuleset1.xml)
assertNotNull(rs.getRuleByName("MockRule1"));
assertNotNull(rs.getRuleByName("MockRule2"));
@ -116,9 +112,9 @@ public class RuleSetFactoryTest {
assertEquals(2, ruleset4Rule2.getPriority().getPriority());
}
private int countRule(RuleSets rs, String ruleName) {
private int countRule(RuleSet rs, String ruleName) {
int count = 0;
for (Rule r : rs.getAllRules()) {
for (Rule r : rs.getRules()) {
if (ruleName.equals(r.getName())) {
count++;
}
@ -187,8 +183,8 @@ public class RuleSetFactoryTest {
+ " <priority>2</priority>\n <properties>\n <property name=\"packageRegEx\""
+ " value=\"com.aptsssss|com.abc\" \ntype=\"List[String]\" "
+ "description=\"valid packages\"/>\n </properties></rule></ruleset>");
PropertyDescriptor<List<String>> prop = (PropertyDescriptor<List<String>>) r.getPropertyDescriptor("packageRegEx");
List<String> values = r.getProperty(prop);
PropertyDescriptor<?> prop = r.getPropertyDescriptor("packageRegEx");
Object values = r.getProperty(prop);
assertEquals(Arrays.asList("com.aptsssss", "com.abc"), values);
}
@ -203,8 +199,8 @@ public class RuleSetFactoryTest {
+ " value=\"com.aptsssss,com.abc\" \ntype=\"List[String]\" delimiter=\",\" "
+ "description=\"valid packages\"/>\n"
+ " </properties></rule>" + "</ruleset>");
PropertyDescriptor<List<String>> prop = (PropertyDescriptor<List<String>>) r.getPropertyDescriptor("packageRegEx");
List<String> values = r.getProperty(prop);
PropertyDescriptor<?> prop = r.getPropertyDescriptor("packageRegEx");
Object values = r.getProperty(prop);
assertEquals(Arrays.asList("com.aptsssss", "com.abc"), values);
}
@ -258,8 +254,9 @@ public class RuleSetFactoryTest {
*/
@Test
public void testRuleSetWithDeprecatedRenamedRuleForDoc() throws Exception {
RuleSetFactory rsf = RulesetsFactoryUtils.createFactory(RulePriority.LOW, false, false, true);
RuleSet rs = rsf.createRuleSet(createRuleSetReferenceId("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<ruleset name=\"test\">\n"
RuleSetParser parser = new RuleSetParser().warnDeprecated(false).includeDeprecatedRuleReferences(true);
RuleSet rs = parser.parseFromResource(createRuleSetReferenceId(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<ruleset name=\"test\">\n"
+ " <description>ruleset desc</description>\n"
+ " <rule deprecated=\"true\" ref=\"NewName\" name=\"OldName\"/>"
+ " <rule name=\"NewName\" message=\"m\" class=\"net.sourceforge.pmd.lang.rule.XPathRule\" language=\"dummy\">"
@ -273,8 +270,6 @@ public class RuleSetFactoryTest {
/**
* This is an example of a custom user ruleset, that references a rule, that has been renamed.
* The user should get a deprecation warning.
*
* @throws Exception
*/
@Test
public void testRuleSetReferencesADeprecatedRenamedRule() throws Exception {
@ -495,49 +490,50 @@ public class RuleSetFactoryTest {
@Test
public void testReferencePriority() throws RuleSetNotFoundException {
ResourceLoader rl = new ResourceLoader();
RuleSetFactory rsf = new RuleSetFactory(rl, RulePriority.LOW, false, true);
RuleSetParser parser = new RuleSetParser().warnDeprecated(false).enableCompatibility(true);
RuleSet ruleSet;
RuleSet ruleSet = rsf.createRuleSet(createRuleSetReferenceId(REF_INTERNAL_TO_INTERNAL_CHAIN));
assertEquals("Number of Rules", 3, ruleSet.getRules().size());
assertNotNull(ruleSet.getRuleByName("MockRuleName"));
assertNotNull(ruleSet.getRuleByName("MockRuleNameRef"));
assertNotNull(ruleSet.getRuleByName("MockRuleNameRefRef"));
{
final RuleSetReferenceId refInternalInternal = createRuleSetReferenceId(REF_INTERNAL_TO_INTERNAL_CHAIN);
rsf = new RuleSetFactory(rl, RulePriority.MEDIUM_HIGH, false, true);
ruleSet = rsf.createRuleSet(createRuleSetReferenceId(REF_INTERNAL_TO_INTERNAL_CHAIN));
assertEquals("Number of Rules", 2, ruleSet.getRules().size());
assertNotNull(ruleSet.getRuleByName("MockRuleNameRef"));
assertNotNull(ruleSet.getRuleByName("MockRuleNameRefRef"));
ruleSet = parser.filterAbovePriority(RulePriority.LOW).parseFromResource(refInternalInternal);
assertEquals("Number of Rules", 3, ruleSet.getRules().size());
assertNotNull(ruleSet.getRuleByName("MockRuleName"));
assertNotNull(ruleSet.getRuleByName("MockRuleNameRef"));
assertNotNull(ruleSet.getRuleByName("MockRuleNameRefRef"));
rsf = new RuleSetFactory(rl, RulePriority.HIGH, false, true);
ruleSet = rsf.createRuleSet(createRuleSetReferenceId(REF_INTERNAL_TO_INTERNAL_CHAIN));
assertEquals("Number of Rules", 1, ruleSet.getRules().size());
assertNotNull(ruleSet.getRuleByName("MockRuleNameRefRef"));
ruleSet = parser.filterAbovePriority(RulePriority.MEDIUM_HIGH).parseFromResource(refInternalInternal);
assertEquals("Number of Rules", 2, ruleSet.getRules().size());
assertNotNull(ruleSet.getRuleByName("MockRuleNameRef"));
assertNotNull(ruleSet.getRuleByName("MockRuleNameRefRef"));
rsf = new RuleSetFactory(rl, RulePriority.LOW, false, true);
ruleSet = rsf.createRuleSet(createRuleSetReferenceId(REF_INTERNAL_TO_EXTERNAL_CHAIN));
ruleSet = parser.filterAbovePriority(RulePriority.HIGH).parseFromResource(refInternalInternal);
assertEquals("Number of Rules", 1, ruleSet.getRules().size());
assertNotNull(ruleSet.getRuleByName("MockRuleNameRefRef"));
}
final RuleSetReferenceId refInternalToExternal = createRuleSetReferenceId(REF_INTERNAL_TO_EXTERNAL_CHAIN);
ruleSet = parser.filterAbovePriority(RulePriority.LOW).parseFromResource(refInternalToExternal);
assertEquals("Number of Rules", 3, ruleSet.getRules().size());
assertNotNull(ruleSet.getRuleByName("ExternalRefRuleName"));
assertNotNull(ruleSet.getRuleByName("ExternalRefRuleNameRef"));
assertNotNull(ruleSet.getRuleByName("ExternalRefRuleNameRefRef"));
rsf = new RuleSetFactory(rl, RulePriority.MEDIUM_HIGH, false, true);
ruleSet = rsf.createRuleSet(createRuleSetReferenceId(REF_INTERNAL_TO_EXTERNAL_CHAIN));
ruleSet = parser.filterAbovePriority(RulePriority.MEDIUM_HIGH).parseFromResource(refInternalToExternal);
assertEquals("Number of Rules", 2, ruleSet.getRules().size());
assertNotNull(ruleSet.getRuleByName("ExternalRefRuleNameRef"));
assertNotNull(ruleSet.getRuleByName("ExternalRefRuleNameRefRef"));
rsf = new RuleSetFactory(rl, RulePriority.HIGH, false, true);
ruleSet = rsf.createRuleSet(createRuleSetReferenceId(REF_INTERNAL_TO_EXTERNAL_CHAIN));
ruleSet = parser.filterAbovePriority(RulePriority.HIGH).parseFromResource(refInternalToExternal);
assertEquals("Number of Rules", 1, ruleSet.getRules().size());
assertNotNull(ruleSet.getRuleByName("ExternalRefRuleNameRefRef"));
}
@Test
public void testOverridePriorityLoadWithMinimum() throws RuleSetNotFoundException {
RuleSetFactory rsf = new RuleSetFactory(new ResourceLoader(), RulePriority.MEDIUM_LOW, true, true);
RuleSet ruleset = rsf.createRuleSet("net/sourceforge/pmd/rulesets/ruleset-minimum-priority.xml");
RuleSetParser parser = new RuleSetParser().filterAbovePriority(RulePriority.MEDIUM_LOW).warnDeprecated(true).enableCompatibility(true);
RuleSet ruleset = parser.parseFromResource("net/sourceforge/pmd/rulesets/ruleset-minimum-priority.xml");
// only one rule should remain, since we filter out the other rule by minimum priority
assertEquals("Number of Rules", 1, ruleset.getRules().size());
@ -548,8 +544,8 @@ public class RuleSetFactoryTest {
assertNotNull(ruleset.getRuleByName("SampleXPathRule"));
// now, load with default minimum priority
rsf = RulesetsFactoryUtils.defaultFactory();
ruleset = rsf.createRuleSet("net/sourceforge/pmd/rulesets/ruleset-minimum-priority.xml");
parser = new RuleSetParser();
ruleset = parser.parseFromResource("net/sourceforge/pmd/rulesets/ruleset-minimum-priority.xml");
assertEquals("Number of Rules", 2, ruleset.getRules().size());
Rule dummyBasicMockRule = ruleset.getRuleByName("DummyBasicMockRule");
assertEquals("Wrong Priority", RulePriority.LOW, dummyBasicMockRule.getPriority());
@ -557,14 +553,14 @@ public class RuleSetFactoryTest {
@Test
public void testExcludeWithMinimumPriority() throws RuleSetNotFoundException {
RuleSetFactory rsf = RulesetsFactoryUtils.createFactory(RulePriority.HIGH, true, true);
RuleSet ruleset = rsf.createRuleSet("net/sourceforge/pmd/rulesets/ruleset-minimum-priority-exclusion.xml");
RuleSetParser parser = new RuleSetParser().filterAbovePriority(RulePriority.HIGH);
RuleSet ruleset = parser.parseFromResource("net/sourceforge/pmd/rulesets/ruleset-minimum-priority-exclusion.xml");
// no rules should be loaded
assertEquals("Number of Rules", 0, ruleset.getRules().size());
// now, load with default minimum priority
rsf = RulesetsFactoryUtils.defaultFactory();
ruleset = rsf.createRuleSet("net/sourceforge/pmd/rulesets/ruleset-minimum-priority-exclusion.xml");
parser.filterAbovePriority(RulePriority.LOW);
ruleset = parser.parseFromResource("net/sourceforge/pmd/rulesets/ruleset-minimum-priority-exclusion.xml");
// only one rule, we have excluded one...
assertEquals("Number of Rules", 1, ruleset.getRules().size());
// rule is excluded
@ -592,11 +588,10 @@ public class RuleSetFactoryTest {
@Test
public void testSetPriority() throws RuleSetNotFoundException {
ResourceLoader rl = new ResourceLoader();
RuleSetFactory rsf = new RuleSetFactory(rl, RulePriority.MEDIUM_HIGH, false, true);
assertEquals(0, rsf.createRuleSet(createRuleSetReferenceId(SINGLE_RULE)).size());
rsf = new RuleSetFactory(rl, RulePriority.MEDIUM_LOW, false, true);
assertEquals(1, rsf.createRuleSet(createRuleSetReferenceId(SINGLE_RULE)).size());
RuleSetParser rsf = new RuleSetParser().filterAbovePriority(RulePriority.MEDIUM_HIGH);
assertEquals(0, rsf.parseFromResource(createRuleSetReferenceId(SINGLE_RULE)).size());
rsf.filterAbovePriority(RulePriority.MEDIUM_LOW);
assertEquals(1, rsf.parseFromResource(createRuleSetReferenceId(SINGLE_RULE)).size());
}
@Test
@ -774,7 +769,7 @@ public class RuleSetFactoryTest {
+ " <description>Ruleset which references a empty ruleset</description>\n" + "\n"
+ " <rule ref=\"rulesets/dummy/empty-ruleset.xml\" />\n"
+ "</ruleset>\n");
RuleSetFactory ruleSetFactory = new RuleSetFactory(new ResourceLoader(), RulePriority.LOW, true, true);
RuleSetFactory ruleSetFactory = new RuleSetParser().loadResourcesWith(new ResourceLoader()).filterAbovePriority(RulePriority.LOW).warnDeprecated(true).enableCompatibility(true).toFactory();
RuleSet ruleset = ruleSetFactory.createRuleSet(ref);
assertEquals(0, ruleset.getRules().size());
@ -796,8 +791,7 @@ public class RuleSetFactoryTest {
+ " xsi:schemaLocation=\"http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd\">\n"
+ " <description>Custom ruleset for tests</description>\n"
+ " <rule ref=\"net/sourceforge/pmd/TestRuleset1.xml/ThisRuleDoesNotExist\"/>\n" + "</ruleset>\n");
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
ruleSetFactory.createRuleSet(ref);
new RuleSetParser().parseFromResource(ref);
}
/**
@ -816,8 +810,7 @@ public class RuleSetFactoryTest {
+ " <description>PMD Plugin preferences rule set</description>\n" + "\n"
+ "<rule name=\"OverriddenDummyBasicMockRule\"\n"
+ " ref=\"rulesets/dummy/basic.xml/DummyBasicMockRule\">\n" + "</rule>\n" + "\n" + "</ruleset>");
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
RuleSet rs = ruleSetFactory.createRuleSet(ref);
RuleSet rs = new RuleSetParser().parseFromResource(ref);
Rule r = rs.getRules().toArray(new Rule[1])[0];
assertEquals("OverriddenDummyBasicMockRule", r.getName());
@ -843,8 +836,7 @@ public class RuleSetFactoryTest {
+ " <description>Custom ruleset for tests</description>\n"
+ " <rule ref=\"net/sourceforge/pmd/TestRuleset1.xml\">\n"
+ " <exclude name=\"ThisRuleDoesNotExist\"/>\n" + " </rule>\n" + "</ruleset>\n");
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
RuleSet ruleset = ruleSetFactory.createRuleSet(ref);
RuleSet ruleset = new RuleSetParser().parseFromResource(ref);
assertEquals(4, ruleset.getRules().size());
}
@ -873,8 +865,7 @@ public class RuleSetFactoryTest {
+ " <description>Custom ruleset for tests</description>\n"
+ " <rule ref=\"rulesets/dummy/basic.xml\">\n" + " <exclude name=\"DummyBasicMockRule\"/>\n"
+ " </rule>\n" + "</ruleset>\n");
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
RuleSet ruleset = ruleSetFactory.createRuleSet(ref1);
RuleSet ruleset = new RuleSetParser().parseFromResource(ref1);
assertNull(ruleset.getRuleByName("DummyBasicMockRule"));
RuleSetReferenceId ref2 = createRuleSetReferenceId(
@ -885,8 +876,7 @@ public class RuleSetFactoryTest {
+ " <description>Custom ruleset for tests</description>\n"
+ " <rule ref=\"rulesets/dummy/basic.xml\">\n" + " <exclude name=\"DummyBasicMockRule\"/>\n"
+ " </rule>\n" + " <rule ref=\"rulesets/dummy/basic.xml\"/>\n" + "</ruleset>\n");
RuleSetFactory ruleSetFactory2 = RulesetsFactoryUtils.defaultFactory();
RuleSet ruleset2 = ruleSetFactory2.createRuleSet(ref2);
RuleSet ruleset2 = new RuleSetParser().parseFromResource(ref2);
assertNotNull(ruleset2.getRuleByName("DummyBasicMockRule"));
RuleSetReferenceId ref3 = createRuleSetReferenceId(
@ -897,8 +887,7 @@ public class RuleSetFactoryTest {
+ " <description>Custom ruleset for tests</description>\n"
+ " <rule ref=\"rulesets/dummy/basic.xml\"/>\n" + " <rule ref=\"rulesets/dummy/basic.xml\">\n"
+ " <exclude name=\"DummyBasicMockRule\"/>\n" + " </rule>\n" + "</ruleset>\n");
RuleSetFactory ruleSetFactory3 = RulesetsFactoryUtils.defaultFactory();
RuleSet ruleset3 = ruleSetFactory3.createRuleSet(ref3);
RuleSet ruleset3 = new RuleSetParser().parseFromResource(ref3);
assertNotNull(ruleset3.getRuleByName("DummyBasicMockRule"));
}
@ -915,8 +904,7 @@ public class RuleSetFactoryTest {
+ " <description>Custom ruleset for tests</description>\n"
+ " <rule ref=\"rulesets/dummy/basic.xml\"/>\n"
+ " </ruleset>\n");
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
ruleSetFactory.createRuleSet(ref);
new RuleSetParser().parseFromResource(ref);
assertTrue(logging.getLog().contains("RuleSet name is missing."));
}
@ -930,8 +918,7 @@ public class RuleSetFactoryTest {
+ " xsi:schemaLocation=\"http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd\">\n"
+ " <rule ref=\"rulesets/dummy/basic.xml\"/>\n"
+ " </ruleset>\n");
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
ruleSetFactory.createRuleSet(ref);
new RuleSetParser().parseFromResource(ref);
assertTrue(logging.getLog().contains("RuleSet description is missing."));
}
@ -1279,7 +1266,7 @@ public class RuleSetFactoryTest {
}
private RuleSet loadRuleSetWithDeprecationWarnings(String ruleSetXml) throws RuleSetNotFoundException {
RuleSetFactory rsf = RulesetsFactoryUtils.createFactory(RulePriority.LOW, true, false);
RuleSetFactory rsf = new RuleSetParser().warnDeprecated(true).enableCompatibility(false).toFactory();
return rsf.createRuleSet(createRuleSetReferenceId(ruleSetXml));
}

View File

@ -77,21 +77,21 @@ public class RuleSetTest {
@Test
public void testGetRuleByName() {
MockRule mock = new MockRule("name", "desc", "msg", "rulesetname");
RuleSet rs = RulesetsFactoryUtils.defaultFactory().createSingleRuleRuleSet(mock);
RuleSet rs = RuleSet.forSingleRule(mock);
assertEquals("unable to fetch rule by name", mock, rs.getRuleByName("name"));
}
@Test
public void testGetRuleByName2() {
MockRule mock = new MockRule("name", "desc", "msg", "rulesetname");
RuleSet rs = RulesetsFactoryUtils.defaultFactory().createSingleRuleRuleSet(mock);
RuleSet rs = RuleSet.forSingleRule(mock);
assertNull("the rule FooRule must not be found!", rs.getRuleByName("FooRule"));
}
@Test
public void testRuleList() {
MockRule rule = new MockRule("name", "desc", "msg", "rulesetname");
RuleSet ruleset = RulesetsFactoryUtils.defaultFactory().createSingleRuleRuleSet(rule);
RuleSet ruleset = RuleSet.forSingleRule(rule);
assertEquals("Size of RuleSet isn't one.", 1, ruleset.size());

View File

@ -81,7 +81,7 @@ public class RuleSetWriterTest {
ruleRef.setRuleSetReference(ruleSetReference);
ruleRef.setName("Foo"); // override the name
RuleSet ruleSet = ruleSetFactory.createSingleRuleRuleSet(ruleRef);
RuleSet ruleSet = RuleSet.forSingleRule(ruleRef);
writer.write(ruleSet);

View File

@ -32,7 +32,6 @@ import org.junit.rules.ExpectedException;
import net.sourceforge.pmd.FooRule;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.RuleSet;
import net.sourceforge.pmd.RulesetsFactoryUtils;
import net.sourceforge.pmd.properties.constraints.PropertyConstraint;
@ -59,7 +58,7 @@ public class PropertyDescriptorTest {
FooRule rule = new FooRule();
rule.definePropertyDescriptor(intProperty);
rule.setProperty(intProperty, 1000);
RuleSet ruleSet = RulesetsFactoryUtils.defaultFactory().createSingleRuleRuleSet(rule);
RuleSet ruleSet = RuleSet.forSingleRule(rule);
List<Rule> dysfunctional = new ArrayList<>();
ruleSet.removeDysfunctionalRules(dysfunctional);
@ -80,7 +79,7 @@ public class PropertyDescriptorTest {
FooRule rule = new FooRule();
rule.definePropertyDescriptor(descriptor);
rule.setProperty(descriptor, Collections.singletonList(1000d)); // not in range
RuleSet ruleSet = RulesetsFactoryUtils.defaultFactory().createSingleRuleRuleSet(rule);
RuleSet ruleSet = RuleSet.forSingleRule(rule);
List<Rule> dysfunctional = new ArrayList<>();
ruleSet.removeDysfunctionalRules(dysfunctional);

View File

@ -1,92 +0,0 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import org.junit.Before;
import org.junit.Test;
public class CompoundListTest {
private List<String> l1;
private List<String> l2;
private Iterator<String> iterator;
@Before
public void setUp() {
l1 = new ArrayList<>();
l1.add("1");
l1.add("2");
l2 = new ArrayList<>();
l2.add("3");
l2.add("4");
iterator = new CompoundIterator<>(l1.iterator(), l2.iterator());
}
@Test
public void testHappyPath() {
assertTrue(iterator.hasNext());
assertEquals("1", iterator.next());
assertTrue(iterator.hasNext());
assertEquals("2", iterator.next());
assertTrue(iterator.hasNext());
assertEquals("3", iterator.next());
assertTrue(iterator.hasNext());
assertEquals("4", iterator.next());
assertFalse(iterator.hasNext());
assertEquals(2, l1.size());
assertEquals(2, l2.size());
}
@Test
public void testHappyPathRemove() {
assertTrue(iterator.hasNext());
assertEquals("1", iterator.next());
iterator.remove();
assertTrue(iterator.hasNext());
assertEquals("2", iterator.next());
assertTrue(iterator.hasNext());
assertEquals("3", iterator.next());
iterator.remove();
assertTrue(iterator.hasNext());
assertEquals("4", iterator.next());
assertFalse(iterator.hasNext());
assertEquals(1, l1.size());
assertEquals("2", l1.get(0));
assertEquals(1, l2.size());
assertEquals("4", l2.get(0));
}
@Test
public void testEmpty() {
Iterator<?> iterator = new CompoundIterator();
assertFalse(iterator.hasNext());
}
@Test(expected = NoSuchElementException.class)
public void testEmptyBadNext() {
Iterator<?> iterator = new CompoundIterator();
iterator.next();
}
@Test(expected = IllegalStateException.class)
public void testEmptyBadRemove() {
Iterator<?> iterator = new CompoundIterator();
iterator.remove();
}
public static junit.framework.Test suite() {
return new junit.framework.JUnit4TestAdapter(CompoundListTest.class);
}
}

View File

@ -7,16 +7,15 @@ package net.sourceforge.pmd.lang.java;
import org.junit.Assert;
import org.junit.Test;
import net.sourceforge.pmd.RulePriority;
import net.sourceforge.pmd.RuleSet;
import net.sourceforge.pmd.RuleSetFactory;
import net.sourceforge.pmd.util.ResourceLoader;
import net.sourceforge.pmd.RuleSetParser;
public class PMD5RulesetTest {
@Test
public void loadRuleset() throws Exception {
RuleSetFactory ruleSetFactory = new RuleSetFactory(new ResourceLoader(), RulePriority.LOW, true, true);
RuleSetFactory ruleSetFactory = new RuleSetParser().toFactory();
RuleSet ruleset = ruleSetFactory.createRuleSet("net/sourceforge/pmd/lang/java/pmd5ruleset.xml");
Assert.assertNotNull(ruleset);
Assert.assertNull(ruleset.getRuleByName("GuardLogStatementJavaUtil"));

View File

@ -14,11 +14,10 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.SystemErrRule;
import net.sourceforge.pmd.RulePriority;
import net.sourceforge.pmd.RuleSet;
import net.sourceforge.pmd.RuleSetFactory;
import net.sourceforge.pmd.RuleSetNotFoundException;
import net.sourceforge.pmd.util.ResourceLoader;
import net.sourceforge.pmd.RuleSetParser;
public class QuickstartRulesetTest {
@ -50,8 +49,7 @@ public class QuickstartRulesetTest {
}
});
RuleSetFactory ruleSetFactory = new RuleSetFactory(new ResourceLoader(), RulePriority.LOW, true, false);
RuleSet quickstart = ruleSetFactory.createRuleSet("rulesets/java/quickstart.xml");
RuleSet quickstart = new RuleSetParser().enableCompatibility(false).parseFromResource("rulesets/java/quickstart.xml");
Assert.assertFalse(quickstart.getRules().isEmpty());
}
}

View File

@ -160,8 +160,6 @@ public class AbstractLanguageVersionTest {
String rulesetFilenames = props.getProperty("rulesets.filenames");
assertNotNull(rulesetFilenames);
RuleSetFactory factory = RulesetsFactoryUtils.defaultFactory();
if (rulesetFilenames.trim().isEmpty()) {
return;
}
@ -171,7 +169,7 @@ public class AbstractLanguageVersionTest {
try (InputStream stream = rl.loadClassPathResourceAsStream(r)) {
assertNotNull(stream);
}
RuleSet ruleset = factory.createRuleSet(r);
RuleSet ruleset = new RuleSetParser().parseFromResource(r);
assertNotNull(ruleset);
}
}

View File

@ -290,8 +290,7 @@ public abstract class AbstractRuleSetFactoryTest {
}
private RuleSet loadRuleSetByFileName(String ruleSetFileName) throws RuleSetNotFoundException {
RuleSetFactory rsf = RulesetsFactoryUtils.defaultFactory();
return rsf.createRuleSet(ruleSetFileName);
return new RuleSetParser().parseFromResource(ruleSetFileName);
}
private boolean validateAgainstSchema(String fileName)
@ -389,8 +388,7 @@ public abstract class AbstractRuleSetFactoryTest {
// System.out.println("xml2: " + xml2);
// Read RuleSet from XML, first time
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
RuleSet ruleSet2 = ruleSetFactory.createRuleSet(createRuleSetReferenceId(xml2));
RuleSet ruleSet2 = new RuleSetParser().parseFromResource((String) createRuleSetReferenceId(xml2));
// Do write/read a 2nd time, just to be sure
@ -403,7 +401,7 @@ public abstract class AbstractRuleSetFactoryTest {
// System.out.println("xml3: " + xml3);
// Read RuleSet from XML, second time
RuleSet ruleSet3 = ruleSetFactory.createRuleSet(createRuleSetReferenceId(xml3));
RuleSet ruleSet3 = new RuleSetParser().parseFromResource((String) createRuleSetReferenceId(xml3));
// The 2 written XMLs should all be valid w.r.t Schema/DTD
assertTrue("1st roundtrip RuleSet XML is not valid against Schema (filename: " + fileName + ")",

View File

@ -5,19 +5,22 @@
package net.sourceforge.pmd.lang.xml.ast.internal;
import java.util.ArrayList;
import static java.util.Collections.emptyIterator;
import java.util.AbstractList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import net.sourceforge.pmd.internal.util.IteratorUtil;
import net.sourceforge.pmd.lang.rule.xpath.Attribute;
import net.sourceforge.pmd.lang.xml.ast.XmlNode;
import net.sourceforge.pmd.util.CompoundIterator;
import net.sourceforge.pmd.util.DataMap;
import net.sourceforge.pmd.util.DataMap.DataKey;
@ -118,47 +121,34 @@ class XmlNodeWrapper implements XmlNode {
@Override
public Iterator<Attribute> getXPathAttributesIterator() {
List<Iterator<Attribute>> iterators = new ArrayList<>();
// Expose DOM Attributes
final NamedNodeMap attributes = node.getAttributes();
iterators.add(new Iterator<Attribute>() {
private int index;
@Override
public boolean hasNext() {
return attributes != null && index < attributes.getLength();
}
@Override
public Attribute next() {
org.w3c.dom.Node attributeNode = attributes.item(index++);
return new Attribute(XmlNodeWrapper.this,
attributeNode.getNodeName(),
attributeNode.getNodeValue());
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
});
// Expose Text/CDATA nodes to have an 'Image' attribute like AST Nodes
if (node instanceof Text) {
iterators.add(Collections.singletonList(new Attribute(this, "Image", ((Text) node).getData())).iterator());
return Collections.singletonList(new Attribute(this, "Image", ((Text) node).getData())).iterator();
}
// Expose Java Attributes
// iterators.add(new AttributeAxisIterator((net.sourceforge.pmd.lang.ast.Node) p));
// Expose DOM Attributes
if (node.getAttributes() == null) {
return emptyIterator();
} else {
return IteratorUtil.map(asList(node.getAttributes()).iterator(),
n -> new Attribute(this, n.getNodeName(), n.getNodeValue()));
}
}
@SuppressWarnings("unchecked")
Iterator<Attribute>[] it = new Iterator[iterators.size()];
private static List<Node> asList(NamedNodeMap nodeList) {
return new AbstractList<Node>() {
@Override
public Node get(int index) {
return nodeList.item(index);
}
return new CompoundIterator<>(iterators.toArray(it));
@Override
public int size() {
return nodeList.getLength();
}
};
}
@Override