001 /*
002 * Copyright 2010-2013 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
017 package org.codehaus.griffon.runtime.util;
018
019 import griffon.util.ApplicationHolder;
020 import org.slf4j.Logger;
021 import org.slf4j.LoggerFactory;
022
023 import java.io.IOException;
024 import java.net.URL;
025 import java.util.*;
026
027 import static griffon.util.GriffonNameUtils.isBlank;
028
029 /**
030 * @author Andres Almiray
031 * @since 1.1.0
032 */
033 public class CompositeResourceBundle extends ResourceBundle {
034 private static final Logger LOG = LoggerFactory.getLogger(CompositeResourceBundle.class);
035 private final ResourceBundle[] bundles;
036 private final List<String> keys = new ArrayList<String>();
037
038 public static ResourceBundle create(String basename) {
039 return create(basename, Locale.getDefault());
040 }
041
042 public static ResourceBundle create(String basename, Locale locale) {
043 if (isBlank(basename)) {
044 throw new IllegalArgumentException("Cannot create CompositeResourceBundle with basename = '" + basename + "'");
045 }
046
047 String[] combinations = {
048 locale.getLanguage() + "_" + locale.getCountry() + "_" + locale.getVariant(),
049 locale.getLanguage() + "_" + locale.getCountry(),
050 locale.getLanguage()
051 };
052
053 List<ResourceBundle> bundles = new ArrayList<ResourceBundle>();
054 for (String suffix : combinations) {
055 if (suffix.endsWith("_")) continue;
056 bundles.addAll(loadBundleFromProperties(basename + "_" + suffix));
057 bundles.addAll(loadBundleFromScript(basename + "_" + suffix));
058 }
059 bundles.addAll(loadBundleFromProperties(basename));
060 bundles.addAll(loadBundleFromScript(basename));
061
062 return new CompositeResourceBundle(bundles);
063 }
064
065 private static Collection<ResourceBundle> loadBundleFromProperties(String fileName) {
066 List<ResourceBundle> bundles = new ArrayList<ResourceBundle>();
067 for (URL resource : ApplicationHolder.getApplication().getResources(fileName + ".properties")) {
068 if (null == resource) continue;
069 try {
070 bundles.add(new PropertyResourceBundle(resource.openStream()));
071 } catch (IOException e) {
072 // ignore
073 }
074 }
075 return bundles;
076 }
077
078 private static Collection<ResourceBundle> loadBundleFromScript(String fileName) {
079 List<ResourceBundle> bundles = new ArrayList<ResourceBundle>();
080 for (URL resource : ApplicationHolder.getApplication().getResources(fileName + ".groovy")) {
081 if (null == resource) continue;
082 bundles.add(new GroovyScriptResourceBundle(resource));
083 }
084 return bundles;
085 }
086
087 public CompositeResourceBundle(List<ResourceBundle> bundles) {
088 this(toResourceBundleArray(bundles));
089 }
090
091 public CompositeResourceBundle(ResourceBundle[] bundles) {
092 this.bundles = bundles;
093 for (ResourceBundle bundle : bundles) {
094 Enumeration<String> ks = bundle.getKeys();
095 while (ks.hasMoreElements()) {
096 String key = ks.nextElement();
097 if (!keys.contains(key)) {
098 keys.add(key);
099 }
100 }
101 }
102 }
103
104 protected Object handleGetObject(String key) {
105 if(LOG.isTraceEnabled()){
106 LOG.trace("Searching key=" + key);
107 }
108 for (ResourceBundle bundle : bundles) {
109 try {
110 Object value = bundle.getObject(key);
111 if(LOG.isTraceEnabled()) {
112 LOG.trace("Bundle " + bundle + "; key=" + key + "; value='" + value + "'");
113 }
114 if (value != null) {
115 return value;
116 }
117 } catch (Exception e) {
118 // ignore
119 }
120 }
121 return null;
122 }
123
124 @Override
125 public Enumeration<String> getKeys() {
126 return new IteratorAsEnumeration<String>(keys.iterator());
127 }
128
129 private static class IteratorAsEnumeration<E> implements Enumeration<E> {
130 private final Iterator<E> iterator;
131
132 public IteratorAsEnumeration(Iterator<E> iterator) {
133 this.iterator = iterator;
134 }
135
136 public boolean hasMoreElements() {
137 return iterator.hasNext();
138 }
139
140 public E nextElement() {
141 return iterator.next();
142 }
143 }
144
145 private static ResourceBundle[] toResourceBundleArray(List<ResourceBundle> bundles) {
146 if (null == bundles || bundles.isEmpty()) {
147 return new ResourceBundle[0];
148 }
149 return bundles.toArray(new ResourceBundle[bundles.size()]);
150 }
151 }
|