/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2013 by Pentaho : http://www.pentaho.com
*
*******************************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
package org.pentaho.di.core.util;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang.StringUtils;
/**
*
* @author <a href="mailto:thomas.hoedl@aschauer-edv.at">Thomas Hoedl(asc042)</a>
*
* @param <T>
* type of value
*/
public class KeyValue<T> implements Serializable {
/**
* The default true values.
*/
public static final List<String> DEFAULT_TRUE_VALUES = Arrays.asList( new String[] { "j", "y", "on", "true" } );
/**
* Valid key characters.
*/
public static final String VALID_KEY_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789_-";
/**
* Serial version UID.
*/
private static final long serialVersionUID = -6847244072467344205L;
private final String key;
private T value; // NOPMD
/**
* Constructor. Key will be converted to lower case.
*
* @param key
* key to set.
* @param value
* value to set, may be null.
* @throws IllegalArgumentException
* if key is invalid.
*/
public KeyValue( final String key, final T value ) throws IllegalArgumentException {
final String keyToSet = StringUtils.lowerCase( key );
assertKey( keyToSet );
this.key = keyToSet;
this.value = value;
}
/**
* Constructor. Key will be converted to lower case. Value is null.
*
* @param key
* key to set.
* @throws IllegalArgumentException
* if key is invalid.
*/
public KeyValue( final String key ) throws IllegalArgumentException {
this( key, null );
}
/**
* @param lowerKey
* key to test.
* @throws IllegalArgumentException
* if key is invalid.
*/
public static final void assertKey( final String lowerKey ) throws IllegalArgumentException {
Assert.assertNotEmpty( lowerKey, "Key cannot be null or empty" );
if ( !StringUtils.containsOnly( lowerKey, VALID_KEY_CHARS ) ) {
throw new IllegalArgumentException( "Key contains invalid characters [validKeyCharacters="
+ VALID_KEY_CHARS + "]" );
}
if ( lowerKey.charAt( 0 ) == '-' ) {
throw new IllegalArgumentException( "Key must not start with '-'" );
}
if ( lowerKey.endsWith( "-" ) ) {
throw new IllegalArgumentException( "Key must not end with '-'" );
}
if ( "_".equals( lowerKey ) ) {
throw new IllegalArgumentException( "Key must not be '_'" );
}
}
/**
* @return the key, never null.
*/
public String getKey() {
return this.key;
}
/**
* @return the value
*/
public T getValue() {
return this.value;
}
/**
* @param value
* the value to set
*/
public void setValue( final T value ) {
this.value = value;
}
/**
* @param newValue
* value to set.
* @return this.
*/
public KeyValue<T> value( final T newValue ) {
this.value = newValue;
return this;
}
/**
* @return value.
*/
public T value() {
return this.value;
}
/**
* @param trueValues
* string true values, case is ignored.
* @return boolean value, null if value is null.
*/
public Boolean booleanValue( final String... trueValues ) {
return this.booleanValue( Arrays.asList( trueValues ) );
}
/**
* @param trueValues
* string true values, case is ignored.
* @return boolean value, null if value is null.
*/
public Boolean booleanValue( final List<String> trueValues ) {
return this.booleanValue( trueValues, true );
}
/**
* @param trueValues
* string true values.
* @param ignoreCase
* ignore case?
* @return boolean value, null if value is null.
*/
public Boolean booleanValue( final List<String> trueValues, final boolean ignoreCase ) {
if ( this.value == null ) {
return null;
}
if ( this.value instanceof Boolean ) {
return (Boolean) this.value;
}
final String stringValue = this.stringValue();
if ( ignoreCase ) {
return trueValues.contains( StringUtils.lowerCase( stringValue ) );
}
return trueValues.contains( stringValue );
}
/**
* Uses DEFAULT_TRUE_VALUES, ignore case.
*
* @return boolean value or null if value is null.
*/
public Boolean booleanValue() {
return this.booleanValue( DEFAULT_TRUE_VALUES, true );
}
/**
* @param defaultValue
* the default value
* @return boolean value or default value if value is null.
*/
public Boolean booleanValue( final Boolean defaultValue ) {
final Boolean returnValue = this.booleanValue();
if ( returnValue == null ) {
return defaultValue;
}
return returnValue;
}
/**
* @return string value or null if value is null.
*/
public String stringValue() {
if ( this.value == null ) {
return null;
}
if ( this.value instanceof String ) {
return (String) this.value;
}
return String.valueOf( this.value );
}
/**
* @param defaultValue
* the default value.
* @return string value or default value if value is null.
*/
public String stringValue( final String defaultValue ) {
final String returnValue = this.stringValue();
if ( returnValue == null ) {
return defaultValue;
}
return returnValue;
}
/**
* @param defaultValue
* the default value.
* @return string value or default value if value is blank.
*/
public String stringValueDefaultIfBlank( final String defaultValue ) {
final String returnValue = this.stringValue();
if ( StringUtils.isBlank( returnValue ) ) {
return defaultValue;
}
return returnValue;
}
/**
* @return integer value or null if value is null.
* @throws NumberFormatException
* if string value of value cannot be converted to Integer
*/
public Integer integerValue() throws NumberFormatException {
if ( this.value == null ) {
return null;
}
if ( this.value instanceof Integer ) {
return (Integer) this.value;
}
return Integer.valueOf( String.valueOf( this.value ) );
}
/**
* @param defaultValue
* the default value.
* @return integer value or default value if value is null or cannot be converted to integer.
*/
public Integer integerValue( final Integer defaultValue ) {
if ( this.value == null ) {
return defaultValue;
}
try {
return this.integerValue();
} catch ( NumberFormatException e ) {
return defaultValue;
}
}
/**
* @return long value or null if value is null.
* @throws NumberFormatException
* if string value of value cannot be converted to Long
*/
public Long longValue() throws NumberFormatException {
if ( this.value == null ) {
return null;
}
if ( this.value instanceof Long ) {
return (Long) this.value;
}
return Long.valueOf( String.valueOf( this.value ) );
}
/**
* @param defaultValue
* the default value.
* @return long value or default value if value is null or cannot be converted to long.
*/
public Long longValue( final Long defaultValue ) {
if ( this.value == null ) {
return defaultValue;
}
try {
return this.longValue();
} catch ( NumberFormatException e ) {
return defaultValue;
}
}
/**
* @return double value or null if value is null.
* @throws NumberFormatException
* if string value of value cannot be converted to Double
*/
public Double doubleValue() throws NumberFormatException {
if ( this.value == null ) {
return null;
}
if ( this.value instanceof Double ) {
return (Double) this.value;
}
return Double.valueOf( String.valueOf( this.value ) );
}
/**
* @param defaultValue
* the default value.
* @return double value or default value if value is null or cannot be converted to double.
*/
public Double doubleValue( final Double defaultValue ) {
if ( this.value == null ) {
return defaultValue;
}
try {
return this.doubleValue();
} catch ( NumberFormatException e ) {
return defaultValue;
}
}
/**
* @return float value or null if value is null.
* @throws NumberFormatException
* if string value of value cannot be converted to Float
*/
public Float floatValue() throws NumberFormatException {
if ( this.value == null ) {
return null;
}
if ( this.value instanceof Float ) {
return (Float) this.value;
}
return Float.valueOf( String.valueOf( this.value ) );
}
/**
* @param defaultValue
* the default value.
* @return float value or default value if value is null or cannot be converted to float.
*/
public Float floatValue( final Float defaultValue ) {
if ( this.value == null ) {
return defaultValue;
}
try {
return this.floatValue();
} catch ( NumberFormatException e ) {
return defaultValue;
}
}
/**
* {@inheritDoc}
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append( KeyValue.class.getSimpleName() );
builder.append( '(' );
builder.append( this.key );
if ( this.value == null ) {
builder.append( "<null>)" );
} else {
builder.append( "=[" );
builder.append( this.value );
builder.append( "])" );
}
return builder.toString();
}
}