org.pgptool.gui.config.impl.ConfigRepositoryImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.pgptool.gui.config.impl.ConfigRepositoryImpl.java

Source

/*******************************************************************************
 * PGPTool is a desktop application for pgp encryption/decryption
 * Copyright (C) 2017 Sergey Karpushin
 *
 * 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/>
 *******************************************************************************/
package org.pgptool.gui.config.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import org.apache.log4j.Logger;
import org.pgptool.gui.config.api.ConfigRepository;
import org.pgptool.gui.config.api.ConfigsBasePathResolver;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.summerb.approaches.jdbccrud.api.dto.EntityChangedEvent;
import org.summerb.approaches.jdbccrud.common.DtoBase;

import com.google.common.base.Preconditions;
import com.google.common.eventbus.EventBus;

public class ConfigRepositoryImpl implements ConfigRepository, InitializingBean {
    private static Logger log = Logger.getLogger(ConfigRepositoryImpl.class);
    private ConfigsBasePathResolver configsBasePathResolver;
    private String configsBasepath = File.separator + "configs";
    private EventBus eventBus;

    @Override
    public void afterPropertiesSet() throws Exception {
        ensureAllDirsCreated();
    }

    private void ensureAllDirsCreated() {
        File configsFolder = new File(configsBasePathResolver.getConfigsBasePath() + configsBasepath);
        if (!configsFolder.exists() && !configsFolder.mkdirs()) {
            throw new RuntimeException("Failed to ensure all dirs for config files: " + configsFolder);
        }
    }

    @Override
    public <T extends DtoBase> void persist(T object) {
        persist(object, null);
    }

    @Override
    public <T extends DtoBase> void persist(T object, String clarification) {
        try {
            Preconditions.checkArgument(object != null, "Can't persist null object");
            String filename = buildFilenameForClass(object.getClass());
            filename = addClarification(filename, clarification);
            writeObject(object, filename);
            eventBus.post(EntityChangedEvent.updated(object));
        } catch (Throwable t) {
            throw new RuntimeException("Failed to persist object " + object, t);
        }
    }

    private String addClarification(String filename, String clarification) {
        if (StringUtils.hasText(clarification)) {
            filename += "." + clarification;
        }
        return filename;
    }

    private String buildFilenameForClass(Class<?> clazz) {
        return configsBasePathResolver.getConfigsBasePath() + configsBasepath + File.separator
                + clazz.getSimpleName();
    }

    @Override
    public <T extends DtoBase> T read(Class<T> clazz) {
        return read(clazz, null);
    }

    @Override
    public <T extends DtoBase> T read(Class<T> clazz, String clarification) {
        try {
            Preconditions.checkArgument(clazz != null, "Class must be provided");
            String filename = buildFilenameForClass(clazz);
            filename = addClarification(filename, clarification);
            if (!new File(filename).exists()) {
                return null;
            }
            return readObject(filename);
        } catch (Throwable t) {
            throw new RuntimeException("Failed to read object of class " + clazz, t);
        }
    }

    @Override
    public <T extends DtoBase> T readOrConstruct(Class<T> clazz) {
        return readOrConstruct(clazz, null);
    }

    @Override
    public <T extends DtoBase> T readOrConstruct(Class<T> clazz, String clarification) {
        T result = read(clazz, clarification);
        if (result == null) {
            try {
                result = clazz.newInstance();
            } catch (Throwable t) {
                throw new RuntimeException("Failed to create new instance of " + clazz, t);
            }
        }

        return result;
    }

    @SuppressWarnings("unchecked")
    public static <T extends DtoBase> T readObject(String sourceFile) {
        ObjectInputStream ois = null;
        try {
            File file = new File(sourceFile);
            if (!file.exists()) {
                return null;
            }

            FileInputStream fis = new FileInputStream(file);
            ois = new ObjectInputStream(fis);
            T ret = (T) ois.readObject();
            ois.close();
            return ret;
        } catch (Throwable t) {
            log.warn("Failed to read " + sourceFile, t);
            return null;
        } finally {
            safeClose(ois);
        }
    }

    public static void safeClose(ObjectInputStream fis) {
        if (fis != null) {
            try {
                fis.close();
            } catch (Throwable t) {
                // don't care
            }
        }
    }

    public static void writeObject(Object o, String destinationFile) {
        ObjectOutputStream oos = null;
        try {
            log.trace(String.format("Persisting %s to %s", o, destinationFile));

            File file = new File(destinationFile);
            if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) {
                throw new RuntimeException("Failed to create all parent directories");
            }

            FileOutputStream fout = new FileOutputStream(file);
            oos = new ObjectOutputStream(fout);
            oos.writeObject(o);
            oos.flush();
            oos.close();
            fout.close();
        } catch (Throwable t) {
            throw new RuntimeException("Failed to write config: " + destinationFile, t);
        } finally {
            safeClose(oos);
        }
    }

    public static void safeClose(ObjectOutputStream fis) {
        if (fis != null) {
            try {
                fis.close();
            } catch (Throwable t) {
                // don't care
            }
        }
    }

    public ConfigsBasePathResolver getConfigsBasePathResolver() {
        return configsBasePathResolver;
    }

    @Autowired
    public void setConfigsBasePathResolver(ConfigsBasePathResolver configsBasePathResolver) {
        this.configsBasePathResolver = configsBasePathResolver;
    }

    public EventBus getEventBus() {
        return eventBus;
    }

    @Autowired
    public void setEventBus(EventBus eventBus) {
        this.eventBus = eventBus;
    }

}