View Javadoc
1   /*
2    * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package com.sun.istack.internal.localization;
27  
28  import java.text.MessageFormat;
29  import java.util.HashMap;
30  import java.util.Locale;
31  import java.util.MissingResourceException;
32  import java.util.ResourceBundle;
33  
34  /**
35   * Localizes the {@link Localizable} into a message
36   * by using a configured {@link Locale}.
37   *
38   * @author WS Development Team
39   */
40  public class Localizer {
41  
42      private final Locale _locale;
43      private final HashMap _resourceBundles;
44  
45      public Localizer() {
46          this(Locale.getDefault());
47      }
48  
49      public Localizer(Locale l) {
50          _locale = l;
51          _resourceBundles = new HashMap();
52      }
53  
54      public Locale getLocale() {
55          return _locale;
56      }
57  
58      public String localize(Localizable l) {
59          String key = l.getKey();
60          if (key == Localizable.NOT_LOCALIZABLE) {
61              // this message is not localizable
62              return (String) l.getArguments()[0];
63          }
64          String bundlename = l.getResourceBundleName();
65  
66          try {
67              ResourceBundle bundle =
68                  (ResourceBundle) _resourceBundles.get(bundlename);
69  
70              if (bundle == null) {
71                  try {
72                      bundle = ResourceBundle.getBundle(bundlename, _locale);
73                  } catch (MissingResourceException e) {
74                      // work around a bug in the com.sun.enterprise.deployment.WebBundleArchivist:
75                      //   all files with an extension different from .class (hence all the .properties files)
76                      //   get copied to the top level directory instead of being in the package where they
77                      //   are defined
78                      // so, since we can't find the bundle under its proper name, we look for it under
79                      //   the top-level package
80  
81                      int i = bundlename.lastIndexOf('.');
82                      if (i != -1) {
83                          String alternateBundleName =
84                              bundlename.substring(i + 1);
85                          try {
86                              bundle =
87                                  ResourceBundle.getBundle(
88                                      alternateBundleName,
89                                      _locale);
90                          } catch (MissingResourceException e2) {
91                              //try context classloader
92                              try {
93                                  bundle = ResourceBundle.getBundle(bundlename, _locale, Thread.currentThread().getContextClassLoader());
94                              } catch (MissingResourceException e3) {
95                                  // give up
96                                  return getDefaultMessage(l);
97                              }
98  
99                          }
100                     }
101                 }
102 
103                 _resourceBundles.put(bundlename, bundle);
104             }
105 
106             if (bundle == null) {
107                 return getDefaultMessage(l);
108             }
109 
110             if (key == null)
111                 key = "undefined";
112 
113             String msg;
114             try {
115                 msg = bundle.getString(key);
116             } catch (MissingResourceException e) {
117                 // notice that this may throw a MissingResourceException of its own (caught below)
118                 msg = bundle.getString("undefined");
119             }
120 
121             // localize all arguments to the given localizable object
122             Object[] args = l.getArguments();
123             for (int i = 0; i < args.length; ++i) {
124                 if (args[i] instanceof Localizable)
125                     args[i] = localize((Localizable) args[i]);
126             }
127 
128             String message = MessageFormat.format(msg, args);
129             return message;
130 
131         } catch (MissingResourceException e) {
132             return getDefaultMessage(l);
133         }
134 
135     }
136 
137     private String getDefaultMessage(Localizable l) {
138         String key = l.getKey();
139         Object[] args = l.getArguments();
140         StringBuilder sb = new StringBuilder();
141         sb.append("[failed to localize] ");
142         sb.append(key);
143         if (args != null) {
144             sb.append('(');
145             for (int i = 0; i < args.length; ++i) {
146                 if (i != 0)
147                     sb.append(", ");
148                 sb.append(String.valueOf(args[i]));
149             }
150             sb.append(')');
151         }
152         return sb.toString();
153     }
154 
155 }