Fix initialisation bug

This commit is contained in:
oowekyala
2017-07-15 16:36:11 +02:00
parent 278e857bf6
commit 35dee58bc8
17 changed files with 141 additions and 146 deletions

View File

@ -4,7 +4,7 @@
package net.sourceforge.pmd; 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.DEFAULT_VALUE;
import static net.sourceforge.pmd.PropertyDescriptorField.DELIMITER; import static net.sourceforge.pmd.PropertyDescriptorField.DELIMITER;
import static net.sourceforge.pmd.PropertyDescriptorField.DESCRIPTION; import static net.sourceforge.pmd.PropertyDescriptorField.DESCRIPTION;
@ -19,6 +19,8 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.util.StringUtil; import net.sourceforge.pmd.util.StringUtil;
/** /**
@ -30,26 +32,18 @@ import net.sourceforge.pmd.util.StringUtil;
*/ */
public abstract class AbstractPropertyDescriptorFactory<T> implements PropertyDescriptorFactory<T> { public abstract class AbstractPropertyDescriptorFactory<T> implements PropertyDescriptorFactory<T> {
static {
System.err.println(CORE_FIELD_TYPES_BY_KEY);
}
private final Class<?> valueType; private final Class<?> valueType;
/** /**
* Denote the identifiers of the expected fields paired with booleans * 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<PropertyDescriptorField, Boolean> expectedFields; private final Map<PropertyDescriptorField, Boolean> expectedFields;
public AbstractPropertyDescriptorFactory(Class<?> theValueType) { public AbstractPropertyDescriptorFactory(Class<?> theValueType) {
valueType = theValueType; valueType = theValueType;
expectedFields = CORE_FIELD_TYPES_BY_KEY; expectedFields = CORE_EXPECTED_FIELDS;
} }
@ -57,12 +51,12 @@ public abstract class AbstractPropertyDescriptorFactory<T> implements PropertyDe
valueType = theValueType; valueType = theValueType;
if (additionalFieldTypesByKey == null) { if (additionalFieldTypesByKey == null) {
expectedFields = CORE_FIELD_TYPES_BY_KEY; expectedFields = CORE_EXPECTED_FIELDS;
return; return;
} }
Map<PropertyDescriptorField, Boolean> temp Map<PropertyDescriptorField, Boolean> temp
= new HashMap<>(CORE_FIELD_TYPES_BY_KEY.size() + additionalFieldTypesByKey.size()); = new HashMap<>(CORE_EXPECTED_FIELDS.size() + additionalFieldTypesByKey.size());
temp.putAll(CORE_FIELD_TYPES_BY_KEY); temp.putAll(CORE_EXPECTED_FIELDS);
temp.putAll(additionalFieldTypesByKey); temp.putAll(additionalFieldTypesByKey);
expectedFields = Collections.unmodifiableMap(temp); expectedFields = Collections.unmodifiableMap(temp);
@ -116,7 +110,7 @@ public abstract class AbstractPropertyDescriptorFactory<T> implements PropertyDe
*/ */
protected String defaultValueIn(Map<PropertyDescriptorField, String> valuesById) { protected String defaultValueIn(Map<PropertyDescriptorField, String> valuesById) {
String deft = valuesById.get(DEFAULT_VALUE); String deft = valuesById.get(DEFAULT_VALUE);
if (StringUtil.isEmpty(deft)) { if (isValueMissing(deft)) {
throw new RuntimeException("Default value was null, empty, or missing"); throw new RuntimeException("Default value was null, empty, or missing");
} }
return deft; return deft;
@ -125,7 +119,7 @@ public abstract class AbstractPropertyDescriptorFactory<T> implements PropertyDe
@Override @Override
public final PropertyDescriptor<T> createWith(Map<PropertyDescriptorField, String> valuesById) { public final PropertyDescriptor<T> createWith(Map<PropertyDescriptorField, String> valuesById) {
// checkRequiredFields(valuesById); checkRequiredFields(valuesById);
return createWith(valuesById, false); return createWith(valuesById, false);
} }
@ -133,7 +127,7 @@ public abstract class AbstractPropertyDescriptorFactory<T> implements PropertyDe
/** Checks whether all required fields are present in the map. */ /** Checks whether all required fields are present in the map. */
private void checkRequiredFields(Map<PropertyDescriptorField, String> valuesById) { private void checkRequiredFields(Map<PropertyDescriptorField, String> valuesById) {
for (Entry<PropertyDescriptorField, Boolean> entry : expectedFields.entrySet()) { for (Entry<PropertyDescriptorField, Boolean> 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()); throw new RuntimeException("Missing required value for key: " + entry.getKey());
} }
} }
@ -249,7 +243,7 @@ public abstract class AbstractPropertyDescriptorFactory<T> implements PropertyDe
characterStr = valuesById.get(DELIMITER).trim(); characterStr = valuesById.get(DELIMITER).trim();
} }
if (StringUtil.isEmpty(characterStr)) { if (StringUtils.isBlank(characterStr)) {
return defaultDelimiter; return defaultDelimiter;
} }
@ -272,7 +266,7 @@ public abstract class AbstractPropertyDescriptorFactory<T> implements PropertyDe
protected static String[] minMaxFrom(Map<PropertyDescriptorField, String> valuesById) { protected static String[] minMaxFrom(Map<PropertyDescriptorField, String> valuesById) {
String min = minValueIn(valuesById); String min = minValueIn(valuesById);
String max = maxValueIn(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"); throw new RuntimeException("min and max values must be specified");
} }
return new String[] {min, max}; return new String[] {min, max};
@ -291,7 +285,7 @@ public abstract class AbstractPropertyDescriptorFactory<T> implements PropertyDe
protected static String[] legalPackageNamesIn(Map<PropertyDescriptorField, String> valuesById, char delimiter) { protected static String[] legalPackageNamesIn(Map<PropertyDescriptorField, String> valuesById, char delimiter) {
String names = valuesById.get(LEGAL_PACKAGES); String names = valuesById.get(LEGAL_PACKAGES);
if (StringUtil.isEmpty(names)) { if (StringUtils.isBlank(names)) {
return null; return null;
} }
return StringUtil.substringsOf(names, delimiter); return StringUtil.substringsOf(names, delimiter);
@ -299,18 +293,19 @@ public abstract class AbstractPropertyDescriptorFactory<T> 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 otherKeys Additional keys
* @param otherValues * @param otherValues Whether the corresponding keys are required or not
* *
* @return * @return The complete map of expected fields.
*/ */
public static Map<PropertyDescriptorField, Boolean> expectedFieldTypesWith(PropertyDescriptorField[] otherKeys, static Map<PropertyDescriptorField, Boolean> expectedFieldTypesWith(PropertyDescriptorField[] otherKeys,
Boolean[] otherValues) { Boolean[] otherValues) {
Map<PropertyDescriptorField, Boolean> largerMap = new HashMap<>( Map<PropertyDescriptorField, Boolean> largerMap = new HashMap<>(
otherKeys.length + CORE_FIELD_TYPES_BY_KEY.size()); otherKeys.length + CORE_EXPECTED_FIELDS.size());
largerMap.putAll(CORE_FIELD_TYPES_BY_KEY); largerMap.putAll(CORE_EXPECTED_FIELDS);
for (int i = 0; i < otherKeys.length; i++) { for (int i = 0; i < otherKeys.length; i++) {
largerMap.put(otherKeys[i], otherValues[i]); largerMap.put(otherKeys[i], otherValues[i]);
} }

View File

@ -7,8 +7,10 @@ package net.sourceforge.pmd;
import java.util.List; import java.util.List;
/** /**
* Specializes property descriptors for single valued descriptors. For this type of property, the return value of the * 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 the interface {@link PropertyDescriptor}. * {@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 <i>not</i> the same as the type parameter of {@link PropertyDescriptor} they inherit!
* *
* @param <V> The type of value this descriptor works with. This is the type of the list's component. * @param <V> The type of value this descriptor works with. This is the type of the list's component.
* *

View File

@ -9,7 +9,7 @@ import static net.sourceforge.pmd.PropertyDescriptorField.MIN;
import java.util.Map; 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 * 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<T> extends PropertyDescriptor<T> { public interface NumericPropertyDescriptor<T> extends PropertyDescriptor<T> {
Map<PropertyDescriptorField, Boolean> NUMBER_FIELD_TYPES_BY_KEY Map<PropertyDescriptorField, Boolean> NUMBER_FIELD_TYPES_BY_KEY
= PropertyDescriptorUtil.expectedFields().put(MIN, true).put(MAX, true).get(); = ExpectedFieldsBuilder.instance().put(MIN, true).put(MAX, true).build();
/** /**

View File

@ -11,7 +11,7 @@ import static net.sourceforge.pmd.PropertyDescriptorField.NAME;
import java.util.Map; 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 &amp; requirements for setting * Property value descriptor that defines the use &amp; requirements for setting
@ -35,13 +35,13 @@ import net.sourceforge.pmd.lang.rule.properties.PropertyDescriptorUtil.ExpectedF
public interface PropertyDescriptor<T> extends Comparable<PropertyDescriptor<?>> { public interface PropertyDescriptor<T> extends Comparable<PropertyDescriptor<?>> {
/** Default expected fields. Unmodifiable. */ /** Default expected fields. Unmodifiable. */
Map<PropertyDescriptorField, Boolean> CORE_FIELD_TYPES_BY_KEY Map<PropertyDescriptorField, Boolean> CORE_EXPECTED_FIELDS
= (new ExpectedFieldsBuilder()) = ExpectedFieldsBuilder.instance()
.put(NAME, true) .put(NAME, true)
.put(DESCRIPTION, true) .put(DESCRIPTION, true)
.put(DEFAULT_VALUE, true) .put(DEFAULT_VALUE, true)
.put(DELIMITER, false) .put(DELIMITER, false)
.get(); .build();
/** /**

View File

@ -16,6 +16,8 @@ import java.util.Objects;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.benchmark.Benchmark; import net.sourceforge.pmd.benchmark.Benchmark;
import net.sourceforge.pmd.benchmark.Benchmarker; import net.sourceforge.pmd.benchmark.Benchmarker;
import net.sourceforge.pmd.cache.ChecksumAware; import net.sourceforge.pmd.cache.ChecksumAware;
@ -179,7 +181,7 @@ public class RuleSet implements ChecksumAware {
* @return The same builder, for a fluid programming interface * @return The same builder, for a fluid programming interface
*/ */
public RuleSetBuilder addRuleByReference(final String ruleSetFileName, final Rule rule) { public RuleSetBuilder addRuleByReference(final String ruleSetFileName, final Rule rule) {
if (StringUtil.isEmpty(ruleSetFileName)) { if (StringUtils.isBlank(ruleSetFileName)) {
throw new RuntimeException( throw new RuntimeException(
"Adding a rule by reference is not allowed with an empty rule set file name."); "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, public RuleSetBuilder addRuleSetByReference(final RuleSet ruleSet, final boolean allRules,
final String... excludes) { final String... excludes) {
if (StringUtil.isEmpty(ruleSet.getFileName())) { if (StringUtils.isBlank(ruleSet.getFileName())) {
throw new RuntimeException( throw new RuntimeException(
"Adding a rule by reference is not allowed with an empty rule set file name."); "Adding a rule by reference is not allowed with an empty rule set file name.");
} }

View File

@ -4,6 +4,8 @@
package net.sourceforge.pmd; package net.sourceforge.pmd;
import static net.sourceforge.pmd.PropertyDescriptorField.DEFAULT_VALUE;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
@ -23,6 +25,7 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
@ -414,7 +417,7 @@ public class RuleSetFactory {
String ref = ruleElement.getAttribute("ref"); String ref = ruleElement.getAttribute("ref");
if (ref.endsWith("xml")) { if (ref.endsWith("xml")) {
parseRuleSetReferenceNode(ruleSetReferenceId, ruleSetBuilder, ruleElement, ref); parseRuleSetReferenceNode(ruleSetReferenceId, ruleSetBuilder, ruleElement, ref);
} else if (StringUtil.isEmpty(ref)) { } else if (StringUtils.isBlank(ref)) {
parseSingleRuleNode(ruleSetReferenceId, ruleSetBuilder, ruleNode); parseSingleRuleNode(ruleSetReferenceId, ruleSetBuilder, ruleNode);
} else { } else {
parseRuleReferenceNode(ruleSetReferenceId, ruleSetBuilder, ruleNode, ref, withDeprecatedRuleReferences); parseRuleReferenceNode(ruleSetReferenceId, ruleSetBuilder, ruleNode, ref, withDeprecatedRuleReferences);
@ -812,13 +815,13 @@ public class RuleSetFactory {
Element propertyElement = (Element) propertyNode; Element propertyElement = (Element) propertyNode;
String typeId = propertyElement.getAttribute(PropertyDescriptorField.TYPE.attributeName()); String typeId = propertyElement.getAttribute(PropertyDescriptorField.TYPE.attributeName());
String strValue = propertyElement.getAttribute(PropertyDescriptorField.DEFAULT_VALUE.attributeName()); String strValue = propertyElement.getAttribute(DEFAULT_VALUE.attributeName());
if (StringUtil.isEmpty(strValue)) { if (StringUtils.isBlank(strValue)) {
strValue = valueFrom(propertyElement); strValue = valueFrom(propertyElement);
} }
// Setting of existing property, or defining a new property? // Setting of existing property, or defining a new property?
if (StringUtil.isEmpty(typeId)) { if (StringUtils.isBlank(typeId)) {
String name = propertyElement.getAttribute(PropertyDescriptorField.NAME.attributeName()); String name = propertyElement.getAttribute(PropertyDescriptorField.NAME.attributeName());
PropertyDescriptor<?> propertyDescriptor = rule.getPropertyDescriptor(name); PropertyDescriptor<?> propertyDescriptor = rule.getPropertyDescriptor(name);
@ -842,9 +845,19 @@ public class RuleSetFactory {
// populate a map of values for an individual descriptor // populate a map of values for an individual descriptor
for (PropertyDescriptorField field : valueKeys) { for (PropertyDescriptorField field : valueKeys) {
String valueStr = propertyElement.getAttribute(field.attributeName()); String valueStr = propertyElement.getAttribute(field.attributeName());
if (valueStr != null)
values.put(field, valueStr); 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 // casting is not pretty but prevents the interface from having this method
PropertyDescriptor<?> desc = ((AbstractPropertyDescriptorFactory) pdFactory).createExternalWith(values); PropertyDescriptor<?> desc = ((AbstractPropertyDescriptorFactory) pdFactory).createExternalWith(values);

View File

@ -408,7 +408,7 @@ public class RuleSetReferenceId {
*/ */
public InputStream getInputStream(ClassLoader classLoader) throws RuleSetNotFoundException { public InputStream getInputStream(ClassLoader classLoader) throws RuleSetNotFoundException {
if (externalRuleSetReferenceId == null) { if (externalRuleSetReferenceId == null) {
InputStream in = StringUtil.isEmpty(ruleSetFileName) ? null InputStream in = StringUtils.isBlank(ruleSetFileName) ? null
: ResourceLoader.loadResourceAsStream(ruleSetFileName, classLoader); : ResourceLoader.loadResourceAsStream(ruleSetFileName, classLoader);
if (in == null) { if (in == null) {
throw new RuleSetNotFoundException("Can't find resource '" + ruleSetFileName + "' for rule '" + ruleName throw new RuleSetNotFoundException("Can't find resource '" + ruleSetFileName + "' for rule '" + ruleName

View File

@ -9,6 +9,8 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.PropertyDescriptorFactory; import net.sourceforge.pmd.PropertyDescriptorFactory;
import net.sourceforge.pmd.PropertyDescriptorField; import net.sourceforge.pmd.PropertyDescriptorField;
import net.sourceforge.pmd.lang.rule.properties.ValueParser.Companion; import net.sourceforge.pmd.lang.rule.properties.ValueParser.Companion;
@ -28,7 +30,7 @@ public final class CharacterMultiProperty extends AbstractMultiValueProperty<Cha
@Override @Override
protected boolean isValueMissing(String value) { protected boolean isValueMissing(String value) {
return StringUtil.isMissing(value); return StringUtils.isEmpty(value);
} }
@Override @Override

View File

@ -8,6 +8,8 @@ import static net.sourceforge.pmd.lang.rule.properties.ValueParser.CHARACTER_PAR
import java.util.Map; import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.PropertyDescriptorFactory; import net.sourceforge.pmd.PropertyDescriptorFactory;
import net.sourceforge.pmd.PropertyDescriptorField; import net.sourceforge.pmd.PropertyDescriptorField;
import net.sourceforge.pmd.util.StringUtil; import net.sourceforge.pmd.util.StringUtil;
@ -25,7 +27,7 @@ public final class CharacterProperty extends AbstractSingleValueProperty<Charact
@Override @Override
protected boolean isValueMissing(String value) { protected boolean isValueMissing(String value) {
return StringUtil.isMissing(value); return StringUtils.isEmpty(value);
} }
@Override @Override

View File

@ -21,18 +21,18 @@ import net.sourceforge.pmd.PropertyDescriptorField;
*/ */
public final class DoubleProperty extends AbstractNumericProperty<Double> { public final class DoubleProperty extends AbstractNumericProperty<Double> {
/** Factory. */
public static final PropertyDescriptorFactory<Double> FACTORY // @formatter:off public static final PropertyDescriptorFactory<Double> FACTORY // @formatter:off
= new SingleValuePropertyDescriptorFactory<Double>(Double.class, NUMBER_FIELD_TYPES_BY_KEY) { = new SingleValuePropertyDescriptorFactory<Double>(Double.class, NUMBER_FIELD_TYPES_BY_KEY) {
@Override @Override
public DoubleProperty createWith(Map<PropertyDescriptorField, String> valuesById, public DoubleProperty createWith(Map<PropertyDescriptorField, String> valuesById,
boolean isDefinedExternally) { boolean isDefinedExternally) {
final String[] minMax = minMaxFrom(valuesById); final String[] minMax = minMaxFrom(valuesById);
System.out.println(Arrays.asList(minMax));
return new DoubleProperty(nameIn(valuesById), return new DoubleProperty(nameIn(valuesById),
descriptionIn(valuesById), descriptionIn(valuesById),
DOUBLE_PARSER.valueOf(minMax[0]), doubleFrom(minMax[0]),
DOUBLE_PARSER.valueOf(minMax[1]), doubleFrom(minMax[1]),
DOUBLE_PARSER.valueOf(defaultValueIn(valuesById)), doubleFrom(defaultValueIn(valuesById)),
0f, 0f,
isDefinedExternally); isDefinedExternally);
} }
@ -73,8 +73,8 @@ public final class DoubleProperty extends AbstractNumericProperty<Double> {
* *
* @return Parsed Double * @return Parsed Double
*/ */
public static Double doubleFrom(String numberString) { private static Double doubleFrom(String numberString) {
return Double.valueOf(numberString); return DOUBLE_PARSER.valueOf(numberString);
} }

View File

@ -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<PropertyDescriptorField, Boolean> 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<PropertyDescriptorField, Boolean> 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();
}
}

View File

@ -92,4 +92,6 @@ public final class FloatProperty extends AbstractNumericProperty<Float> {
protected Float createFrom(String value) { protected Float createFrom(String value) {
return FLOAT_PARSER.valueOf(value); return FLOAT_PARSER.valueOf(value);
} }
} }

View File

@ -19,6 +19,7 @@ import net.sourceforge.pmd.PropertyDescriptorField;
*/ */
public final class IntegerProperty extends AbstractNumericProperty<Integer> { public final class IntegerProperty extends AbstractNumericProperty<Integer> {
/** Factory. */
public static final PropertyDescriptorFactory<Integer> FACTORY // @formatter:off public static final PropertyDescriptorFactory<Integer> FACTORY // @formatter:off
= new SingleValuePropertyDescriptorFactory<Integer>(Integer.class, NUMBER_FIELD_TYPES_BY_KEY) { = new SingleValuePropertyDescriptorFactory<Integer>(Integer.class, NUMBER_FIELD_TYPES_BY_KEY) {
@ -36,11 +37,6 @@ public final class IntegerProperty extends AbstractNumericProperty<Integer> {
}; // @formatter:on }; // @formatter:on
static {
System.err.println(FACTORY);
}
/** /**
* Constructor that limits itself to a single value within the specified limits. * Constructor that limits itself to a single value within the specified limits.
* *

View File

@ -9,7 +9,6 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import net.sourceforge.pmd.PropertyDescriptorFactory; 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 * 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 { static {
Map<String, PropertyDescriptorFactory<?>> temp = new HashMap<>(18); Map<String, PropertyDescriptorFactory<?>> temp = new HashMap<>(18);
temp.put("Boolean", BooleanProperty.FACTORY); temp.put("Boolean", BooleanProperty.FACTORY);
temp.put("List<Boolean>", BooleanMultiProperty.FACTORY); temp.put("List<Boolean>", BooleanMultiProperty.FACTORY);
@ -33,6 +31,7 @@ public final class PropertyDescriptorUtil {
temp.put("Character", CharacterProperty.FACTORY); temp.put("Character", CharacterProperty.FACTORY);
temp.put("List<Character>", CharacterMultiProperty.FACTORY); temp.put("List<Character>", CharacterMultiProperty.FACTORY);
temp.put("Integer", IntegerProperty.FACTORY); temp.put("Integer", IntegerProperty.FACTORY);
temp.put("List<Integer>", IntegerMultiProperty.FACTORY); temp.put("List<Integer>", IntegerMultiProperty.FACTORY);
temp.put("Long", LongProperty.FACTORY); temp.put("Long", LongProperty.FACTORY);
@ -41,7 +40,6 @@ public final class PropertyDescriptorUtil {
temp.put("List<Float>", FloatMultiProperty.FACTORY); temp.put("List<Float>", FloatMultiProperty.FACTORY);
temp.put("Double", DoubleProperty.FACTORY); temp.put("Double", DoubleProperty.FACTORY);
temp.put("List<Double>", DoubleMultiProperty.FACTORY); temp.put("List<Double>", DoubleMultiProperty.FACTORY);
// temp.put("Enum", EnumeratedProperty.FACTORY); // TODO:cf implement that // temp.put("Enum", EnumeratedProperty.FACTORY); // TODO:cf implement that
// temp.put("List<Enum>", EnumeratedMultiProperty.FACTORY); // temp.put("List<Enum>", 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<PropertyDescriptorField, Boolean> 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<PropertyDescriptorField, Boolean> get() {
return Collections.unmodifiableMap(requiredFields);
}
}
} }

View File

@ -10,6 +10,8 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.PropertyDescriptorFactory; import net.sourceforge.pmd.PropertyDescriptorFactory;
import net.sourceforge.pmd.PropertyDescriptorField; import net.sourceforge.pmd.PropertyDescriptorField;
import net.sourceforge.pmd.lang.rule.properties.ValueParser.Companion; import net.sourceforge.pmd.lang.rule.properties.ValueParser.Companion;
@ -30,7 +32,7 @@ public final class StringMultiProperty extends AbstractMultiValueProperty<String
@Override @Override
protected boolean isValueMissing(String value) { protected boolean isValueMissing(String value) {
return StringUtil.isMissing(value); return StringUtils.isEmpty(value);
} }
@Override @Override

View File

@ -6,6 +6,8 @@ package net.sourceforge.pmd.lang.rule.properties;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.PropertyDescriptorFactory; import net.sourceforge.pmd.PropertyDescriptorFactory;
import net.sourceforge.pmd.PropertyDescriptorField; import net.sourceforge.pmd.PropertyDescriptorField;
import net.sourceforge.pmd.util.StringUtil; import net.sourceforge.pmd.util.StringUtil;
@ -24,7 +26,7 @@ public final class StringProperty extends AbstractSingleValueProperty<String> {
@Override @Override
protected boolean isValueMissing(String value) { protected boolean isValueMissing(String value) {
return StringUtil.isMissing(value); return StringUtils.isEmpty(value);
} }
@Override @Override

View File

@ -8,6 +8,8 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.StringUtils;
/** /**
* A number of String-specific utility methods for use by PMD or its IDE * A number of String-specific utility methods for use by PMD or its IDE
* plugins. * plugins.
@ -100,14 +102,14 @@ public final class StringUtil {
/** /**
* Returns true if the value arg is either null, empty, or full of * Returns true if the value arg is either null, empty, or full of
* whitespace characters. More efficient that calling * whitespace characters. More efficient that calling
* (string).trim().length() == 0 * (string).trim().length() == 0.
* *
* @param value * @param value String to test
* *
* @return <code>true</code> if the value is empty, <code>false</code> otherwise. * @return <code>true</code> if the value is empty, <code>false</code> otherwise.
*/ */
public static boolean isEmpty(String value) { 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 * @return True if the argument is null or the empty string
*/ */
public static boolean isMissing(String value) { public static boolean isMissing(String value) {
return StringUtils.isEmpty(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);
} }