All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.mmm.base.metainfo.MetaInfo Maven / Gradle / Ivy

The newest version!
/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
 * http://www.apache.org/licenses/LICENSE-2.0 */
package io.github.mmm.base.metainfo;

import java.lang.reflect.AnnotatedElement;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.function.Function;

import io.github.mmm.base.exception.ObjectNotFoundException;
import io.github.mmm.base.lang.ValueType;
import io.github.mmm.base.metainfo.impl.MetaInfoEmpty;
import io.github.mmm.base.metainfo.impl.MetaInfoValues;
import io.github.mmm.base.number.NumberType;

/**
 * Interface for meta-information similar to {@link java.util.Properties} but more sophisticated. Implements
 * {@link Iterable} allowing to {@link #iterator() iterate} the available meta-information keys.
* Use {@link #empty()} to get the empty instance and then call any {@code with} method to extended with real data. * Example to show usage: * *
 * {@literal @}{@link MetaInfoValues}({"key1=value1", "key2=value2"})
 * public class AnnotatedClass {
 *   public static void main(String[] args) {
 *     {@link MetaInfo} metaInfo = {@link MetaInfo}.{@link #empty()}.{@link #with(AnnotatedElement) with}(AnnotatedClass.class);
 *     metaInfo = metaInfo.{@link #with(Map) with}(Map.of("key2", "two", "key3", "value3"));
 *     for (String key : metaInfo) {
 *       String value = metaInfo.{@link #get(String) get}(key);
 *       System.out.println(key + "=" + value);
 *     }
 *   }
 * }
 * 
* * This will print the following output (order is undefined): * *
 * key1=value1
 * key2=two
 * key3=value3
 * 
* * ATTENTION: Typically the {@code with} methods will return a new instance of {@link MetaInfo} with the invoked * {@link MetaInfo} as {@link #getParent() parent}. However, this is not guaranteed. Especially immutable * implementations may return a {@link MetaInfo} with a different {@link #getParent() parent}. * * @since 1.0.0 */ public interface MetaInfo extends Iterable { /** * @param key the key of the requested meta-information. * @return the value of the meta-information for the given {@code key}. Will be {@code null} if no value is defined * for the given {@code key}. */ default String get(String key) { return get(true, key); } /** * @param key the key of the requested meta-information. * @return the value of the meta-information for the given {@code key}. Will be {@code null} if no value is defined * for the given {@code key}. * @throws ObjectNotFoundException if the specified value is undefined. */ default String getRequired(String key) { return get(true, true, key); } /** * @param key the key of the requested meta-information. * @param defaultValue the default value returned if the actual value is undefined. * @return the value of the meta-information for the given {@code key}. Will be {@code null} if no value is defined * for the given {@code key}. */ default String get(String key, String defaultValue) { return get(true, key, defaultValue); } /** * @param inherit - {@code true} to inherit meta-information from the {@link #getParent() parent}, {@code false} to * only return plain meta-information defined in this {@link MetaInfo} itself. * @param key the key of the requested meta-information. * @param defaultValue the default value returned if the actual value is undefined. * @return the value of the meta-information for the given {@code key}. Will be {@code null} if no value is defined * for the given {@code key}. */ default String get(boolean inherit, String key, String defaultValue) { String value = get(inherit, key); if (value == null) { value = defaultValue; } return value; } /** * @param inherit - {@code true} to inherit meta-information from the {@link #getParent() parent}, {@code false} to * only return plain meta-information defined in this {@link MetaInfo} itself. * @param key the key of the requested meta-information. * @return the value of the meta-information for the given {@code key}. Will be {@code null} if no value is defined * for the given {@code key}. */ String get(boolean inherit, String key); /** * @param inherit - {@code true} to inherit meta-information from the {@link #getParent() parent}, {@code false} to * only return plain meta-information defined in this {@link MetaInfo} itself. * @param required - {@code true} if the requested value is required and an exception shall be raised if it is * undefined, {@code false} otherwise (return {@code null} if undefined). * @param key the key of the requested meta-information. * @return the value of the meta-information for the given {@code key}. Will be {@code null} if no value is defined * for the given {@code key}. * @throws ObjectNotFoundException if the specified value is undefined and {@code required} was {@code true}. */ String get(boolean inherit, boolean required, String key); /** * @param type of the requested value. * @param inherit - {@code true} to inherit meta-information from the {@link #getParent() parent}, {@code false} to * only return plain meta-information defined in this {@link MetaInfo} itself. * @param required - {@code true} if the requested value is required and an exception shall be raised if it is * undefined, {@code false} otherwise (return {@code null} if undefined). * @param key the key of the requested meta-information. * @param type the {@link Class} reflecting the requested value. * @param parser the {@link Function} to {@link Function#apply(Object) parse} the value from a {@link String} to the * expected value type. * @return the value of the meta-information for the given {@code key}. Will be {@code null} if no value is defined * for the given {@code key}. * @throws ObjectNotFoundException if the specified value is undefined and {@code required} was {@code true}. */ T getGeneric(boolean inherit, boolean required, String key, ValueType type); /** * @param key the key of the requested meta-information. * @return the value of the meta-information for the given {@code key} parsed as {@link Integer}. Will be {@code null} * if no value is defined for the given {@code key}. * @throws IllegalArgumentException if the value cannot be parsed as {@link Integer}. */ default Integer getAsInteger(String key) { return getAsInteger(true, false, key); } /** * @param key the key of the requested meta-information. * @return the value of the meta-information for the given {@code key} parsed as {@link Integer}. * @throws ObjectNotFoundException if the specified value is undefined. * @throws IllegalArgumentException if the value cannot be parsed as {@link Integer}. */ default int getAsIntegerRequired(String key) { return getAsInteger(true, true, key).intValue(); } /** * @param inherit - {@code true} to inherit meta-information from the {@link #getParent() parent}, {@code false} to * only return plain meta-information defined in this {@link MetaInfo} itself. * @param required - {@code true} if the requested value is required and an exception shall be raised if it is * undefined, {@code false} otherwise (return {@code null} if undefined). * @param key the key of the requested meta-information. * @return the value of the meta-information for the given {@code key} parsed as {@link Long}. Will be {@code null} if * no value is defined for the given {@code key}. * @throws ObjectNotFoundException if the specified value is undefined and {@code required} was {@code true}. * @throws IllegalArgumentException if the value cannot be parsed as {@link Integer}. */ default Integer getAsInteger(boolean inherit, boolean required, String key) { return getGeneric(inherit, required, key, NumberType.INTEGER); } /** * @param key the key of the requested meta-information. * @param defaultValue the default value returned if the actual value is undefined. * @return the value of the meta-information for the given {@code key} parsed as {@link int}. If the actual value is * undefined, the given {@code defaultValue} will be returned. * @throws IllegalArgumentException if the value cannot be parsed as {@link int}. */ default int getAsInteger(String key, int defaultValue) { return getAsInteger(true, key, defaultValue); } /** * @param inherit - {@code true} to inherit meta-information from the {@link #getParent() parent}, {@code false} to * only return plain meta-information defined in this {@link MetaInfo} itself. * @param key the key of the requested meta-information. * @param defaultValue the default value returned if the actual value is undefined. * @return the value of the meta-information for the given {@code key} parsed as {@link int}. If the actual value is * undefined, the given {@code defaultValue} will be returned. * @throws IllegalArgumentException if the value cannot be parsed as {@link int}. */ default int getAsInteger(boolean inherit, String key, int defaultValue) { Integer value = getAsInteger(inherit, false, key); if (value == null) { return defaultValue; } return value.intValue(); } /** * @param key the key of the requested meta-information. * @return the value of the meta-information for the given {@code key} parsed as {@link Long}. Will be {@code null} if * no value is defined for the given {@code key}. * @throws IllegalArgumentException if the value cannot be parsed as {@link Long}. */ default Long getAsLong(String key) { return getAsLong(true, false, key); } /** * @param key the key of the requested meta-information. * @return the value of the meta-information for the given {@code key} parsed as {@link Long}. * @throws ObjectNotFoundException if the specified value is undefined. * @throws IllegalArgumentException if the value cannot be parsed as {@link Long}. */ default long getAsLongRequired(String key) { return getAsLong(true, true, key).longValue(); } /** * @param inherit - {@code true} to inherit meta-information from the {@link #getParent() parent}, {@code false} to * only return plain meta-information defined in this {@link MetaInfo} itself. * @param required - {@code true} if the requested value is required and an exception shall be raised if it is * undefined, {@code false} otherwise (return {@code null} if undefined). * @param key the key of the requested meta-information. * @return the value of the meta-information for the given {@code key} parsed as {@link Long}. Will be {@code null} if * no value is defined for the given {@code key}. * @throws ObjectNotFoundException if the specified value is undefined and {@code required} was {@code true}. * @throws IllegalArgumentException if the value cannot be parsed as {@link Long}. */ default Long getAsLong(boolean inherit, boolean required, String key) { return getGeneric(inherit, required, key, NumberType.LONG); } /** * @param key the key of the requested meta-information. * @param defaultValue the default value returned if the actual value is undefined. * @return the value of the meta-information for the given {@code key} parsed as {@link long}. If the actual value is * undefined, the given {@code defaultValue} will be returned. * @throws IllegalArgumentException if the value cannot be parsed as {@link long}. */ default long getAsLong(String key, long defaultValue) { return getAsLong(true, key, defaultValue); } /** * @param inherit - {@code true} to inherit meta-information from the {@link #getParent() parent}, {@code false} to * only return plain meta-information defined in this {@link MetaInfo} itself. * @param key the key of the requested meta-information. * @param defaultValue the default value returned if the actual value is undefined. * @return the value of the meta-information for the given {@code key} parsed as {@link long}. If the actual value is * undefined, the given {@code defaultValue} will be returned. * @throws IllegalArgumentException if the value cannot be parsed as {@link long}. */ default long getAsLong(boolean inherit, String key, long defaultValue) { Long value = getAsLong(inherit, false, key); if (value == null) { return defaultValue; } return value.longValue(); } /** * @param key the key of the requested meta-information. * @return the value of the meta-information for the given {@code key} parsed as {@link Boolean}. Will be {@code null} * if no value is defined for the given {@code key}. * @throws IllegalArgumentException if the value cannot be parsed as {@link Boolean}. */ default Boolean getAsBoolean(String key) { return getAsBoolean(true, false, key); } /** * @param key the key of the requested meta-information. * @return the value of the meta-information for the given {@code key} parsed as {@link Boolean}. * @throws ObjectNotFoundException if the specified value is undefined. * @throws IllegalArgumentException if the value cannot be parsed as {@link Boolean}. */ default boolean getAsBooleanRequired(String key) { return getAsBoolean(true, true, key).booleanValue(); } /** * @param inherit - {@code true} to inherit meta-information from the {@link #getParent() parent}, {@code false} to * only return plain meta-information defined in this {@link MetaInfo} itself. * @param required - {@code true} if the requested value is required and an exception shall be raised if it is * undefined, {@code false} otherwise (return {@code null} if undefined). * @param key the key of the requested meta-information. * @return the value of the meta-information for the given {@code key} parsed as {@link Boolean}. Will be {@code null} * if no value is defined for the given {@code key}. * @throws ObjectNotFoundException if the specified value is undefined and {@code required} was {@code true}. * @throws IllegalArgumentException if the value cannot be parsed as {@link Boolean}. */ default Boolean getAsBoolean(boolean inherit, boolean required, String key) { return getGeneric(inherit, required, key, ValueType.BOOLEAN); } /** * @param key the key of the requested meta-information. * @param defaultValue the default value returned if the actual value is undefined. * @return the value of the meta-information for the given {@code key} parsed as {@link boolean}. If the actual value * is undefined, the given {@code defaultValue} will be returned. * @throws IllegalArgumentException if the value cannot be parsed as {@link Boolean}. */ default boolean getAsBoolean(String key, boolean defaultValue) { return getAsBoolean(true, key, defaultValue); } /** * @param inherit - {@code true} to inherit meta-information from the {@link #getParent() parent}, {@code false} to * only return plain meta-information defined in this {@link MetaInfo} itself. * @param key the key of the requested meta-information. * @param defaultValue the default value returned if the actual value is undefined. * @return the value of the meta-information for the given {@code key} parsed as {@link boolean}. If the actual value * is undefined, the given {@code defaultValue} will be returned. * @throws IllegalArgumentException if the value cannot be parsed as {@link Boolean}. */ default boolean getAsBoolean(boolean inherit, String key, boolean defaultValue) { Boolean value = getAsBoolean(inherit, false, key); if (value == null) { return defaultValue; } return value.booleanValue(); } /** * @return the number of {@link #get(String) entries} contained in this {@link MetaInfo}. */ int size(); /** * @return {@code true} if empty, {@code false} otherwise. */ default boolean isEmpty() { return !iterator().hasNext(); } /** * @return the potential parent {@link MetaInfo} to inherit from. Will be {@code null} if nothing is inherited. */ default MetaInfo getParent() { return null; } /** * @return the prefix for the {@link #get(String) keys} as namespace. E.g. if the key prefix is "spring.datasource." * and you call {@link #get(String)} with "password" it will return the property for the key * "spring.datasource.password" from the underlying mapping. The default key prefix is the empty * {@link String}. */ default String getKeyPrefix() { return ""; } /** * Adds or updates the specified meta-info.
* ATTENTION: Please consider using {@link #with(Map)} and other related factory methods instead of * sequentially using this method that may be inefficient. * * @param key the new key of the meta-info. * @param value the new value of the meta-info. * @return a new {@link MetaInfo} that extends this {@link MetaInfo} with the specified meta-information. */ MetaInfo with(String key, String value); /** * @param map the {@link Map} with the meta-information to wrap. * @return a new {@link MetaInfo} that {@link #getParent() inherits} from this {@link MetaInfo} and extends it with * the meta-information from the specified parameters. */ default MetaInfo with(Map map) { return with(map, ""); } /** * @param map the {@link Map} with the meta-information to wrap. * @param keyPrefix the {@link #getKeyPrefix() key prefix}. * @return a new {@link MetaInfo} that extends this {@link MetaInfo} with the specified meta-information. */ MetaInfo with(Map map, String keyPrefix); /** * ATTENTION: Due to the design of {@link Properties} (with ability for inheritance but no API to get access to * the parent defaults) the result will be inefficient. * * @param properties the {@link Properties} with the meta-information to wrap. * @return a new {@link MetaInfo} that extends this {@link MetaInfo} with the specified meta-information. */ default MetaInfo with(Properties properties) { return with(properties, ""); } /** * ATTENTION: Due to the design of {@link Properties} (with ability for inheritance but no API to get access to * the parent defaults) the result will be inefficient. * * @param properties the {@link Properties} with the meta-information to wrap. * @param keyPrefix the {@link #getKeyPrefix() key prefix}. * @return a new {@link MetaInfo} that extends this {@link MetaInfo} with the specified meta-information. */ MetaInfo with(Properties properties, String keyPrefix); /** * @param annotatedElement the {@link AnnotatedElement} (e.g. {@link Class}) that is (potentially) annotated with * {@link MetaInfos}. * @return a new {@link MetaInfo} that extends this {@link MetaInfo} with the meta-information from the given * {@link AnnotatedElement}. Will be {@code this} instance itself if the given {@link AnnotatedElement} has no * {@link MetaInfos} annotation. */ default MetaInfo with(AnnotatedElement annotatedElement) { MetaInfos metaInfos = annotatedElement.getAnnotation(MetaInfos.class); if (metaInfos == null) { return this; } else { return with(metaInfos); } } /** * @param metaValues the {@link MetaInfos}. * @return a new {@link MetaInfo} that extends this {@link MetaInfo} with the specified meta-information. */ MetaInfo with(MetaInfos metaValues); /** * @param keyPrefix the {@link #getKeyPrefix() key prefix}. * @return a new {@link MetaInfo} that wraps this {@link MetaInfo} with all its parents using the given * {@link #getKeyPrefix() key prefix}. The resulting {@link MetaInfo} will return {@code null} as * {@link #getParent() parent}. */ MetaInfo with(String keyPrefix); /** * @return a new {@link Properties} instance with all values from this {@link MetaInfo}. */ default Properties asProperties() { Properties properties = new Properties(); for (String key : this) { properties.setProperty(key, get(key)); } return properties; } /** * @return a new {@link Map} instance with all values from this {@link MetaInfo}. */ default Map asMap() { Map map = new HashMap<>(size()); for (String key : this) { map.put(key, get(key)); } return map; } /** * @return an instance of {@link MetaInfo} that is {@link #isEmpty() empty}. */ static MetaInfo empty() { return MetaInfoEmpty.INSTANCE; } /** * @return the {@link MetaInfo} with the configuration for the running application. */ static MetaInfo config() { return io.github.mmm.base.metainfo.impl.AppConfigHolder.CONFIG; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy