org.pentaho.cdf.localization.MessageBundlesHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.pentaho.cdf.localization.MessageBundlesHelper.java

Source

/*!
 * Copyright 2002 - 2014 Webdetails, a Pentaho company.  All rights reserved.
 * 
 * This software was developed by Webdetails and is provided under the terms
 * of the Mozilla Public License, Version 2.0, or any later version. You may not use
 * this file except in compliance with the license. If you need a copy of the license,
 * please go to  http://mozilla.org/MPL/2.0/. The Initial Developer is Webdetails.
 *
 * Software distributed under the Mozilla Public License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or  implied. Please refer to
 * the license for the specific language governing your rights and limitations.
 */

package org.pentaho.cdf.localization;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.pentaho.cdf.CdfConstants;
import org.pentaho.cdf.environment.CdfEngine;
import pt.webdetails.cpf.Util;
import pt.webdetails.cpf.repository.api.IBasicFile;
import pt.webdetails.cpf.repository.api.IRWAccess;
import pt.webdetails.cpf.repository.api.IReadAccess;
import pt.webdetails.cpf.repository.api.IUserContentAccess;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class MessageBundlesHelper {

    private String globalBaseMessageFile;
    private String targetDashboardCacheDir;
    private String targetDashboardBaseMsgFile;
    private String sourceDashboardBaseMsgFile;
    private String languagesCacheUrl;

    public MessageBundlesHelper(String dashboardSolution, String dashboardPath,
            String dashboardsMessagesBaseFilename) {
        init(CdfConstants.BASE_GLOBAL_MESSAGE_SET_FILENAME, dashboardSolution, dashboardPath,
                dashboardsMessagesBaseFilename);
    }

    public MessageBundlesHelper(String dashboardSolutionPath, String dashboardsMessagesBaseFilename) {
        init(CdfConstants.BASE_GLOBAL_MESSAGE_SET_FILENAME, dashboardSolutionPath, dashboardsMessagesBaseFilename);
    }

    public void saveI18NMessageFilesToCache() throws IOException {
        createCacheDirIfNotExists(targetDashboardCacheDir);
        copyStdGlobalMessageFileToCache();
        if (sourceDashboardBaseMsgFile != null) {
            appendMessageFiles(sourceDashboardBaseMsgFile, globalBaseMessageFile, targetDashboardBaseMsgFile);
        } else {
            appendMessageFiles(globalBaseMessageFile, targetDashboardBaseMsgFile);
        }
    }

    public String getMessageFilesCacheUrl() {
        return FilenameUtils.separatorsToUnix(languagesCacheUrl);
    }

    protected void init(String baseGlobalMessageSetFilename, String dashboardSolution, String dashboardPath,
            String dashboardsMessagesBaseFilename) {

        globalBaseMessageFile = Util.joinPath(CdfConstants.BASE_GLOBAL_MESSAGE_SET_URL,
                baseGlobalMessageSetFilename);
        languagesCacheUrl = Util.joinPath(CdfConstants.BASE_CDF_CACHE_DIR, dashboardSolution + dashboardPath);
        targetDashboardCacheDir = getMessageFilesCacheUrl();
        // Name the dashboard target i18n messages file. If we have a dashboard specific language file it will be named
        // the same otherwise it will have the name of the global message file. The target message file contains globals and
        // local translations
        // (if the dashboard has a specific set of translations) or the name of the global one if no translations are
        // specified.
        // This way we eliminate fake error messages that are given by the unexpected unavailability of message files.
        targetDashboardBaseMsgFile = Util.joinPath(languagesCacheUrl,
                (dashboardsMessagesBaseFilename != null ? dashboardsMessagesBaseFilename
                        : baseGlobalMessageSetFilename));
        if (!StringUtils.isEmpty(dashboardsMessagesBaseFilename)) {
            sourceDashboardBaseMsgFile = Util.joinPath(dashboardSolution, dashboardPath,
                    dashboardsMessagesBaseFilename);
        }
    }

    protected void init(String baseGlobalMessageSetFilename, String dashboardSolutionPath,
            String dashboardsMessagesBaseFilename) {

        globalBaseMessageFile = Util.joinPath(CdfConstants.BASE_GLOBAL_MESSAGE_SET_URL,
                baseGlobalMessageSetFilename);
        languagesCacheUrl = Util.joinPath(CdfConstants.BASE_CDF_CACHE_DIR, dashboardSolutionPath);
        targetDashboardCacheDir = getMessageFilesCacheUrl();
        // Name the dashboard target i18n messages file. If we have a dashboard specific language file it will be named
        // the same otherwise it will have the name of the global message file. The target message file contains globals and
        // local translations
        // (if the dashboard has a specific set of translations) or the name of the global one if no translations are
        // specified.
        // This way we eliminate fake error messages that are given by the unexpected unavailability of message files.
        targetDashboardBaseMsgFile = Util.joinPath(languagesCacheUrl,
                (dashboardsMessagesBaseFilename != null ? dashboardsMessagesBaseFilename
                        : baseGlobalMessageSetFilename));
        if (!StringUtils.isEmpty(dashboardsMessagesBaseFilename)) {
            sourceDashboardBaseMsgFile = Util.joinPath(dashboardSolutionPath, dashboardsMessagesBaseFilename);
        }
    }

    protected void createCacheDirIfNotExists(String targetDashboardCacheDir) {
        if (!getSystemReader().fileExists(targetDashboardCacheDir)) {
            getSystemWriter().createFolder(targetDashboardCacheDir);
        }
    }

    protected void appendMessageFiles(String globalBaseMessageFile, String targetDashboardBaseMsgFile)
            throws IOException {
        appendMessageFiles(null, globalBaseMessageFile, targetDashboardBaseMsgFile);
    }

    protected void appendMessageFiles(String sourceDashboardBaseMsgFile, String globalBaseMessageFile,
            String targetDashboardBaseMsgFile) throws IOException {

        String localeSuffix = "_" + CdfEngine.getEnvironment().getLocale().getLanguage();

        targetDashboardBaseMsgFile = !targetDashboardBaseMsgFile.endsWith(localeSuffix)
                ? targetDashboardBaseMsgFile + localeSuffix
                : targetDashboardBaseMsgFile;
        IBasicFile fBaseMsgGlobal = getSystemReader().fetchFile(
                globalBaseMessageFile + "_" + CdfEngine.getEnvironment().getLocale().getLanguage() + ".properties");

        String theLine;
        if (!getSystemReader().fileExists(targetDashboardBaseMsgFile + ".properties")) {

            File tempMessageFile = null;
            String locale = CdfEngine.getEnvironment().getLocale().getLanguage();

            try {

                // we append the content of global and base message files here,
                // then we write the end result to targetDashboardBaseMsgFile
                String tempMessageFileName = System.getProperty("java.io.tmpdir") + "tempMessageFile_"
                        + System.currentTimeMillis();
                tempMessageFile = new File(tempMessageFileName);
                BufferedWriter bwTempBaseMsgTarget = new BufferedWriter(new FileWriter(tempMessageFile, true));

                // If localized global message file doesn't exists then use the standard base global message file
                // and generate a fake global message file. So this way we're sure that we always have the file
                String globalBaseMessageFileName = globalBaseMessageFile + "_" + locale + ".properties";

                if (!getSystemReader().fileExists(globalBaseMessageFileName)) {

                    InputStream content = new ByteArrayInputStream(StringUtils.EMPTY.getBytes());

                    if (getSystemReader().fileExists(globalBaseMessageFile + ".properties")) {
                        content = getSystemReader().fetchFile(globalBaseMessageFile + ".properties").getContents();
                    }

                    getSystemWriter().saveFile(globalBaseMessageFileName, content);
                    fBaseMsgGlobal = getSystemReader().fetchFile(globalBaseMessageFileName);
                }

                BufferedReader brBaseMsgGlobal = new BufferedReader(
                        new InputStreamReader(fBaseMsgGlobal.getContents()));
                while ((theLine = brBaseMsgGlobal.readLine()) != null) {
                    bwTempBaseMsgTarget.write(theLine + "\n");
                }
                brBaseMsgGlobal.close();

                // Append specific message file only if it exists otherwise just use the global message files
                if (!StringUtils.isEmpty(sourceDashboardBaseMsgFile)) {

                    IBasicFile msgFile = null;

                    if (getUserContentReader()
                            .fileExists(sourceDashboardBaseMsgFile + "_" + locale + ".properties")) {

                        // a local Messages_<locale>.properties exists
                        msgFile = getUserContentReader()
                                .fetchFile(sourceDashboardBaseMsgFile + "_" + locale + ".properties");

                    } else if (getUserContentReader().fileExists(sourceDashboardBaseMsgFile + ".properties")) {

                        // a local Messages_<locale>.properties does not exist, but a local Messages.properties does
                        msgFile = getUserContentReader().fetchFile(sourceDashboardBaseMsgFile + ".properties");
                    }

                    if (msgFile != null && msgFile.getContents() != null) {
                        BufferedReader brBaseMsgDashboard = new BufferedReader(
                                new InputStreamReader(msgFile.getContents()));
                        while ((theLine = brBaseMsgDashboard.readLine()) != null) {
                            bwTempBaseMsgTarget.write(theLine + "\n");
                        }
                        brBaseMsgDashboard.close();
                    }
                }
                bwTempBaseMsgTarget.close();

                getSystemWriter().saveFile(targetDashboardBaseMsgFile + ".properties",
                        new FileInputStream(tempMessageFile));

            } finally {

                if (tempMessageFile != null && tempMessageFile.exists()) {
                    tempMessageFile.delete();
                }
            }
        }
    }

    protected void copyStdGlobalMessageFileToCache() throws IOException {

        String standardGlobalMessageFilename = CdfConstants.BASE_GLOBAL_MESSAGE_SET_FILENAME + ".properties";

        String standardGlobalMessageFilenamePath = Util.joinPath(CdfConstants.BASE_GLOBAL_MESSAGE_SET_URL,
                standardGlobalMessageFilename);

        // failsafe: if somehow Message.properties does not exist at
        // CdfConstants.BASE_GLOBAL_MESSAGE_SET_URL, create it blank
        if (!getSystemReader().fileExists(standardGlobalMessageFilenamePath)) {
            getSystemWriter().saveFile(standardGlobalMessageFilenamePath, new ByteArrayInputStream("".getBytes()));
        }

        IBasicFile fromFile = getSystemReader().fetchFile(standardGlobalMessageFilenamePath);
        String toFile = Util.joinPath(targetDashboardCacheDir, standardGlobalMessageFilename);

        if (getSystemWriter().fileExists(toFile)) {
            return;
        }

        getSystemWriter().saveFile(toFile, fromFile.getContents());
    }

    private IReadAccess getSystemReader() {
        return CdfEngine.getPluginSystemReader(null);
    }

    private IRWAccess getSystemWriter() {
        return CdfEngine.getEnvironment().getContentAccessFactory().getPluginSystemWriter(null);
    }

    private IUserContentAccess getUserContentReader() {
        return CdfEngine.getUserContentReader(null);
    }
}