/* * Copyright 2008-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package griffon.util; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Enumeration; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.ResourceBundle; import static griffon.util.ConfigUtils.getConfigValue; import static griffon.util.GriffonNameUtils.requireNonBlank; import static java.util.Objects.requireNonNull; /** * @author Andres Almiray * @since 2.0.0 */ public class ExpandableResourceBundle extends ResourceBundle { private final Map<String, Object> entries = new LinkedHashMap<>(); @Nonnull public static ResourceBundle wrapResourceBundle(@Nonnull ResourceBundle resourceBundle) { requireNonNull(resourceBundle, "Argument 'resourceBundle' must not be null"); if (!(resourceBundle instanceof ExpandableResourceBundle)) { return new ExpandableResourceBundle(resourceBundle); } return resourceBundle; } public ExpandableResourceBundle(@Nonnull ResourceBundle delegate) { requireNonNull(delegate, "Argument 'delegate' must not be null"); for (String key : delegate.keySet()) { Object value = getConfigValue(delegate, key); processKey(key, entries, value); entries.put(key, value); } } @SuppressWarnings("unchecked") private void processKey(@Nonnull String key, @Nonnull Map<String, Object> map, @Nullable Object value) { String[] keys = split(key); if (keys[1] == null) { map.put(keys[0], value); } else { Map<String, Object> m = (Map<String, Object>) map.get(keys[0]); if (m == null) { m = new LinkedHashMap<>(); map.put(keys[0], m); } processKey(keys[1], m, value); } } @Nonnull private String[] split(@Nonnull String input) { int split = input.indexOf("."); String head = split < 0 ? input : input.substring(0, split); String tail = split > 0 ? input.substring(split + 1) : null; return new String[]{head, tail}; } @Nullable @Override protected final Object handleGetObject(@Nonnull String key) { return entries.get(requireNonBlank(key, "Argument 'key' must not be blank")); } @Nonnull @Override public final Enumeration<String> getKeys() { return new IteratorAsEnumeration<>(entries.keySet().iterator()); } private static class IteratorAsEnumeration<E> implements Enumeration<E> { private final Iterator<E> iterator; public IteratorAsEnumeration(Iterator<E> iterator) { this.iterator = iterator; } public boolean hasMoreElements() { return iterator.hasNext(); } public E nextElement() { return iterator.next(); } } }