<commit_before>/*
 * Copyright (c) 2008-2013 Haulmont. All rights reserved.
 * Use is subject to license terms, see http://www.cuba-platform.com/license for details.
 */

package com.haulmont.cuba.core.sys;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.haulmont.bali.util.Preconditions;
import com.haulmont.chile.core.datatypes.Datatypes;
import com.haulmont.chile.core.datatypes.FormatStrings;
import com.haulmont.cuba.core.global.*;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.text.StrBuilder;
import org.apache.commons.lang.text.StrTokenizer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.perf4j.StopWatch;
import org.perf4j.log4j.Log4JStopWatch;

import javax.annotation.Nullable;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.io.*;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <code>Messages</code> implementation common for all tiers.
 *
 * @author krivopustov
 * @version $Id$
 */
public abstract class AbstractMessages implements Messages {

    public static final String BUNDLE_NAME = "messages";
    public static final String EXT = ".properties";
    public static final String ENCODING = "UTF-8";

    protected Log log = LogFactory.getLog(getClass());

    @Inject
    protected MessageTools messageTools;

    protected Pattern enumSubclassPattern = Pattern.compile("\\$[1-9]");

    protected GlobalConfig globalConfig;

    protected String confDir;

    protected String mainMessagePack;

    protected Map<String, String> strCache = new ConcurrentHashMap<>();

    // Using ConcurrentHashMap instead of synchronized Set for better parallelism
    protected Map<String, String> notFoundCache = new ConcurrentHashMap<>();

    protected Cache<String, Properties> filePropertiesCache = CacheBuilder.newBuilder().build();
    protected Cache<String, Properties> resourcePropertiesCache = CacheBuilder.newBuilder().build();

    protected final static Properties PROPERTIES_NOT_FOUND = new Properties();

    protected abstract Locale getUserLocale();

    protected abstract String searchRemotely(String pack, String key, Locale locale);

    @Inject
    public void setConfiguration(Configuration configuration) {
        globalConfig = configuration.getConfig(GlobalConfig.class);
        confDir = globalConfig.getConfDir().replaceAll("\\\\", "/");
    }

    @PostConstruct
    protected void init() {
        mainMessagePack = AppContext.getProperty("cuba.mainMessagePack");
        if (mainMessagePack == null) {
            throw new DevelopmentException("Property cuba.mainMessagePack is not set");
        }

        log.debug("Main message pack: " + mainMessagePack);

        for (Locale locale : globalConfig.getAvailableLocales().values()) {
            Datatypes.setFormatStrings(
                    messageTools.trimLocale(locale),
                    new FormatStrings(
                            getMessage(mainMessagePack, "numberDecimalSeparator", locale).charAt(0),
                            getMessage(mainMessagePack, "numberGroupingSeparator", locale).charAt(0),
                            getMessage(mainMessagePack, "integerFormat", locale),
                            getMessage(mainMessagePack, "doubleFormat", locale),
                            getMessage(mainMessagePack, "decimalFormat", locale),
                            getMessage(mainMessagePack, "dateFormat", locale),
                            getMessage(mainMessagePack, "dateTimeFormat", locale),
                            getMessage(mainMessagePack, "timeFormat", locale),
                            getMessage(mainMessagePack, "trueString", locale),
                            getMessage(mainMessagePack, "falseString", locale)
                    )<commit_msg>Raise error on start if cuba.mainMessagePack property value is invalid. #PL-4015<commit_after>/*
 * Copyright (c) 2008-2013 Haulmont. All rights reserved.
 * Use is subject to license terms, see http://www.cuba-platform.com/license for details.
 */

package com.haulmont.cuba.core.sys;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.haulmont.bali.util.Preconditions;
import com.haulmont.chile.core.datatypes.Datatypes;
import com.haulmont.chile.core.datatypes.FormatStrings;
import com.haulmont.cuba.core.global.*;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.text.StrBuilder;
import org.apache.commons.lang.text.StrTokenizer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.perf4j.StopWatch;
import org.perf4j.log4j.Log4JStopWatch;

import javax.annotation.Nullable;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.io.*;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <code>Messages</code> implementation common for all tiers.
 *
 * @author krivopustov
 * @version $Id$
 */
public abstract class AbstractMessages implements Messages {

    public static final String BUNDLE_NAME = "messages";
    public static final String EXT = ".properties";
    public static final String ENCODING = "UTF-8";

    protected Log log = LogFactory.getLog(getClass());

    @Inject
    protected MessageTools messageTools;

    protected Pattern enumSubclassPattern = Pattern.compile("\\$[1-9]");

    protected GlobalConfig globalConfig;

    protected String confDir;

    protected String mainMessagePack;

    protected Map<String, String> strCache = new ConcurrentHashMap<>();

    // Using ConcurrentHashMap instead of synchronized Set for better parallelism
    protected Map<String, String> notFoundCache = new ConcurrentHashMap<>();

    protected Cache<String, Properties> filePropertiesCache = CacheBuilder.newBuilder().build();
    protected Cache<String, Properties> resourcePropertiesCache = CacheBuilder.newBuilder().build();

    protected final static Properties PROPERTIES_NOT_FOUND = new Properties();

    protected abstract Locale getUserLocale();

    protected abstract String searchRemotely(String pack, String key, Locale locale);

    @Inject
    public void setConfiguration(Configuration configuration) {
        globalConfig = configuration.getConfig(GlobalConfig.class);
        confDir = globalConfig.getConfDir().replaceAll("\\\\", "/");
    }

    @PostConstruct
    protected void init() {
        mainMessagePack = AppContext.getProperty("cuba.mainMessagePack");
        if (mainMessagePack == null) {
            throw new DevelopmentException("Property cuba.mainMessagePack is not set");
        }

        log.debug("Main message pack: " + mainMessagePack);

        for (Locale locale : globalConfig.getAvailableLocales().values()) {
            String numberDecimalSeparator = getMessage(mainMessagePack, "numberDecimalSeparator", locale);
            String numberGroupingSeparator = getMessage(mainMessagePack, "numberGroupingSeparator", locale);
            String integerFormat = getMessage(mainMessagePack, "integerFormat", locale);
            String doubleFormat = getMessage(mainMessagePack, "doubleFormat", locale);
            String decimalFormat = getMessage(mainMessagePack, "decimalFormat", locale);
            String dateFormat = getMessage(mainMessagePack, "dateFormat", locale);
            String dateTimeFormat = getMessage(mainMessagePack, "dateTimeFormat", locale);
            String timeFormat = getMessage(mainMessagePack, "timeFormat", locale);
            String trueString = getMessage(mainMessagePack, "trueString", locale);
            String falseString = getMessage(mainMessagePack, "falseString", locale);
            if (numberDecimalSeparator.equals("numberDecimalSeparator")
                    || numberGroupingSeparator.equals("numberGroupingSeparator")
                    || integerFormat.equals("integerFormat")
                    || doubleFormat.equals("doubleFormat")
                    || decimalFormat.equals("decimalFormat")
                    || dateFormat.equals("dateFormat")
                    || dateTimeFormat.equals("dateTimeFormat")
                    || timeFormat.equals("timeFormat"))
                throw new DevelopmentException("Localized format strings are not defined. " +
                        "Check cuba.mainMessagePack application property, it must point to a valid set of main message packs.");

            Datatypes.setFormatStrings(
                    messageTools.trimLocale(locale),
                    new FormatStrings(
                            numberDecimalSeparator.charAt(0),
                            numberGroupingSeparator.charAt(0),
                            integerFormat,
                            doubleFormat,
                            decimalFormat,
                            dateFormat,
                            dateTimeFormat,
                            timeFormat,
                            trueString,
                            falseString
                    )
{'fraction_non_alphanumeric': 0.09572793114306707, 'fraction_numerical': 0.0039886637976277945, 'mean_word_length': 3.0805139186295505, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5452070', 'n_tokens_mistral': 2402, 'n_tokens_neox': 2364, 'n_words': 558}