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