javacommons/utils/javasrc/com/nokia/mj/impl/utils/ResourceLoaderQt.java
author hgs
Fri, 15 Oct 2010 12:29:39 +0300
changeset 80 d6dafc5d983f
permissions -rw-r--r--
v2.2.19_1

/*
* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/


package com.nokia.mj.impl.utils;

import com.nokia.mj.impl.coreui.CoreUi;
import java.util.Hashtable;


/**
 * Resource loader to get localised strings and Formatter patterns.
 * <br>
 * Usage:
 * <pre>
 *   ResourceLoader res = ResourceLoader.getInstance("javaapplicationinstaller", "txt_java_inst_");
 *   Label subjectLabel = createLabel(
 *       res.format("subject").arg(certificate.getSubject()).toString(),
 *       horizontalSpan, labelStyle);
 * </pre>
 * @see ResourceLoader
 */
class ResourceLoaderQt extends ResourceLoader
{
    /**
     * Resource string map for the resources that have been fetched
     * at least once.
     */
    private Hashtable iResourceMap = new Hashtable();

    /** Resource name passed when ResourceLoader is constructed. */
    private String iResourceName = null;

    /** Array of resource names. */
    private String[] iResourceNames = null;

    /** Resource name prefix passed when ResourceLoader is constructed. */
    private String iPrefix = null;

    /** Array of resource name prefixes. */
    private String[] iPrefixes = null;

    /** Array of handles to native translator objects. */
    private int[] iTranslators = null;

    /*** ----------------------------- PUBLIC ------------------------------ */

    /**
     * Returns a resource loader instance.
     *
     * @param avkonFileName this parameter is ignored
     * @param avkonPrefix this parameter is ignored
     * @param qtFileName name of the Qt resource file
     * @param qtPrefix prefix added before each id when retrieving
     * @return resource loader instance
     */
    public static ResourceLoader getInstance(String avkonFileName,
                                             String avkonPrefix,
                                             String qtFileName,
                                             String qtPrefix)
    {
        return getInstance(qtFileName, qtPrefix);
    }

    /**
     * Returns a resource loader instance.
     *
     * @param resourceName comma separated list of resource file names
     * @param prefix comma separated list of prefixes added before each
     * id when retrieving
     * @return resource loader instance
     */
    public static ResourceLoader getInstance(String resourceName, String prefix)
    {
        String key = resourceName + ":" + prefix;
        ResourceLoader result = (ResourceLoader)iResourceLoaders.get(key);
        if (result == null)
        {
            result = new ResourceLoaderQt(resourceName, prefix);
            iResourceLoaders.put(key, result);
        }
        return result;
    }

    /**
     * Get a string formatter of a given resource id.
     *
     * @param id comma separated list of resource ids
     * @return formatter instance
     * @see Formatter
     */
    public Formatter format(String id)
    {
        return new FormatterQt(this, id);
    }

    /**
     * Get a string formatter of a given resource id.
     *
     * @param id resource id
     * @return formatter instance
     * @see Formatter
     */
    public Formatter format(Id id)
    {
        return new FormatterQt(this, id.getString(QT));
    }

    /**
     * Formats localised text with specified parameters from an array.
     *
     * @param id comma separated list of resource ids
     * @param textParameters parameters to be filled into the text
     * @return localised text formatted with the provided parameters
     * @see Formatter
     */
    public String format(String id, Object[] textParameters)
    {
        return new FormatterQt(this, id).format(textParameters);
    }

    /**
     * Formats localised text with specified parameters from an array.
     *
     * @param id resource id
     * @param textParameters parameters to be filled into the text
     * @return localised text formatted with the provided parameters
     * @see Formatter
     */
    public String format(Id id, Object[] textParameters)
    {
        return new FormatterQt(this, id.getString(QT)).format(textParameters);
    }


    /*** ----------------------------- PACKAGE ---------------------------- */

    /**
     * Releases resources and destroys this ResourceLoader instance.
     */
    void destroy()
    {
        deleteTranslators();
    }

    /**
     * Get a plain string resource with a given resource id.
     *
     * @param id resource id, either with prefix or without
     * @param n used to identify plural forms
     * @return resource string, or the id if does not exist
     */
    synchronized String string(final String id, final int n)
    {
        String str = (String)iResourceMap.get(id+n);
        if (str == null)
        {
            str = getResourceStringByList(id, n);
            // Put to resource map with original key for quick retrieval.
            iResourceMap.put(id, str+n);
        }
        return str;
    }

    /*** ----------------------------- PRIVATE ---------------------------- */

    /**
     * Creates resource loader, using the current locale of the environment.
     *
     * @param resourceName name of the resource
     * @param aPrefix prefix added before each id when retrieving
     */
    private ResourceLoaderQt(String aResourceName, String aPrefix)
    {
        setResourceName(aResourceName);
        setPrefix(aPrefix);
        if (!loadTranslators())
        {
            throw new IllegalArgumentException(
                "Translations not found for " + aResourceName);
        }
    }

    /**
     * Initializes member variables according to given resource name.
     *
     * @param aResourceName comma separated list of resource names
     */
    private void setResourceName(String aResourceName)
    {
        iResourceName = aResourceName;
        iResourceNames = Tokenizer.split(iResourceName, SEPARATOR);
        if (iResourceNames == null)
        {
            iResourceNames = new String[0];
        }
        for (int i = 0; i < iResourceNames.length; i++)
        {
            iResourceNames[i] = iResourceNames[i].trim();
        }
    }

    /**
     * Initializes member variables according to given prefix.
     *
     * @param aPrefix comma separated list of text id prefixes
     */
    private void setPrefix(String aPrefix)
    {
        iPrefix = aPrefix;
        iPrefixes = Tokenizer.split(iPrefix, SEPARATOR);
        if (iPrefixes == null)
        {
            iPrefixes = new String[0];
        }
        for (int i = 0; i < iPrefixes.length; i++)
        {
            iPrefixes[i] = iPrefixes[i].trim();
        }
    }

    /**
     * Initializes iTranslators array from given resource files.
     *
     * @param true if operation succeeds.
     */
    private boolean loadTranslators()
    {
        if (iResourceName == null)
        {
            return false;
        }
        iTranslators = new int[iResourceNames.length];
        CoreUi.runInSyncUiThread(new Runnable() {
            public void run()
            {
                for (int i = 0; i < iResourceNames.length; i++)
                {
                    iTranslators[i] = _createTranslator(iResourceNames[i]);
                    if (iTranslators[i] < 0)
                    {
                        Logger.ILOG(Logger.EUtils,
                                    "ResourceLoaderQt: Cannot load resource file " +
                                    iResourceNames[i] + ", error: " +
                                    iTranslators[i]);
                    }
                }
            }
        });
        boolean result = false;
        for (int i = 0; i < iTranslators.length; i++)
        {
            if (iTranslators[i] > 0)
            {
                // Return true if loading succeeds for at least one translator.
                result = true;
                break;
            }
        }
        return result;
    }

    /**
     * Deletes translator from iTranslators array.
     */
    private void deleteTranslators()
    {
        CoreUi.runInSyncUiThread(new Runnable() {
            public void run()
            {
                for (int i = 0; i < iTranslators.length; i++)
                {
                    if (iTranslators[i] <= 0)
                    {
                        continue;
                    }
                    int result = _deleteTranslator(iTranslators[i]);
                    if (result < 0)
                    {
                        Logger.WLOG(Logger.EUtils,
                                    "ResourceLoaderQt: Deleting translator for resource " +
                                    iResourceNames[i] + " failed, error: " +
                                    result);
                    }
                }
            }
        });
    }

    /**
     * Get a string with a given comma separated resource id list.
     *
     * @param id comma separated resource id list, either with prefix or without
     * @param n used to identify plural forms
     * @return resource string, or the id if does not exist
     */
    private String getResourceStringByList(String id, int n)
    {
        String str = null;
        String[] ids = Tokenizer.split(id, SEPARATOR);
        String strIn = null;
        String strOut = null;
        for (int i = 0; i < ids.length && str == null; i++)
        {
            for (int j = 0; j < iTranslators.length && str == null; j++)
            {
                if (iTranslators[j] <= 0)
                {
                    // Skip invalid translator handles.
                    continue;
                }
                // Check if id already has prefix.
                if (iPrefixes != null && iPrefixes.length > j &&
                    !ids[i].startsWith(iPrefixes[j]))
                {
                    // Try with prefix and id.
                    strIn = iPrefixes[j] + ids[i];
                }
                else
                {
                    // Try with id.
                    strIn = ids[i];
                }
                strOut = _translate(iTranslators[j], strIn, n);
                if (!strIn.equals(strOut))
                {
                    // Translation was found.
                    str = strOut;
                }
            }
        }
        if (str == null)
        {
            // Not found. Use the id itself.
            str = id;
            Logger.WLOG(Logger.EUtils,
                        "ResourceLoaderQt: Cannot find resource: " + id +
                        ", prefix: " + iPrefix);
        }
        return str;
    }

    /*** ----------------------------- NATIVE ----------------------------- */

    /**
     * Creates native translator object.
     *
     * @param aResourceFilename resource filename
     * @return handle to native side translator object, or negative
     * error code
     */
    private static native int _createTranslator(String aResourceFilename);

    /**
     * Deletes native translator object.
     *
     * @param handle to native side translator object
     * @return 0 if deletion was successful, or negative error code
     */
    private static native int _deleteTranslator(int aHandle);

    /**
     * Fetches localized text for given text id.
     *
     * @param aHandle translator to be used
     * @param aId text id
     * @param aN used to identify plural forms
     * @return localized text, or aId if text is not found
     */
    private static native String _translate(int aHandle, String aId, int aN);
}