001 /*
002 * SPDX-License-Identifier: Apache-2.0
003 *
004 * Copyright 2008-2017 the original author or authors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 package griffon.util;
019
020 import griffon.core.env.Environment;
021 import griffon.core.env.Metadata;
022
023 import javax.annotation.Nonnull;
024 import javax.annotation.Nullable;
025 import javax.inject.Inject;
026 import java.util.Collections;
027 import java.util.LinkedHashMap;
028 import java.util.Map;
029
030 import static griffon.util.GriffonNameUtils.isBlank;
031 import static griffon.util.GriffonNameUtils.isNotBlank;
032 import static java.util.Objects.requireNonNull;
033
034 /**
035 * @author Andres Almiray
036 * @since 2.11.0
037 */
038 public class MapReader {
039 private static final String ENVIRONMENTS_METHOD = "environments";
040
041 private final Map<String, String> conditionValues = new LinkedHashMap<>();
042
043 public static class Provider implements javax.inject.Provider<MapReader> {
044 @Inject private Metadata metadata;
045 @Inject private Environment environment;
046
047 @Override
048 public MapReader get() {
049 MapReader propertiesReader = new MapReader();
050 propertiesReader.registerConditionalBlock("environments", environment.getName());
051 propertiesReader.registerConditionalBlock("projects", metadata.getApplicationName());
052 propertiesReader.registerConditionalBlock("platforms", GriffonApplicationUtils.getPlatform());
053 return propertiesReader;
054 }
055 }
056
057 public void registerConditionalBlock(@Nullable String blockName, @Nullable String blockValue) {
058 if (isNotBlank(blockName)) {
059 if (isBlank(blockValue)) {
060 conditionValues.remove(blockName);
061 } else {
062 conditionValues.put(blockName, blockValue);
063 }
064 }
065 }
066
067 @Nonnull
068 public Map<String, String> getConditionalBlockValues() {
069 return Collections.unmodifiableMap(conditionValues);
070 }
071
072 @Nonnull
073 public String getEnvironment() {
074 return conditionValues.get(ENVIRONMENTS_METHOD);
075 }
076
077 public void setEnvironment(String environment) {
078 conditionValues.put(ENVIRONMENTS_METHOD, environment);
079 }
080
081 @Nonnull
082 public Map<String, Object> read(final @Nonnull Map<String, Object> map) {
083 requireNonNull(map, "Argument 'map' must not be null");
084 return processMap(map);
085 }
086
087 @Nonnull
088 protected Map<String, Object> processMap(@Nonnull Map<String, Object> input) {
089 Map<String, Object> output = new LinkedHashMap<>();
090
091 for (String key : input.keySet()) {
092 ConditionalBlockMatch match = resolveConditionalBlockMatch(key);
093 if (match != null) {
094 if (match.key != null) {
095 output.put(match.key, input.get(key));
096 }
097 } else {
098 output.put(key, input.get(key));
099 }
100 }
101
102 return output;
103 }
104
105 @Nullable
106 private ConditionalBlockMatch resolveConditionalBlockMatch(@Nonnull String key) {
107 for (Map.Entry<String, String> e : conditionValues.entrySet()) {
108 String blockName = e.getKey();
109 if (!key.startsWith(blockName + ".")) {
110 continue;
111 }
112
113 String prefix = blockName + "." + e.getValue() + ".";
114 if (key.startsWith(prefix)) {
115 String subkey = key.substring(prefix.length());
116 ConditionalBlockMatch match = resolveConditionalBlockMatch(subkey);
117 if (match == null) {
118 match = new ConditionalBlockMatch(subkey);
119 }
120 return match;
121 } else {
122 return new ConditionalBlockMatch(null);
123 }
124 }
125
126 return null;
127 }
128
129 private static class ConditionalBlockMatch {
130 public final String key;
131
132 private ConditionalBlockMatch(String key) {
133 this.key = key;
134 }
135 }
136 }
|