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