From 564ff791dba51da02d021b7ef45e647c7269d02d Mon Sep 17 00:00:00 2001 From: Oluwatobi Bashir-Bello Date: Wed, 13 Aug 2014 15:51:58 -0400 Subject: Add a feature to import a specified settings jar. Change-Id: Idfa2a80d4a57ef5a26228363a7ce7a9286ae3942 --- google-cloud-tools.iml | 1 + .../google/gct/idea/settings/ImportSettings.java | 137 +++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 src/com/google/gct/idea/settings/ImportSettings.java diff --git a/google-cloud-tools.iml b/google-cloud-tools.iml index 9126f4b..6d1ab7c 100644 --- a/google-cloud-tools.iml +++ b/google-cloud-tools.iml @@ -54,6 +54,7 @@ + diff --git a/src/com/google/gct/idea/settings/ImportSettings.java b/src/com/google/gct/idea/settings/ImportSettings.java new file mode 100644 index 0000000..a509fc6 --- /dev/null +++ b/src/com/google/gct/idea/settings/ImportSettings.java @@ -0,0 +1,137 @@ +package com.google.gct.idea.settings; + +import com.google.common.annotations.VisibleForTesting; +import com.intellij.ide.IdeBundle; +import com.intellij.ide.actions.ImportSettingsFilenameFilter; +import com.intellij.ide.plugins.PluginManager; +import com.intellij.ide.startup.StartupActionScriptManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ApplicationNamesInfo; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.ex.ApplicationEx; +import com.intellij.openapi.components.ExportableApplicationComponent; +import com.intellij.openapi.components.ExportableComponent; +import com.intellij.openapi.components.ServiceBean; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.updateSettings.impl.UpdateSettings; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.io.ZipUtil; + +import java.io.File; +import java.io.IOException; +import java.util.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipException; +import java.util.zip.ZipFile; + +/** + * Provides functionality to update IDEA setting from a jar containing new settings + */ +public class ImportSettings { + private static final String DIALOG_TITLE = "Setting Synchronization"; + public static final String SETTINGS_JAR_MARKER = "IntelliJ IDEA Global Settings"; + + /** + * Parse and update the IDEA settings in the jar at path. + * Note: This function might require a restart of the application. + * @param path The location of the jar with the new IDEA settings. + */ + public static void doImport(String path) { + final File saveFile = new File(path); + try { + if (!saveFile.exists()) { + Messages.showErrorDialog(IdeBundle.message("error.cannot.find.file", presentableFileName(saveFile)), DIALOG_TITLE); + return; + } + + // What is this file used for? + final ZipEntry magicEntry = new ZipFile(saveFile).getEntry(SETTINGS_JAR_MARKER); + if (magicEntry == null) { + Messages.showErrorDialog("The file " + presentableFileName(saveFile) + " contains no settings to import", + DIALOG_TITLE); + return; + } + + final ArrayList registeredComponents = new ArrayList( + Arrays.asList(ApplicationManager.getApplication().getComponents(ExportableApplicationComponent.class))); + registeredComponents.addAll(ServiceBean.loadServicesFromBeans(ExportableComponent.EXTENSION_POINT, ExportableComponent.class)); + + List storedComponents = getComponentsStored(saveFile, registeredComponents); + + Set relativeNamesToExtract = new HashSet(); + for (final ExportableComponent aComponent : storedComponents) { + final File[] exportFiles = aComponent.getExportFiles(); + for (File exportFile : exportFiles) { + final File configPath = new File(PathManager.getConfigPath()); + final String rPath = FileUtil.getRelativePath(configPath, exportFile); + assert rPath != null; + final String relativePath = FileUtil.toSystemIndependentName(rPath); + relativeNamesToExtract.add(relativePath); + } + } + + relativeNamesToExtract.add(PluginManager.INSTALLED_TXT); + + final File tempFile = new File(PathManager.getPluginTempPath() + "/" + saveFile.getName()); + FileUtil.copy(saveFile, tempFile); + File outDir = new File(PathManager.getConfigPath()); + final ImportSettingsFilenameFilter filenameFilter = new ImportSettingsFilenameFilter(relativeNamesToExtract); + StartupActionScriptManager.ActionCommand unzip = new StartupActionScriptManager.UnzipCommand(tempFile, outDir, filenameFilter); + StartupActionScriptManager.addActionCommand(unzip); + + // remove temp file + StartupActionScriptManager.ActionCommand deleteTemp = new StartupActionScriptManager.DeleteCommand(tempFile); + StartupActionScriptManager.addActionCommand(deleteTemp); + + UpdateSettings.getInstance().forceCheckForUpdateAfterRestart(); + + String key = ApplicationManager.getApplication().isRestartCapable() + ? "message.settings.imported.successfully.restart" + : "message.settings.imported.successfully"; + final int ret = Messages.showOkCancelDialog(IdeBundle.message(key, + ApplicationNamesInfo.getInstance().getProductName(), + ApplicationNamesInfo.getInstance().getFullProductName()), + IdeBundle.message("title.restart.needed"), Messages.getQuestionIcon()); + if (ret == Messages.OK) { + ((ApplicationEx)ApplicationManager.getApplication()).restart(true); + } + } + catch (ZipException e1) { + Messages.showErrorDialog( + "Error reading file " + presentableFileName(saveFile) + ".\\nThere was " + e1.getMessage(), + DIALOG_TITLE); + } + catch (IOException e1) { + Messages.showErrorDialog(IdeBundle.message("error.reading.settings.file.2", presentableFileName(saveFile), e1.getMessage()), + DIALOG_TITLE); + } + } + + private static String presentableFileName(final File file) { + return "'" + FileUtil.toSystemDependentName(file.getPath()) + "'"; + } + + private static List getComponentsStored(File zipFile, + ArrayList registeredComponents) + throws IOException { + final File configPath = new File(PathManager.getConfigPath()); + + final ArrayList components = new ArrayList(); + for (ExportableComponent component : registeredComponents) { + final File[] exportFiles = component.getExportFiles(); + for (File exportFile : exportFiles) { + final String rPath = FileUtil.getRelativePath(configPath, exportFile); + assert rPath != null; + String relativePath = FileUtil.toSystemIndependentName(rPath); + if (exportFile.isDirectory()) relativePath += "/"; + if (ZipUtil.isZipContainsEntry(zipFile, relativePath)) { + components.add(component); + break; + } + } + } + return components; + } +} -- cgit v1.2.3