From 35dee58bc809ff9254e3214f6898594cadab0121 Mon Sep 17 00:00:00 2001 From: oowekyala Date: Sat, 15 Jul 2017 16:36:11 +0200 Subject: [PATCH] Fix initialisation bug --- .../AbstractPropertyDescriptorFactory.java | 49 +++++++-------- .../pmd/MultiValuePropertyDescriptor.java | 6 +- .../pmd/NumericPropertyDescriptor.java | 4 +- .../sourceforge/pmd/PropertyDescriptor.java | 8 +-- .../java/net/sourceforge/pmd/RuleSet.java | 6 +- .../net/sourceforge/pmd/RuleSetFactory.java | 21 +++++-- .../sourceforge/pmd/RuleSetReferenceId.java | 2 +- .../properties/CharacterMultiProperty.java | 4 +- .../rule/properties/CharacterProperty.java | 4 +- .../lang/rule/properties/DoubleProperty.java | 12 ++-- .../properties/ExpectedFieldsBuilder.java | 59 +++++++++++++++++++ .../lang/rule/properties/FloatProperty.java | 2 + .../lang/rule/properties/IntegerProperty.java | 6 +- .../properties/PropertyDescriptorUtil.java | 52 +--------------- .../rule/properties/StringMultiProperty.java | 4 +- .../lang/rule/properties/StringProperty.java | 4 +- .../net/sourceforge/pmd/util/StringUtil.java | 44 ++------------ 17 files changed, 141 insertions(+), 146 deletions(-) create mode 100644 pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/ExpectedFieldsBuilder.java diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/AbstractPropertyDescriptorFactory.java b/pmd-core/src/main/java/net/sourceforge/pmd/AbstractPropertyDescriptorFactory.java index 29bea13d47..308d47d963 100755 --- a/pmd-core/src/main/java/net/sourceforge/pmd/AbstractPropertyDescriptorFactory.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/AbstractPropertyDescriptorFactory.java @@ -4,7 +4,7 @@ package net.sourceforge.pmd; -import static net.sourceforge.pmd.PropertyDescriptor.CORE_FIELD_TYPES_BY_KEY; +import static net.sourceforge.pmd.PropertyDescriptor.CORE_EXPECTED_FIELDS; import static net.sourceforge.pmd.PropertyDescriptorField.DEFAULT_VALUE; import static net.sourceforge.pmd.PropertyDescriptorField.DELIMITER; import static net.sourceforge.pmd.PropertyDescriptorField.DESCRIPTION; @@ -19,6 +19,8 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import org.apache.commons.lang3.StringUtils; + import net.sourceforge.pmd.util.StringUtil; /** @@ -30,26 +32,18 @@ import net.sourceforge.pmd.util.StringUtil; */ public abstract class AbstractPropertyDescriptorFactory implements PropertyDescriptorFactory { - - - - static { - System.err.println(CORE_FIELD_TYPES_BY_KEY); - } - - private final Class valueType; /** * Denote the identifiers of the expected fields paired with booleans - * denoting whether they are required (non-null) or not. + * denoting whether they are required or not. */ private final Map expectedFields; public AbstractPropertyDescriptorFactory(Class theValueType) { valueType = theValueType; - expectedFields = CORE_FIELD_TYPES_BY_KEY; + expectedFields = CORE_EXPECTED_FIELDS; } @@ -57,12 +51,12 @@ public abstract class AbstractPropertyDescriptorFactory implements PropertyDe valueType = theValueType; if (additionalFieldTypesByKey == null) { - expectedFields = CORE_FIELD_TYPES_BY_KEY; + expectedFields = CORE_EXPECTED_FIELDS; return; } Map temp - = new HashMap<>(CORE_FIELD_TYPES_BY_KEY.size() + additionalFieldTypesByKey.size()); - temp.putAll(CORE_FIELD_TYPES_BY_KEY); + = new HashMap<>(CORE_EXPECTED_FIELDS.size() + additionalFieldTypesByKey.size()); + temp.putAll(CORE_EXPECTED_FIELDS); temp.putAll(additionalFieldTypesByKey); expectedFields = Collections.unmodifiableMap(temp); @@ -116,7 +110,7 @@ public abstract class AbstractPropertyDescriptorFactory implements PropertyDe */ protected String defaultValueIn(Map valuesById) { String deft = valuesById.get(DEFAULT_VALUE); - if (StringUtil.isEmpty(deft)) { + if (isValueMissing(deft)) { throw new RuntimeException("Default value was null, empty, or missing"); } return deft; @@ -125,7 +119,7 @@ public abstract class AbstractPropertyDescriptorFactory implements PropertyDe @Override public final PropertyDescriptor createWith(Map valuesById) { - // checkRequiredFields(valuesById); + checkRequiredFields(valuesById); return createWith(valuesById, false); } @@ -133,7 +127,7 @@ public abstract class AbstractPropertyDescriptorFactory implements PropertyDe /** Checks whether all required fields are present in the map. */ private void checkRequiredFields(Map valuesById) { for (Entry entry : expectedFields.entrySet()) { - if (entry.getValue() && StringUtil.isEmpty(valuesById.get(entry.getKey()))) { + if (entry.getValue() && isValueMissing(valuesById.get(entry.getKey()))) { throw new RuntimeException("Missing required value for key: " + entry.getKey()); } } @@ -249,7 +243,7 @@ public abstract class AbstractPropertyDescriptorFactory implements PropertyDe characterStr = valuesById.get(DELIMITER).trim(); } - if (StringUtil.isEmpty(characterStr)) { + if (StringUtils.isBlank(characterStr)) { return defaultDelimiter; } @@ -272,7 +266,7 @@ public abstract class AbstractPropertyDescriptorFactory implements PropertyDe protected static String[] minMaxFrom(Map valuesById) { String min = minValueIn(valuesById); String max = maxValueIn(valuesById); - if (StringUtil.isEmpty(min) || StringUtil.isEmpty(max)) { + if (StringUtils.isBlank(min) || StringUtils.isBlank(max)) { throw new RuntimeException("min and max values must be specified"); } return new String[] {min, max}; @@ -291,7 +285,7 @@ public abstract class AbstractPropertyDescriptorFactory implements PropertyDe protected static String[] legalPackageNamesIn(Map valuesById, char delimiter) { String names = valuesById.get(LEGAL_PACKAGES); - if (StringUtil.isEmpty(names)) { + if (StringUtils.isBlank(names)) { return null; } return StringUtil.substringsOf(names, delimiter); @@ -299,18 +293,19 @@ public abstract class AbstractPropertyDescriptorFactory implements PropertyDe /** - * Returns a map describing which fields are required to build an + * Returns a map describing which fields are required to build a property using this factory. The parameters are + * added to the {@link PropertyDescriptor#CORE_EXPECTED_FIELDS}, which are required for all descriptors. * - * @param otherKeys - * @param otherValues + * @param otherKeys Additional keys + * @param otherValues Whether the corresponding keys are required or not * - * @return + * @return The complete map of expected fields. */ - public static Map expectedFieldTypesWith(PropertyDescriptorField[] otherKeys, + static Map expectedFieldTypesWith(PropertyDescriptorField[] otherKeys, Boolean[] otherValues) { Map largerMap = new HashMap<>( - otherKeys.length + CORE_FIELD_TYPES_BY_KEY.size()); - largerMap.putAll(CORE_FIELD_TYPES_BY_KEY); + otherKeys.length + CORE_EXPECTED_FIELDS.size()); + largerMap.putAll(CORE_EXPECTED_FIELDS); for (int i = 0; i < otherKeys.length; i++) { largerMap.put(otherKeys[i], otherValues[i]); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/MultiValuePropertyDescriptor.java b/pmd-core/src/main/java/net/sourceforge/pmd/MultiValuePropertyDescriptor.java index 092bd6edf5..765b6feec1 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/MultiValuePropertyDescriptor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/MultiValuePropertyDescriptor.java @@ -7,8 +7,10 @@ package net.sourceforge.pmd; import java.util.List; /** - * Specializes property descriptors for single valued descriptors. For this type of property, the return value of the - * {@link #type()} method must be the class literal of the type parameter of the interface {@link PropertyDescriptor}. + * Specializes property descriptors for multi valued descriptors. For this type of property, the return value of the + * {@link #type()} method must be the class literal of the type parameter of this interface, which is the type of the + * components of the list (not the type of the list). Notice that for implementors, the type parameter of this interface + * is not the same as the type parameter of {@link PropertyDescriptor} they inherit! * * @param The type of value this descriptor works with. This is the type of the list's component. * diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/NumericPropertyDescriptor.java b/pmd-core/src/main/java/net/sourceforge/pmd/NumericPropertyDescriptor.java index 6ce13033a3..d99db5c96e 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/NumericPropertyDescriptor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/NumericPropertyDescriptor.java @@ -9,7 +9,7 @@ import static net.sourceforge.pmd.PropertyDescriptorField.MIN; import java.util.Map; -import net.sourceforge.pmd.lang.rule.properties.PropertyDescriptorUtil; +import net.sourceforge.pmd.lang.rule.properties.ExpectedFieldsBuilder; /** * Defines a descriptor type whose instance values are required to lie within @@ -22,7 +22,7 @@ import net.sourceforge.pmd.lang.rule.properties.PropertyDescriptorUtil; public interface NumericPropertyDescriptor extends PropertyDescriptor { Map NUMBER_FIELD_TYPES_BY_KEY - = PropertyDescriptorUtil.expectedFields().put(MIN, true).put(MAX, true).get(); + = ExpectedFieldsBuilder.instance().put(MIN, true).put(MAX, true).build(); /** diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PropertyDescriptor.java b/pmd-core/src/main/java/net/sourceforge/pmd/PropertyDescriptor.java index 2e990f25ac..2bdd515460 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PropertyDescriptor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PropertyDescriptor.java @@ -11,7 +11,7 @@ import static net.sourceforge.pmd.PropertyDescriptorField.NAME; import java.util.Map; -import net.sourceforge.pmd.lang.rule.properties.PropertyDescriptorUtil.ExpectedFieldsBuilder; +import net.sourceforge.pmd.lang.rule.properties.ExpectedFieldsBuilder; /** * Property value descriptor that defines the use & requirements for setting @@ -35,13 +35,13 @@ import net.sourceforge.pmd.lang.rule.properties.PropertyDescriptorUtil.ExpectedF public interface PropertyDescriptor extends Comparable> { /** Default expected fields. Unmodifiable. */ - Map CORE_FIELD_TYPES_BY_KEY - = (new ExpectedFieldsBuilder()) + Map CORE_EXPECTED_FIELDS + = ExpectedFieldsBuilder.instance() .put(NAME, true) .put(DESCRIPTION, true) .put(DEFAULT_VALUE, true) .put(DELIMITER, false) - .get(); + .build(); /** diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSet.java b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSet.java index 6dc28c6110..c5e25f052b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSet.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSet.java @@ -16,6 +16,8 @@ import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; +import org.apache.commons.lang3.StringUtils; + import net.sourceforge.pmd.benchmark.Benchmark; import net.sourceforge.pmd.benchmark.Benchmarker; import net.sourceforge.pmd.cache.ChecksumAware; @@ -179,7 +181,7 @@ public class RuleSet implements ChecksumAware { * @return The same builder, for a fluid programming interface */ public RuleSetBuilder addRuleByReference(final String ruleSetFileName, final Rule rule) { - if (StringUtil.isEmpty(ruleSetFileName)) { + if (StringUtils.isBlank(ruleSetFileName)) { throw new RuntimeException( "Adding a rule by reference is not allowed with an empty rule set file name."); } @@ -246,7 +248,7 @@ public class RuleSet implements ChecksumAware { */ public RuleSetBuilder addRuleSetByReference(final RuleSet ruleSet, final boolean allRules, final String... excludes) { - if (StringUtil.isEmpty(ruleSet.getFileName())) { + if (StringUtils.isBlank(ruleSet.getFileName())) { throw new RuntimeException( "Adding a rule by reference is not allowed with an empty rule set file name."); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetFactory.java b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetFactory.java index b3ff0b3021..a79c98f6f5 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetFactory.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetFactory.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd; +import static net.sourceforge.pmd.PropertyDescriptorField.DEFAULT_VALUE; + import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -23,6 +25,7 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import org.apache.commons.lang3.StringUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -414,7 +417,7 @@ public class RuleSetFactory { String ref = ruleElement.getAttribute("ref"); if (ref.endsWith("xml")) { parseRuleSetReferenceNode(ruleSetReferenceId, ruleSetBuilder, ruleElement, ref); - } else if (StringUtil.isEmpty(ref)) { + } else if (StringUtils.isBlank(ref)) { parseSingleRuleNode(ruleSetReferenceId, ruleSetBuilder, ruleNode); } else { parseRuleReferenceNode(ruleSetReferenceId, ruleSetBuilder, ruleNode, ref, withDeprecatedRuleReferences); @@ -812,13 +815,13 @@ public class RuleSetFactory { Element propertyElement = (Element) propertyNode; String typeId = propertyElement.getAttribute(PropertyDescriptorField.TYPE.attributeName()); - String strValue = propertyElement.getAttribute(PropertyDescriptorField.DEFAULT_VALUE.attributeName()); - if (StringUtil.isEmpty(strValue)) { + String strValue = propertyElement.getAttribute(DEFAULT_VALUE.attributeName()); + if (StringUtils.isBlank(strValue)) { strValue = valueFrom(propertyElement); } // Setting of existing property, or defining a new property? - if (StringUtil.isEmpty(typeId)) { + if (StringUtils.isBlank(typeId)) { String name = propertyElement.getAttribute(PropertyDescriptorField.NAME.attributeName()); PropertyDescriptor propertyDescriptor = rule.getPropertyDescriptor(name); @@ -842,9 +845,19 @@ public class RuleSetFactory { // populate a map of values for an individual descriptor for (PropertyDescriptorField field : valueKeys) { String valueStr = propertyElement.getAttribute(field.attributeName()); + if (valueStr != null) values.put(field, valueStr); } + if (StringUtils.isBlank(values.get(DEFAULT_VALUE))) { + NodeList children = propertyElement.getElementsByTagName(DEFAULT_VALUE.attributeName()); + if (children.getLength() == 1) { + values.put(DEFAULT_VALUE, children.item(0).getTextContent()); + } else { + throw new RuntimeException("No value defined!"); + } + } + // casting is not pretty but prevents the interface from having this method PropertyDescriptor desc = ((AbstractPropertyDescriptorFactory) pdFactory).createExternalWith(values); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetReferenceId.java b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetReferenceId.java index dbf958d305..b0c033ceea 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetReferenceId.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetReferenceId.java @@ -408,7 +408,7 @@ public class RuleSetReferenceId { */ public InputStream getInputStream(ClassLoader classLoader) throws RuleSetNotFoundException { if (externalRuleSetReferenceId == null) { - InputStream in = StringUtil.isEmpty(ruleSetFileName) ? null + InputStream in = StringUtils.isBlank(ruleSetFileName) ? null : ResourceLoader.loadResourceAsStream(ruleSetFileName, classLoader); if (in == null) { throw new RuleSetNotFoundException("Can't find resource '" + ruleSetFileName + "' for rule '" + ruleName diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/CharacterMultiProperty.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/CharacterMultiProperty.java index ed97dbe004..b325bc1ded 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/CharacterMultiProperty.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/CharacterMultiProperty.java @@ -9,6 +9,8 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.StringUtils; + import net.sourceforge.pmd.PropertyDescriptorFactory; import net.sourceforge.pmd.PropertyDescriptorField; import net.sourceforge.pmd.lang.rule.properties.ValueParser.Companion; @@ -28,7 +30,7 @@ public final class CharacterMultiProperty extends AbstractMultiValueProperty { + /** Factory. */ public static final PropertyDescriptorFactory FACTORY // @formatter:off = new SingleValuePropertyDescriptorFactory(Double.class, NUMBER_FIELD_TYPES_BY_KEY) { @Override public DoubleProperty createWith(Map valuesById, boolean isDefinedExternally) { final String[] minMax = minMaxFrom(valuesById); - System.out.println(Arrays.asList(minMax)); return new DoubleProperty(nameIn(valuesById), descriptionIn(valuesById), - DOUBLE_PARSER.valueOf(minMax[0]), - DOUBLE_PARSER.valueOf(minMax[1]), - DOUBLE_PARSER.valueOf(defaultValueIn(valuesById)), + doubleFrom(minMax[0]), + doubleFrom(minMax[1]), + doubleFrom(defaultValueIn(valuesById)), 0f, isDefinedExternally); } @@ -73,8 +73,8 @@ public final class DoubleProperty extends AbstractNumericProperty { * * @return Parsed Double */ - public static Double doubleFrom(String numberString) { - return Double.valueOf(numberString); + private static Double doubleFrom(String numberString) { + return DOUBLE_PARSER.valueOf(numberString); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/ExpectedFieldsBuilder.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/ExpectedFieldsBuilder.java new file mode 100644 index 0000000000..11c3160d7d --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/ExpectedFieldsBuilder.java @@ -0,0 +1,59 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.rule.properties; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.pmd.PropertyDescriptorField; + +/** Builder for an expected fields map. */ +public final class ExpectedFieldsBuilder { + + private final Map requiredFields = new HashMap<>(); + + + private ExpectedFieldsBuilder() { + + } + + + /** + * Adds a mapping of field/ required to the map. + * + * @param field The field to expect + * @param isRequired Whether it's required or not + * + * @return This instance, so that we have a fluent interface + */ + public ExpectedFieldsBuilder put(PropertyDescriptorField field, boolean isRequired) { + requiredFields.put(field, isRequired); + return this; + } + + + /** + * Gets an immutable map containing the fields we've put here. + * + * @return The map of field/ isRequired mappings + */ + public Map build() { + return Collections.unmodifiableMap(requiredFields); + } + + + /** + * Gets a builder for a required fields map. + * + * @return A builder + * + * @see ExpectedFieldsBuilder + */ + public static ExpectedFieldsBuilder instance() { + return new ExpectedFieldsBuilder(); + } + +} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/FloatProperty.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/FloatProperty.java index 761039e27a..c2b6d68cfb 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/FloatProperty.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/FloatProperty.java @@ -92,4 +92,6 @@ public final class FloatProperty extends AbstractNumericProperty { protected Float createFrom(String value) { return FLOAT_PARSER.valueOf(value); } + + } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/IntegerProperty.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/IntegerProperty.java index d0aefd36d5..da4412232c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/IntegerProperty.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/IntegerProperty.java @@ -19,6 +19,7 @@ import net.sourceforge.pmd.PropertyDescriptorField; */ public final class IntegerProperty extends AbstractNumericProperty { + /** Factory. */ public static final PropertyDescriptorFactory FACTORY // @formatter:off = new SingleValuePropertyDescriptorFactory(Integer.class, NUMBER_FIELD_TYPES_BY_KEY) { @@ -36,11 +37,6 @@ public final class IntegerProperty extends AbstractNumericProperty { }; // @formatter:on - static { - System.err.println(FACTORY); - } - - /** * Constructor that limits itself to a single value within the specified limits. * diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/PropertyDescriptorUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/PropertyDescriptorUtil.java index 59fafa8298..3b1f87fe7f 100755 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/PropertyDescriptorUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/PropertyDescriptorUtil.java @@ -9,7 +9,6 @@ import java.util.HashMap; import java.util.Map; import net.sourceforge.pmd.PropertyDescriptorFactory; -import net.sourceforge.pmd.PropertyDescriptorField; /** * Utility class allowing to find the factory of a specific type of descriptor. That's used to define descriptors in @@ -24,7 +23,6 @@ public final class PropertyDescriptorUtil { static { Map> temp = new HashMap<>(18); - temp.put("Boolean", BooleanProperty.FACTORY); temp.put("List", BooleanMultiProperty.FACTORY); @@ -33,6 +31,7 @@ public final class PropertyDescriptorUtil { temp.put("Character", CharacterProperty.FACTORY); temp.put("List", CharacterMultiProperty.FACTORY); + temp.put("Integer", IntegerProperty.FACTORY); temp.put("List", IntegerMultiProperty.FACTORY); temp.put("Long", LongProperty.FACTORY); @@ -41,7 +40,6 @@ public final class PropertyDescriptorUtil { temp.put("List", FloatMultiProperty.FACTORY); temp.put("Double", DoubleProperty.FACTORY); temp.put("List", DoubleMultiProperty.FACTORY); - // temp.put("Enum", EnumeratedProperty.FACTORY); // TODO:cf implement that // temp.put("List", EnumeratedMultiProperty.FACTORY); @@ -90,52 +88,4 @@ public final class PropertyDescriptorUtil { } - /** - * Gets a builder for a required fields map. - * - * @return A builder - * - * @see ExpectedFieldsBuilder - */ - public static ExpectedFieldsBuilder expectedFields() { - return new ExpectedFieldsBuilder(); - } - - - /** Builder for an expected fields map. */ - public static final class ExpectedFieldsBuilder { - - Map requiredFields = new HashMap<>(); - - - public ExpectedFieldsBuilder() { - - } - - - /** - * Adds a mapping of field/ required to the map. - * - * @param field The field to expect - * @param isRequired Whether it's required or not - * - * @return This instance, so that we have a fluent interface - */ - public ExpectedFieldsBuilder put(PropertyDescriptorField field, boolean isRequired) { - requiredFields.put(field, isRequired); - return this; - } - - - /** - * Gets an immutable map containing the fields we've put here. - * - * @return The map of field/ isRequired mappings - */ - public Map get() { - return Collections.unmodifiableMap(requiredFields); - } - - } - } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/StringMultiProperty.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/StringMultiProperty.java index 9bd2d8f2da..805b79b01d 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/StringMultiProperty.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/properties/StringMultiProperty.java @@ -10,6 +10,8 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.StringUtils; + import net.sourceforge.pmd.PropertyDescriptorFactory; import net.sourceforge.pmd.PropertyDescriptorField; import net.sourceforge.pmd.lang.rule.properties.ValueParser.Companion; @@ -30,7 +32,7 @@ public final class StringMultiProperty extends AbstractMultiValueProperty { @Override protected boolean isValueMissing(String value) { - return StringUtil.isMissing(value); + return StringUtils.isEmpty(value); } @Override diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/StringUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/StringUtil.java index 759bd406db..375892308a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/StringUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/StringUtil.java @@ -8,6 +8,8 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import org.apache.commons.lang3.StringUtils; + /** * A number of String-specific utility methods for use by PMD or its IDE * plugins. @@ -100,14 +102,14 @@ public final class StringUtil { /** * Returns true if the value arg is either null, empty, or full of * whitespace characters. More efficient that calling - * (string).trim().length() == 0 + * (string).trim().length() == 0. * - * @param value + * @param value String to test * * @return true if the value is empty, false otherwise. */ public static boolean isEmpty(String value) { - return isMissing(value) || nullSafeIsBlank(value); + return StringUtils.isBlank(value); } @@ -119,41 +121,7 @@ public final class StringUtil { * @return True if the argument is null or the empty string */ public static boolean isMissing(String value) { - - if (value == null || "".equals(value)) { - return true; - } - - return false; - } - - - /** Argument must not be null. */ - private static boolean nullSafeIsBlank(String value) { - for (int i = 0; i < value.length(); i++) { - if (!Character.isWhitespace(value.charAt(i))) { - return false; - } - } - - return true; - } - - - /** - * Returns true if the argument is null or entirely composed of whitespace characters. - * - * @param value String to test - * - * @return True if the argument is null or entirely composed of whitespace characters. - */ - public static boolean isBlank(String value) { - - if (value == null) { - return true; - } - - return nullSafeIsBlank(value); + return StringUtils.isEmpty(value); }