/**
* Copyright (c) 2002-2012 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.perftest.enterprise.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import static java.util.Collections.addAll;
import static java.util.Collections.emptyList;
public abstract class Setting<T>
{
public static Setting<String> stringSetting( String name )
{
return stringSetting( name, null );
}
public static Setting<String> stringSetting( String name, String defaultValue )
{
return new Setting<String>( name, defaultValue )
{
@Override
String parse( String value )
{
return value;
}
};
}
public static Setting<Long> integerSetting( String name, long defaultValue )
{
return new Setting<Long>( name, defaultValue )
{
@Override
Long parse( String value )
{
return Long.parseLong( value );
}
};
}
public static Setting<Boolean> booleanSetting( String name, boolean defaultValue )
{
return new Setting<Boolean>( name, defaultValue )
{
@Override
Boolean parse( String value )
{
return Boolean.parseBoolean( value );
}
@Override
boolean isBoolean()
{
return true;
}
};
}
public static <T> Setting<T> restrictSetting( Setting<T> setting, Predicate<? super T> firstPredicate,
Predicate<? super T>... morePredicates )
{
final Collection<Predicate<? super T>> predicates = new ArrayList<Predicate<? super T>>(
1 + (morePredicates == null ? 0 : morePredicates.length) );
predicates.add( firstPredicate );
addAll( predicates, morePredicates );
return new SettingAdapter<T, T>( setting )
{
@Override
T adapt( T value )
{
for ( Predicate<? super T> predicate : predicates )
{
if ( !predicate.matches( value ) )
{
throw new IllegalArgumentException(
String.format( "'%s' does not match %s", value, predicate ) );
}
}
return value;
}
};
}
public static <T extends Enum<T>> Setting<T> enumSetting( final Class<T> enumType, String name )
{
return new Setting<T>( name, null )
{
@Override
T parse( String value )
{
return Enum.valueOf( enumType, value );
}
};
}
public static <T extends Enum<T>> Setting<T> enumSetting( String name, T defaultValue )
{
final Class<T> enumType = defaultValue.getDeclaringClass();
return new Setting<T>( name, defaultValue )
{
@Override
T parse( String value )
{
return Enum.valueOf( enumType, value );
}
};
}
public static <T> Setting<List<T>> listSetting( final Setting<T> singleSetting, final List<T> defaultValue )
{
return new Setting<List<T>>( singleSetting.name(), defaultValue )
{
@Override
List<T> parse( String value )
{
if ( value.trim().equals( "" ) )
{
return emptyList();
}
String[] parts = value.split( "," );
List<T> result = new ArrayList<T>( parts.length );
for ( String part : parts )
{
result.add( singleSetting.parse( part ) );
}
return result;
}
@Override
public String asString( List<T> value )
{
StringBuilder result = new StringBuilder();
Iterator<T> iterator = value.iterator();
while ( iterator.hasNext() )
{
result.append( singleSetting.asString( iterator.next() ) );
if ( iterator.hasNext() )
{
result.append( ',' );
}
}
return result.toString();
}
};
}
public static <FROM, TO> Setting<TO> adaptSetting( Setting<FROM> source,
final Conversion<? super FROM, TO> conversion )
{
return new SettingAdapter<FROM, TO>( source )
{
@Override
TO adapt( FROM value )
{
return conversion.convert( value );
}
};
}
private final String name;
private final T defaultValue;
private Setting( String name, T defaultValue )
{
this.name = name;
this.defaultValue = defaultValue;
}
@Override
public String toString()
{
return String.format( "Setting[%s]", name );
}
public String name()
{
return name;
}
T defaultValue()
{
if ( defaultValue == null )
{
throw new IllegalStateException( String.format( "Required setting '%s' not configured.", name ) );
}
return defaultValue;
}
abstract T parse( String value );
boolean isBoolean()
{
return false;
}
void validateValue( String value )
{
parse( value );
}
public String asString( T value )
{
return value.toString();
}
private static abstract class SettingAdapter<FROM, TO> extends Setting<TO>
{
private final Setting<FROM> source;
SettingAdapter( Setting<FROM> source )
{
super( source.name, null );
this.source = source;
}
@Override
TO parse( String value )
{
return adapt( source.parse( value ) );
}
abstract TO adapt( FROM value );
@Override
TO defaultValue()
{
return adapt( source.defaultValue() );
}
}
}