    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one
    003 * or more contributor license agreements.  See the NOTICE file
    004 * distributed with this work for additional information
    005 * regarding copyright ownership.  The ASF licenses this file
    006 * to you under the Apache License, Version 2.0 (the
    007 * "License"); you may not use this file except in compliance
    008 * with the License.  You may obtain a copy of the License at
    009 *
    010 *   https://www.apache.org/licenses/LICENSE-2.0
    011 *
    012 * Unless required by applicable law or agreed to in writing,
    013 * software distributed under the License is distributed on an
    014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    015 * KIND, either express or implied.  See the License for the
    016 * specific language governing permissions and limitations
    017 * under the License.
    018 */
    019
    020/*
    021 * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
    022 * All changes made to this file manually will be overwritten
    023 * if this tool runs again. Better make changes in the template file.
    024 */
    025
    026package org.apache.commons.compress.harmony.archive.internal.nls;
    027
    028import java.security.AccessController;
    029import java.security.PrivilegedAction;
    030import java.util.Arrays;
    031import java.util.Locale;
    032import java.util.MissingResourceException;
    033import java.util.Objects;
    034import java.util.ResourceBundle;
    035
    036//import org.apache.commons.compress.harmony.kernel.vm.VM;
    037
    038/**
    039 * This class retrieves strings from a resource bundle and returns them, formatting them with MessageFormat when required.
    040 * <p>
    041 * It is used by the system classes to provide national language support, by looking up messages in the {@code
    042 *    org.apache.commons.compress.harmony.archive.internal.nls.messages
    043 * } resource bundle. Note that if this file is not available, or an invalid key is looked up, or resource bundle support is not available, the key itself
    044 * will be returned as the associated message. This means that the <em>KEY</em> should a reasonable human-readable (english) string.
    045 */
    046public class Messages {
    047
    048    // ResourceBundle holding the system messages.
    049    private static ResourceBundle bundle;
    050
    051    static {
    052        // Attempt to load the messages.
    053        try {
    054            bundle = setLocale(Locale.getDefault(), "org.apache.commons.compress.harmony.archive.internal.nls.messages"); //$NON-NLS-1$
    055        } catch (final Throwable e) {
    056            e.printStackTrace();
    057        }
    058    }
    059
    060    /**
    061     * Generates a formatted text string given a source string containing "argument markers" of the form "{argNum}" where each argNum must be in the range 0..9.
    062     * The result is generated by inserting the toString of each argument into the position indicated in the string.
    063     * <p>
    064     * To insert the "{" character into the output, use a single backslash character to escape it (i.e. "\{"). The "}" character does not need to be escaped.
    065     *
    066     * @param format String the format to use when printing.
    067     * @param args   Object[] the arguments to use.
    068     * @return String the formatted message.
    069     */
    070    public static String format(final String format, final Object[] args) {
    071        final StringBuilder answer = new StringBuilder(format.length() + args.length * 20);
    072        final String[] argStrings = new String[args.length];
    073        Arrays.setAll(argStrings, i -> Objects.toString(args[i], "<null>")); //$NON-NLS-1$
    074        int lastI = 0;
    075        for (int i = format.indexOf('{', 0); i >= 0; i = format.indexOf('{', lastI)) {
    076            if (i != 0 && format.charAt(i - 1) == '\\') {
    077                // It's escaped, just print and loop.
    078                if (i != 1) {
    079                    answer.append(format.substring(lastI, i - 1));
    080                }
    081                answer.append('{');
    082                lastI = i + 1;
    083            } else // It's a format character.
    084            if (i > format.length() - 3) {
    085                // Bad format, just print and loop.
    086                answer.append(format.substring(lastI));
    087                lastI = format.length();
    088            } else {
    089                final int argnum = (byte) Character.digit(format.charAt(i + 1), 10);
    090                if (argnum < 0 || format.charAt(i + 2) != '}') {
    091                    // Bad format, just print and loop.
    092                    answer.append(format.substring(lastI, i + 1));
    093                    lastI = i + 1;
    094                } else {
    095                    // Got a good one!
    096                    answer.append(format.substring(lastI, i));
    097                    if (argnum >= argStrings.length) {
    098                        answer.append("<missing argument>"); //$NON-NLS-1$
    099                    } else {
    100                        answer.append(argStrings[argnum]);
    101                    }
    102                    lastI = i + 3;
    103                }
    104            }
    105        }
    106        if (lastI < format.length()) {
    107            answer.append(format.substring(lastI));
    108        }
    109        return answer.toString();
    110    }
    111
    112    /**
    113     * Gets a message which has no arguments.
    114     *
    115     * @param msg String the key to look up.
    116     * @return String the message for that key in the system message bundle.
    117     */
    118    public static String getString(final String msg) {
    119        if (bundle == null) {
    120            return msg;
    121        }
    122        try {
    123            return bundle.getString(msg);
    124        } catch (final MissingResourceException e) {
    125            return "Missing message: " + msg; //$NON-NLS-1$
    126        }
    127    }
    128
    129    /**
    130     * Gets a message which takes 1 character argument.
    131     *
    132     * @param msg String the key to look up.
    133     * @param arg char the character to insert in the formatted output.
    134     * @return String the message for that key in the system message bundle.
    135     */
    136    public static String getString(final String msg, final char arg) {
    137        return getString(msg, new Object[] { String.valueOf(arg) });
    138    }
    139
    140    /**
    141     * Gets a message which takes 1 integer argument.
    142     *
    143     * @param msg String the key to look up.
    144     * @param arg int the integer to insert in the formatted output.
    145     * @return String the message for that key in the system message bundle.
    146     */
    147    public static String getString(final String msg, final int arg) {
    148        return getString(msg, new Object[] { Integer.toString(arg) });
    149    }
    150
    151    /**
    152     * Gets a message which takes 1 argument.
    153     *
    154     * @param msg String the key to look up.
    155     * @param arg Object the object to insert in the formatted output.
    156     * @return String the message for that key in the system message bundle.
    157     */
    158    public static String getString(final String msg, final Object arg) {
    159        return getString(msg, new Object[] { arg });
    160    }
    161
    162    /**
    163     * Gets a message which takes 2 arguments.
    164     *
    165     * @param msg  String the key to look up.
    166     * @param arg1 Object an object to insert in the formatted output.
    167     * @param arg2 Object another object to insert in the formatted output.
    168     * @return String the message for that key in the system message bundle.
    169     */
    170    public static String getString(final String msg, final Object arg1, final Object arg2) {
    171        return getString(msg, new Object[] { arg1, arg2 });
    172    }
    173
    174    /**
    175     * Gets a message which takes several arguments.
    176     *
    177     * @param msg  String the key to look up.
    178     * @param args Object[] the objects to insert in the formatted output.
    179     * @return String the message for that key in the system message bundle.
    180     */
    181    public static String getString(final String msg, final Object[] args) {
    182        String format = msg;
    183
    184        if (bundle != null) {
    185            try {
    186                format = bundle.getString(msg);
    187            } catch (final MissingResourceException ignored) {
    188                // ignored
    189            }
    190        }
    191
    192        return format(format, args);
    193    }
    194
    195    /**
    196     * Changes the locale of the messages.
    197     *
    198     * @param locale   Locale the locale to change to.
    199     * @param resource resource name.
    200     * @return The ResourceBundle.
    201     */
    202    public static ResourceBundle setLocale(final Locale locale, final String resource) {
    203        try {
    204            // VM.bootCallerClassLoader() returns null
    205            final ClassLoader loader = null; // VM.bootCallerClassLoader();
    206            return (ResourceBundle) AccessController.doPrivileged(
    207                    (PrivilegedAction<Object>) () -> ResourceBundle.getBundle(resource, locale, loader != null ? loader : ClassLoader.getSystemClassLoader()));
    208        } catch (final MissingResourceException ignored) {
    209            // ignored
    210        }
    211        return null;
    212    }
    213}