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