Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2013 Jonatan Jönsson
* 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 se.softhouse.common.strings;
import javax.annotation.CheckReturnValue;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;
import java.io.File;
import java.text.NumberFormat;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Function;
import static java.util.Collections.unmodifiableMap;
import static java.util.Objects.requireNonNull;
import static se.softhouse.common.guavaextensions.Preconditions2.check;
import static se.softhouse.common.strings.StringsUtil.NEWLINE;
/**
* Gives you static access to implementations of the {@link Describer} interface.
*/
@Immutable
public final class Describers
{
private Describers()
{
}
private static final String NULL = "null";
/**
* Always describes any value of type {@code T} with the given {@code constant}. For instance,
* if you have implemented a time related parser and don't want different times in the
* usage depending on when the usage is printed you could pass in "The current time", then this
* describer would describe any time object with "The current time".
*/
@Nonnull
@CheckReturnValue
public static Describer withConstantString(final String constant)
{
requireNonNull(constant);
return (value, locale) -> constant;
}
/**
* Calls {@link String#valueOf(Object)} for input values. As this goes
* against the very purpose of the {@link Describer} interface it may seem
* odd but this {@link Describer} works really well as a null object, it can
* also act as a functor for calling toString.
*/
@Nonnull
@CheckReturnValue
public static Describer toStringDescriber()
{
return (value, locale) -> String.valueOf(value);
}
/**
* Describes {@link Character}s by printing explanations for unprintable characters.
*/
@Nonnull
@CheckReturnValue
public static Describer characterDescriber()
{
return CharDescriber.INSTANCE;
}
private static final class CharDescriber implements Describer
{
private static final Describer INSTANCE = new CharDescriber();
@Override
public String describe(Character value, Locale inLocale)
{
if(value == null)
return NULL;
// TODO(jontejj): describe more characters? All ASCII characters perhaps?
// Character.isISOControl...
return ((int) value == 0) ? "the Null character" : value.toString();
}
}
/**
* Describes {@link File}s with {@link File#getAbsolutePath()} instead of {@link File#getPath()}
* as {@link File#toString()} does.
*/
@Nonnull
@CheckReturnValue
public static Describer fileDescriber()
{
return FileDescriber.INSTANCE;
}
private static final class FileDescriber implements Describer
{
private static final Describer INSTANCE = new FileDescriber();
@Override
public String describe(File file, Locale inLocale)
{
if(file == null)
return NULL;
return file.getAbsolutePath();
}
}
/**
* Describes a boolean as enabled when {@code true} and disabled when {@code false}
*/
@Nonnull
@CheckReturnValue
public static Describer booleanAsEnabledDisabled()
{
return BooleanDescribers.ENABLED_DISABLED;
}
/**
* Describes a boolean as on when {@code true} and off when {@code false}
*/
@Nonnull
@CheckReturnValue
public static Describer booleanAsOnOff()
{
return BooleanDescribers.ON_OFF;
}
enum BooleanDescribers implements Describer
{
ENABLED_DISABLED
{
@Override
public String describe(Boolean value, Locale inLocale)
{
return value ? "enabled" : "disabled";
}
},ON_OFF{
@Override
public String describe(Boolean value, Locale inLocale)
{
return value ? "on" : "off";
}
};}
/**
* Describes {@link Number}s in a {@link Locale} sensitive manner using {@link NumberFormat}.
*/
public static Describer numberDescriber()
{
return NumberDescriber.INSTANCE;
}
private static final class NumberDescriber implements Describer
{
private static final Describer INSTANCE = new NumberDescriber();
@Override
public String describe(Number number, Locale locale)
{
if(number == null)
return NULL;
return NumberFormat.getInstance(locale).format(number);
}
@Override
public String toString()
{
return "NumberDescriber";
}
}
/**
* Describes what a key=value in a {@link Map} means by fetching a
* description from {@code descriptions} for each key in a given map. So {@code descriptions}
* need to have values (descriptions) for all keys in any given map,
* otherwise a {@link NullPointerException} is thrown. For example:
*
*
*
* Map<String, Integer> defaults = newLinkedHashMap();
* defaults.put("population", 42);
* defaults.put("hello", 1);
*
* Map<String, String> descriptions = newLinkedHashMap();
* descriptions.put("population", "The number of citizens in the world");
* descriptions.put("hello", "The number of times to say hello");
* Describer<Map<String, Integer>> d = mapDescriber(descriptions);
*
* String describedMap = d.describe(defaults);
*
*
*
* would return:
*
*
*
* population=42
* The number of citizens in the world
* hello=1
* The number of times to say hello
*
*
*
* You could even implement a
* {@code addProperty(String key, int defaultValue, String description)} method to enforce the
* use of descriptions at compile-time.
*/
@Nonnull
@CheckReturnValue
public static Describer