View Javadoc

1   /* ==========================================================================
2    * Copyright 2003-2004 Mevenide Team
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   * =========================================================================
16   */
17  package org.mevenide.idea;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.text.MessageFormat;
22  import java.util.*;
23  import org.apache.commons.io.IOUtils;
24  import org.apache.commons.lang.StringUtils;
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  
28  /***
29   * Loads UTF-8 resources from resource bundles.
30   *
31   * <p>This is an enhancement over the standard java.util.ResourceBundle class which allows
32   * providing additional properties to the message (for inline place holders) as well as
33   * supporting hierarchical bundles.</p>
34   *
35   * @author Arik
36   */
37  public final class Res {
38      private static final Object LOCK = new Object();
39      private static final Log LOG = LogFactory.getLog(Res.class);
40      private static final String UNKNOWN_KEY = "(unknown resource key)";
41  
42      private static final Map<String, Res> cache = Collections.synchronizedMap(new HashMap<String, Res>(
43          10));
44  
45      privateong> final String packageName;
46      private final String bundleName;
47      private final Res parent;
48      private final ResourceBundle bundle;
49      private static final String DEFAULT_BUNDLE_NAME = "res";
50  
51      private Res(final String pPackageName,
52                  final String pBundleName,
53                  final Res pParent,
54                  final ResourceBundle pBundle) {
55          if (pPackageName != null && pPackageName.trim().length() == 0)
56              packageName = null;
57          else
58              packageName = pPackageName;
59          bundleName = pBundleName;
60          bundle = pBundle;
61          parent = pParent;
62      }
63  
64      public String getPackageName() {
65          return</strong> packageName;
66      }
67  
68      public String getBundleName() {
69          return bundleName;
70      }
71  
72      public String getName() {
73          return</strong> buildBundleName(packageName, bundleName);
74      }
75  
76      public Res getParent() {
77          return parent;
78      }
79  
80      public ResourceBundle getBundle() {
81          return bundle;
82      }
83  
84      public String getResource(final String pResourceName) {
85          final String res;
86          if</strong> (packageName != null) {
87              String lPackageName = packageName.replace('.', '/');
88              if (!lPackageName.endsWith("/"))
89                  lPackageName = lPackageName + "/";
90              res = lPackageName + pResourceName;
91          }
92          else
93              res = pResourceName;
94  
95          final ClassLoader cl = Thread.currentThread().getContextClassLoader();
96          final InputStream is = cl.getResourceAsStream(res);
97          if (is == null)
98              throw new MissingResourceException(
99                  "Can't find resource '" + res + "'", "", "");
100 
101         try {
102             return IOUtils.toString(is, "UTF-8");
103         }
104         catch (IOException e) {
105             final MissingResourceException exc = new MissingResourceException(
106                 "Error reading resource '" + res + "'", "", "");
107             throw (MissingResourceException) exc.initCause(e);
108         }
109         finally {
110             IOUtils.closeQuietly(is);
111         }
112     }
113 
114     public String get(final String pKey, final Object... pArguments) {
115         if (pKey == null) {
116             LOG.warn("null key has been passed for bundle '" + bundleName + "'");
117             return UNKNOWN_KEY;
118         }
119 
120         try {
121             String msg = bundle.getString(pKey);
122             if (msg == null || msg.trim().length() == 0)
123                 return "";
124             else {
125                 msg = StringUtils.replace(msg, "${", "'${'");
126                 msg = StringUtils.replace(msg, "'", "''");
127                 return MessageFormat.format(msg, pArguments);
128             }
129         }
130         catch (MissingResourceException e) {
131             if (parent == null)
132                 throw e;
133             return parent.get(pKey, pArguments);
134         }
135     }
136 
137     public Map getAll() {
138         final Enumeration<String> keys = bundle.getKeys();
139         final Map<String, String> all = new HashMap<String, String>();
140 
141         while (keys.hasMoreElements()) {
142             final String key = keys.nextElement();
143             all.put(key, get(key));
144         }
145 
146         return all;
147     }
148 
149     public static Res getInstance(final Class pClass) {
150         return getInstance(pClass, DEFAULT_BUNDLE_NAME);
151     }
152 
153     public static Res getInstance(final Class pClass, final String pBundleName) {
154         return getInstance(pClass.getPackage().getName(), pBundleName);
155     }
156 
157     public static Res getInstance(final String pPackageName) {
158         return getInstance(pPackageName, DEFAULT_BUNDLE_NAME);
159     }
160 
161     public static Res getInstance(final String pPackageName,
162                                   final String pBundleName) {
163 
164         synchronized (LOCK) {
165             return getRes(pPackageName, pBundleName);
166         }
167     }
168 
169     static Res getRes(final String pPackageName,
170                       final String pBundleName) {
171 
172 
173         //find the ResourceBundle for the given base bundleName
174         String packageName = pPackageName;
175         String baseName;
176         baseName = buildBundleName(packageName, pBundleName);
177 
178         //if we have already searched for this res, return the cached instance
179         final Res cachedRes = cache.get(baseName);
180         if (cachedRes != null)
181             return cachedRes;
182 
183         //otherwise, start by searching for a resource bundle
184         ResourceBundle bundle = null;
185         while (bundle == null) {
186             try {
187                 bundle = ResourceBundle.getBundle(baseName);
188             }
189             catch (MissingResourceException e) {
190                 rong>if (packageName == null || packageName.trim().length() == 0)
191                     break;
192 
193                 g>final int lastDotIndex = packageName.lastIndexOf('.');
194                 if (lastDotIndex < 0) {
195                     packageName = null;
196                     baseName = pBundleName;
197                 }
198                 else {
199                     packageName = packageName.substring(0, lastDotIndex);
200                     baseName = packageName + "." + pBundleName;
201                 }
202             }
203         }
204 
205         if (bundle == null) {
206             throw new MissingResourceException(
207                 "Can't find bundle for base bundleName '" + baseName + "'",
208                 baseName,
209                 "");
210         }
211 
212         Res parent = null;
213         if (packageName != null && packageName.trim().length() > 0) {
214             int lastDotIndex = packageName.lastIndexOf('.');
215 
216             //we iterate while 'lastDotIndex' is > 0 and not >= 0. Since if it is 0
217             //there's no point to keep searcing anyway, and we subtract 1 from it
218             //so we better not do that.
219             while (parent == null && lastDotIndex > 0) {
220                 final String parentPackageName = pPackageName.substring(0, lastDotIndex);
221                 try {
222                     parent = getInstance(parentPackageName, pBundleName);
223                 }
224                 catch (MissingResourceException e) {
225                     lastDotIndex = pPackageName.lastIndexOf('.', lastDotIndex - 1);
226                 }
227             }
228         }
229 
230         final<Res res = new Res(packageName, pBundleName, parent, bundle)/package-summary.html">/strong> Res res = new Res(packageName, pBundleName, parent, bundle);
231 
232         //cache the new Res
233         cache.put(baseName, res);
234 
235         return res;
236     }
237 
238     protected static String buildBundleName(final String pPackageName,
239                                             final String pBundleName) {
240         final String baseName;
241         if (pPackageName == null || pPackageName.trim().length() == 0)
242             baseName = pBundleName;
243         else
244             baseName = pPackageName + "." + pBundleName;
245         return baseName;
246     }
247 }