[FELIX-3757] Processed comments of fmeschbe:
- applied correct code formatting;
- when min/max values were defined for types other than integer, the validation
failed (possibly with a class cast exception);
- some other small issues fixed regarding the validation of the different types;
- updated the changelog to include the set of changes.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1410279 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/metatype/changelog.txt b/metatype/changelog.txt
index af4d409..f6c26b9 100644
--- a/metatype/changelog.txt
+++ b/metatype/changelog.txt
@@ -1,3 +1,11 @@
+Changes from 1.0.6 to 1.0.8
+---------------------------
+
+** Bug
+ * [FELIX-3756] - Optional attributes validated invalid data as correct;
+ * [FELIX-3757] - If an AttributeDefinition did not specify a minimum, maximum or option values, it did not detect missing values;
+ * [FELIX-3758] - AttributeDefinition.validate() did not take non-zero cardinality into consideration.
+
Changes from 1.0.4 to 1.0.6
---------------------------
diff --git a/metatype/src/main/java/org/apache/felix/metatype/AD.java b/metatype/src/main/java/org/apache/felix/metatype/AD.java
index a083f68..f2456f2 100644
--- a/metatype/src/main/java/org/apache/felix/metatype/AD.java
+++ b/metatype/src/main/java/org/apache/felix/metatype/AD.java
@@ -18,7 +18,6 @@
*/
package org.apache.felix.metatype;
-
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -28,7 +27,6 @@
import org.osgi.service.log.LogService;
import org.osgi.service.metatype.AttributeDefinition;
-
/**
* The <code>AD</code> class represents the <code>AD</code> element of the
* meta type descriptor.
@@ -84,255 +82,221 @@
private String max;
private boolean isRequired = true;
-
public String getID()
{
return id;
}
-
public String getName()
{
return name;
}
-
public String getDescription()
{
return description;
}
-
public int getType()
{
return type;
}
-
public int getCardinality()
{
return cardinality;
}
-
public String[] getOptionLabels()
{
return optionLabels;
}
-
public String[] getOptionValues()
{
return optionValues;
}
-
public String[] getDefaultValue()
{
return defaultValue;
}
-
public String getMin()
{
return min;
}
-
public String getMax()
{
return max;
}
-
public boolean isRequired()
{
return isRequired;
}
-
/**
* Implements validation of the <code>valueString</code> and returns an
- * indication of the success:
- * <dl>
- * <dt><code>null</code>
- * <dd>If neither a {@link #getMin() minimal value} nor a
- * {@link #getMax() maximal value} nor any
- * {@link #getOptionValues() optional values} are defined in this
- * instance, validation cannot be performed.
- * <dt>Empty String
- * <dd>If validation succeeds. This value is also returned if the
- * <code>valueString</code> is empty or <code>null</code> or cannot be
- * converted into a numeric type.
- * <dt><b>%</b>message
- * <dd>If the value falls below the minimum, higher than the maximum or is
- * not any of the option values, an explanatory message, which may be
- * localized is returned. If any of the minimum, maximum or option
- * values is <code>null</code>, the respective value is not checked.
- * </dl>
+ * indication of the validation result.
*
- * @param valueString The string representation of the value to validate.
+ * @param valueString The string representation of the value to validate,
+ * can be <code>null</code>.
*
- * @return As explained above.
+ * @return <code>null</code> if no validation is performed, <tt>""</tt> if
+ * the value is accepted as valid, or a non-empty string
+ * indicating a validation problem was found.
*
+ * @see ADValidator#validate(AD, String)
* @see #VALIDATE_GREATER_THAN_MAXIMUM
- * @see #VALIDATE_LESS_THAN_MINIMUM
* @see #VALIDATE_NOT_A_VALID_OPTION
+ * @see #VALIDATE_LESS_THAN_MINIMUM
+ * @see #VALIDATE_INVALID_VALUE
+ * @see #VALIDATE_MISSING
*/
- public String validate( String valueString )
+ public String validate(String valueString)
{
- return ADValidator.validate(this, valueString);
+ return ADValidator.validate(this, valueString);
}
-
//--------- Setters for setting up this instance --------------------------
/**
* @param id the id to set
*/
- public void setID( String id )
+ public void setID(String id)
{
this.id = id;
}
-
/**
* @param name the name to set
*/
- public void setName( String name )
+ public void setName(String name)
{
this.name = name;
}
-
/**
* @param description the description to set
*/
- public void setDescription( String description )
+ public void setDescription(String description)
{
this.description = description;
}
-
/**
* @param typeString the type to set
*/
- public void setType( String typeString )
+ public void setType(String typeString)
{
- this.type = toType( typeString );
+ this.type = toType(typeString);
}
-
/**
* @param cardinality the cardinality to set
*/
- public void setCardinality( int cardinality )
+ public void setCardinality(int cardinality)
{
this.cardinality = cardinality;
}
-
/**
* @param options the options to set
*/
- public void setOptions( Map options )
+ public void setOptions(Map options)
{
optionLabels = new String[options.size()];
optionValues = new String[options.size()];
int i = 0;
- for ( Iterator oi = options.entrySet().iterator(); oi.hasNext(); i++ )
+ for (Iterator oi = options.entrySet().iterator(); oi.hasNext(); i++)
{
- Map.Entry entry = ( Map.Entry ) oi.next();
- optionValues[i] = String.valueOf( entry.getKey() );
- optionLabels[i] = String.valueOf( entry.getValue() );
+ Map.Entry entry = (Map.Entry) oi.next();
+ optionValues[i] = String.valueOf(entry.getKey());
+ optionLabels[i] = String.valueOf(entry.getValue());
}
}
-
/**
* @param defaultValue the defaultValue to set
*/
- public void setDefaultValue( String defaultValue )
+ public void setDefaultValue(String defaultValue)
{
- this.defaultValue = splitList( defaultValue );
+ this.defaultValue = splitList(defaultValue);
}
-
/**
* @param min the min to set
*/
- public void setMin( String min )
+ public void setMin(String min)
{
this.min = min;
}
-
/**
* @param max the max to set
*/
- public void setMax( String max )
+ public void setMax(String max)
{
this.max = max;
}
-
/**
* @param defaultValue the defaultValue to set
*/
- public void setDefaultValue( String[] defaultValue )
+ public void setDefaultValue(String[] defaultValue)
{
- this.defaultValue = ( String[] ) defaultValue.clone();
+ this.defaultValue = (String[]) defaultValue.clone();
}
-
/**
* @param isRequired the isRequired to set
*/
- public void setRequired( boolean isRequired )
+ public void setRequired(boolean isRequired)
{
this.isRequired = isRequired;
}
-
- public static int toType( String typeString )
+ public static int toType(String typeString)
{
- if ( "String".equals( typeString ) )
+ if ("String".equals(typeString))
{
return AttributeDefinition.STRING;
}
- else if ( "Long".equals( typeString ) )
+ else if ("Long".equals(typeString))
{
return AttributeDefinition.LONG;
}
- else if ( "Double".equals( typeString ) )
+ else if ("Double".equals(typeString))
{
return AttributeDefinition.DOUBLE;
}
- else if ( "Float".equals( typeString ) )
+ else if ("Float".equals(typeString))
{
return AttributeDefinition.FLOAT;
}
- else if ( "Integer".equals( typeString ) )
+ else if ("Integer".equals(typeString))
{
return AttributeDefinition.INTEGER;
}
- else if ( "Byte".equals( typeString ) )
+ else if ("Byte".equals(typeString))
{
return AttributeDefinition.BYTE;
}
- else if ( "Char".equals( typeString ) )
+ else if ("Char".equals(typeString))
{
return AttributeDefinition.CHARACTER;
}
- else if ( "Boolean".equals( typeString ) )
+ else if ("Boolean".equals(typeString))
{
return AttributeDefinition.BOOLEAN;
}
- else if ( "Short".equals( typeString ) )
+ else if ("Short".equals(typeString))
{
return AttributeDefinition.SHORT;
}
- else if ( "Password".equals( typeString ) )
+ else if ("Password".equals(typeString))
{
return AttributeDefinition.PASSWORD;
}
@@ -341,90 +305,102 @@
return AttributeDefinition.STRING;
}
-
- public static String[] splitList( String listString )
+ public static String[] splitList(String listString)
{
- if (listString == null) {
- return null;
- } else if (listString.length() == 0) {
- return new String[] { "" };
- }
+ if (listString == null)
+ {
+ return null;
+ }
+ else if (listString.length() == 0)
+ {
+ return new String[] { "" };
+ }
- List strings = new ArrayList();
- StringBuffer sb = new StringBuffer();
+ List strings = new ArrayList();
+ StringBuffer sb = new StringBuffer();
- int length = listString.length();
- boolean escaped = false;
-
- for (int i = 0; i < length; i++) {
- char ch = listString.charAt(i);
- if (ch == '\\') {
- if (!escaped) {
- escaped = true;
- continue;
- }
- } else if (ch == ',') {
- if (!escaped) {
- // unescaped comma, this is a string delimiter...
- strings.add(sb.toString());
- sb.setLength(0);
- continue;
- }
- } else if (ch == ' ') {
- // we should ignore spaces normally, unless they are escaped...
- if (!escaped) {
- continue;
- }
- } else if (Character.isWhitespace(ch)) {
- // Other whitespaces are ignored...
- continue;
- }
+ int length = listString.length();
+ boolean escaped = false;
- sb.append(ch);
- escaped = false;
- }
+ for (int i = 0; i < length; i++)
+ {
+ char ch = listString.charAt(i);
+ if (ch == '\\')
+ {
+ if (!escaped)
+ {
+ escaped = true;
+ continue;
+ }
+ }
+ else if (ch == ',')
+ {
+ if (!escaped)
+ {
+ // unescaped comma, this is a string delimiter...
+ strings.add(sb.toString());
+ sb.setLength(0);
+ continue;
+ }
+ }
+ else if (ch == ' ')
+ {
+ // we should ignore spaces normally, unless they are escaped...
+ if (!escaped)
+ {
+ continue;
+ }
+ }
+ else if (Character.isWhitespace(ch))
+ {
+ // Other whitespaces are ignored...
+ continue;
+ }
- // Always add the last string, as it contains everything after the last comma...
- strings.add(sb.toString());
+ sb.append(ch);
+ escaped = false;
+ }
- return (String[]) strings.toArray(new String[strings.size()]);
+ // Always add the last string, as it contains everything after the last comma...
+ strings.add(sb.toString());
+
+ return (String[]) strings.toArray(new String[strings.size()]);
}
-
- protected Comparable convertToType( final String value )
+ protected Comparable convertToType(final String value)
{
- if ( value != null && value.length() > 0 )
+ if (value != null && value.length() > 0)
{
try
{
- switch ( getType() )
+ switch (getType())
{
case AttributeDefinition.BOOLEAN:
// Boolean is only Comparable starting with Java 5
- return new ComparableBoolean( value );
+ return new ComparableBoolean(value);
case AttributeDefinition.CHARACTER:
- return new Character( value.charAt( 0 ) );
+ return new Character(value.charAt(0));
case AttributeDefinition.BYTE:
- return Byte.valueOf( value );
+ return Byte.valueOf(value);
case AttributeDefinition.SHORT:
- return Short.valueOf( value );
+ return Short.valueOf(value);
case AttributeDefinition.INTEGER:
- return Integer.valueOf( value );
+ return Integer.valueOf(value);
case AttributeDefinition.LONG:
- return Long.valueOf( value );
+ return Long.valueOf(value);
case AttributeDefinition.FLOAT:
- return Float.valueOf( value );
+ return Float.valueOf(value);
case AttributeDefinition.DOUBLE:
- return Double.valueOf( value );
+ return Double.valueOf(value);
case AttributeDefinition.STRING:
case AttributeDefinition.PASSWORD:
default:
return value;
}
}
- catch ( NumberFormatException nfe )
+ catch (NumberFormatException nfe)
{
- Activator.log( LogService.LOG_INFO, "Cannot convert value '" + value + "'", nfe );
+ Activator.log(LogService.LOG_INFO, "Cannot convert value '" + value + "'", nfe);
}
}
@@ -435,17 +411,15 @@
{
private boolean value;
-
- ComparableBoolean( String boolValue )
+ ComparableBoolean(String boolValue)
{
- value = Boolean.valueOf( boolValue ).booleanValue();
+ value = Boolean.valueOf(boolValue).booleanValue();
}
-
- public int compareTo( Object obj )
+ public int compareTo(Object obj)
{
- ComparableBoolean cb = ( ComparableBoolean ) obj;
- return ( cb.value == value ? 0 : ( value ? 1 : -1 ) );
+ ComparableBoolean cb = (ComparableBoolean) obj;
+ return (cb.value == value ? 0 : (value ? 1 : -1));
}
}
}
diff --git a/metatype/src/main/java/org/apache/felix/metatype/ADValidator.java b/metatype/src/main/java/org/apache/felix/metatype/ADValidator.java
index d82b136..60b35a0 100644
--- a/metatype/src/main/java/org/apache/felix/metatype/ADValidator.java
+++ b/metatype/src/main/java/org/apache/felix/metatype/ADValidator.java
@@ -30,319 +30,407 @@
*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-final class ADValidator {
+final class ADValidator
+{
+ /**
+ * Validates a given input string according to the type specified by the given attribute
+ * definition.
+ * <p>
+ * The validation is done in the following way:
+ * </p>
+ * <ul>
+ * <li>If the input is undefined (ie. <code>null</code>), and the attribute is mandatory, the
+ * validation fails due to a missing value. If the attribute is optional, the input is
+ * accepted;</li>
+ * <li>If the input represents a <em>boolean</em> value, it is tested whether it is defined (in
+ * case of non-zero cardinality) and represents either <tt>"true"</tt> or <tt>"false"</tt>. The
+ * minimum and maximum parameters are <b>not</b> used in this validation;</li>
+ * <li>If the input represents a <em>character</em> value, it is tested whether it is defined
+ * (in case of non-zero cardinality). The character value must be defined within the character
+ * range specified by the minimum and maximum parameters (if defined);</li>
+ * <li>If the input represents a <em>numeric</em> value, it is tested whether it is defined (in
+ * case of non-zero cardinality). The numeric value must be defined within the numeric range
+ * specified by the minimum and maximum parameters (if defined);</li>
+ * <li>If the input represents a <em>string</em> or <em>password</em>, it is tested whether it
+ * is defined (in case of non-zero cardinality). The length of the string value must be in the
+ * range specified by the minimum and maximum parameters (if defined).</li>
+ * </ul>
+ * <p>
+ * For all types of attributes, if it defines option values, the input should be present as one
+ * of the defined option values.
+ * </p>
+ *
+ * @param ad
+ * the attribute definition to use in the validation;
+ * @param rawInput
+ * the raw input value to validate.
+ * @return <code>null</code> if no validation is available, <tt>""</tt> if
+ * validation was successful, or any other non-empty string in case
+ * validation fails.
+ */
+ public static String validate(AD ad, String rawInput)
+ {
+ // Handle the case in which the given input is not defined...
+ if (rawInput == null)
+ {
+ if (ad.isRequired())
+ {
+ return AD.VALIDATE_MISSING;
+ }
- /**
- * Validates a given input string according to the type specified by the
- * given attribute definition.
- *
- * @param ad
- * the attribute definition to use in the validation;
- * @param rawInput
- * the raw input value to validate.
- * @return <code>null</code> if no validation is available, <tt>""</tt> if
- * validation was successful, or any other non-empty string in case
- * validation fails.
- */
- public static String validate(AD ad, String rawInput) {
- // Handle the case in which the given input is not defined...
- if (rawInput == null) {
- if (ad.isRequired()) {
- return AD.VALIDATE_MISSING;
- }
+ return ""; // accept null value...
+ }
- return ""; // accept null value...
- }
+ // Raw input is defined, validate it further
+ String[] input;
+ if (ad.getCardinality() == 0)
+ {
+ input = new String[] { rawInput.trim() };
+ }
+ else
+ {
+ input = AD.splitList(rawInput);
+ }
- // Raw input is defined, validate it further
- String[] input;
+ int type = ad.getType();
+ switch (type)
+ {
+ case AttributeDefinition.BOOLEAN:
+ return validateBooleanValue(ad, input);
- if (ad.getCardinality() == 0) {
- input = new String[] { rawInput.trim() };
- } else {
- input = AD.splitList(rawInput);
- }
+ case AttributeDefinition.CHARACTER:
+ return validateCharacterValue(ad, input);
- int type = ad.getType();
- switch (type) {
- case AttributeDefinition.BOOLEAN:
- return validateBooleanValue(ad, input);
+ case AttributeDefinition.BIGDECIMAL:
+ case AttributeDefinition.BIGINTEGER:
+ case AttributeDefinition.BYTE:
+ case AttributeDefinition.DOUBLE:
+ case AttributeDefinition.FLOAT:
+ case AttributeDefinition.INTEGER:
+ case AttributeDefinition.LONG:
+ case AttributeDefinition.SHORT:
+ return validateNumericValue(ad, input);
- case AttributeDefinition.CHARACTER:
- return validateCharacterValue(ad, input);
+ case AttributeDefinition.PASSWORD:
+ case AttributeDefinition.STRING:
+ return validateString(ad, input);
- case AttributeDefinition.BIGDECIMAL:
- case AttributeDefinition.BIGINTEGER:
- case AttributeDefinition.BYTE:
- case AttributeDefinition.DOUBLE:
- case AttributeDefinition.FLOAT:
- case AttributeDefinition.INTEGER:
- case AttributeDefinition.LONG:
- case AttributeDefinition.SHORT:
- return validateNumericValue(ad, input);
+ default:
+ return null; // no validation present...
+ }
+ }
- case AttributeDefinition.PASSWORD:
- case AttributeDefinition.STRING:
- return validateString(ad, input);
+ /**
+ * Searches for a given search value in a given array of options.
+ *
+ * @param searchValue
+ * the value to search for;
+ * @param optionValues
+ * the values to search in.
+ * @return <code>null</code> if the given search value is not found in the
+ * given options, the searched value if found, or <tt>""</tt> if no
+ * search value or options were given.
+ */
+ private static String findOptionValue(String searchValue, String[] optionValues)
+ {
+ if ((searchValue == null) || (optionValues == null) || (optionValues.length == 0))
+ {
+ // indicates that we've not searched...
+ return "";
+ }
- default:
- return null; // no validation present...
- }
- }
+ for (int i = 0; i < optionValues.length; i++)
+ {
+ if (optionValues[i].equals(searchValue))
+ {
+ return optionValues[i];
+ }
+ }
- /**
- * Searches for a given search value in a given array of options.
- *
- * @param searchValue
- * the value to search for;
- * @param optionValues
- * the values to search in.
- * @return <code>null</code> if the given search value is not found in the
- * given options, the searched value if found, or <tt>""</tt> if no
- * search value or options were given.
- */
- private static String findOptionValue(String searchValue, String[] optionValues) {
- if ((searchValue == null) || (optionValues == null) || (optionValues.length == 0)) {
- // indicates that we've not searched
- return "";
- }
+ return null;
+ }
- for (int i = 0; i < optionValues.length; i++) {
- if (optionValues[i].equals(searchValue)) {
- return optionValues[i];
- }
- }
+ /**
+ * Parses a given string value into a numeric type.
+ *
+ * @param type
+ * the type to parse;
+ * @param value
+ * the value to parse.
+ * @return a {@link Number} representation of the given value, or
+ * <code>null</code> if the input was <code>null</code>, empty, or
+ * not a numeric type.
+ * @throws NumberFormatException
+ * in case the given value cannot be parsed as numeric value.
+ */
+ private static Comparable parseNumber(int type, String value) throws NumberFormatException
+ {
+ if ((value != null) && (value.length() > 0))
+ {
+ switch (type)
+ {
+ case AttributeDefinition.BIGDECIMAL:
+ return new BigDecimal(value);
+ case AttributeDefinition.BIGINTEGER:
+ return new BigInteger(value);
+ case AttributeDefinition.BYTE:
+ return Byte.valueOf(value);
+ case AttributeDefinition.SHORT:
+ return Short.valueOf(value);
+ case AttributeDefinition.INTEGER:
+ return Integer.valueOf(value);
+ case AttributeDefinition.LONG:
+ return Long.valueOf(value);
+ case AttributeDefinition.FLOAT:
+ return Float.valueOf(value);
+ case AttributeDefinition.DOUBLE:
+ return Double.valueOf(value);
+ default:
+ return null;
+ }
+ }
+ return null;
+ }
- return null;
- }
+ /**
+ * Parses a given string value as character, allowing <code>null</code>
+ * -values and empty values to be given as input.
+ *
+ * @param value
+ * the value to parse as character, can be <code>null</code> or
+ * an empty value.
+ * @return the character value if, and only if, the given input was non-
+ * <code>null</code> and a non-empty string.
+ */
+ private static Character parseOptionalChar(String value)
+ {
+ if ((value != null) && (value.length() > 0))
+ {
+ return Character.valueOf(value.charAt(0));
+ }
+ return null;
+ }
- /**
- * Parses a given string value into a numeric type.
- *
- * @param type
- * the type to parse;
- * @param value
- * the value to parse.
- * @return a {@link Number} representation of the given value, or
- * <code>null</code> if the input was <code>null</code>, empty, or
- * not a numeric type.
- * @throws NumberFormatException
- * in case the given value cannot be parsed as numeric value.
- */
- private static Comparable parseNumber(int type, String value) throws NumberFormatException {
- if ((value != null) && (value.length() > 0)) {
- switch (type) {
- case AttributeDefinition.BIGDECIMAL:
- return new BigDecimal(value);
- case AttributeDefinition.BIGINTEGER:
- return new BigInteger(value);
- case AttributeDefinition.BYTE:
- return Byte.valueOf(value);
- case AttributeDefinition.SHORT:
- return Short.valueOf(value);
- case AttributeDefinition.INTEGER:
- return Integer.valueOf(value);
- case AttributeDefinition.LONG:
- return Long.valueOf(value);
- case AttributeDefinition.FLOAT:
- return Float.valueOf(value);
- case AttributeDefinition.DOUBLE:
- return Double.valueOf(value);
- default:
- return null;
- }
- }
- return null;
- }
+ /**
+ * Parses a given string value as numeric value, allowing
+ * <code>null</code>-values and invalid numeric values to be given as
+ * input.
+ *
+ * @param type the type of number, should only be a numeric type;
+ * @param value
+ * the value to parse as integer, can be <code>null</code> or a
+ * non-numeric value.
+ * @return the integer value if, and only if, the given input was non-
+ * <code>null</code> and a valid integer representation.
+ */
+ private static Comparable parseOptionalNumber(int type, String value)
+ {
+ if (value != null)
+ {
+ try
+ {
+ return parseNumber(type, value);
+ }
+ catch (NumberFormatException e)
+ {
+ // Ignore; invalid value...
+ }
+ }
+ return null;
+ }
- /**
- * Parses a given string value as character, allowing <code>null</code>
- * -values and empty values to be given as input.
- *
- * @param value
- * the value to parse as character, can be <code>null</code> or
- * an empty value.
- * @return the character value if, and only if, the given input was non-
- * <code>null</code> and a non-empty string.
- */
- private static Character parseOptionalChar(String value) {
- if ((value != null) && (value.length() > 0)) {
- return Character.valueOf(value.charAt(0));
- }
- return null;
- }
+ /**
+ * Validates a given input string as boolean value.
+ *
+ * @param ad
+ * the attribute definition to use in the validation;
+ * @param input
+ * the array with input values to validate.
+ * @return <code>null</code> if no validation is available, <tt>""</tt> if
+ * validation was successful, or any other non-empty string in case
+ * validation fails.
+ */
+ private static String validateBooleanValue(AD ad, String[] input)
+ {
+ for (int i = 0; i < input.length; i++)
+ {
+ String value = input[i];
+ int length = (value == null) ? 0 : value.length();
- /**
- * Parses a given string value as integer, allowing <code>null</code>-values
- * and invalid numeric values to be given as input.
- *
- * @param value
- * the value to parse as integer, can be <code>null</code> or a
- * non-numeric value.
- * @return the integer value if, and only if, the given input was non-
- * <code>null</code> and a valid integer representation.
- */
- private static Integer parseOptionalInt(String value) {
- if (value != null) {
- try {
- return Integer.valueOf(value);
- } catch (NumberFormatException e) {
- // Ignore; invalid value...
- }
- }
- return null;
- }
+ if ((length == 0) && ad.isRequired())
+ {
+ return AD.VALIDATE_MISSING;
+ }
+ else if (length > 0 && !"true".equalsIgnoreCase(value) && !"false".equalsIgnoreCase(value))
+ {
+ return AD.VALIDATE_INVALID_VALUE;
+ }
+ }
- /**
- * Validates a given input string as boolean value.
- *
- * @param ad
- * the attribute definition to use in the validation;
- * @param input
- * the array with input values to validate.
- * @return <code>null</code> if no validation is available, <tt>""</tt> if
- * validation was successful, or any other non-empty string in case
- * validation fails.
- */
- private static String validateBooleanValue(AD ad, String[] input) {
- for (int i = 0; i < input.length; i++) {
- int length = input[i].length();
- if ((length == 0) && ad.isRequired()) {
- return AD.VALIDATE_MISSING;
- } else if (length > 0 && !"true".equalsIgnoreCase(input[i]) && !"false".equalsIgnoreCase(input[i])) {
- return AD.VALIDATE_INVALID_VALUE;
- }
- }
+ String[] optionValues = ad.getOptionValues();
+ if ((optionValues != null) && (optionValues.length > 0))
+ {
+ return null; // no validation possible for this type...
+ }
- String[] optionValues = ad.getOptionValues();
- if (optionValues != null && optionValues.length > 0) {
- return null; // no validation possible for this type...
- }
+ return ""; // accept given value...
+ }
- return ""; // accept given value...
- }
+ /**
+ * Validates a given input string as character value.
+ *
+ * @param ad
+ * the attribute definition to use in the validation;
+ * @param input
+ * the array with input values to validate.
+ * @return <code>null</code> if no validation is available, <tt>""</tt> if
+ * validation was successful, or any other non-empty string in case
+ * validation fails.
+ */
+ private static String validateCharacterValue(AD ad, String[] input)
+ {
+ Character min = parseOptionalChar(ad.getMin());
+ Character max = parseOptionalChar(ad.getMax());
+ String[] optionValues = ad.getOptionValues();
- /**
- * Validates a given input string as character value.
- *
- * @param ad
- * the attribute definition to use in the validation;
- * @param input
- * the array with input values to validate.
- * @return <code>null</code> if no validation is available, <tt>""</tt> if
- * validation was successful, or any other non-empty string in case
- * validation fails.
- */
- private static String validateCharacterValue(AD ad, String[] input) {
- Character min = parseOptionalChar(ad.getMin());
- Character max = parseOptionalChar(ad.getMax());
- String[] optionValues = ad.getOptionValues();
+ for (int i = 0; i < input.length; i++)
+ {
+ Character ch = null;
- for (int i = 0; i < input.length; i++) {
- Character ch = null;
- int length = input[i].length();
- if (length > 1) {
- return AD.VALIDATE_GREATER_THAN_MAXIMUM;
- } else if ((length == 0) && ad.isRequired()) {
- return AD.VALIDATE_MISSING;
- } else if (length == 1) {
- ch = Character.valueOf(input[i].charAt(0));
- // Check whether the minimum value is adhered for all values...
- if ((min != null) && (ch.compareTo(min) < 0)) {
- return AD.VALIDATE_LESS_THAN_MINIMUM;
- }
- // Check whether the maximum value is adhered for all values...
- if ((max != null) && (ch.compareTo(max) > 0)) {
- return AD.VALIDATE_GREATER_THAN_MAXIMUM;
- }
- }
+ int length = (input[i] == null) ? 0 : input[i].length();
+ if (length > 1)
+ {
+ return AD.VALIDATE_GREATER_THAN_MAXIMUM;
+ }
+ else if ((length == 0) && ad.isRequired())
+ {
+ return AD.VALIDATE_MISSING;
+ }
+ else if (length == 1)
+ {
+ ch = Character.valueOf(input[i].charAt(0));
+ // Check whether the minimum value is adhered for all values...
+ if ((min != null) && (ch.compareTo(min) < 0))
+ {
+ return AD.VALIDATE_LESS_THAN_MINIMUM;
+ }
+ // Check whether the maximum value is adhered for all values...
+ if ((max != null) && (ch.compareTo(max) > 0))
+ {
+ return AD.VALIDATE_GREATER_THAN_MAXIMUM;
+ }
+ }
- if (findOptionValue(input[i], optionValues) == null) {
- return AD.VALIDATE_NOT_A_VALID_OPTION;
- }
- }
+ if (findOptionValue(input[i], optionValues) == null)
+ {
+ return AD.VALIDATE_NOT_A_VALID_OPTION;
+ }
+ }
- return ""; // accept given value...
- }
+ return ""; // accept given value...
+ }
- /**
- * Validates a given input string as numeric value.
- *
- * @param ad
- * the attribute definition to use in the validation;
- * @param input
- * the array with input values to validate.
- * @return <code>null</code> if no validation is available, <tt>""</tt> if
- * validation was successful, or any other non-empty string in case
- * validation fails.
- */
- private static String validateNumericValue(AD ad, String[] input) {
- Integer min = parseOptionalInt(ad.getMin());
- Integer max = parseOptionalInt(ad.getMax());
- String[] optionValues = ad.getOptionValues();
+ /**
+ * Validates a given input string as numeric value.
+ *
+ * @param ad
+ * the attribute definition to use in the validation;
+ * @param input
+ * the array with input values to validate.
+ * @return <code>null</code> if no validation is available, <tt>""</tt> if
+ * validation was successful, or any other non-empty string in case
+ * validation fails.
+ */
+ private static String validateNumericValue(AD ad, String[] input)
+ {
+ Comparable min = parseOptionalNumber(ad.getType(), ad.getMin());
+ Comparable max = parseOptionalNumber(ad.getType(), ad.getMax());
+ String[] optionValues = ad.getOptionValues();
- for (int i = 0; i < input.length; i++) {
- Comparable value = null;
- try {
- value = parseNumber(ad.getType(), input[i]);
- } catch (NumberFormatException e) {
- return AD.VALIDATE_INVALID_VALUE;
- }
+ for (int i = 0; i < input.length; i++)
+ {
+ Comparable value = null;
+ try
+ {
+ value = parseNumber(ad.getType(), input[i]);
+ }
+ catch (NumberFormatException e)
+ {
+ return AD.VALIDATE_INVALID_VALUE;
+ }
- if ((value == null) && ad.isRequired()) {
- // Possible if the cardinality != 0 and input was something like
- // "0,,1"...
- return AD.VALIDATE_MISSING;
- }
- // Check whether the minimum value is adhered for all values...
- if ((min != null) && (value != null) && (value.compareTo(min) < 0)) {
- return AD.VALIDATE_LESS_THAN_MINIMUM;
- }
- // Check whether the maximum value is adhered for all values...
- if ((max != null) && (value != null) && (value.compareTo(max) > 0)) {
- return AD.VALIDATE_GREATER_THAN_MAXIMUM;
- }
+ if ((value == null) && ad.isRequired())
+ {
+ // Possible if the cardinality != 0 and input was something like
+ // "0,,1"...
+ return AD.VALIDATE_MISSING;
+ }
+ // Check whether the minimum value is adhered for all values...
+ if ((min != null) && (value != null) && (value.compareTo(min) < 0))
+ {
+ return AD.VALIDATE_LESS_THAN_MINIMUM;
+ }
+ // Check whether the maximum value is adhered for all values...
+ if ((max != null) && (value != null) && (value.compareTo(max) > 0))
+ {
+ return AD.VALIDATE_GREATER_THAN_MAXIMUM;
+ }
- if (findOptionValue(input[i], optionValues) == null) {
- return AD.VALIDATE_NOT_A_VALID_OPTION;
- }
- }
+ if (findOptionValue(input[i], optionValues) == null)
+ {
+ return AD.VALIDATE_NOT_A_VALID_OPTION;
+ }
+ }
- return ""; // accept given value...
- }
+ return ""; // accept given value...
+ }
- /**
- * Validates a given input string as string (or password).
- *
- * @param ad
- * the attribute definition to use in the validation;
- * @param input
- * the array with input values to validate.
- * @return <code>null</code> if no validation is available, <tt>""</tt> if
- * validation was successful, or any other non-empty string in case
- * validation fails.
- */
- private static String validateString(AD ad, String[] input) {
- Integer min = parseOptionalInt(ad.getMin());
- Integer max = parseOptionalInt(ad.getMax());
- String[] optionValues = ad.getOptionValues();
+ /**
+ * Validates a given input string as string (or password).
+ *
+ * @param ad
+ * the attribute definition to use in the validation;
+ * @param input
+ * the array with input values to validate.
+ * @return <code>null</code> if no validation is available, <tt>""</tt> if
+ * validation was successful, or any other non-empty string in case
+ * validation fails.
+ */
+ private static String validateString(AD ad, String[] input)
+ {
+ // The length() method of a string yields an Integer, so the maximum string length is 2^31-1...
+ Integer min = (Integer) parseOptionalNumber(AttributeDefinition.INTEGER, ad.getMin());
+ Integer max = (Integer) parseOptionalNumber(AttributeDefinition.INTEGER, ad.getMax());
+ String[] optionValues = ad.getOptionValues();
- for (int i = 0; i < input.length; i++) {
- int length = input[i].length();
- // Check whether the minimum length is adhered for all values...
- if ((min != null) && (length < min.intValue())) {
- return AD.VALIDATE_LESS_THAN_MINIMUM;
- }
- // Check whether the maximum length is adhered for all values...
- if ((max != null) && (length > max.intValue())) {
- return AD.VALIDATE_GREATER_THAN_MAXIMUM;
- }
+ for (int i = 0; i < input.length; i++)
+ {
+ String value = input[i];
+ int length = (value == null) ? 0 : value.length();
- if (findOptionValue(input[i], optionValues) == null) {
- return AD.VALIDATE_NOT_A_VALID_OPTION;
- }
- }
+ if (ad.isRequired() && ((value == null) || (length == 0)))
+ {
+ // Possible if the cardinality != 0 and input was something like
+ // "0,,1"...
+ return AD.VALIDATE_MISSING;
+ }
+ // Check whether the minimum length is adhered for all values...
+ if ((min != null) && (length < min.intValue()))
+ {
+ return AD.VALIDATE_LESS_THAN_MINIMUM;
+ }
+ // Check whether the maximum length is adhered for all values...
+ if ((max != null) && (length > max.intValue()))
+ {
+ return AD.VALIDATE_GREATER_THAN_MAXIMUM;
+ }
- return ""; // accept given value...
- }
+ if (findOptionValue(value, optionValues) == null)
+ {
+ return AD.VALIDATE_NOT_A_VALID_OPTION;
+ }
+ }
+
+ return ""; // accept given value...
+ }
}
diff --git a/metatype/src/test/java/org/apache/felix/metatype/ADTest.java b/metatype/src/test/java/org/apache/felix/metatype/ADTest.java
index 065f0c9..00cbc27 100644
--- a/metatype/src/test/java/org/apache/felix/metatype/ADTest.java
+++ b/metatype/src/test/java/org/apache/felix/metatype/ADTest.java
@@ -18,12 +18,10 @@
*/
package org.apache.felix.metatype;
-
import junit.framework.TestCase;
import org.osgi.service.metatype.AttributeDefinition;
-
/**
* The <code>ADTest</code> class tests the static helper methods of the
* {@link AD} class.
@@ -35,59 +33,54 @@
private static final String BLANK = " \r\n \t";
-
public void testNull()
{
String listString = null;
- String[] list = AD.splitList( listString );
- assertNull( list );
+ String[] list = AD.splitList(listString);
+ assertNull(list);
}
-
public void testEmpty()
{
String listString = "";
- String[] list = AD.splitList( listString );
- assertNotNull( list );
- assertEquals( 1, list.length );
- assertEquals( listString, list[0] );
+ String[] list = AD.splitList(listString);
+ assertNotNull(list);
+ assertEquals(1, list.length);
+ assertEquals(listString, list[0]);
}
-
public void testSingle()
{
String value0 = "value";
String listString = value0;
- String[] list = AD.splitList( listString );
- assertNotNull( list );
- assertEquals( 1, list.length );
- assertEquals( value0, list[0] );
+ String[] list = AD.splitList(listString);
+ assertNotNull(list);
+ assertEquals(1, list.length);
+ assertEquals(value0, list[0]);
}
-
public void testTwo()
{
String value0 = "value0";
String value1 = "value1";
String listString = value0 + "," + value1;
- String[] list = AD.splitList( listString );
- assertNotNull( list );
- assertEquals( 2, list.length );
- assertEquals( value0, list[0] );
- assertEquals( value1, list[1] );
+ String[] list = AD.splitList(listString);
+ assertNotNull(list);
+ assertEquals(2, list.length);
+ assertEquals(value0, list[0]);
+ assertEquals(value1, list[1]);
}
-
public void testEmptySecond()
{
String value0 = "value0";
String value1 = "";
String listString = value0 + ",";
- String[] list = AD.splitList( listString );
- assertNotNull( list );
- assertEquals( 2, list.length );
- assertEquals( value0, list[0] );
- assertEquals( value1, list[1] );
+ String[] list = AD.splitList(listString);
+ assertNotNull(list);
+ assertEquals(2, list.length);
+ assertEquals(value0, list[0]);
+ assertEquals(value1, list[1]);
}
public void testSpacedSecond()
@@ -95,38 +88,35 @@
String value0 = "value0";
String value1 = "";
String listString = value0 + ", ";
- String[] list = AD.splitList( listString );
- assertNotNull( list );
- assertEquals( 2, list.length );
- assertEquals( value0, list[0] );
- assertEquals( value1, list[1] );
+ String[] list = AD.splitList(listString);
+ assertNotNull(list);
+ assertEquals(2, list.length);
+ assertEquals(value0, list[0]);
+ assertEquals(value1, list[1]);
}
-
public void testSingleBlanks()
{
String value0 = "value";
String listString = BLANK + value0 + BLANK;
- String[] list = AD.splitList( listString );
- assertNotNull( list );
- assertEquals( 1, list.length );
- assertEquals( value0, list[0] );
+ String[] list = AD.splitList(listString);
+ assertNotNull(list);
+ assertEquals(1, list.length);
+ assertEquals(value0, list[0]);
}
-
public void testTwoBlanks()
{
String value0 = "value0";
String value1 = "value1";
String listString = BLANK + value0 + BLANK + "," + BLANK + value1 + BLANK;
- String[] list = AD.splitList( listString );
- assertNotNull( list );
- assertEquals( 2, list.length );
- assertEquals( value0, list[0] );
- assertEquals( value1, list[1] );
+ String[] list = AD.splitList(listString);
+ assertNotNull(list);
+ assertEquals(2, list.length);
+ assertEquals(value0, list[0]);
+ assertEquals(value1, list[1]);
}
-
public void testStandardSample()
{
String value0 = "a,b";
@@ -134,66 +124,68 @@
String value2 = " c\\";
String value3 = "d";
String listString = "a\\,b,b\\,c,\\ c\\\\,d";
- String[] list = AD.splitList( listString );
- assertNotNull( list );
- assertEquals( 4, list.length );
- assertEquals( value0, list[0] );
- assertEquals( value1, list[1] );
- assertEquals( value2, list[2] );
- assertEquals( value3, list[3] );
+ String[] list = AD.splitList(listString);
+ assertNotNull(list);
+ assertEquals(4, list.length);
+ assertEquals(value0, list[0]);
+ assertEquals(value1, list[1]);
+ assertEquals(value2, list[2]);
+ assertEquals(value3, list[3]);
}
-
public void testToTypeString()
{
- assertEquals( AttributeDefinition.STRING, AD.toType( "String" ) );
- assertEquals( AttributeDefinition.LONG, AD.toType( "Long" ) );
- assertEquals( AttributeDefinition.DOUBLE, AD.toType( "Double" ) );
- assertEquals( AttributeDefinition.FLOAT, AD.toType( "Float" ) );
- assertEquals( AttributeDefinition.INTEGER, AD.toType( "Integer" ) );
- assertEquals( AttributeDefinition.BYTE, AD.toType( "Byte" ) );
- assertEquals( AttributeDefinition.CHARACTER, AD.toType( "Char" ) );
- assertEquals( AttributeDefinition.BOOLEAN, AD.toType( "Boolean" ) );
- assertEquals( AttributeDefinition.SHORT, AD.toType( "Short" ) );
- assertEquals( AttributeDefinition.PASSWORD, AD.toType( "Password" ) );
- assertEquals( AttributeDefinition.STRING, AD.toType( "JohnDoe" ) );
+ assertEquals(AttributeDefinition.STRING, AD.toType("String"));
+ assertEquals(AttributeDefinition.LONG, AD.toType("Long"));
+ assertEquals(AttributeDefinition.DOUBLE, AD.toType("Double"));
+ assertEquals(AttributeDefinition.FLOAT, AD.toType("Float"));
+ assertEquals(AttributeDefinition.INTEGER, AD.toType("Integer"));
+ assertEquals(AttributeDefinition.BYTE, AD.toType("Byte"));
+ assertEquals(AttributeDefinition.CHARACTER, AD.toType("Char"));
+ assertEquals(AttributeDefinition.BOOLEAN, AD.toType("Boolean"));
+ assertEquals(AttributeDefinition.SHORT, AD.toType("Short"));
+ assertEquals(AttributeDefinition.PASSWORD, AD.toType("Password"));
+ assertEquals(AttributeDefinition.STRING, AD.toType("JohnDoe"));
}
-
+
/**
* FELIX-3757: if an AD has only its 'required' property set, but no
* min/max or option values defined, the validation still should detect
* empty values.
*/
- public void testValidateRequiredValueWithMinimalOptions() {
- AD ad = new AD();
- ad.setType("Integer");
- ad.setRequired(true);
+ public void testValidateRequiredValueWithMinimalOptions()
+ {
+ AD ad = new AD();
+ ad.setType("Integer");
+ ad.setRequired(true);
- assertEquals(AD.VALIDATE_MISSING, ad.validate(null));
+ assertEquals(AD.VALIDATE_MISSING, ad.validate(null));
}
-
+
/**
* FELIX-3756: if an AD is optional, but its validate method is called
* with invalid data, the value is regarded missing.
*/
- public void testValidateOptionalValueWithInvalidData() {
- AD ad = new AD();
- ad.setType("Integer");
- ad.setRequired(false);
-
- assertEquals(AD.VALIDATE_INVALID_VALUE, ad.validate("abc"));
+ public void testValidateOptionalValueWithInvalidData()
+ {
+ AD ad = new AD();
+ ad.setType("Integer");
+ ad.setRequired(false);
+
+ assertEquals(AD.VALIDATE_INVALID_VALUE, ad.validate("abc"));
}
-
+
/**
* FELIX-3758: if an AD has a cardinality != 0, the validation method
* cannot handle a comma-separated input.
*/
- public void testValidateValueWithMultiValueCardinality() {
- AD ad = new AD();
- ad.setType("Integer");
- ad.setCardinality(2);
- ad.setRequired(true);
-
- assertEquals("", ad.validate("1,2"));
+ public void testValidateValueWithMultiValueCardinality()
+ {
+ AD ad = new AD();
+ ad.setType("Integer");
+ ad.setCardinality(2);
+ ad.setRequired(true);
+
+ assertEquals("", ad.validate("1,2"));
}
}
diff --git a/metatype/src/test/java/org/apache/felix/metatype/ADValidatorTest.java b/metatype/src/test/java/org/apache/felix/metatype/ADValidatorTest.java
index 8640629..33c02c3 100644
--- a/metatype/src/test/java/org/apache/felix/metatype/ADValidatorTest.java
+++ b/metatype/src/test/java/org/apache/felix/metatype/ADValidatorTest.java
@@ -30,240 +30,348 @@
*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-public class ADValidatorTest extends TestCase {
+public class ADValidatorTest extends TestCase
+{
+ /**
+ * Tests the validation of boolean is only done minimally.
+ */
+ public void testValidateBoolean()
+ {
+ AD ad = new AD();
+ ad.setType("Boolean");
+ ad.setRequired(false);
- /**
- * Tests the validation of boolean is only done minimally.
- */
- public void testValidateBoolean() {
- AD ad = new AD();
- ad.setType("Boolean");
- ad.setRequired(false);
+ // optional value
+ assertEquals("", ADValidator.validate(ad, null));
+ // adhere minimal value
+ assertEquals("", ADValidator.validate(ad, "true"));
+ // adhere maximal value
+ assertEquals("", ADValidator.validate(ad, "false"));
+ // not a valid value
+ assertEquals(AD.VALIDATE_INVALID_VALUE, ADValidator.validate(ad, "foobar"));
- // optional value
- assertEquals("", ADValidator.validate(ad, null));
- // adhere minimal value
- assertEquals("", ADValidator.validate(ad, "true"));
- // adhere maximal value
- assertEquals("", ADValidator.validate(ad, "false"));
- // not a valid value
- assertEquals(AD.VALIDATE_INVALID_VALUE, ADValidator.validate(ad, "foobar"));
+ ad.setCardinality(3); // up to three values are allowed...
- ad.setCardinality(3); // up to three values are allowed...
-
- // mandatory value
- assertEquals("", ADValidator.validate(ad, null));
- // 2nd value is missing
- assertEquals("", ADValidator.validate(ad, "true,,false"));
+ // optional value
+ assertEquals("", ADValidator.validate(ad, null));
+ // 2nd value is missing, but that's ok...
+ assertEquals("", ADValidator.validate(ad, "true,,false"));
- ad.setRequired(true);
+ ad.setRequired(true);
- // mandatory value
- assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
- // 2nd value is missing
- assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, "false,,true"));
- assertEquals("", ADValidator.validate(ad, "false, true, false"));
+ // mandatory value
+ assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
+ // 2nd value is missing
+ assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, "false,,true"));
+ // correct values
+ assertEquals("", ADValidator.validate(ad, "false, true, false"));
+ // correct values
+ assertEquals(AD.VALIDATE_INVALID_VALUE, ADValidator.validate(ad, "false, yessir, false"));
- ad.setOptions(Collections.singletonMap("true", "Yes!"));
+ ad.setOptions(Collections.singletonMap("true", "Yes!"));
- assertEquals(null, ADValidator.validate(ad, "false, true, false"));
- }
+ assertEquals(null, ADValidator.validate(ad, "false, true, false"));
+ }
- /**
- * Tests the validation of characters with only limited set of options.
- */
- public void testValidateCharacterOptionValues() {
- AD ad = new AD();
- ad.setType("Char");
- ad.setRequired(false);
+ /**
+ * Tests the validation of bytes works and uses the correct minimum and maximum values.
+ */
+ public void testValidateByte()
+ {
+ AD ad = new AD();
+ ad.setType("Byte");
+ ad.setRequired(false);
- // optional value
- assertEquals("", ADValidator.validate(ad, null));
- // option too long
- assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "ab"));
- // adhere first option value
- assertEquals("", ADValidator.validate(ad, "b"));
- // adhere last option value
- assertEquals("", ADValidator.validate(ad, "e"));
+ // optional value
+ assertEquals("", ADValidator.validate(ad, null));
+ assertEquals("", ADValidator.validate(ad, ""));
- ad.setCardinality(3); // up to three values are allowed...
+ ad.setRequired(true);
- // mandatory value
- assertEquals("", ADValidator.validate(ad, ""));
- // 2nd value is missing
- assertEquals("", ADValidator.validate(ad, "b,,c"));
+ // mandatory value
+ assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, ""));
+ // value too small
+ assertEquals(AD.VALIDATE_INVALID_VALUE, ADValidator.validate(ad, "-129"));
+ // value too small
+ assertEquals("", ADValidator.validate(ad, "-128"));
+ // value within bounds
+ assertEquals("", ADValidator.validate(ad, "0"));
+ // value within bounds
+ assertEquals("", ADValidator.validate(ad, "127"));
+ // value is invalid
+ assertEquals(AD.VALIDATE_INVALID_VALUE, ADValidator.validate(ad, "128"));
- ad.setRequired(true);
+ ad.setMin("0");
+ ad.setMax("128"); // !!! this is an invalid value for maximum, this means that we cannot do this validation...
- // mandatory value
- assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
- // 2nd value is missing
- assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, "b,,c"));
- // adhere minimal values
- assertEquals("", ADValidator.validate(ad, "b, c, d"));
- // adhere maximal values
- assertEquals("", ADValidator.validate(ad, "c, d, e"));
+ // value too small
+ assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "-1"));
+ // value within bounds
+ assertEquals("", ADValidator.validate(ad, "0"));
+ // value within bounds
+ assertEquals("", ADValidator.validate(ad, "127"));
+ // value is invalid
+ assertEquals(AD.VALIDATE_INVALID_VALUE, ADValidator.validate(ad, "128"));
+ }
- Map options = new HashMap();
- options.put("b", "B");
- options.put("c", "C");
- options.put("d", "D");
- options.put("e", "E");
+ /**
+ * Tests the validation of characters with only limited set of options.
+ */
+ public void testValidateCharacter()
+ {
+ AD ad = new AD();
+ ad.setType("Char");
+ ad.setRequired(false);
- ad.setOptions(options);
- // no option given
- assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, ""));
- // invalid option
- assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "a"));
- // too great
- assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "f"));
- // 2nd value is too less
- assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "b,a,c"));
- // 3rd value is too great
- assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "d, e, f"));
+ // optional value
+ assertEquals("", ADValidator.validate(ad, null));
+ // option too long
+ assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "ab"));
+ // adhere first option value
+ assertEquals("", ADValidator.validate(ad, "b"));
+ // adhere last option value
+ assertEquals("", ADValidator.validate(ad, "e"));
- ad.setMin("b");
- ad.setMax("c");
- ad.setOptions(Collections.emptyMap());
+ ad.setCardinality(3); // up to three values are allowed...
- // adhere minimal values
- assertEquals("", ADValidator.validate(ad, "b, c, b"));
- // d is too great
- assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "b, c, d"));
- // a is too less
- assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "a, b, c"));
- }
+ // mandatory value
+ assertEquals("", ADValidator.validate(ad, ""));
+ // 2nd value is missing
+ assertEquals("", ADValidator.validate(ad, "b,,c"));
- /**
- * Tests the validation of characters with only limited set of options.
- */
- public void testValidateDoubleOptionValues() {
- Map options = new HashMap();
- options.put("1.1", "B");
- options.put("2.2", "C");
- options.put("3.3", "D");
- options.put("4.4", "E");
+ ad.setRequired(true);
- AD ad = new AD();
- ad.setType("Double");
- ad.setOptions(options);
- ad.setRequired(false);
+ // mandatory value
+ assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
+ // 2nd value is missing
+ assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, "b,,c"));
+ // adhere minimal values
+ assertEquals("", ADValidator.validate(ad, "b, c, d"));
+ // adhere maximal values
+ assertEquals("", ADValidator.validate(ad, "c, d, e"));
- // optional value
- assertEquals("", ADValidator.validate(ad, null));
- // invalid option
- assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "1.0"));
- // adhere first option value
- assertEquals("", ADValidator.validate(ad, "1.1"));
- // adhere last option value
- assertEquals("", ADValidator.validate(ad, "4.4"));
- // too great
- assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "4.5"));
+ Map options = new HashMap();
+ options.put("b", "B");
+ options.put("c", "C");
+ options.put("d", "D");
+ options.put("e", "E");
- ad.setCardinality(3); // up to three values are allowed...
- ad.setRequired(true);
+ ad.setOptions(options);
+ // no option given
+ assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, ""));
+ // invalid option
+ assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "a"));
+ // too great
+ assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "f"));
+ // 2nd value is too less
+ assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "b,a,c"));
+ // 3rd value is too great
+ assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "d, e, f"));
- // mandatory value
- assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
- // 2nd value is too less
- assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "1.1,1.0,2.2"));
- // adhere minimal values
- assertEquals("", ADValidator.validate(ad, "1.1, 2.2, 3.3"));
- // adhere maximal values
- assertEquals("", ADValidator.validate(ad, "2.2, 3.3, 4.4"));
- // 3rd value is too great
- assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "3.3, 4.4, 5.5"));
- }
+ ad.setMin("b");
+ ad.setMax("c");
+ ad.setOptions(Collections.emptyMap());
- /**
- * Tests the validation of integers is based on the minimum and maximum values.
- */
- public void testValidateInteger() {
- AD ad = new AD();
- ad.setType("Integer");
- ad.setMin("3"); // only values greater than 2
- ad.setMax("6"); // only values less than 7
- ad.setRequired(false);
+ // adhere minimal values
+ assertEquals("", ADValidator.validate(ad, "b, c, b"));
+ // d is too great
+ assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "b, c, d"));
+ // a is too small
+ assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "a, b, c"));
+ }
- // optional value
- assertEquals("", ADValidator.validate(ad, null));
- // too less
- assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "2"));
- // adhere minimal value
- assertEquals("", ADValidator.validate(ad, "3"));
- // adhere maximal value
- assertEquals("", ADValidator.validate(ad, "6"));
- // too great
- assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "7"));
+ /**
+ * Tests the validation of double value works as expected.
+ */
+ public void testValidateDouble()
+ {
+ AD ad = new AD();
+ ad.setType("Double");
+ ad.setRequired(false);
- ad.setCardinality(3); // up to three values are allowed...
-
- // mandatory value
- assertEquals("", ADValidator.validate(ad, null));
- // 2nd value is missing
- assertEquals("", ADValidator.validate(ad, "3,,3"));
+ ad.setMin("-123.45");
+ ad.setMax("+123.45");
- ad.setRequired(true);
+ // Value is too small...
+ assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "-123.4501"));
+ // Value is within range...
+ assertEquals("", ADValidator.validate(ad, "-123.45000"));
+ // Value is within range...
+ assertEquals("", ADValidator.validate(ad, "123.45000"));
+ // Value is too great...
+ assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "123.4501"));
- // mandatory value
- assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
- // 2nd value is missing
- assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, "3,,3"));
- // 2nd value is invalid
- assertEquals(AD.VALIDATE_INVALID_VALUE, ADValidator.validate(ad, "3,a,3"));
- // 2nd value is too less
- assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "3,2,3"));
- // adhere minimal values
- assertEquals("", ADValidator.validate(ad, "3, 4, 5"));
- // adhere maximal values
- assertEquals("", ADValidator.validate(ad, "6, 5, 4"));
- // 3rd value is too great
- assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "5, 6, 7"));
- }
+ Map options = new HashMap();
+ options.put("1.1", "B");
+ options.put("2.2", "C");
+ options.put("3.3", "D");
+ options.put("4.4", "E");
- /**
- * Tests the validation of strings is based on the minimum and maximum lengths.
- */
- public void testValidateString() {
- AD ad = new AD();
- ad.setType("String");
- ad.setRequired(false);
+ ad.setOptions(options);
- // optional value
- assertEquals("", ADValidator.validate(ad, null));
- // any length of input is accepted
- assertEquals("", ADValidator.validate(ad, "1234567890"));
+ // optional value
+ assertEquals("", ADValidator.validate(ad, null));
+ // invalid option
+ assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "1.0"));
+ // adhere first option value
+ assertEquals("", ADValidator.validate(ad, "1.1"));
+ // adhere last option value
+ assertEquals("", ADValidator.validate(ad, "4.4"));
+ // too great
+ assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "4.5"));
- ad.setMin("3"); // minimal length == 3
- ad.setMax("6"); // maximum length == 6
+ ad.setCardinality(3); // up to three values are allowed...
+ ad.setRequired(true);
- // too short
- assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "12"));
- // adhere minimum length
- assertEquals("", ADValidator.validate(ad, "123"));
- // adhere maximum length
- assertEquals("", ADValidator.validate(ad, "12356"));
- // too long
- assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "1234567"));
+ // mandatory value
+ assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
+ // 2nd value is too less
+ assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "1.1,1.0,2.2"));
+ // adhere minimal values
+ assertEquals("", ADValidator.validate(ad, "1.1, 2.2, 3.3"));
+ // adhere maximal values
+ assertEquals("", ADValidator.validate(ad, "2.2, 3.3, 4.4"));
+ // 3rd value is too great
+ assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "3.3, 4.4, 5.5"));
+ }
- ad.setCardinality(3); // up to three values are allowed...
- ad.setRequired(true);
+ /**
+ * Tests the validation of integers is based on the minimum and maximum values.
+ */
+ public void testValidateInteger()
+ {
+ AD ad = new AD();
+ ad.setType("Integer");
+ ad.setMin("3"); // only values greater than 2
+ ad.setMax("6"); // only values less than 7
+ ad.setRequired(false);
- // mandatory value
- assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
- // 2nd value is too short
- assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "321,12,123"));
- // adhere minimum lengths
- assertEquals("", ADValidator.validate(ad, "123, 123, 123"));
- // adhere maximum lengths
- assertEquals("", ADValidator.validate(ad, "12356, 654321, 123456"));
- // 3rd value is too long
- assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "123, 123, 1234567"));
-
- ad.setOptions(Collections.singletonMap("123", "foo"));
+ // optional value
+ assertEquals("", ADValidator.validate(ad, null));
+ assertEquals("", ADValidator.validate(ad, ""));
+ // too less
+ assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "2"));
+ // adhere minimal value
+ assertEquals("", ADValidator.validate(ad, "3"));
+ // adhere maximal value
+ assertEquals("", ADValidator.validate(ad, "6"));
+ // too great
+ assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "7"));
- // adhere minimum lengths
- assertEquals("", ADValidator.validate(ad, "123, 123, 123"));
- assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "2134"));
- }
+ ad.setCardinality(3); // up to three values are allowed...
+
+ // mandatory value
+ assertEquals("", ADValidator.validate(ad, null));
+ // 2nd value is missing
+ assertEquals("", ADValidator.validate(ad, "3,,3"));
+
+ ad.setRequired(true);
+
+ // mandatory value
+ assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
+ // 2nd value is missing
+ assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, "3,,3"));
+ // 2nd value is invalid
+ assertEquals(AD.VALIDATE_INVALID_VALUE, ADValidator.validate(ad, "3,a,3"));
+ // 2nd value is too less
+ assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "3,2,3"));
+ // adhere minimal values
+ assertEquals("", ADValidator.validate(ad, "3, 4, 5"));
+ // adhere maximal values
+ assertEquals("", ADValidator.validate(ad, "6, 5, 4"));
+ // 3rd value is too great
+ assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "5, 6, 7"));
+ }
+
+ /**
+ * Tests the validation of long values works as expected.
+ */
+ public void testValidateLong()
+ {
+ AD ad = new AD();
+ ad.setType("Long");
+ ad.setRequired(true);
+
+ ad.setMin("-20");
+ ad.setMax("-15");
+
+ // value too small
+ assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "-21"));
+ // value within bounds
+ assertEquals("", ADValidator.validate(ad, "-15"));
+ // value within bounds
+ assertEquals("", ADValidator.validate(ad, "-20"));
+ // value too great
+ assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "-14"));
+
+ // Set minimum and maximum beyond the range of plain integers...
+ ad.setMin("2147483650");
+ ad.setMax("2147483655");
+
+ // value too small
+ assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "2147483649"));
+ // value within bounds
+ assertEquals("", ADValidator.validate(ad, "2147483650"));
+ // value within bounds
+ assertEquals("", ADValidator.validate(ad, "2147483655"));
+ // value too great
+ assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "2147483656"));
+ }
+
+ /**
+ * Tests the validation of strings is based on the minimum and maximum lengths.
+ */
+ public void testValidateString()
+ {
+ AD ad = new AD();
+ ad.setType("String");
+ ad.setRequired(false);
+
+ // optional value
+ assertEquals("", ADValidator.validate(ad, null));
+ // any length of input is accepted
+ assertEquals("", ADValidator.validate(ad, "1234567890"));
+
+ ad.setMin("3"); // minimal length == 3
+ ad.setMax("6"); // maximum length == 6
+
+ // too short
+ assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "12"));
+ // adhere minimum length
+ assertEquals("", ADValidator.validate(ad, "123"));
+ // adhere maximum length
+ assertEquals("", ADValidator.validate(ad, "12356"));
+ // too long
+ assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "1234567"));
+
+ ad.setCardinality(3); // up to three values are allowed...
+ ad.setMin("");
+
+ // optional value
+ assertEquals("", ADValidator.validate(ad, null));
+ // 2nd value is missing; but that's ok
+ assertEquals("", ADValidator.validate(ad, "321, , 123"));
+
+ ad.setRequired(true);
+ ad.setMin("3");
+
+ // mandatory value
+ assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, null));
+ // 2nd value is missing
+ assertEquals(AD.VALIDATE_MISSING, ADValidator.validate(ad, "321, , 123"));
+ // 2nd value is too short
+ assertEquals(AD.VALIDATE_LESS_THAN_MINIMUM, ADValidator.validate(ad, "321,12,123"));
+ // adhere minimum lengths
+ assertEquals("", ADValidator.validate(ad, "123, 123, 123"));
+ // adhere maximum lengths
+ assertEquals("", ADValidator.validate(ad, "12356, 654321, 123456"));
+ // 3rd value is too long
+ assertEquals(AD.VALIDATE_GREATER_THAN_MAXIMUM, ADValidator.validate(ad, "123, 123, 1234567"));
+
+ ad.setOptions(Collections.singletonMap("123", "foo"));
+
+ // adhere minimum lengths
+ assertEquals("", ADValidator.validate(ad, "123, 123, 123"));
+ assertEquals(AD.VALIDATE_NOT_A_VALID_OPTION, ADValidator.validate(ad, "2134"));
+ }
}