Mega Code Archive

 
Categories / Java / Internationalization
 

Given a message and parameters, resolve all messages parameter placeholders with the parameter value

import java.text.Format; import java.text.MessageFormat; import java.util.Locale; import java.util.ResourceBundle; /**  * Internationalisation (I18N) helper  * @author eliott bartley  */ public class I18N {     private I18N() { }     /**      * Given a message and parameters, resolve all message's parameter      *  placeholders with the parameter value. The firstParam can change which      *  parameter relates to {0} placeholder in the message, and all increment      *  from this index. If any of the parameters also have placeholders, this      *  recursively calls itself to fill their placeholders, setting the      *  firstParam to the index following all parameters that are used by the      *  current message so params must be in the order p0..pN, p00..p0N..pMN,      *  p000..p00N..p0MN..pLMN... where each additional index is for nested      *  placeholders (ones in params) and assumes every message/param contains      *  N M L placeholders; any that don't contain placeholders can have their      *  pXXX.. taken out, so long as the order of remaining params don't change      * @param message Message to format      * @param firstParam Index of parameter that relates to {0} placeholder,      *  all parameters following this one relate to incrementing placeholders      * @param params The parameters used to fill the placeholders      * @return Message with all placeholders filled with relative parameters      */     private static String formatMessage     (   String message,         int firstParam,         Object[] params     ){         // Only need to do any formatting if there are parameters to do the         //  formatting with. If there are none, the message input is returned         //  unmodified         if(params != null && firstParam < params.length)         {   MessageFormat parser;             Locale locale = Locale.getDefault();             Format[] formats;             // Set up             parser = new MessageFormat("");             parser.setLocale(locale);             parser.applyPattern(message);             // Used only to count how many parameters are needed by this message             formats = parser.getFormatsByArgumentIndex();             // Recursively format the parameters used by this message             for(int paramIndex = 0; paramIndex < formats.length; paramIndex++)                 if(params[firstParam + paramIndex] instanceof String)                     params[firstParam + paramIndex] = formatMessage                     (   params[firstParam + paramIndex].toString(),                         firstParam + formats.length,                         params                     );             // Format the message using the formatted parameters             message = parser.format(getParams             (   params,                 firstParam,                 firstParam + formats.length             ));         }         return message;     }     /**      * MessageFormat.format always matches the placeholder's index directly to      *  the param array index, but because placeholders can be nested, the      *  zeroth placeholder may not match the zeroth array element, so this      *  method copies the array so that only the required array elements are      *  present, and start from the zeroth element      * @param params Complete param array      * @param firstParam First element that will be used in complete param array      * @param lastParam Last element that will be used in complete param array      * @return Param array containing just the elements from      *  firstParam..lastParam-1. If lastParam is less or equal to firstParam,      *  null is returned rather than an empty array      */     private static Object[] getParams     (   Object[]    params,         int     firstParam,         int      lastParam     ){  Object[] newParams = null;         if(firstParam < lastParam)         {   newParams = new Object[lastParam - firstParam];             for(int i = firstParam; i < lastParam; i++)                 newParams[i - firstParam] = params[i];         }         return newParams;     } }