org.bidib.wizard.server.spring.SettingsLocationEnvironmentPostProcessor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bidibwizard-server Show documentation
Show all versions of bidibwizard-server Show documentation
jBiDiB BiDiB Wizard Server POM
package org.bidib.wizard.server.spring;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Properties;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.apache.commons.logging.Log;
import org.bidib.wizard.api.locale.Resources;
import org.bidib.wizard.api.utils.WizardUtils;
import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.config.ConfigDataEnvironmentUpdateListener;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.logging.DeferredLogFactory;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.ResourceLoader;
public class SettingsLocationEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
public static final int ORDER = Ordered.HIGHEST_PRECEDENCE + 7;
private final Log logger;
private final ConfigurableBootstrapContext bootstrapContext;
private final ConfigDataEnvironmentUpdateListener environmentUpdateListener;
public SettingsLocationEnvironmentPostProcessor(DeferredLogFactory logFactory,
ConfigurableBootstrapContext bootstrapContext) {
this(logFactory, bootstrapContext, null);
}
public SettingsLocationEnvironmentPostProcessor(DeferredLogFactory logFactory,
ConfigurableBootstrapContext bootstrapContext, ConfigDataEnvironmentUpdateListener environmentUpdateListener) {
this.logger = logFactory.getLog(getClass());
this.bootstrapContext = bootstrapContext;
this.environmentUpdateListener = environmentUpdateListener;
}
@Override
public int getOrder() {
return ORDER;
}
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
postProcessEnvironment(environment, application.getResourceLoader(), application.getAdditionalProfiles());
}
private static final String WIZARD_SETTINGSFILE_LOCATION_REFERENCE = "wizard2.properties";
private static final String WIZARD_SETTINGSFILE_LOCATION_PROPERTY = "wizard.settings.file-location";
private String wizardConfigurationFileLocationReference;
void postProcessEnvironment(
ConfigurableEnvironment environment, ResourceLoader resourceLoader, Collection additionalProfiles) {
try {
wizardConfigurationFileLocationReference =
environment.getProperty(WIZARD_SETTINGSFILE_LOCATION_PROPERTY, "${user.home}/.bidib");
wizardConfigurationFileLocationReference =
environment.resolvePlaceholders(wizardConfigurationFileLocationReference);
this.logger
.info("Location of settings file location reference: " + wizardConfigurationFileLocationReference);
// check if the reference file to the settings location exists
final File file =
new File(wizardConfigurationFileLocationReference, WIZARD_SETTINGSFILE_LOCATION_REFERENCE);
if (!file.exists()) {
this.logger.info("The settings file location reference was not found.");
selectLocation(environment, file);
}
else {
// get the location of the wizard configuration files
this.logger.info("The settings file location reference was found.");
try (InputStream is = new FileInputStream(file)) {
//
Properties props = new Properties();
props.load(is);
wizardConfigurationFileLocationReference = props.getProperty(WIZARD_SETTINGSFILE_LOCATION_PROPERTY);
SettingsLocationEnvironmentPostProcessor.this.logger
.info("Read wizardSettingsFileLocationReference from location: " + file.getPath()
+ ", wizardConfigurationFileLocationReference: "
+ wizardConfigurationFileLocationReference);
final File location = new File(wizardConfigurationFileLocationReference);
if (!location.exists()) {
try {
FileUtils.forceMkdir(location);
}
catch (Exception ex) {
SettingsLocationEnvironmentPostProcessor.this.logger
.warn("Create directory for wizardSettingsFiles failed.", ex);
}
}
}
catch (Exception ex) {
SettingsLocationEnvironmentPostProcessor.this.logger
.warn("Failed to read the wizardSettingsFileLocationReference from location: " + file.getPath(),
ex);
throw new RuntimeException(
"Failed to read the wizardSettingsFileLocationReference from location: " + file.getPath());
}
}
environment
.getSystemProperties()
.put("wizard.configuration.file-location", wizardConfigurationFileLocationReference);
}
catch (Exception ex) {
this.logger.warn("Fetch the location of settings file location reference failed.", ex);
}
}
private void selectLocation(final ConfigurableEnvironment environment, final File file) {
String userHome = environment.resolvePlaceholders("${user.home}");
logger.info("Select the location for wizard settings files.");
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException ex) {
logger.warn("Set look and feel failed", ex);
}
boolean foundAndUseOldLocation = false;
boolean copyWizardConfigFromOldLocation = false;
// check if the wizard.yml exists in the 'old default directory'
try {
final File oldWizardConfigurationFile = new File(userHome, ".bidib/wizard.yml");
if (oldWizardConfigurationFile.exists()) {
this.logger
.info("Found the wizard.yml in the old default directory: " + oldWizardConfigurationFile.getPath());
// ask the user if he wants to keep this location
int result =
JOptionPane
.showConfirmDialog(JOptionPane.getFrameForComponent(null),
Resources
.getString(SettingsLocationEnvironmentPostProcessor.class, "keep-old-location.message",
oldWizardConfigurationFile.getParentFile().getPath()),
Resources
.getString(SettingsLocationEnvironmentPostProcessor.class, "keep-old-location.title"),
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.YES_OPTION) {
this.logger.info("User accepted to use old configuration location.");
wizardConfigurationFileLocationReference = oldWizardConfigurationFile.getParentFile().getPath();
this.logger
.info("Found and use the configuration from the old location: "
+ wizardConfigurationFileLocationReference);
foundAndUseOldLocation = true;
}
else {
this.logger.info("User declined to use old configuration location.");
copyWizardConfigFromOldLocation = true;
}
}
}
catch (Exception ex) {
this.logger.warn("Check if the wizard.yml exists in the 'old default directory' failed.", ex);
}
if (!foundAndUseOldLocation) {
File defaultDirectory = new File(userHome, WizardUtils.getDefaultConfigSubDir());
SettingsLocationEnvironmentPostProcessor.this.logger
.info("Prepared the default location directory: " + defaultDirectory.getPath());
wizardConfigurationFileLocationReference = defaultDirectory.getPath();
if (!defaultDirectory.exists()) {
SettingsLocationEnvironmentPostProcessor.this.logger
.info("The selected location does not exist and will be created: "
+ wizardConfigurationFileLocationReference);
try {
FileUtils.forceMkdir(defaultDirectory);
}
catch (Exception ex) {
SettingsLocationEnvironmentPostProcessor.this.logger
.warn("Create directory for wizardSettingsFiles failed.", ex);
}
}
else {
SettingsLocationEnvironmentPostProcessor.this.logger
.info("The selected location does exist: " + wizardConfigurationFileLocationReference);
}
SettingsLocationEnvironmentPostProcessor.this.logger
.info("Use the wizardSettingsFileLocationReference: " + wizardConfigurationFileLocationReference);
}
if (!file.getParentFile().exists()) {
try {
FileUtils.forceMkdir(file.getParentFile());
}
catch (Exception ex) {
SettingsLocationEnvironmentPostProcessor.this.logger
.warn("Create directory for wizardSettingsFileLocationReference failed.", ex);
}
}
try (OutputStream os = new FileOutputStream(file)) {
//
Properties props = new Properties();
props.put(WIZARD_SETTINGSFILE_LOCATION_PROPERTY, wizardConfigurationFileLocationReference);
props.store(os, "Added by Wizard 2");
SettingsLocationEnvironmentPostProcessor.this.logger
.info("Wrote wizardSettingsFileLocationReference to location: " + file.getPath());
}
catch (Exception ex) {
SettingsLocationEnvironmentPostProcessor.this.logger
.warn("Write the wizardSettingsFileLocationReference failed: " + file, ex);
throw new RuntimeException("Write the wizardSettingsFileLocationReference failed: " + file);
}
// check if we must copy the existing configuration files to the new location
if (copyWizardConfigFromOldLocation) {
// check if the configuration files exist in the new location already
try {
final File oldDirectory = new File(userHome, ".bidib");
final File newLocationConfigurationFile =
new File(wizardConfigurationFileLocationReference, "wizard.yml");
if (!newLocationConfigurationFile.exists()) {
SettingsLocationEnvironmentPostProcessor.this.logger
.info("copy the existing wizard configuration files to the new location.");
// ask the user if he wants to keep this location
int result =
JOptionPane
.showConfirmDialog(JOptionPane.getFrameForComponent(null),
Resources
.getString(SettingsLocationEnvironmentPostProcessor.class,
"copy-config-from-old-location.message", oldDirectory.getPath()),
Resources
.getString(SettingsLocationEnvironmentPostProcessor.class,
"copy-config-from-old-location.title"),
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.YES_OPTION) {
SettingsLocationEnvironmentPostProcessor.this.logger
.info("User accepted to copy existing configuration files.");
final File oldWizardConfigurationFile = new File(oldDirectory, "wizard.yml");
copyFile(oldWizardConfigurationFile, newLocationConfigurationFile);
FileFilter fileFilter = new WildcardFileFilter("wizardmodule_*.yml");
File[] files = oldDirectory.listFiles(fileFilter);
if (files != null && files.length > 0) {
for (File sourceFile : files) {
File targetFile =
new File(wizardConfigurationFileLocationReference, sourceFile.getName());
copyFile(sourceFile, targetFile);
}
}
else {
SettingsLocationEnvironmentPostProcessor.this.logger
.info("No wizard module configuration files found.");
}
}
else {
SettingsLocationEnvironmentPostProcessor.this.logger
.info("User declined to copy existing configuration files.");
}
}
else {
SettingsLocationEnvironmentPostProcessor.this.logger
.info(
"The wizard configuration file exists in the new location already. Skip copy existing files.");
}
}
catch (Exception ex) {
SettingsLocationEnvironmentPostProcessor.this.logger
.warn("Write the wizardSettingsFileLocationReference failed: " + file, ex);
}
}
}
private void copyFile(File source, File target) {
try (InputStream sourceStream = new FileInputStream(source);
OutputStream targetStream = new FileOutputStream(target)) {
IOUtils.copy(sourceStream, targetStream);
}
catch (Exception ex) {
SettingsLocationEnvironmentPostProcessor.this.logger.warn("Copy configuration file failed: " + source, ex);
}
}
}