javacommons/utils/javasrc/com/nokia/mj/impl/utils/ResourceLoader.java
branchRCL_3
changeset 19 04becd199f91
child 48 e0d6e9bd3ca7
equal deleted inserted replaced
16:f5050f1da672 19:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 package com.nokia.mj.impl.utils;
       
    20 
       
    21 import java.io.*;
       
    22 import java.util.*;
       
    23 
       
    24 /**
       
    25  * Resource loader to get localised strings and Formatter patterns.
       
    26  * <br>
       
    27  * Usage:
       
    28  * <pre>
       
    29  *   ResourceLoader res = new ResourceLoader("javainstaller", "qtn_java_installer_");
       
    30  *   Label subjectLabel = createLabel(
       
    31  *       res.format("subject").arg(certificate.getSubject()).toString(),
       
    32  *       horizontalSpan, labelStyle);
       
    33  *
       
    34  *   Label noteLabel = createLabel(
       
    35  *       res.string("note"), horizontalSpan, labelStyle);
       
    36  * </pre>
       
    37  *
       
    38  * @author Nokia Corporation
       
    39  * @version 1.0
       
    40  */
       
    41 public class ResourceLoader
       
    42 {
       
    43     /** Localisation resource basepath */
       
    44     private static final String LOC_RESOURCE_BASE = "/resources/com/nokia/mj/impl/";
       
    45 
       
    46     /** Map for ResourceLoader instances. */
       
    47     private static Hashtable resourceLoaders = new Hashtable();
       
    48 
       
    49     /** Resource string map. Null if resource could not be loaded. */
       
    50     private Hashtable resourceMap = new Hashtable();
       
    51 
       
    52     /** Resource name prefix */
       
    53     private String prefix;
       
    54 
       
    55     /*** ----------------------------- PUBLIC ------------------------------ */
       
    56 
       
    57     /**
       
    58      * Returns a resource loader instance.
       
    59      *
       
    60      * @param resourceName name of the resource
       
    61      * @param prefix prefix added before each id when retrieving
       
    62      * @return resource loader instance
       
    63      */
       
    64     public static ResourceLoader getInstance(String resourceName, String prefix)
       
    65     {
       
    66         String key = resourceName + ":" + prefix;
       
    67         ResourceLoader result = (ResourceLoader)resourceLoaders.get(key);
       
    68         if (result == null)
       
    69         {
       
    70             result = new ResourceLoader(resourceName, prefix);
       
    71             resourceLoaders.put(key, result);
       
    72         }
       
    73         return result;
       
    74     }
       
    75 
       
    76     /**
       
    77      * Creates resource loader, using the current locale of the environment.
       
    78      *
       
    79      * @param resourceName name of the resource
       
    80      * @param aPrefix prefix added before each id when retrieving
       
    81      */
       
    82     public ResourceLoader(String resourceName, String aPrefix)
       
    83     {
       
    84         prefix = aPrefix;
       
    85         loadFile(resourceName);
       
    86     }
       
    87 
       
    88     /**
       
    89      * Get a string formatter of a given resource id.
       
    90      *
       
    91      * @param id resource id
       
    92      * @return formatter instance
       
    93      * @see Formatter
       
    94      */
       
    95     public Formatter format(String id)
       
    96     {
       
    97         return new Formatter(string(id));
       
    98     }
       
    99 
       
   100     /**
       
   101      * Formats localised text with specified parameters from an array.
       
   102      *
       
   103      * @param id resource id
       
   104      * @param textParameters parameters to be filled into the text
       
   105      * @return localised text formatted with the provided parameters
       
   106      * @see Formatter
       
   107      */
       
   108     public String format(String id, Object[] textParameters)
       
   109     {
       
   110         return new Formatter(string(id)).format(textParameters);
       
   111     }
       
   112 
       
   113     /**
       
   114      * Get a plain string resource with a given resource id.
       
   115      *
       
   116      * @param id resource id, either with prefix or without
       
   117      * @return resource string, or the id if does not exist
       
   118      */
       
   119     public String string(String id)
       
   120     {
       
   121         String str = (String)resourceMap.get(id);
       
   122         if (str == null)
       
   123         {
       
   124             // Try with prefix
       
   125             str = (String)resourceMap.get(prefix + id);
       
   126             if (str == null)
       
   127             {
       
   128                 // Not found even with prefix. Use the id itself
       
   129                 if (!id.startsWith(prefix))
       
   130                 {
       
   131                     str = prefix + id;
       
   132                 }
       
   133                 else
       
   134                 {
       
   135                     str = id;
       
   136                 }
       
   137 
       
   138                 Logger.WLOG(Logger.EUtils, "Cannot find resource: " + id);
       
   139             }
       
   140 
       
   141             // Put back to hash with original key for quick retrieval
       
   142             resourceMap.put(id, str);
       
   143         }
       
   144 
       
   145         str = decode(str);
       
   146         str = replaceCharacterCodes(str);
       
   147 
       
   148         return str;
       
   149     }
       
   150 
       
   151     /**
       
   152      * Gets the locale ID currently being used on the phone. This can be used
       
   153      * e.g. to load a localized icon file, by adding the locale id as suffix.
       
   154      *
       
   155      * @return Locale ID as provided by the platform
       
   156      */
       
   157     public String getLocaleId()
       
   158     {
       
   159         int localeId = _getLocaleId();
       
   160         if (localeId > 0)
       
   161         {
       
   162             if (localeId < 10)
       
   163             {
       
   164                 // Ensure that the returned locale ID has at least two digits.
       
   165                 return "0" + Integer.toString(localeId);
       
   166             }
       
   167             else
       
   168             {
       
   169                 return Integer.toString(localeId);
       
   170             }
       
   171         }
       
   172         return "sc";
       
   173     }
       
   174 
       
   175     /*** ----------------------------- PRIVATE ---------------------------- */
       
   176 
       
   177     /**
       
   178      * Loads the resources from .loc type file
       
   179      */
       
   180     private void loadFile(String resourceName)
       
   181     {
       
   182         InputStream is = null;
       
   183 
       
   184         // Load with real locale id
       
   185         is = this.getClass().getResourceAsStream(
       
   186                  LOC_RESOURCE_BASE + resourceName + "_" + getLocaleId() + ".loc");
       
   187         if (is == null)
       
   188         {
       
   189             // Load the engineering english
       
   190             is = this.getClass().getResourceAsStream(
       
   191                      LOC_RESOURCE_BASE + resourceName + "_sc" + ".loc");
       
   192         }
       
   193         if (is == null)
       
   194         {
       
   195             // Load the reference engineering english
       
   196             is = this.getClass().getResourceAsStream(
       
   197                      LOC_RESOURCE_BASE + resourceName + ".loc");
       
   198         }
       
   199         if (is == null)
       
   200         {
       
   201             Logger.WLOG(Logger.EUtils,
       
   202                         "Cannot load resource file: " + resourceName);
       
   203             return;
       
   204         }
       
   205 
       
   206         try
       
   207         {
       
   208             // Loc-files area always on UTF8 format
       
   209             LineReader lr = new LineReader(
       
   210                 new BufferedReader(new InputStreamReader(is, "UTF-8")));
       
   211             String line;
       
   212 
       
   213             while ((line = lr.readLine()) != null)
       
   214             {
       
   215                 // Ignore lines which are not #define's
       
   216                 if (!line.startsWith("#define "))
       
   217                 {
       
   218                     continue;
       
   219                 }
       
   220                 try
       
   221                 {
       
   222                     // Skip "#define" + any whitespace
       
   223                     line = line.substring(line.indexOf(' ')).trim();
       
   224 
       
   225                     int idEnd = line.indexOf(' ');
       
   226                     String id = line.substring(0, idEnd);
       
   227 
       
   228                     int strStart = line.indexOf('"', idEnd);
       
   229                     int strEnd = line.lastIndexOf('"');
       
   230                     String str = line.substring(strStart + 1, strEnd);
       
   231 
       
   232                     resourceMap.put(id, str);
       
   233 
       
   234                 }
       
   235                 catch (IndexOutOfBoundsException ex)
       
   236                 {
       
   237                     String error = "Incorrect line " + lr.getLineNumber() + "\"" +
       
   238                                    line + "\"";
       
   239                     Logger.WLOG(Logger.EUtils, error);
       
   240                 }
       
   241             }
       
   242             is.close();
       
   243 
       
   244         }
       
   245         catch (IOException ex)
       
   246         {
       
   247             Logger.WLOG(Logger.EUtils,
       
   248                         "Resource file " + resourceName + " handling failed: "
       
   249                         + ex.getMessage());
       
   250         }
       
   251     }
       
   252 
       
   253     /**
       
   254      * Decode given string. Decoding means unescaping escaped characters.
       
   255      * Currently \n, \t, \', \\ and \" patterns are decoded to respective
       
   256      * characters.
       
   257      *
       
   258      * @param str to be decoded.
       
   259      * @return decoded String.
       
   260      */
       
   261     private String decode(String str)
       
   262     {
       
   263         str = replacePattern(str, "\\n", '\n');
       
   264         str = replacePattern(str, "\\\\", '\\');
       
   265         str = replacePattern(str, "\\\"", '\"');
       
   266         str = replacePattern(str, "\\t", '\t');
       
   267         str = replacePattern(str, "\\'", '\'');
       
   268 
       
   269         return str;
       
   270     }
       
   271 
       
   272     /**
       
   273      * Replace all occurrences of the pattern in the given String.
       
   274      *
       
   275      * @param resource string to be replaced.
       
   276      * @param pattern to replace.
       
   277      * @param replacement replacement character.
       
   278      * @return String where all occurrences of the pattern are replaced.
       
   279      */
       
   280     private String replacePattern(
       
   281         String resource, String pattern, char replacement)
       
   282     {
       
   283         StringBuffer sb = new StringBuffer();
       
   284 
       
   285         int startIndex = resource.indexOf(pattern);
       
   286         if (startIndex != -1)
       
   287         {
       
   288             sb.append(resource.substring(0, startIndex)).append(replacement);
       
   289             startIndex = startIndex + pattern.length();
       
   290             int endIndex = 0;
       
   291 
       
   292             while ((endIndex = resource.indexOf(pattern, startIndex)) != -1)
       
   293             {
       
   294                 sb.append(resource.substring(startIndex, endIndex))
       
   295                 .append(replacement);
       
   296                 startIndex = endIndex + pattern.length();
       
   297             }
       
   298 
       
   299             if (startIndex < resource.length())
       
   300             {
       
   301                 sb.append(resource.substring(startIndex, resource.length()));
       
   302             }
       
   303             return sb.toString();
       
   304         }
       
   305         return resource;
       
   306     }
       
   307 
       
   308     /**
       
   309      * Replace character codes. They are given as <0x0000> format. Where 0x0000
       
   310      * contains character unicode as hex representation.
       
   311      *
       
   312      * @param str to replace characters.
       
   313      * @return String where characters are replaced.
       
   314      */
       
   315     private String replaceCharacterCodes(String str)
       
   316     {
       
   317         StringBuffer sb = new StringBuffer();
       
   318         int startIndex = str.indexOf("<0x");
       
   319 
       
   320         if (startIndex != -1 && str.charAt(startIndex + 7) == '>')
       
   321         {
       
   322             sb.append(str.substring(0, startIndex));
       
   323             try
       
   324             {
       
   325                 int charint = Integer.parseInt(
       
   326                                   str.substring(startIndex + 3, startIndex + 7), 16);
       
   327                 sb.append((char) charint);
       
   328 
       
   329                 int endIndex = 0;
       
   330                 startIndex+= 7;
       
   331 
       
   332                 while ((endIndex = str.indexOf("<0x", startIndex)) != -1
       
   333                         && str.charAt(endIndex + 7) == '>')
       
   334                 {
       
   335                     sb.append(str.substring(startIndex + 1, endIndex));
       
   336 
       
   337                     charint = Integer.parseInt(
       
   338                                   str.substring(endIndex + 3, endIndex + 7), 16);
       
   339                     sb.append((char) charint);
       
   340                     startIndex = endIndex + 7;
       
   341                 }
       
   342             }
       
   343             catch (NumberFormatException nfe)
       
   344             {
       
   345                 Logger.ELOG(Logger.EUtils,
       
   346                             "Cannot replace character from string: " + str);
       
   347                 return str;
       
   348             }
       
   349 
       
   350             if (startIndex < str.length())
       
   351             {
       
   352                 sb.append(str.substring(startIndex + 1, str.length()));
       
   353             }
       
   354             return sb.toString();
       
   355         }
       
   356         return str;
       
   357     }
       
   358 
       
   359 
       
   360     /*** ----------------------------- NATIVE ----------------------------- */
       
   361 
       
   362     /**
       
   363      * Get device language code.
       
   364      *
       
   365      * @return languege code.
       
   366      */
       
   367     private native int _getLocaleId();
       
   368 
       
   369 }