org.neo4j.util.FeatureToggles Maven / Gradle / Ivy
Show all versions of neo4j-common Show documentation
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.neo4j.util;
import java.util.Objects;
/**
* Feature toggles are used for features that are possible to configure, but where the configuration is always fixed in
* a production system.
*
* Typical use cases for feature toggles are features that are integrated into the code base for integration and
* testing purposes, but are not ready for inclusion in the finished product yet, or features that are always on or has
* a fixed configured value in the finished product, but can assume a different configuration or be turned off in some
* test.
*
* Feature toggles are passed to the JVM through {@linkplain System#getProperty(String) system properties}, and
* expected to be looked up from a static context, a {@code static final} fields of the class the toggle controls.
*
* All methods in this class returns the default value if the system property has not been assigned, or if the value of
* the system property cannot be interpreted as a value of the expected type.
*
* For features that the user is ever expected to touch, feature toggles is the wrong abstraction!
*/
public final class FeatureToggles {
/**
* Get the value of a {@code boolean} system property.
*
* The absolute name of the system property is computed based on the provided class and local name.
*
* @param location the class that owns the flag.
* @param name the local name of the flag.
* @param defaultValue the default value of the flag if the system property is not assigned.
* @return the parsed value of the system property, or the default value.
*/
public static boolean flag(Class> location, String name, boolean defaultValue) {
return booleanProperty(name(location, name), defaultValue);
}
/**
* Get the value of a {@code long} system property.
*
* The absolute name of the system property is computed based on the provided class and local name.
*
* @param location the class that owns the flag.
* @param name the local name of the flag.
* @param defaultValue the default value of the flag if the system property is not assigned.
* @return the parsed value of the system property, or the default value.
*/
public static long getLong(Class> location, String name, long defaultValue) {
return Long.getLong(name(location, name), defaultValue);
}
/**
* Get the value of a {@code int} system property.
*
* The absolute name of the system property is computed based on the provided class and local name.
*
* @param location the class that owns the flag.
* @param name the local name of the flag.
* @param defaultValue the default value of the flag if the system property is not assigned.
* @return the parsed value of the system property, or the default value.
*/
public static int getInteger(Class> location, String name, int defaultValue) {
return Integer.getInteger(name(location, name), defaultValue);
}
/**
* Get the value of a {@code double} system property.
*
* The absolute name of the system property is computed based on the provided class and local name.
*
* @param location the class that owns the flag.
* @param name the local name of the flag
* @param defaultValue the default value of the flag if the system property is not assigned.
* @return the parsed value of the system property, or the default value.
*/
public static double getDouble(Class> location, String name, double defaultValue) {
try {
String propertyValue = System.getProperty(name(location, name));
if (propertyValue != null && !propertyValue.isEmpty()) {
return Double.parseDouble(propertyValue);
}
} catch (Exception e) {
// ignored
}
return defaultValue;
}
/**
* Get the value of a {@link String} system property.
*
* The absolute name of the system property is computed based on the provided class and local name.
*
* @param location the class that owns the flag.
* @param name the local name of the flag
* @param defaultValue the default value of the flag if the system property is not assigned.
* @return the parsed value of the system property, or the default value.
*/
public static String getString(Class> location, String name, String defaultValue) {
String propertyValue = System.getProperty(name(location, name));
return propertyValue == null || propertyValue.isEmpty() ? defaultValue : propertyValue;
}
/**
* Get the value of a {@code enum} system property.
*
* The absolute name of the system property is computed based on the provided class and local name.
*
* @param location the class that owns the flag.
* @param name the local name of the flag.
* @param defaultValue the default value of the flag if the system property is not assigned.
* @param the enum value type.
* @return the parsed value of the system property, or the default value.
*/
public static > E flag(Class> location, String name, E defaultValue) {
return enumProperty(defaultValue.getDeclaringClass(), name(location, name), defaultValue);
}
/**
* Set the value of a system property.
*
* The name of the system property is computed based on the provided class and local name.
*
* @param location the class that owns the flag.
* @param name the local name of the flag.
* @param value the value to assign to the system property.
*/
public static void set(Class> location, String name, Object value) {
System.setProperty(name(location, name), Objects.toString(value));
}
/**
* Clear the value of a system property.
*
* The name of the system property is computed based on the provided class and local name.
*
* @param location the class that owns the flag.
* @param name the local name of the flag.
*/
public static void clear(Class> location, String name) {
System.clearProperty(name(location, name));
}
private FeatureToggles() {}
private static String name(Class> location, String name) {
return location.getCanonicalName() + "." + name;
}
private static boolean booleanProperty(String flag, boolean defaultValue) {
return parseBoolean(System.getProperty(flag), defaultValue);
}
private static boolean parseBoolean(String value, boolean defaultValue) {
return defaultValue ? !"false".equalsIgnoreCase(value) : "true".equalsIgnoreCase(value);
}
private static > E enumProperty(Class enumClass, String name, E defaultValue) {
try {
return Enum.valueOf(enumClass, System.getProperty(name, defaultValue.name()));
} catch (IllegalArgumentException e) {
return defaultValue;
}
}
}