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