EMMA Coverage Report (generated Sat Oct 08 11:41:37 CEST 2011)
[all classes][net.sf.jomic.tools]

COVERAGE SUMMARY FOR SOURCE FILE [LocaleTools.java]

nameclass, %method, %block, %line, %
LocaleTools.java100% (1/1)96%  (23/24)97%  (425/440)97%  (95.8/99)

COVERAGE BREAKDOWN BY CLASS AND METHOD

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

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