com.xse.optstack.persconftool.base.persistence.PersConfExport.java Source code

Java tutorial

Introduction

Here is the source code for com.xse.optstack.persconftool.base.persistence.PersConfExport.java

Source

/*******************************************************************************
 * Persistence Configuration Tool Base
 *
 * Copyright (c) 2015 Mentor Graphics and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *      Mentor Graphics - initial API and implementation
 ******************************************************************************/
package com.xse.optstack.persconftool.base.persistence;

import java.io.File;
import java.io.FileFilter;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Function;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;

import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.xse.eclipseui.util.Logger;
import com.xse.eclipseui.util.StringUtils;
import com.xse.optstack.persconf.EApplication;
import com.xse.optstack.persconf.EApplicationGroup;
import com.xse.optstack.persconf.EConfiguration;
import com.xse.optstack.persconf.EDefaultData;
import com.xse.optstack.persconf.EDefaultDataType;
import com.xse.optstack.persconf.EPolicy;
import com.xse.optstack.persconf.EResource;
import com.xse.optstack.persconf.EStorage;
import com.xse.optstack.persconf.impl.EApplicationImpl;
import com.xse.optstack.persconf.impl.EConfigurationImpl;
import com.xse.optstack.persconf.impl.EDefaultDataImpl;
import com.xse.optstack.persconftool.base.Activator;

/**
 * Utility class fully handling the export procedure of persconf configurations.
 *
 * @author philipb
 *
 */
public class PersConfExport {

    private final File rootFolder;

    /**
     *
     * @param targetPath
     *            fully qualified path to the folder a configuration should be exported to
     */
    public PersConfExport(final String targetPath) {
        this.rootFolder = new File(targetPath);
    }

    /**
     * Actually starts the exporting of the specified {@link Resource} to the location assigned on construction of this
     * exporter instance.
     *
     * @param resource
     *            persconf resource that should be exported
     * @return true if the export did fully succeed, false if there have been errors and the configuration probably
     *         hasn't been fully exported
     */
    public boolean export(final Resource resource) {
        final File resourceFolder = new File(
                this.rootFolder.getAbsolutePath() + File.separator + PersConfDefinitions.RESOURCE_FOLDER_NAME);
        try {
            resourceFolder.mkdir();
        } catch (final SecurityException e) {
            Logger.error(Activator.PLUGIN_ID,
                    "Not allowed to create resource folder: " + resourceFolder.getAbsolutePath(), e);
            return false;
        }

        boolean persistStatus = true;
        for (final EObject eObject : resource.getContents()) {
            if (eObject instanceof EApplicationGroup) {
                final boolean status = this.persistGroup(resourceFolder, (EApplicationGroup) eObject);
                if (!status) {
                    persistStatus = false;
                }
            }
        }

        this.exportAppSizes(resource);

        return persistStatus;
    }

    private void exportCHeader(final EApplication application) {
        if (application.getResources().size() > 0) {
            final File headerFolder = new File(this.rootFolder + File.separator + "header");
            try {
                headerFolder.mkdir();
            } catch (final SecurityException e) {
                Logger.error(Activator.PLUGIN_ID,
                        "Not allowed to create header folder: " + headerFolder.getAbsolutePath(), e);
            }
            if (headerFolder.exists() && headerFolder.canExecute()) {
                final String lineSeparator = System.getProperty("line.separator");
                try (final FileWriter fileWriter = new FileWriter(
                        headerFolder + File.separator + application.getName() + ".h")) {
                    for (final EResource eResource : application.getResources()) {
                        fileWriter.write("#define ");
                        fileWriter.write(
                                application.getName().toUpperCase() + "_" + eResource.getName().toUpperCase());
                        fileWriter.write(" " + eResource.getName() + lineSeparator);
                    }
                } catch (final IOException e) {
                    Logger.error(Activator.PLUGIN_ID,
                            "Unable to create header file for " + application.getName() + ".", e);
                }
            } else {
                Logger.error(Activator.PLUGIN_ID,
                        "Unable to read header folder: " + headerFolder.getAbsolutePath());
            }
        }
    }

    private void exportAppSizes(final Resource resource) {
        final String lineSeparator = System.getProperty("line.separator");

        final StringBuilder outputBuilder = new StringBuilder();
        for (final EObject eObject : resource.getContents()) {
            if (eObject instanceof EApplicationGroup) {
                final EApplicationGroup group = (EApplicationGroup) eObject;
                for (final EApplication application : group.getApplications()) {
                    if (application.getSize() != null) {
                        outputBuilder.append(application.getName() + " ");
                        outputBuilder.append(application.getSize().toString() + lineSeparator);
                    }
                }
            }
        }

        if (outputBuilder.length() > 1) {
            final File file = new File(
                    this.rootFolder.getAbsolutePath() + File.separator + PersConfDefinitions.APP_SIZES_FILE_NAME);

            try (final FileWriter fileWriter = new FileWriter(file)) {
                fileWriter.write(outputBuilder.toString());
            } catch (final IOException e) {
                Logger.error(Activator.PLUGIN_ID,
                        "Unable to create application size config file " + file.getAbsolutePath() + ".", e);
            }
        }
    }

    private static GsonBuilder createGsonBuilder() {
        final GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.setExclusionStrategies(new EmfExclusionStrategy());
        gsonBuilder.setPrettyPrinting();

        return gsonBuilder;
    }

    private boolean persistGroup(final File resourceFolder, final EApplicationGroup group) {
        final boolean persistStatus = true;

        final File groupFolder = new File(
                resourceFolder.getAbsolutePath() + File.separator + group.getType().getLiteral().toLowerCase());
        try {
            groupFolder.mkdir();
        } catch (final SecurityException e) {
            Logger.error(Activator.PLUGIN_ID,
                    "Not allowed to create group folder: " + groupFolder.getAbsolutePath(), e);
            return false;
        }

        final Set<String> appNames = new HashSet<>();

        // ################ Installation Rules
        final Gson installRulesJson = PersConfExport.createGsonBuilder().create();
        final JsonObject installRulesObj = new JsonObject();
        for (final EApplication eApplication : group.getApplications()) {
            if (eApplication.getInstallRule() != null) {
                installRulesObj.add(eApplication.getName(), new JsonPrimitive(
                        PersConfDefinitions.INSTALL_RULE_PREFIX + eApplication.getInstallRule().getLiteral()));
            }
        }
        try (final FileWriter fileWriter = new FileWriter(new File(
                groupFolder.getAbsolutePath() + File.separator + PersConfDefinitions.INSTALL_RULES_FILE))) {
            fileWriter.write(installRulesJson.toJson(installRulesObj));
        } catch (final IOException e) {
            Logger.error(Activator.PLUGIN_ID, "Error writing install rules configuration file!", e);
        }

        // ################ Ownership Configuration
        final Gson ownershipConfigurationJson = PersConfExport.createGsonBuilder().create();
        final JsonObject ownershipConfigurationObj = new JsonObject();
        for (final EApplication eApplication : group.getApplications()) {
            final JsonObject appElement = new JsonObject();

            boolean saveApplication = false;

            if (eApplication.getUserName() == null || eApplication.getUserName().equals(""))
                appElement.add(PersConfDefinitions.USERNAME_KEY_NAME, new JsonPrimitive(""));
            else {
                appElement.add(PersConfDefinitions.USERNAME_KEY_NAME,
                        new JsonPrimitive(eApplication.getUserName()));
                saveApplication = true;
            }

            if (eApplication.getGroupName() == null || eApplication.getGroupName().equals(""))
                appElement.add(PersConfDefinitions.GROUPNAME_KEY_NAME, new JsonPrimitive(""));
            else {
                appElement.add(PersConfDefinitions.GROUPNAME_KEY_NAME,
                        new JsonPrimitive(eApplication.getGroupName()));
                saveApplication = true;
            }

            if (eApplication.getUserId() == null)
                appElement.add(PersConfDefinitions.USERID_KEY_NAME, new JsonPrimitive(""));
            else {
                appElement.add(PersConfDefinitions.USERID_KEY_NAME,
                        new JsonPrimitive(String.valueOf(eApplication.getUserId())));
                saveApplication = true;
            }

            if (eApplication.getGroupId() == null)
                appElement.add(PersConfDefinitions.GROUPID_KEY_NAME, new JsonPrimitive(""));
            else {
                appElement.add(PersConfDefinitions.GROUPID_KEY_NAME,
                        new JsonPrimitive(String.valueOf(eApplication.getGroupId())));
                saveApplication = true;
            }

            if (saveApplication)
                ownershipConfigurationObj.add(eApplication.getName(), appElement);
        }
        try (final FileWriter fileWriter = new FileWriter(new File(groupFolder.getAbsolutePath() + File.separator
                + PersConfDefinitions.OWNERSHIP_CONFIGURATION_FILE))) {
            fileWriter.write(ownershipConfigurationJson.toJson(ownershipConfigurationObj));
        } catch (final IOException e) {
            Logger.error(Activator.PLUGIN_ID, "Error writing ownership configuration file!", e);
        }

        for (final EApplication eApplication : group.getApplications()) {
            final File applicationFolder = new File(groupFolder + File.separator + eApplication.getName());
            applicationFolder.mkdir();

            this.exportCHeader(eApplication);

            // ################ Resource Configuration
            final GsonBuilder resourceConfigJsonBuilder = PersConfExport.createGsonBuilder();
            resourceConfigJsonBuilder.registerTypeAdapter(EApplicationImpl.class,
                    new ResouceConfigurationApplicationTypeAdapter());
            resourceConfigJsonBuilder.registerTypeAdapter(EConfigurationImpl.class,
                    new ResourceConfigurationConfigurationTypeAdapter());
            resourceConfigJsonBuilder.registerTypeAdapter(EPolicy.class, new ResouceConfigurationTypeAdapter());
            resourceConfigJsonBuilder.registerTypeAdapter(EStorage.class, new ResouceConfigurationTypeAdapter());
            resourceConfigJsonBuilder.registerTypeAdapter(EDefaultDataType.class,
                    new ResouceConfigurationTypeAdapter());
            resourceConfigJsonBuilder.setExclusionStrategies(new ExclusionStrategy() {
                @Override
                public boolean shouldSkipField(final FieldAttributes fieldAttributes) {
                    return false;
                }

                @Override
                public boolean shouldSkipClass(final Class<?> clazz) {
                    return clazz.isAssignableFrom(EDefaultData.class);
                }
            });
            final Gson gson = resourceConfigJsonBuilder.create();
            try (final FileWriter fileWriter = new FileWriter(new File(applicationFolder.getAbsolutePath()
                    + File.separator + PersConfDefinitions.RESOURCE_CONFIGURATION_FILE))) {
                fileWriter.write(gson.toJson(eApplication));
            } catch (final IOException e) {
                Logger.error(Activator.PLUGIN_ID, "Error writing resource configuration file!", e);
            }

            // ################ Install Exceptions
            final Gson installExceptionsGson = PersConfExport.createGsonBuilder().create();
            final JsonObject installExceptionsObj = new JsonObject();
            for (final EResource resource : eApplication.getResources()) {
                if (resource.getInstallException() != null) {
                    installExceptionsObj.add(resource.getName(),
                            new JsonPrimitive(PersConfDefinitions.INSTALL_EXCEPTION_PREFIX
                                    + resource.getInstallException().getLiteral()));
                }
            }
            try (final FileWriter fileWriter = new FileWriter(new File(applicationFolder.getAbsolutePath()
                    + File.separator + PersConfDefinitions.INSTALL_EXCEPTIONS_FILE))) {
                fileWriter.write(installExceptionsGson.toJson(installExceptionsObj));
            } catch (final IOException e) {
                Logger.error(Activator.PLUGIN_ID, "Error writing install exceptions configuration file!", e);
            }

            final File fileFolder = new File(applicationFolder + File.separator + PersConfDefinitions.FILE_FOLDER);
            fileFolder.mkdir();
            final File configDefaultFileFolder = new File(
                    fileFolder + File.separator + PersConfDefinitions.CONFIGURABLE_DEFAULT_DATA_FOLDER);
            configDefaultFileFolder.mkdir();
            final File defaultFileFolder = new File(
                    fileFolder + File.separator + PersConfDefinitions.DEFAULT_DATA_FOLDER);
            defaultFileFolder.mkdir();

            // ################ Default Data
            final File keyFolder = new File(applicationFolder + File.separator + PersConfDefinitions.KEY_FOLDER);
            keyFolder.mkdir();

            // ################ Factory Default
            //            boolean hasDefaultKeyData = false;
            //            for (final EResource eResource : eApplication.getResources()) {
            //                if (DefaultDataApplicationTypeAdapter.hasDefaultDataValue(eResource.getConfiguration().getFactoryDefault())) {
            //                    hasDefaultKeyData = true;
            //                    break;
            //                }
            //            }

            PersConfExport.copyDefaultDataFiles(defaultFileFolder, eApplication, EConfiguration::getFactoryDefault);

            final File factoryDefaultsFile = new File(
                    keyFolder.getAbsolutePath() + File.separator + PersConfDefinitions.FACTORY_DEFAULTS_FILE);
            final GsonBuilder factoryDefaultGsonBuilder = PersConfExport.createGsonBuilder();
            factoryDefaultGsonBuilder.registerTypeAdapter(EApplicationImpl.class,
                    new DefaultDataApplicationTypeAdapter(true));
            factoryDefaultGsonBuilder.registerTypeAdapter(EDefaultDataImpl.class, new DefaultDataTypeAdapter());
            final Gson factoryDefaultGson = factoryDefaultGsonBuilder.create();
            try (final FileWriter fileWriter = new FileWriter(factoryDefaultsFile)) {
                fileWriter.write(factoryDefaultGson.toJson(eApplication));
            } catch (final IOException e) {
                e.printStackTrace();
            }

            // ################ Configurable Default
            //            hasDefaultKeyData = false;
            //            for (final EResource eResource : eApplication.getResources()) {
            //                if (DefaultDataApplicationTypeAdapter.hasDefaultDataValue(eResource.getConfiguration().getConfigDefault())) {
            //                    hasDefaultKeyData = true;
            //                    break;
            //                }
            //            }

            PersConfExport.copyDefaultDataFiles(configDefaultFileFolder, eApplication,
                    EConfiguration::getConfigDefault);

            final File configDefaultsFile = new File(
                    keyFolder.getAbsolutePath() + File.separator + PersConfDefinitions.CONFIGURABLE_DEFAULTS_FILE);
            final GsonBuilder configurableDefaultGsonBuilder = PersConfExport.createGsonBuilder();
            configurableDefaultGsonBuilder.registerTypeAdapter(EApplicationImpl.class,
                    new DefaultDataApplicationTypeAdapter(false));
            configurableDefaultGsonBuilder.registerTypeAdapter(EDefaultDataImpl.class,
                    new DefaultDataTypeAdapter());
            final Gson configurableDefaultGson = configurableDefaultGsonBuilder.create();
            try (final FileWriter fileWriter = new FileWriter(configDefaultsFile)) {
                fileWriter.write(configurableDefaultGson.toJson(eApplication));
            } catch (final IOException e) {
                e.printStackTrace();
            }

            appNames.add(eApplication.getName());
        }

        final File[] groupFiles = groupFolder.listFiles((FileFilter) DirectoryFileFilter.INSTANCE);
        // remove all application folders not part of the current configuration anymore
        if (groupFiles != null) {
            for (final File appFolder : groupFiles) {
                if (!appNames.contains(appFolder.getName())) {
                    try {
                        FileUtils.deleteDirectory(appFolder);
                    } catch (final IOException e) {
                        Logger.error(Activator.PLUGIN_ID,
                                "Unable to delete removed application directory: " + appFolder.getName(), e);
                    }
                }
            }
        }

        return persistStatus;
    }

    private static void copyDefaultDataFiles(final File targetBaseFolder, final EApplication application,
            final Function<EConfiguration, EDefaultData> defaultDataProvider) {
        for (final EResource eResource : application.getResources()) {
            // copy default data files in case we have a file-based default data configuration with new file refs
            if (eResource.getConfiguration().getType() == EDefaultDataType.FILE) {
                final EDefaultData factoryDefaultData = defaultDataProvider.apply(eResource.getConfiguration());
                if (!StringUtils.isEmpty(factoryDefaultData.getLocalResourcePath())) {
                    final File dataFile = new File(factoryDefaultData.getLocalResourcePath());
                    if (dataFile.exists() && dataFile.canRead()) {
                        try {
                            final Path source = Paths.get(dataFile.toURI());
                            final Path target = Paths.get(new File(
                                    targetBaseFolder.getAbsolutePath() + File.separator + eResource.getName())
                                            .toURI());
                            Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
                        } catch (final IOException | IllegalArgumentException | SecurityException e) {
                            Logger.error(Activator.PLUGIN_ID,
                                    "Error copying factory default file to target location: " + eResource.getName(),
                                    e);
                        }
                    } else {
                        Logger.warn(Activator.PLUGIN_ID, "Invalid factory default data path!");
                    }
                }
            }
        }
    }

}