sernet.gs.ui.rcp.main.CnAWorkspace.java Source code

Java tutorial

Introduction

Here is the source code for sernet.gs.ui.rcp.main.CnAWorkspace.java

Source

/*******************************************************************************
 * Copyright (c) 2009 Alexander Koderman <ak[at]sernet[dot]de>.
 * This program is free software: you can redistribute it and/or 
 * modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
 *     You should have received a copy of the GNU Lesser General Public 
 * License along with this program. 
 * If not, see <http://www.gnu.org/licenses/>.
 * 
 * Contributors:
 *     Alexander Koderman <ak[at]sernet[dot]de> - initial API and implementation
 ******************************************************************************/
package sernet.gs.ui.rcp.main;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
import org.eclipse.osgi.util.NLS;

import sernet.gs.service.VeriniceCharset;
import sernet.gs.ui.rcp.gsimport.GstoolTypeMapper;
import sernet.gs.ui.rcp.main.preferences.PreferenceConstants;
import sernet.verinice.interfaces.report.IReportService;

/**
 * Prepare the workspace directory for the application. Created needed files
 * etc.
 * 
 * @author akoderman[at]sernet[dot]de
 * 
 */
public class CnAWorkspace {

    private static final String CONF = "conf";

    private static final Logger LOG = Logger.getLogger(CnAWorkspace.class);

    private static final String OFFICEDIR = "office"; //$NON-NLS-1$

    public static final String LINE_SEP = System.getProperty("line.separator"); //$NON-NLS-1$

    private static String workDir;

    // copy binary data using 100K buffer:
    private static final int BUFF_SIZE = 100000;

    private static final byte[] BUFFER = new byte[BUFF_SIZE];

    /**
     * Version number to check against version file. When changing this, also
     * change version number in skeleton file "conf/configuration.version"
     */
    public static final Object CONFIG_CURRENT_VERSION = "1.12"; //$NON-NLS-1$

    protected static final String VERINICEDB = "verinicedb"; //$NON-NLS-1$

    protected static final String TEMPIMPORTDB = "tempGstoolImportDb"; //$NON-NLS-1$

    private static volatile CnAWorkspace instance;

    private final IPropertyChangeListener prefChangeListener = new IPropertyChangeListener() {
        @Override
        public void propertyChange(PropertyChangeEvent event) {
            if ((event.getProperty().equals(PreferenceConstants.GS_DB_URL)
                    || event.getProperty().equals(PreferenceConstants.GS_DB_USER)
                    || event.getProperty().equals(PreferenceConstants.GS_DB_PASS))) {

                Preferences prefs = Activator.getDefault().getPluginPreferences();
                try {
                    String dbUrl = prefs.getString(PreferenceConstants.GS_DB_URL);

                    createGstoolImportDatabaseConfig(dbUrl, prefs.getString(PreferenceConstants.GS_DB_USER),
                            prefs.getString(PreferenceConstants.GS_DB_PASS));

                } catch (Exception e) {
                    ExceptionUtil.log(e, Messages.CnAWorkspace_0);
                }
            }
        }
    };

    private File confDir;

    protected CnAWorkspace() {
    }

    public String createTempImportDbUrl() {
        String tmpDerbyUrl = PreferenceConstants.DB_URL_DERBY.replace("%s", //$NON-NLS-1$
                CnAWorkspace.getInstance().getWorkdir().replaceAll("\\\\", "/")); //$NON-NLS-1$ //$NON-NLS-2$
        return tmpDerbyUrl.replace(VERINICEDB, TEMPIMPORTDB);
    }

    public String getTempImportDbDirName() {
        return CnAWorkspace.getInstance().getWorkdir() + File.separator + TEMPIMPORTDB;
    }

    public static synchronized CnAWorkspace getInstance() {
        if (instance == null) {
            instance = new CnAWorkspace();
            Activator.getDefault().getPluginPreferences().addPropertyChangeListener(instance.prefChangeListener);
        }
        return instance;
    }

    /**
     * Initialize new workspace folder with config and other files that are
     * distributed with the application.
     *
     *
     */
    public void prepare(boolean force) {
        prepareWorkDir();

        if (!force && confDir.exists() && confDir.isDirectory()) {
            File confFile = new File(confDir, "configuration.version"); //$NON-NLS-1$
            if (confFile.exists()) {
                Properties props = new Properties();
                FileInputStream fis = null;
                try {
                    fis = new FileInputStream(confFile);
                    props.load(fis);

                    if (props.get("version").equals(CONFIG_CURRENT_VERSION)) { //$NON-NLS-1$
                        LOG.debug("Arbeitsverzeichnis bereits vorhanden, wird nicht neu erzeugt: " //$NON-NLS-1$
                                + confDir.getAbsolutePath());
                        return;
                    }
                } catch (Exception e) {
                    LOG.debug(e);
                } finally {
                    if (fis != null) {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            LOG.error("Error while closing FileInputStream", e);
                        }
                    }
                }
            }

        }

        CnAWorkspace workspace = new CnAWorkspace();
        try {
            workspace.createConfDir();
            workspace.createConfDirFiles();
            workspace.createHtmlDir();
            workspace.createOfficeDir();
            workspace.createDatabaseConfig();
            workspace.createGstoolPropertyFiles();
        } catch (Exception e) {
            ExceptionUtil.log(e, NLS.bind(Messages.CnAWorkspace_4, confDir.getAbsolutePath()));
        }

    }

    public synchronized void prepareWorkDir() {
        URL url = Platform.getInstanceLocation().getURL();
        String path = url.getPath().replaceAll("/", "\\" + File.separator); //$NON-NLS-1$ //$NON-NLS-2$
        workDir = (new File(path)).getAbsolutePath();
        confDir = new File(url.getPath() + File.separator + CONF); //$NON-NLS-1$
    }

    public String getWorkdir() {
        return workDir;
    }

    /**
     * Returns the full path to configuration dir of the client: usually:
     * <verinice_install_dir>/workspace/conf e.g.:
     * /home/fifi/verinice-1.1.0/workspace/conf
     *
     * @return the full path to configuration dir of the client
     */
    public String getConfDir() {
        return workDir + File.separator + CONF; //$NON-NLS-1$
    }

    private void createConfDirFiles() throws IOException {
        createTextFile(CONF + File.separator + "reports.properties_skeleton", workDir, //$NON-NLS-1$
                CONF + File.separator + "reports.properties"); //$NON-NLS-1$ //$NON-NLS-3$ //$NON-NLS-4$
        createTextFile(CONF + File.separator + "configuration.version", workDir); //$NON-NLS-1$ //$NON-NLS-2$
    }

    public void createConfDir() throws IOException {
        URL url = Platform.getInstanceLocation().getURL();
        File dir = new File(url.getPath() + File.separator + CONF); //$NON-NLS-1$
        dir.mkdirs();
    }

    private void createOfficeDir() throws IOException {
        URL url = Platform.getInstanceLocation().getURL();
        File officeDir = new File(url.getPath() + File.separator + OFFICEDIR);
        officeDir.mkdirs();

        createBinaryFile(OFFICEDIR + File.separator + "report.ods", workDir); //$NON-NLS-1$
        createBinaryFile(OFFICEDIR + File.separator + "report.odt", workDir); //$NON-NLS-1$
        createBinaryFile(OFFICEDIR + File.separator + "sernet.png", workDir); //$NON-NLS-1$

    }

    private void createHtmlDir() throws IOException {
        URL url = Platform.getInstanceLocation().getURL();
        String html = "html";
        File htmlDir = new File(url.getPath() + File.separator + html); //$NON-NLS-1$
        htmlDir.mkdirs();

        createTextFile(html + File.separator + "screen.css", workDir); //$NON-NLS-1$ //$NON-NLS-2$
        createTextFile(html + File.separator + "about.html", workDir); //$NON-NLS-1$ //$NON-NLS-2$
        createBinaryFile("browserdefault.png", workDir + File.separator + html); //$NON-NLS-1$ //$NON-NLS-2$
    }

    private void createGstoolPropertyFiles() throws IOException {
        createTextFile(CONF + File.separator + GstoolTypeMapper.TYPE_PROPERTIES_FILE,
                VeriniceCharset.CHARSET_ISO_8859_15, getConfDir(), GstoolTypeMapper.TYPE_PROPERTIES_FILE,
                VeriniceCharset.CHARSET_ISO_8859_15, null);
        createTextFile(CONF + File.separator + GstoolTypeMapper.SUBTYPE_PROPERTIES_FILE,
                VeriniceCharset.CHARSET_ISO_8859_15, getConfDir(), GstoolTypeMapper.SUBTYPE_PROPERTIES_FILE,
                VeriniceCharset.CHARSET_ISO_8859_15, null);
    }

    /**
     * Copy resource from classpath (i.e. inside JAR file) to local filesystem.
     *
     * @param infile
     * @param toDir
     * @throws IOException
     */
    private void createBinaryFile(String infile, String toDir) throws IOException {

        backupFile(toDir, infile);

        String infileResource = infile.replace('\\', '/');
        InputStream in = getClass().getClassLoader().getResourceAsStream(infileResource);
        OutputStream out = null;
        try {
            out = new FileOutputStream(toDir + File.separator + infile);
            while (true) {
                synchronized (BUFFER) {
                    int amountRead = in.read(BUFFER);
                    if (amountRead == -1) {
                        break;
                    }
                    out.write(BUFFER, 0, amountRead);
                }
            }
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
        }
    }

    public void createGstoolImportDatabaseConfig(String url, String user, String pass) throws IOException {
        final int settingsSize = 5;
        HashMap<String, String> settings = new HashMap<String, String>(settingsSize);
        settings.put("url", url.replace("\\", "\\\\")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        settings.put("user", user); //$NON-NLS-1$
        settings.put("pass", pass); //$NON-NLS-1$

        // import from .mdb file over odbc bridge goes into temporary derby db
        // first:
        if (url.indexOf("odbc") > -1) { //$NON-NLS-1$
            // change db url to temporary DB when importing from mdb file
            String dbUrl = createTempImportDbUrl();
            settings.put("url", dbUrl); //$NON-NLS-1$
            settings.put("driver", PreferenceConstants.DB_DRIVER_DERBY); //$NON-NLS-1$
            settings.put("dialect", PreferenceConstants.DB_DIALECT_DERBY); //$NON-NLS-1$
        } else {
            // direct import from ms sql server or desktop engine:
            settings.put("driver", PreferenceConstants.GS_DB_DRIVER_JTDS); //$NON-NLS-1$
            settings.put("dialect", PreferenceConstants.GS_DB_DIALECT_JTDS); //$NON-NLS-1$
        }

        createTextFile(CONF + File.separator + "skel_hibernate-vampire.cfg.xml", //$NON-NLS-1$ //$NON-NLS-2$
                workDir, CONF + File.separator + "hibernate-vampire.cfg.xml", //$NON-NLS-1$ //$NON-NLS-2$
                settings);
    }

    public void createGstoolImportDatabaseConfig() throws IOException {
        Preferences prefs = Activator.getDefault().getPluginPreferences();
        createGstoolImportDatabaseConfig(prefs.getString(PreferenceConstants.GS_DB_URL),
                prefs.getString(PreferenceConstants.GS_DB_USER), prefs.getString(PreferenceConstants.GS_DB_PASS));
    }

    private void createTextFile(String infile, String toDir) throws IOException {
        createTextFile(infile, toDir, infile, null);
    }

    private void createTextFile(String infile, String toDir, String outfile)
            throws NullPointerException, IOException {
        createTextFile(infile, toDir, outfile, null);
    }

    /**
     * Create a text file in the local file system from a resource (i.e. inside
     * a JAR file distributed with the application).
     * 
     * Adapt line-feeds to local settings and optionally replace variables with
     * values given in a hashmap.
     * 
     * @param infile
     *            relative path to a file accessed by a class loader
     * @param toDir
     *            path to directory of the created file
     * @param outfile
     *            name of created file
     * @param variables
     *            property added to the file, may be null
     * @throws NullPointerException
     * @throws IOException
     */
    protected void createTextFile(String infile, String toDir, String outfile, Map<String, String> variables)
            throws NullPointerException, IOException {
        createTextFile(infile, VeriniceCharset.CHARSET_DEFAULT, toDir, outfile, VeriniceCharset.CHARSET_DEFAULT,
                variables);
    }

    /**
     * Create a text file in the local file system from a resource (i.e. inside
     * a JAR file distributed with the application).
     *
     * Adapt line-feeds to local settings and optionally replace variables with
     * values given in a hashmap.
     *
     * Files are converted from charsetInfile to CHARSET_DEFAULT.
     *
     * @param infile
     *            relative path to a file accessed by a class loader
     * @param charsetInfile
     *            charset of input file Files are converted from charsetInfile
     *            to VeriniceCharset.CHARSET_DEFAULT
     * @param toDir
     *            path to directory of the created file
     * @param outfile
     *            name of created file
     * @param variables
     *            property added to the file, may be null
     * @throws NullPointerException
     * @throws IOException
     */
    protected void createTextFile(String infile, Charset charsetInfile, String toDir, String outfile,
            Map<String, String> variables) throws NullPointerException, IOException {
        createTextFile(infile, charsetInfile, toDir, outfile, VeriniceCharset.CHARSET_DEFAULT, variables);
    }

    /**
     * Create a text file in the local file system from a resource (i.e. inside
     * a JAR file distributed with the application).
     *
     * Adapt line-feeds to local settings and optionally replace variables with
     * values given in a hashmap.
     *
     * Files are converted from charsetInfile to CHARSET_DEFAULT.
     *
     * @param infile
     *            relative path to a file accessed by a class loader
     * @param charsetInfile
     *            charset of input file Files are converted from charsetInfile
     *            to charsetOutfile
     * @param toDir
     *            path to directory of the created file
     * @param outfile
     *            name of created file
     * @param charsetOutfile
     *            charset of output file
     * @param variables
     *            property added to the file, may be null
     * @throws NullPointerException
     * @throws IOException
     */
    protected void createTextFile(String infile, Charset charsetInfile, String toDir, String outfile,
            Charset charsetOutfile, Map<String, String> variables) throws NullPointerException, IOException {

        String infileResource = infile.replace('\\', '/');
        InputStream is = getClass().getClassLoader().getResourceAsStream(infileResource);
        InputStreamReader inRead = new InputStreamReader(is, charsetInfile);
        BufferedReader bufRead = new BufferedReader(inRead);
        StringBuffer skelFile = new StringBuffer();

        // write from skel file, replacing newline characters to system
        // specific:
        String line;
        Pattern var = Pattern.compile("\\{(.*)\\}"); //$NON-NLS-1$
        while ((line = bufRead.readLine()) != null) {
            line = line.replaceFirst("\n", LINE_SEP); //$NON-NLS-1$
            if (variables != null) {
                Matcher match = var.matcher(line);
                if (match.find()) {
                    line = match.replaceFirst(variables.get(match.group(1)));
                }
            }
            skelFile.append(line + LINE_SEP);
        }
        bufRead.close();
        inRead.close();
        is.close();

        backupFile(toDir, outfile);
        FileOutputStream fout = new FileOutputStream(toDir + File.separator + outfile, false);
        OutputStreamWriter outWrite = new OutputStreamWriter(fout, charsetOutfile);
        outWrite.write(skelFile.toString());
        outWrite.close();
        fout.close();
    }

    private void backupFile(String dir, String filepath) throws IOException {
        File file = new File(dir + File.separator + filepath);
        if (file.exists()) {
            File outfile = new File(dir + File.separator + filepath + ".bak"); //$NON-NLS-1$
            FileUtils.copyFile(file, outfile);
        }
    }

    public synchronized void createDatabaseConfig() throws IOException, IllegalStateException {

        Preferences prefs = Activator.getDefault().getPluginPreferences();

        Activator.getDefault().getInternalServer().configureDatabase(prefs.getString(PreferenceConstants.DB_URL),
                prefs.getString(PreferenceConstants.DB_USER), prefs.getString(PreferenceConstants.DB_PASS),
                prefs.getString(PreferenceConstants.DB_DRIVER), prefs.getString(PreferenceConstants.DB_DIALECT));

        Activator.getDefault().getInternalServer().configureSearch(
                prefs.getBoolean(PreferenceConstants.SEARCH_DISABLE),
                prefs.getBoolean(PreferenceConstants.SEARCH_INDEX_ON_STARTUP));

        createGstoolImportDatabaseConfig(prefs.getString(PreferenceConstants.GS_DB_URL),
                prefs.getString(PreferenceConstants.GS_DB_USER), prefs.getString(PreferenceConstants.GS_DB_PASS));
    }

    public void prepare() {
        prepare(false);
    }

    public boolean createReportTemplateDir(String reportFolder) {
        StringBuilder sb = new StringBuilder();
        sb.append(getWorkdir());
        sb.append(File.separatorChar);
        sb.append(reportFolder);
        sb.append(File.separatorChar);
        File reportDir = new File(sb.toString());
        if (!reportDir.exists()) {
            return reportDir.mkdirs(); // cretae directory
        } else {
            return true; // everythings fine
        }
    }

    public boolean createLocalReportTemplateDir(String reportFolder) {

        File reportDir = new File(reportFolder);
        if (!reportDir.exists()) {
            return reportDir.mkdirs(); // cretae directory
        } else {
            return true; // everythings fine
        }
    }

    public String getLocalReportTemplateDir() {
        return attachDirToWorkDir(IReportService.VERINICE_REPORTS_LOCAL);
    }

    public String getRemoteReportTemplateDir() {
        return attachDirToWorkDir(IReportService.VERINICE_REPORTS_REMOTE);
    }

    private String attachDirToWorkDir(String dir) {
        StringBuilder sb = new StringBuilder();
        sb.append(getWorkdir());
        sb.append(File.separatorChar);
        sb.append(dir);
        sb.append(File.separatorChar);
        return sb.toString();
    }

}