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.
/*
* JGrapes Event Driven Framework
* Copyright (C) 2022 Michael N. Lipp
*
* This program 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 .
*/
package org.jgrapes.util;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAccessor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Queue;
import java.util.TreeMap;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.jgrapes.core.Channel;
import org.jgrapes.core.Component;
import org.jgrapes.core.Event;
import org.jgrapes.core.Manager;
import org.jgrapes.core.annotation.Handler;
import org.jgrapes.core.annotation.HandlerDefinition.ChannelReplacements;
import org.jgrapes.util.events.InitialConfiguration;
/**
* A base class for configuration stores. Implementing classes must
* override one of the methods {@link #structured(String)} or
* {@link #values(String)} as the default implementations of either
* calls the other.
*/
@SuppressWarnings({ "PMD.DataflowAnomalyAnalysis", "PMD.GodClass" })
public abstract class ConfigurationStore extends Component {
public static final Pattern NUMBER = Pattern.compile("^\\d+$");
/**
* Creates a new component with its channel set to itself.
*/
public ConfigurationStore() {
// Nothing to do.
}
/**
* Creates a new component base with its channel set to the given
* channel. As a special case {@link Channel#SELF} can be
* passed to the constructor to make the component use itself
* as channel. The special value is necessary as you
* obviously cannot pass an object to be constructed to its
* constructor.
*
* @param componentChannel the channel that the component's
* handlers listen on by default and that
* {@link Manager#fire(Event, Channel...)} sends the event to
*/
public ConfigurationStore(Channel componentChannel) {
super(componentChannel);
}
/**
* Creates a new component base like {@link #ConfigurationStore(Channel)}
* but with channel mappings for {@link Handler} annotations.
*
* @param componentChannel the channel that the component's
* handlers listen on by default and that
* {@link Manager#fire(Event, Channel...)} sends the event to
* @param channelReplacements the channel replacements to apply
* to the `channels` elements of the {@link Handler} annotations
*/
public ConfigurationStore(Channel componentChannel,
ChannelReplacements channelReplacements) {
super(componentChannel, channelReplacements);
}
/**
* Configuration information should be kept simple. Sometimes,
* however, it is unavoidable to structure the information
* associated with a (logical) key. This can be done by
* reflecting the structure in the names of actual keys, derived
* from the logical key. Names such as "key.0", "key.1", "key.2"
* can be used to express that the value associated with "key"
* is a list of values. "key.a", "key.b", "key.c" can be used
* to associate "key" with a map from "a", "b", "c" to some values.
*
* This methods looks at all values in the map passed as
* argument. If the value is a collection or map, the entry is
* converted to several entries following the pattern outlined
* above.
*
* @param structured the map with possibly structured properties
* @return the map with flattened properties
*/
public static Map flatten(Map structured) {
@SuppressWarnings("PMD.UseConcurrentHashMap")
Map result = new HashMap<>();
flattenObject(result, null, structured);
return result;
}
@SuppressWarnings({ "unchecked", "PMD.AvoidDuplicateLiterals" })
private static void flattenObject(Map result,
String prefix, Object value) {
if (value instanceof Map) {
for (var entry : ((Map