EMMA Coverage Report (generated Sun Apr 20 22:38:01 CEST 2008)
[all classes][net.sf.jomic.tools]

COVERAGE SUMMARY FOR SOURCE FILE [LocaleTools.java]

nameclass, %method, %block, %line, %
LocaleTools.java100% (1/1)96%  (23/24)96%  (431/451)97%  (96.6/100)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class LocaleTools100% (1/1)96%  (23/24)96%  (431/451)97%  (96.6/100)
getBundle (): ResourceBundle 0%   (0/1)0%   (0/3)0%   (0/1)
propertyChange (PropertyChangeEvent): void 100% (1/1)76%  (19/25)75%  (6/8)
LocaleTools (): void 100% (1/1)84%  (31/37)96%  (6.7/7)
setLocaleHelper (Locale): void 100% (1/1)90%  (47/52)97%  (5.8/6)
asByteText (long): String 100% (1/1)100% (75/75)100% (10/10)
createButton (String): JButton 100% (1/1)100% (10/10)100% (3/3)
createButtonWithLabel (String): JButton 100% (1/1)100% (7/7)100% (2/2)
createCancelButton (): JButton 100% (1/1)100% (5/5)100% (1/1)
createMenu (String): JMenu 100% (1/1)100% (11/11)100% (3/3)
createMenuItem (String, String): JMenuItem 100% (1/1)100% (12/12)100% (3/3)
createRadioButtonMenuItem (String, ButtonGroup, String): JRadioButtonMenuItem 100% (1/1)100% (15/15)100% (4/4)
getCancelText (): String 100% (1/1)100% (3/3)100% (1/1)
getLocale (): Locale 100% (1/1)100% (3/3)100% (1/1)
getLocaleForLanguageCountryVariant (String): Locale 100% (1/1)100% (19/19)100% (3/3)
getMenuItemLabel (String, String): String 100% (1/1)100% (15/15)100% (1/1)
getMenuLabel (String): String 100% (1/1)100% (11/11)100% (1/1)
getMessage (String): String 100% (1/1)100% (5/5)100% (1/1)
getMessage (String, Object []): String 100% (1/1)100% (25/25)100% (7/7)
getMessage (String, Object): String 100% (1/1)100% (12/12)100% (2/2)
getOkText (): String 100% (1/1)100% (3/3)100% (1/1)
instance (): LocaleTools 100% (1/1)100% (8/8)100% (3/3)
parseLanguageCountryVariant (String): String [] 100% (1/1)100% (83/83)100% (26/26)
setLocale (Locale): void 100% (1/1)100% (4/4)100% (2/2)
setLocale (String): void 100% (1/1)100% (8/8)100% (3/3)

1// Jomic - a viewer for comic book archives.
2// Copyright (C) 2004-2008 Thomas Aglassinger
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16package net.sf.jomic.tools;
17 
18import java.beans.PropertyChangeEvent;
19import java.beans.PropertyChangeListener;
20import java.text.DecimalFormat;
21import java.text.MessageFormat;
22import java.text.NumberFormat;
23import java.util.Locale;
24import java.util.ResourceBundle;
25import java.util.StringTokenizer;
26 
27import javax.swing.ButtonGroup;
28import javax.swing.JButton;
29import javax.swing.JMenu;
30import javax.swing.JMenuItem;
31import javax.swing.JRadioButtonMenuItem;
32import javax.swing.UIManager;
33 
34import net.sf.jomic.common.PropertyConstants;
35import net.sf.wraplog.Logger;
36 
37/**
38 *  Tools for localization.
39 *
40 * @author    Thomas Aglassinger
41 */
42public final class LocaleTools implements PropertyChangeListener
43{
44    public static final String MENU_EDIT = "edit";
45    public static final String MENU_FILE = "file";
46    public static final String MENU_GO = "go";
47    public static final String MENU_HELP = "help";
48    public static final String MENU_VIEW = "view";
49 
50    /**
51     *  "1000" in terms of base 2.
52     */
53    private static final int BASE2_KILO = 1024;
54    private static final int LOCALE_ELEMENT_COUNT = 3;
55 
56    private static /*@ spec_public nullable @*/ LocaleTools instance;
57    private Logger logger = Logger.getLogger(LocaleTools.class);
58    private /*@ spec_public @*/ ResourceBundle bundle;
59    private NumberFormat byteFormat;
60    private ErrorTools errorTools;
61    private /*@ spec_public @*/ Locale locale;
62 
63    private LocaleTools() {
64        logger = Logger.getLogger(LocaleTools.class);
65        errorTools = ErrorTools.instance();
66        setLocaleHelper(Locale.getDefault());
67        byteFormat = new DecimalFormat("0.##");
68    }
69 
70    /**
71     *  Set Locale to use with Jomic.
72     */
73    //@ assignable bundle;
74    //@ assignable locale;
75    //@ ensures getLocale().equals(newLocale);
76    public void setLocale(Locale newLocale) {
77        setLocaleHelper(newLocale);
78    }
79 
80    /**
81     *  Set Locale to use with Jomic.
82     */
83    //@ assignable bundle;
84    //@ assignable locale;
85    public void setLocale(String displayName) {
86        Locale newLocale = getLocaleForLanguageCountryVariant(displayName);
87 
88        setLocale(newLocale);
89    }
90 
91    /**
92     *  Get ResourceBundle for localization.
93     */
94    public /*@ pure @*/ ResourceBundle getBundle() {
95        return bundle;
96    }
97 
98    /**
99     *  Get text to be used for "Cancel" buttons.
100     */
101    public /*@ pure @*/ String getCancelText() {
102        return UIManager.getString("OptionPane.cancelButtonText");
103    }
104 
105    public /*@ pure @*/ Locale getLocale() {
106        return locale;
107    }
108 
109    /**
110     *  Get locale specified by <code>languageCountryVariant</code>.
111     *
112     * @param  languageCountryVariant  text of the form "language_region_variant", for example "en"
113     *      or "de_AT"
114     */
115    public /*@ pure @*/ Locale getLocaleForLanguageCountryVariant(String languageCountryVariant) {
116        Locale result;
117        String[] strings = parseLanguageCountryVariant(languageCountryVariant);
118 
119        //@ assert strings.length == LOCALE_ELEMENT_COUNT;
120        result = new Locale(strings[0], strings[1], strings[2]);
121        return result;
122    }
123 
124    public /*@ pure @*/ String getMenuItemLabel(String subMenu, String itemKey) {
125        return getMessage("menus." + subMenu + "." + itemKey);
126    }
127 
128    public /*@ pure @*/ String getMenuLabel(String menuKey) {
129        return getMessage("menus." + menuKey);
130    }
131 
132    /**
133     *  Get localized message (without options).
134     */
135    //@ requires key.length() > 0;
136    public /*@ pure @*/ String getMessage(String key) {
137        return getMessage(key, null);
138    }
139 
140    /**
141     *  Get localized message with several options referred to as {0}, {1}, and so on.
142     */
143    //@ requires key.length() > 0;
144    public /*@ pure @*/ String getMessage(String key, /*@ nullable @*/ Object[] options) {
145        String result;
146        String pattern = bundle.getString(key);
147 
148        if (options == null) {
149            result = pattern;
150        } else {
151            MessageFormat messageFormat = new MessageFormat(pattern);
152            messageFormat.setLocale(getLocale());
153            result = messageFormat.format(options);
154        }
155        return result;
156    }
157 
158    /**
159     *  Get localized message with one option referred to as {0}.
160     */
161    //@ requires key.length() > 0;
162    public /*@ pure @*/ String getMessage(String key, /*@ nullable @*/ Object option) {
163        Object[] options = new Object[]{option};
164 
165        return getMessage(key, options);
166    }
167 
168    /**
169     *  Get text to be used for "OK" buttons.
170     */
171    public /*@ pure @*/ String getOkText() {
172        return UIManager.getString("OptionPane.okButtonText");
173    }
174 
175    //@ ensures instance != null;
176    public static synchronized LocaleTools instance() {
177        if (instance == null) {
178            instance = new LocaleTools();
179        }
180        return instance;
181    }
182 
183    //@ requires amount >= 0;
184    public /*@ pure @*/ String asByteText(long amount) {
185        String result;
186        String[] units = new String[]{"byte", "kilobyte", "megabyte", "gigabyte", "terabyte", "petabyte", "exabyte"};
187        int unitIndex = -1;
188        long unitDivider = 1;
189        double dividedAmount;
190 
191        do {
192            dividedAmount = ((double) amount) / unitDivider;
193            unitDivider *= BASE2_KILO;
194            unitIndex += 1;
195        } while ((dividedAmount >= BASE2_KILO) && (unitIndex < units.length));
196 
197        String amountText = byteFormat.format(dividedAmount);
198 
199        result = getMessage("units." + units[unitIndex], amountText);
200        return result;
201    }
202 
203    public /*@ pure @*/ JButton createButton(String buttonKey) {
204        String label = getMessage(buttonKey);
205        JButton result = createButtonWithLabel(label);
206 
207        return result;
208    }
209 
210    public /*@ pure @*/ JButton createCancelButton() {
211        return createButtonWithLabel(getCancelText());
212    }
213 
214    public /*@ pure @*/ JMenu createMenu(String menuKey) {
215        String label = getMenuLabel(menuKey);
216        JMenu result = new JMenu(label);
217 
218        return result;
219    }
220 
221    public /*@ pure @*/ JMenuItem createMenuItem(String subMenu, String itemKey) {
222        String label = getMenuItemLabel(subMenu, itemKey);
223        JMenuItem result = new JMenuItem(label);
224 
225        return result;
226    }
227 
228    public JRadioButtonMenuItem createRadioButtonMenuItem(String subMenu, ButtonGroup group, String itemKey) {
229        String label = getMenuItemLabel(subMenu, itemKey);
230        JRadioButtonMenuItem result = new JRadioButtonMenuItem(label);
231 
232        group.add(result);
233 
234        return result;
235    }
236 
237    /**
238     *  Parse a string of the form "language_country_variant" (with any of the elements being
239     *  optional), and return an array containing the elements. If no element has been specified, it
240     *  will be empty (<code>""</code>).
241     *
242     * @param  languageCountryVariant  of the form "language_region_variant", for example "en" or
243     *      "de_AT", or <code>null</code> to indicate the default Locale.
244     */
245    //@ signals_only IllegalArgumentException;
246    //@ ensures \nonnullelements(\result);
247    public /*@ pure @*/ String[] parseLanguageCountryVariant(/*@ nullable @*/ String languageCountryVariant) {
248        String[] result = new String[LOCALE_ELEMENT_COUNT];
249        String localeText;
250 
251        if (languageCountryVariant == null) {
252            localeText = Locale.getDefault().toString();
253        } else {
254            localeText = languageCountryVariant;
255        }
256 
257        String language = "";
258        String country = "";
259        String variant = "";
260        int wordIndex = 0;
261        StringTokenizer tokenizer = new StringTokenizer(localeText, "_", true);
262 
263        while (tokenizer.hasMoreTokens()) {
264            String token = tokenizer.nextToken();
265 
266            if (token.equals("_")) {
267                wordIndex += 1;
268                if (wordIndex == LOCALE_ELEMENT_COUNT) {
269                    // English message because we cannot expect the localization bundle to be loaded yet.
270                    throw new IllegalArgumentException(
271                            "locale specification must contain at most 2 underscores (_), but is: "
272                            + languageCountryVariant);
273                }
274            } else if (wordIndex == 0) {
275                language = token;
276            } else if (wordIndex == 1) {
277                country = token;
278            } else if (wordIndex == 2) {
279                variant = token;
280            }
281        }
282        result[0] = language;
283        result[1] = country;
284        result[2] = variant;
285        return result;
286    }
287 
288    //@ also
289    //@   requires event.getPropertyName() != null;
290    public void propertyChange(PropertyChangeEvent event) {
291        try {
292            String propertyName = event.getPropertyName();
293 
294            if (propertyName.equals(PropertyConstants.LOCALE)) {
295                String localeText = (String) event.getNewValue();
296 
297                setLocale(new Locale(localeText));
298            }
299        } catch (Throwable error) {
300            errorTools.showError(event, error);
301        }
302    }
303 
304    private /*@ pure @*/ JButton createButtonWithLabel(String label) {
305        JButton result = new JButton(label);
306 
307        return result;
308    }
309 
310    //@ assignable bundle;
311    //@ assignable locale;
312    private /*@ helper @*/ void setLocaleHelper(Locale newLocale) {
313        if (logger.isInfoEnabled()) {
314            logger.info("setting locale to " + newLocale.toString()
315                    + " (" + newLocale.getDisplayName(Locale.ENGLISH) + ")");
316        }
317        Locale.setDefault(newLocale);
318        locale = newLocale;
319        bundle = ResourceBundle.getBundle(LocaleTools.class.getPackage().getName() + ".bundle", locale);
320    }
321}

[all classes][net.sf.jomic.tools]
EMMA 2.0.4217 (C) Vladimir Roubtsov