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.io.IOException;
025 import java.io.InputStream;
026 import java.io.Reader;
027 import java.net.URL;
028 import java.util.Collections;
029 import java.util.LinkedHashMap;
030 import java.util.Map;
031 import java.util.Properties;
032
033 import static griffon.util.GriffonNameUtils.isBlank;
034 import static java.util.Objects.requireNonNull;
035
036 /**
037 * @author Andres Almiray
038 * @since 2.10.0
039 */
040 public class PropertiesReader {
041 private static final String ENVIRONMENTS_METHOD = "environments";
042
043 private final Map<String, String> conditionValues = new LinkedHashMap<>();
044
045 public static class Provider implements javax.inject.Provider<PropertiesReader> {
046 @Inject private Metadata metadata;
047 @Inject private Environment environment;
048
049 @Override
050 public PropertiesReader get() {
051 PropertiesReader propertiesReader = new PropertiesReader();
052 propertiesReader.registerConditionalBlock("environments", environment.getName());
053 propertiesReader.registerConditionalBlock("projects", metadata.getApplicationName());
054 propertiesReader.registerConditionalBlock("platforms", GriffonApplicationUtils.getPlatform());
055 return propertiesReader;
056 }
057 }
058
059 public void registerConditionalBlock(@Nullable String blockName, @Nullable String blockValue) {
060 if (!isBlank(blockName)) {
061 if (isBlank(blockValue)) {
062 conditionValues.remove(blockName);
063 } else {
064 conditionValues.put(blockName, blockValue);
065 }
066 }
067 }
068
069 @Nonnull
070 public Map<String, String> getConditionalBlockValues() {
071 return Collections.unmodifiableMap(conditionValues);
072 }
073
074 @Nonnull
075 public String getEnvironment() {
076 return conditionValues.get(ENVIRONMENTS_METHOD);
077 }
078
079 public void setEnvironment(String environment) {
080 conditionValues.put(ENVIRONMENTS_METHOD, environment);
081 }
082
083 @Nonnull
084 public Properties load(@Nonnull URL location) throws IOException {
085 return load(requireNonNull(location, "Argument 'location' must not be null").openStream());
086 }
087
088 @Nonnull
089 public Properties load(@Nonnull InputStream stream) throws IOException {
090 Properties p = new Properties();
091 p.load(stream);
092 return processProperties(p);
093 }
094
095 @Nonnull
096 public Properties load(@Nonnull Reader reader) throws IOException {
097 Properties p = new Properties();
098 p.load(reader);
099 return processProperties(p);
100 }
101
102 @Nonnull
103 protected Properties processProperties(@Nonnull Properties input) {
104 Properties output = new Properties();
105
106 for (String key : input.stringPropertyNames()) {
107 ConditionalBlockMatch match = resolveConditionalBlockMatch(key);
108 if (match != null) {
109 if (match.key != null) {
110 output.put(match.key, input.getProperty(key));
111 }
112 } else {
113 output.put(key, input.getProperty(key));
114 }
115 }
116
117 return output;
118 }
119
120 @Nullable
121 private ConditionalBlockMatch resolveConditionalBlockMatch(@Nonnull String key) {
122 for (Map.Entry<String, String> e : conditionValues.entrySet()) {
123 String blockName = e.getKey();
124 if (!key.startsWith(blockName + ".")) {
125 continue;
126 }
127
128 String prefix = blockName + "." + e.getValue() + ".";
129 if (key.startsWith(prefix)) {
130 String subkey = key.substring(prefix.length());
131 ConditionalBlockMatch match = resolveConditionalBlockMatch(subkey);
132 if (match == null) {
133 match = new ConditionalBlockMatch(subkey);
134 }
135 return match;
136 } else {
137 return new ConditionalBlockMatch(null);
138 }
139 }
140
141 return null;
142 }
143
144 private static class ConditionalBlockMatch {
145 public final String key;
146
147 private ConditionalBlockMatch(String key) {
148 this.key = key;
149 }
150 }
151 }
|