com.properned.model.MultiLanguageProperties.java Source code

Java tutorial

Introduction

Here is the source code for com.properned.model.MultiLanguageProperties.java

Source

package com.properned.model;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.properned.application.MessageReader;

/**
 * Properned is a software that can be used to edit java properties files 2015
 * Alexandre NEDJARI
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Alexandre NEDJARI
 * @since 28 october 2015
 */
public class MultiLanguageProperties {

    private BooleanProperty isLoaded = new SimpleBooleanProperty(false);
    private BooleanProperty isDirty = new SimpleBooleanProperty(false);
    private StringProperty baseName = new SimpleStringProperty(
            MessageReader.getInstance().getMessage("mainFrame.defaultFileName"));
    private StringProperty parentDirectoryPath = new SimpleStringProperty();

    private Map<Locale, Properties> mapPropertiesByLocale = new HashMap<Locale, Properties>();
    private Map<Locale, PropertiesFile> mapPropertiesFileByLocale = new HashMap<Locale, PropertiesFile>();
    private ObservableList<String> listMessageKey = FXCollections.observableArrayList();

    private static MultiLanguageProperties instance;

    private Logger logger = LogManager.getLogger(this.getClass());

    public static synchronized MultiLanguageProperties getInstance() {
        if (instance == null) {
            instance = new MultiLanguageProperties();
            instance.init();
        }
        return instance;
    }

    private void init() {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                logger.info("Initializing the multi language properties instance");
                isDirty.set(false);
                isLoaded.set(false);
                mapPropertiesByLocale.clear();
                mapPropertiesFileByLocale.clear();
                listMessageKey.clear();
            }
        });
    }

    private MultiLanguageProperties() {
        // avoid construction
    }

    public BooleanProperty isLoadedProperty() {
        return isLoaded;
    }

    public BooleanProperty isDirtyProperty() {
        return isDirty;
    }

    public StringProperty parentDirectoryPathProperty() {
        return parentDirectoryPath;
    }

    public StringProperty baseNameProperty() {
        return baseName;
    }

    public Map<Locale, Properties> getMapPropertiesByLocale() {
        return mapPropertiesByLocale;
    }

    public Map<Locale, PropertiesFile> getMapPropertiesFileByLocale() {
        return mapPropertiesFileByLocale;
    }

    private void addProperties(Properties properties, Locale locale, PropertiesFile file) {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                logger.info("Add a propertie file for the locale '" + locale + "'");
                mapPropertiesByLocale.put(locale, properties);
                mapPropertiesFileByLocale.put(locale, file);
                Set<String> stringPropertyNames = properties.stringPropertyNames();

                // use of a set to prevent duplicated values into the list
                Set<String> setPropertyTotal = new HashSet<>(listMessageKey);
                setPropertyTotal.addAll(stringPropertyNames);
                listMessageKey.clear();
                listMessageKey.addAll(setPropertyTotal);
                baseName.set(file.getBaseName());
                parentDirectoryPath.set(file.getParent() + File.separator);
                isLoaded.set(true);
                logger.info(listMessageKey.size() + " keys are loaded for locale '" + locale + "'");
            }
        });

    }

    public ObservableList<String> getListMessageKey() {
        return listMessageKey;
    }

    public boolean getIsLoaded() {
        return isLoaded.get();
    }

    public boolean getIsDirty() {
        return isDirty.get();
    }

    public void setIsDirty(boolean isDirty) {
        this.isDirty.set(isDirty);
    }

    public String getBaseName() {
        return baseName.get();
    }

    public void setBaseName(String baseName) {
        logger.info("new baseName : " + baseName);
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                MultiLanguageProperties.this.baseName.set(baseName);
            }
        });
    }

    public void setProperty(String messageKey, String value, Locale locale) {
        if (StringUtils.isNotEmpty(value)) {
            logger.info("new property value : " + messageKey + " (" + locale + ") : " + value);
            this.getMapPropertiesByLocale().get(locale).setProperty(messageKey, value);
        } else {
            logger.info("remove property : " + messageKey + " (" + locale + ")");
            this.getMapPropertiesByLocale().get(locale).remove(messageKey);
        }
        this.setIsDirty(true);

    }

    public void save() throws IOException {
        logger.info("Save the multi language properties instance");
        Set<Locale> setLocale = mapPropertiesFileByLocale.keySet();
        for (Locale locale : setLocale) {
            PropertiesFile propertiesFile = mapPropertiesFileByLocale.get(locale);
            Properties properties = mapPropertiesByLocale.get(locale);
            if (properties == null) {
                continue;
            }
            logger.info("For the locale '" + locale + "', there is " + properties.size() + " properties to save");

            OutputStream fileOutputStream = null;
            try {
                fileOutputStream = new BufferedOutputStream(new FileOutputStream(propertiesFile));
                properties.store(fileOutputStream, "");
            } finally {
                IOUtils.closeQuietly(fileOutputStream);
            }
        }
        this.setIsDirty(false);
    }

    public void loadFileList(String baseName, List<PropertiesFile> fileList) throws IOException {
        logger.info("load a multi language properties (" + baseName + ") with " + fileList.size() + " files");
        // delete current values
        init();

        BufferedInputStream inStream = null;
        for (PropertiesFile file : fileList) {
            logger.info("load the file " + file.getAbsolutePath());
            try {
                if (!file.exists()) {
                    throw new IOException("Missing file " + file.getAbsolutePath());
                }
                Properties properties = new Properties();
                inStream = new BufferedInputStream(new FileInputStream(file));
                properties.load(inStream);

                addProperties(properties, file.getLocale(), file);
            } finally {
                IOUtils.closeQuietly(inStream);
            }
        }
    }

    public void deleteMessageKey(String messageKey) {
        logger.info("Delete the message key '" + messageKey + "'");
        listMessageKey.remove(messageKey);
        Set<Locale> setLocale = mapPropertiesFileByLocale.keySet();
        for (Locale locale : setLocale) {
            Properties properties = mapPropertiesByLocale.get(locale);
            properties.remove(messageKey);
            this.setIsDirty(true);
        }
    }

    public void addLocale(Locale locale) throws IOException {
        logger.info("Ask the creation of a propertie file for locale :" + locale);
        Properties properties = new Properties();
        String newFileAbsolutePath = this.parentDirectoryPath.get() + getFileName(locale);
        logger.info("the new file name is '" + newFileAbsolutePath + "'");
        PropertiesFile propertiesFile = new PropertiesFile(newFileAbsolutePath, baseName.get(), locale);
        propertiesFile.createNewFile();
        this.addProperties(properties, locale, propertiesFile);
    }

    private String getFileName(Locale locale) {
        String fileName = baseName.get();
        if (StringUtils.isNotEmpty(locale.getLanguage())) {
            fileName += "_" + locale.getLanguage();
        }
        if (StringUtils.isNotEmpty(locale.getCountry())) {
            fileName += "_" + locale.getCountry();
        }
        fileName += ".properties";
        return fileName;
    }

    public void deleteLocale(Locale locale) {
        logger.info("Remove locale " + locale.toString());

        PropertiesFile propertiesFile = mapPropertiesFileByLocale.get(locale);
        if (propertiesFile != null) {
            propertiesFile.delete();
        }

        mapPropertiesByLocale.remove(locale);
        mapPropertiesFileByLocale.remove(locale);
    }
}