Package com.bbn.openmap

Source Code of com.bbn.openmap.BasicI18n

// **********************************************************************
//
// <copyright>
//
//  BBN Technologies
//  10 Moulton Street
//  Cambridge, MA 02138
//  (617) 873-8000
//
//  Copyright (C) BBNT Solutions LLC. All rights reserved.
//
// </copyright>
// **********************************************************************
//
// $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/BasicI18n.java,v $
// $RCSfile: BasicI18n.java,v $
// $Revision: 1.3.2.3 $
// $Date: 2005/07/29 14:43:14 $
// $Author: dietrick $
//
// **********************************************************************

package com.bbn.openmap;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;

import com.bbn.openmap.util.Debug;
import com.bbn.openmap.util.FileUtils;

/**
* Basic implementation of internationalization support.
* <P>
* This class backs the I18n interface by I18n.property files that it
* expects to find in each package.
* <P>
* This class provides a mechanism for creating the I18n.property
* files that it expects to use in the application. If the
* 'i18n.create' flag is set in the Debug class, then this class will
* track what resource bundle property files were searched for, and
* what values were returned for requested keys. The
* dumpCreatedResourceBundles() method will cause the resource bundles
* to be written out, where they can be modified to change the strings
* displayed in the GUI. If the 'i18n.default' flag is set, then
* 'I18N.properties' files will be created. If that flag is not set,
* then the name of the files will be modified for the locale
* currently set for the application (i.e. I18N_en_US.properties for
* the US locale). You can add the I18nFileCreateMenuItem to an
* application to trigger the dumpCreatedResourceBundles() method.
*/
public class BasicI18n implements I18n, Serializable {

    /**
     * Debug string, 'i18n'
     */
    public static final String DEBUG = "i18n";

    /**
     * Debug string that causes the BasicI18n class to keep track of
     * resource property files and strings it looks for, as well as
     * their defaults. These files can be created by calling
     * dumpCreatedResourceBundles().
     */
    public static final String DEBUG_CREATE = "i18n.create";

    /**
     * If set, created ResourceBundle files will not have the local
     * suffixes added to them. Otherwise, the locale set in I18n will
     * be used and appended.
     */
    public static final String DEBUG_CREATE_DEFAULT = "i18n.default";

    /**
     * All properties files containing string should be contained in a
     * file called I18N.properties. This string defines the I18N.
     */
    public static final String ResourceFileNamePrefix = "I18N";

    private Locale loc;

    protected transient Hashtable createHash = null;

    // Constructors:
    // /////////////

    /**
     * Create a BasicI18n object from the default locale.
     */
    public BasicI18n() {
        this(Locale.getDefault());
    }

    /**
     * Create a BasicI18n object with given locale.
     */
    public BasicI18n(Locale loc) {
        this.loc = loc;
    }

    public String get(Object requestor, String field, String defaultString) {
        return get(requestor, field, TEXT, defaultString);
    }

    public String get(Object requestor, String field, int type,
                      String defaultString) {
        return get(requestor.getClass(), field, type, defaultString);
    }

    public String get(Class requestor, String field, String defaultString) {
        return get(requestor, field, TEXT, defaultString);
    }

    public String get(Class requestor, String field, int type,
                      String defaultString) {
        String ret = getInternal(requestor, field, type);

        if (Debug.debugging(DEBUG_CREATE)) {
            setForBundleCreation(requestor, field, type, defaultString);
        }

        if (ret == null) {
            return defaultString;
        }
        return ret;
    }

    protected Hashtable getCreateHash() {
        if (createHash == null) {
            createHash = new Hashtable();
        }
        return createHash;
    }

    // Methods making it easier to use MessageFormat:
    // //////////////////////////////////////////////

    public String get(Object requestor, String field, String defaultString,
                      Object param1) {
        return get(requestor.getClass(),
                field,
                TEXT,
                defaultString,
                new Object[] { param1 });
    }

    public String get(Object requestor, String field, int type,
                      String defaultString, Object param1) {
        return get(requestor.getClass(),
                field,
                type,
                defaultString,
                new Object[] { param1 });
    }

    public String get(Class requestor, String field, String defaultString,
                      Object param1) {
        return get(requestor,
                field,
                TEXT,
                defaultString,
                new Object[] { param1 });
    }

    public String get(Class requestor, String field, int type,
                      String defaultString, Object param1) {
        return get(requestor,
                field,
                type,
                defaultString,
                new Object[] { param1 });
    }

    public String get(Object requestor, String field, String defaultString,
                      Object param1, Object param2) {
        return get(requestor.getClass(),
                field,
                TEXT,
                defaultString,
                new Object[] { param1, param2 });
    }

    public String get(Object requestor, String field, int type,
                      String defaultString, Object param1, Object param2) {
        return get(requestor.getClass(),
                field,
                type,
                defaultString,
                new Object[] { param1, param2 });
    }

    public String get(Class requestor, String field, String defaultString,
                      Object param1, Object param2) {
        return get(requestor, field, TEXT, defaultString, new Object[] {
                param1, param2 });
    }

    public String get(Class requestor, String field, int type,
                      String defaultString, Object param1, Object param2) {
        return get(requestor, field, type, defaultString, new Object[] {
                param1, param2 });
    }

    public String get(Object requestor, String field, String defaultString,
                      Object[] params) {
        return get(requestor.getClass(), field, TEXT, defaultString, params);
    }

    public String get(Object requestor, String field, int type,
                      String defaultString, Object[] params) {
        return get(requestor.getClass(), field, type, defaultString, params);
    }

    public String get(Class requestor, String field, String defaultString,
                      Object[] params) {
        return get(requestor, field, TEXT, defaultString, params);
    }

    public String get(Class requestor, String field, int type,
                      String defaultString, Object[] params) {
        return MessageFormat.format(get(requestor, field, type, defaultString),
                params);
    }

    // Methods fill setting the textual properties of common Swing
    // components:
    // ///////////////////////////////////////////////////////////////////////

    public void set(Object requestor, String field, JLabel comp) {
        set(requestor, field, (JComponent) comp);
        comp.setText(getTEXT(requestor, field, comp.getText()));
        comp.setDisplayedMnemonic(getMNEMONIC(requestor,
                field,
                comp.getDisplayedMnemonic(),
                false));
    }

    public void set(Object requestor, String field, JButton comp) {
        set(requestor, field, (JComponent) comp);
        comp.setText(getTEXT(requestor, field, comp.getText()));
        comp.setMnemonic(getMNEMONIC(requestor,
                field,
                comp.getMnemonic(),
                false));
    }

    public void set(Object requestor, String field, JMenu comp) {
        set(requestor, field, (JComponent) comp);
        comp.setText(getTEXT(requestor, field, comp.getText()));
        comp.setMnemonic(getMNEMONIC(requestor, field, comp.getMnemonic(), true));
    }

    public void set(Object requestor, String field, JMenuItem comp) {
        set(requestor, field, (JComponent) comp);
        comp.setText(getTEXT(requestor, field, comp.getText()));
        comp.setMnemonic(getMNEMONIC(requestor, field, comp.getMnemonic(), true));
    }

    public void set(Object requestor, String field, JDialog comp) {
        comp.setTitle(getTITLE(requestor, field, comp.getTitle()));
    }

    public void set(Object requestor, String field, JFrame comp) {
        comp.setTitle(getTITLE(requestor, field, comp.getTitle()));
    }

    public void set(Object requestor, String field, JComponent comp) {
        setTOOLTIP(requestor, field, comp);
        Border b = comp.getBorder();
        if (b instanceof TitledBorder) {
            TitledBorder t = (TitledBorder) b;
            t.setTitle(getTITLE(requestor, field, t.getTitle()));
        }
    }

    // Methods for filling in strings using reflection:
    // ////////////////////////////////////////////////

    public void set(Object requestor, String field) {
        Class c = requestor.getClass();
        Field f = null;
        try {
            f = c.getField(field);
        } catch (NoSuchFieldException e) {
            // We'll try again below.
        } catch (SecurityException e) {
            RuntimeException r = new MissingResourceException("SecurityException trying to reflect on field field", c.getName(), field);
            r.initCause(e);
            throw r;
        }
        if (f == null) {
            try {
                f = c.getDeclaredField(field);
            } catch (NoSuchFieldException e) {
                RuntimeException r = new MissingResourceException("Can't find field via reflection", c.getName(), field);
                r.initCause(e);
                throw r;
            } catch (SecurityException e) {
                RuntimeException r = new MissingResourceException("SecurityException trying to reflect on field field", c.getName(), field);
                r.initCause(e);
                throw r;
            }
        }
        // Try to set it accessible:
        try {
            f.setAccessible(true);
        } catch (SecurityException e) {
            Debug.message(DEBUG, "Coudn't set field " + field + " accessible");
        }
        // Ok, now try to get the data:
        Class type = f.getType();
        Object fd = null;
        try {
            fd = f.get(requestor);
        } catch (IllegalArgumentException e) {
            RuntimeException r = new MissingResourceException("Couldn't get field", c.getName(), field);
            r.initCause(e);
            throw r;
        } catch (IllegalAccessException e) {
            RuntimeException r = new MissingResourceException("Couldn't access field", c.getName(), field);
            r.initCause(e);
            throw r;
        }
        // Now do the calls:
        if (JLabel.class.isInstance(type)) {
            set(requestor, field, (JLabel) fd);
        } else if (JButton.class.isInstance(type)) {
            set(requestor, field, (JButton) fd);
        } else if (JMenu.class.isInstance(type)) {
            set(requestor, field, (JMenu) fd);
        } else if (JMenuItem.class.isInstance(type)) {
            set(requestor, field, (JMenuItem) fd);
        } else if (JDialog.class.isInstance(type)) {
            set(requestor, field, (JDialog) fd);
        } else if (JFrame.class.isInstance(type)) {
            set(requestor, field, (JFrame) fd);
        } else if (JComponent.class.isInstance(type)) {
            set(requestor, field, (JComponent) fd);
        } else {
            Debug.message(DEBUG, "Couldn't assign data for unknown type: "
                    + type);
        }
    }

    public void fill(Object requestor) {

    }

    // //
    // // Implemenation Methods:
    // /////////////////////////
    // /////////////////////////

    /**
     * Set a tooltip on the given component if it has one.
     */
    protected void setTOOLTIP(Object requestor, String field, JComponent comp) {
        String tooltip = get(requestor, field, TOOLTIP, comp.getToolTipText());
        if (tooltip != null) {
            comp.setToolTipText(tooltip);
        } else {
            Debug.message(DEBUG, "No tooltip for: "
                    + getKeyRef(requestor, field));
        }
    }

    /**
     * Get text for the given component.
     */
    protected String getTEXT(Object requestor, String field,
                             String defaultString) {
        String text = get(requestor, field, TEXT, defaultString);
        if (text == null) {
            throw new MissingResourceException("No TEXT resource", requestor.getClass()
                    .getName(), field);
        }
        return text;
    }

    /**
     * Get title for the given component.
     */
    protected String getTITLE(Object requestor, String field,
                              String defaultString) {
        String title = get(requestor, field, TITLE, defaultString);
        if (title == null) {
            throw new MissingResourceException("No TITLE resource", requestor.getClass()
                    .getName(), field);
        }
        return title;
    }

    /**
     * Get text for the given component.
     */
    protected int getMNEMONIC(Object requestor, String field, int defaultInt,
                              boolean verbose) {
        String mn = get(requestor,
                field,
                MNEMONIC,
                Character.toString((char) defaultInt));
        if (mn == null) {
            if (verbose) {
                Debug.message(DEBUG, "No MNEMONIC resource for "
                        + getKeyRef(requestor, field));
            }
            return defaultInt;
        }
        // Now parse this string into something useful:
        // For now, don't deal with virtual keys, though that is an
        // obvious
        // extension:
        return Character.getNumericValue(mn.charAt(0));
    }

    /**
     * Obtain a String from the underlying data for the given
     * class/field/type.
     *
     * @return null if the data can't be found -- defaulting happens
     *         above here.
     */
    protected String getInternal(Class requestor, String field, int type) {
        ResourceBundle bundle = null;
        Package pckg = requestor.getPackage();

        String bString = (pckg == null ? ""
                : (requestor.getPackage().getName() + "."))
                + ResourceFileNamePrefix;

        try {
            bundle = ResourceBundle.getBundle(bString, loc);
        } catch (MissingResourceException e) {
            Debug.message(DEBUG, "Could not locate resource: "
                    + bString.replace('.', '/') + ".properties");
            return null;
        }

        String key = shortClassName(requestor) + "." + field;
        switch (type) {
        case TEXT:
            // Do nothing.
            break;
        case TITLE:
            key += ".title";
            break;
        case TOOLTIP:
            key += ".tooltip";
            break;
        case MNEMONIC:
            key += ".mnemonic";
            break;
        }

        try {

            return bundle.getString(key);

        } catch (MissingResourceException e) {

            Debug.message(DEBUG, "Could not locate string in resource: "
                    + (pckg == null ? "" : (requestor.getPackage().getName().replace('.', '/') + "."))
                    + "properties for key: " + key);

            return null;
        }
    }

    /**
     * Obtain a String from the underlying data for the given
     * class/field/type.
     *
     * @return null if the data can't be found -- defaulting happens
     *         above here.
     */
    protected void setForBundleCreation(Class requestor, String field,
                                        int type, String defaultString) {
        ResourceBundle bundle = null;

        Package pckg = requestor.getPackage();

        String bString = (pckg == null ? ""
                : (requestor.getPackage().getName() + "."))
                + ResourceFileNamePrefix;
       
        String propertyFileNameKey = null;
        Properties propertyFileProperties = null;

        // OK, first see what the property file should be.
        StringBuffer sbuf = new StringBuffer(bString.replace('.', '/'));
        // Scope the desired resource bundle property file if the
        // default isn't wanted.
        if (!Debug.debugging(DEBUG_CREATE_DEFAULT)) {
            sbuf.append("_" + loc.toString());
        }
        sbuf.append(".properties");
        propertyFileNameKey = sbuf.toString().intern();

        // See if we already have a properties file with the key-value
        // pairs for this particular resource bundle.
        propertyFileProperties = (Properties) getCreateHash().get(propertyFileNameKey);

        // If not, create it.
        if (propertyFileProperties == null) {
            propertyFileProperties = new Properties();
            getCreateHash().put(propertyFileNameKey, propertyFileProperties);
        }

        try {
            bundle = ResourceBundle.getBundle(bString, loc);
        } catch (MissingResourceException e) {
        }

        String resourceKey = shortClassName(requestor) + "." + field;
        switch (type) {
        case TEXT:
            // Do nothing.
            break;
        case TITLE:
            resourceKey += ".title";
            break;
        case TOOLTIP:
            resourceKey += ".tooltip";
            break;
        case MNEMONIC:
            resourceKey += ".mnemonic";
            break;
        }

        try {
            if (bundle != null) {
                String resourceValue = bundle.getString(resourceKey);
                propertyFileProperties.put(resourceKey, resourceValue);
            } else {
                propertyFileProperties.put(resourceKey, defaultString);
            }
        } catch (MissingResourceException e) {
            propertyFileProperties.put(resourceKey, defaultString);
        }
    }

    /**
     * If called, will bring up a JFileChooser so you can pick a
     * location to dump the resource files that were searched for,
     * with values that were found or the defaults provided in the
     * code. This will only do something if the BasicI18n class was
     * accessed with the 'i18n.create' flag set in the Debug class.
     */
    public void dumpCreatedResourceBundles() {
        String location = FileUtils.getFilePathToSaveFromUser("Choose Location");
        if (location != null) {
            dumpCreatedResourceBundles(location);
        }
    }

    /**
     * Will dump the resource bundle property files searched for by
     * this class, along with the contents that were returned or with
     * the defaults provided by the application.
     *
     * @param location directory location to use as the root for
     *        resource bundle file hierarchy.
     */
    public void dumpCreatedResourceBundles(String location) {
        Hashtable bundleHash = getCreateHash();
        for (Enumeration enumeration = bundleHash.keys(); enumeration.hasMoreElements();) {
            String key = (String) enumeration.nextElement();
            Properties props = (Properties) bundleHash.get(key);

            try {
                File propFile = new File(location + "/" + key);

                File parentDir = new File(propFile.getParent());
                parentDir.mkdirs();

                propFile.createNewFile();
                FileOutputStream fos = new FileOutputStream(propFile);
                props.store(fos, "I18N Resource File");
                fos.close();
            } catch (FileNotFoundException fnfe) {
                fnfe.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static String shortClassName(Class c) {
        String name = c.getName();
        return name.substring(name.lastIndexOf(".") + 1);
    }

    private static String getKeyRef(Object requestor, String field) {
        return requestor.getClass().getName() + "." + field;
    }
}
TOP

Related Classes of com.bbn.openmap.BasicI18n

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.