001package net.sf.jkniv.jaas;
002
003import java.io.IOException;
004import java.io.InputStream;
005import java.util.ArrayList;
006import java.util.Arrays;
007import java.util.List;
008import java.util.Properties;
009import java.util.logging.Level;
010import java.util.logging.Logger;
011import java.util.regex.Matcher;
012import java.util.regex.Pattern;
013
014
015public class I18nManager
016{
017    private static final Logger    LOG = MyLoggerFactory.getLogger(I18nManager.class);
018    public static final Properties i18n;
019    private static final Pattern PATTERN_MSG = Pattern.compile("\\{[\\d]*\\}");
020    private static final Pattern PATTERN_NUMBER = Pattern.compile("-?\\d+");
021    static
022    {
023        i18n = new Properties();
024        InputStream input = null;
025        try
026        {
027            input = Thread.currentThread().getContextClassLoader().getResourceAsStream("LocalStrings.properties");
028            i18n.load(input);
029        }
030        catch (IOException ex)
031        {
032            LOG.log(Level.WARNING,"Cannot load message properties file: " , ex);
033        }
034        finally
035        {
036            if (input != null)
037            {
038                try
039                {
040                    input.close();
041                }
042                catch (IOException e)
043                {
044                    LOG.log(Level.FINE,"Cannot close input stream from property file" , e);
045                }
046            }
047        }
048    }
049
050    public static String getString(Object... args)
051    {
052        String msg = null;
053        Object[] params = Arrays.copyOfRange(args, 1, args.length);
054        msg = i18n.getProperty(String.valueOf(args[0]));
055        
056        //System.out.println(args[0] + " -> "+msg);
057        String formatted = formatter(msg);
058        msg = String.format(formatted, params);
059        
060        return msg;
061    }
062    
063
064    /**
065     * Formatter a string from <code>org.slf4j.Logger</code> format to <code>String.format</code>
066     * Example:
067     * "The user {} cannot make login with password [{}]"
068     * "The user %1$s cannot make login with password [%2$s]"
069     * 
070     * @param format SLF4J formatter message
071     * @return Return a String with new formatter.
072     */
073    private static String formatter(String format)
074    {
075        StringBuilder sb = new StringBuilder();
076        Matcher matcher = PATTERN_MSG.matcher(format);
077        int index = 1;
078        int initial = 0;
079        List<Integer> groups = new ArrayList<Integer>();
080        while (matcher.find())
081        {
082            groups.add(matcher.start());
083            groups.add(matcher.end());
084            String indexParam = matcher.group();
085            sb.append( format.substring(initial, matcher.start()));
086            if(!"".equals(indexParam))
087            {
088                String i = extractNumber(indexParam);
089                sb.append("%" + i + "$s"); // string format "%1$s";
090                index++;
091            }
092            else
093                sb.append("%" + (index++) + "$s"); // string format "%1$s";
094            initial = matcher.end();
095        }
096        if (initial > 0)
097            sb.append( format.substring(initial, format.length()));
098        else
099            sb.append(format);
100        return sb.toString();
101    }
102    
103    private static String extractNumber(String m)
104    {
105        String ret = "";
106        
107        Matcher matcher = PATTERN_NUMBER.matcher(m);
108        if(matcher.find())
109            ret = matcher.group();
110        
111        return ret;
112    }
113}