From bc167c32a0644eadde9c04eb9bf5639165bebcbc Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 29 Sep 2015 15:28:33 +0200 Subject: [PATCH] Import/Export SettingsAction in kotlin --- .../ide/actions/ExportSettingsAction.java | 507 ++++++++---------- .../ide/actions/ImportSettingsAction.java | 205 +++---- .../src/copyAppSettingsToRepository.kt | 7 +- 3 files changed, 314 insertions(+), 405 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java index f657aa4c95af..33b2de119996 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java @@ -13,320 +13,255 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.intellij.ide.actions -/** - * @author cdr - */ -package com.intellij.ide.actions; +import com.intellij.AbstractBundle +import com.intellij.CommonBundle +import com.intellij.ide.IdeBundle +import com.intellij.ide.plugins.IdeaPluginDescriptor +import com.intellij.ide.plugins.PluginManager +import com.intellij.ide.plugins.PluginManagerCore +import com.intellij.openapi.actionSystem.AnAction +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.application.PathManager +import com.intellij.openapi.application.impl.ApplicationImpl +import com.intellij.openapi.components.* +import com.intellij.openapi.components.impl.ServiceManagerImpl +import com.intellij.openapi.components.impl.stores.StateStorageManager +import com.intellij.openapi.components.impl.stores.StoreUtil +import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.extensions.PluginDescriptor +import com.intellij.openapi.options.OptionsBundle +import com.intellij.openapi.project.DumbAware +import com.intellij.openapi.ui.Messages +import com.intellij.openapi.util.io.FileUtil +import com.intellij.openapi.util.io.FileUtilRt +import com.intellij.openapi.util.text.StringUtil +import com.intellij.openapi.vfs.CharsetToolkit +import com.intellij.util.PairProcessor +import com.intellij.util.PlatformUtils +import com.intellij.util.ReflectionUtil +import com.intellij.util.containers.ContainerUtil +import com.intellij.util.containers.MultiMap +import com.intellij.util.io.ZipUtil +import gnu.trove.THashSet -import com.intellij.AbstractBundle; -import com.intellij.CommonBundle; -import com.intellij.ide.IdeBundle; -import com.intellij.ide.plugins.IdeaPluginDescriptor; -import com.intellij.ide.plugins.PluginManager; -import com.intellij.ide.plugins.PluginManagerCore; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.application.impl.ApplicationImpl; -import com.intellij.openapi.components.*; -import com.intellij.openapi.components.impl.ServiceManagerImpl; -import com.intellij.openapi.components.impl.stores.StateStorageManager; -import com.intellij.openapi.components.impl.stores.StoreUtil; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.extensions.PluginDescriptor; -import com.intellij.openapi.options.OptionsBundle; -import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.io.FileUtilRt; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.CharsetToolkit; -import com.intellij.util.PairProcessor; -import com.intellij.util.PlatformUtils; -import com.intellij.util.ReflectionUtil; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.MultiMap; -import com.intellij.util.io.ZipUtil; -import gnu.trove.THashSet; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import java.io.* +import java.util.* +import java.util.zip.ZipEntry +import java.util.zip.ZipOutputStream -import java.io.*; -import java.util.*; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; +private class ExportSettingsAction : AnAction(), DumbAware { + override fun actionPerformed(e: AnActionEvent?) { + ApplicationManager.getApplication().saveSettings() -public class ExportSettingsAction extends AnAction implements DumbAware { - private static final Logger LOG = Logger.getInstance(ExportSettingsAction.class); - - @Override - public void actionPerformed(@Nullable AnActionEvent e) { - ApplicationManager.getApplication().saveSettings(); - - ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(getExportableComponentsMap(true, true), true, - IdeBundle.message("title.select.components.to.export"), - IdeBundle.message( - "prompt.please.check.all.components.to.export")); + val dialog = ChooseComponentsToExportDialog(getExportableComponentsMap(true, true), true, + IdeBundle.message("title.select.components.to.export"), + IdeBundle.message( + "prompt.please.check.all.components.to.export")) if (!dialog.showAndGet()) { - return; + return } - Set markedComponents = dialog.getExportableComponents(); + val markedComponents = dialog.exportableComponents if (markedComponents.isEmpty()) { - return; + return } - Set exportFiles = new THashSet(FileUtil.FILE_HASHING_STRATEGY); - for (ExportableComponent markedComponent : markedComponents) { - ContainerUtil.addAll(exportFiles, markedComponent.getExportFiles()); + val exportFiles = THashSet(FileUtil.FILE_HASHING_STRATEGY) + for (markedComponent in markedComponents) { + ContainerUtil.addAll>(exportFiles, *markedComponent.exportFiles) } - final File saveFile = dialog.getExportFile(); + val saveFile = dialog.exportFile try { if (saveFile.exists() && Messages.showOkCancelDialog( - IdeBundle.message("prompt.overwrite.settings.file", FileUtil.toSystemDependentName(saveFile.getPath())), + IdeBundle.message("prompt.overwrite.settings.file", FileUtil.toSystemDependentName(saveFile.path)), IdeBundle.message("title.file.already.exists"), Messages.getWarningIcon()) != Messages.OK) { - return; + return } - MyZipOutputStream zipOut = new MyZipOutputStream(new BufferedOutputStream(new FileOutputStream(saveFile))); + val zipOut = MyZipOutputStream(BufferedOutputStream(FileOutputStream(saveFile))) try { - Set writtenItemRelativePaths = new THashSet(); - String configRoot = FileUtilRt.toSystemIndependentName(PathManager.getConfigPath()); - for (File file : exportFiles) { + val writtenItemRelativePaths = THashSet() + val configRoot = FileUtilRt.toSystemIndependentName(PathManager.getConfigPath()) + for (file in exportFiles) { if (file.exists()) { - String relativePath = FileUtilRt.getRelativePath(configRoot, FileUtilRt.toSystemIndependentName(file.getAbsolutePath()), '/'); - assert relativePath != null; - ZipUtil.addFileOrDirRecursively(zipOut, null, file, relativePath, null, writtenItemRelativePaths); + val relativePath = FileUtilRt.getRelativePath(configRoot, FileUtilRt.toSystemIndependentName(file.absolutePath), '/')!! + ZipUtil.addFileOrDirRecursively(zipOut, null, file, relativePath, null, writtenItemRelativePaths) } } - exportInstalledPlugins(zipOut); + exportInstalledPlugins(zipOut) - ZipEntry zipEntry = new ZipEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER); - zipOut.putNextEntry(zipEntry); - zipOut.closeEntry(); + val zipEntry = ZipEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER) + zipOut.putNextEntry(zipEntry) + zipOut.closeEntry() } finally { - zipOut.doClose(); + zipOut.doClose() } - ShowFilePathAction.showDialog(getEventProject(e), IdeBundle.message("message.settings.exported.successfully"), - IdeBundle.message("title.export.successful"), saveFile, null); + ShowFilePathAction.showDialog(AnAction.getEventProject(e), IdeBundle.message("message.settings.exported.successfully"), + IdeBundle.message("title.export.successful"), saveFile, null) } - catch (IOException e1) { - Messages.showErrorDialog(IdeBundle.message("error.writing.settings", e1.toString()), IdeBundle.message("title.error.writing.file")); - } - } - - private static void exportInstalledPlugins(@NotNull MyZipOutputStream zipOut) throws IOException { - List plugins = new ArrayList(); - for (IdeaPluginDescriptor descriptor : PluginManagerCore.getPlugins()) { - if (!descriptor.isBundled() && descriptor.isEnabled()) { - plugins.add(descriptor.getPluginId().getIdString()); - } - } - if (plugins.isEmpty()) { - return; - } - - ZipEntry e = new ZipEntry(PluginManager.INSTALLED_TXT); - zipOut.putNextEntry(e); - try { - PluginManagerCore.writePluginsList(plugins, new OutputStreamWriter(zipOut, CharsetToolkit.UTF8_CHARSET)); - } - finally { - zipOut.closeEntry(); - } - } - - private static class MyZipOutputStream extends ZipOutputStream { - private boolean ignoreClose = true; - - public MyZipOutputStream(@NotNull OutputStream out) { - super(out); - } - - @Override - public void close() throws IOException { - if (!ignoreClose) { - doClose(); - } - } - - public void doClose() throws IOException { - super.close(); - } - } - - @NotNull - public static MultiMap getExportableComponentsMap(boolean onlyExisting, boolean computePresentableNames) { - ApplicationImpl application = (ApplicationImpl)ApplicationManager.getApplication(); - StateStorageManager storageManager = ComponentsPackage.getStateStore(application).getStateStorageManager(); - return getExportableComponentsMap(onlyExisting, computePresentableNames, storageManager); - } - - @NotNull - public static MultiMap getExportableComponentsMap(final boolean onlyExisting, final boolean computePresentableNames, final @NotNull StateStorageManager storageManager) { - @SuppressWarnings("deprecation") - List components1 = ComponentsPackage.getComponents(ApplicationManager.getApplication(), ExportableApplicationComponent.class); - List components2 = ServiceBean.loadServicesFromBeans(ExportableComponent.EXTENSION_POINT, ExportableComponent.class); - final MultiMap result = MultiMap.createLinkedSet(); - for (ExportableComponent component : ContainerUtil.concat(components1, components2)) { - for (File exportFile : component.getExportFiles()) { - result.putValue(exportFile, component); - } - } - - if (onlyExisting) { - for (Iterator it = result.keySet().iterator(); it.hasNext(); ) { - if (!it.next().exists()) { - it.remove(); - } - } - } - - ServiceManagerImpl.processAllImplementationClasses((ApplicationImpl)ApplicationManager.getApplication(), new PairProcessor, PluginDescriptor>() { - @Override - public boolean process(@NotNull Class aClass, @Nullable PluginDescriptor pluginDescriptor) { - State stateAnnotation = StoreUtil.getStateSpec(aClass); - if (stateAnnotation != null && !StringUtil.isEmpty(stateAnnotation.name())) { - if (ExportableComponent.class.isAssignableFrom(aClass)) { - return true; - } - - int storageIndex; - Storage[] storages = stateAnnotation.storages(); - if (storages.length == 1) { - storageIndex = 0; - } - else { - return true; - } - - Storage storage = storages[storageIndex]; - if (storage.roamingType() != RoamingType.DISABLED && - storage.storageClass().equals(StateStorage.class) && - storage.scheme() == StorageScheme.DEFAULT && - !StringUtil.isEmpty(storage.file()) && - storage.file().startsWith(StoragePathMacros.APP_CONFIG)) { - - File additionalExportFile = null; - if (!StringUtil.isEmpty(stateAnnotation.additionalExportFile())) { - String expandedPath = storageManager.expandMacros(stateAnnotation.additionalExportFile()); - additionalExportFile = new File(expandedPath); - if (!additionalExportFile.exists()) { - //noinspection deprecation - additionalExportFile = new File(storageManager.expandMacros(StoragePathMacros.ROOT_CONFIG) + '/' + expandedPath); - } - - if (onlyExisting && !additionalExportFile.exists()) { - additionalExportFile = null; - } - } - - File file = new File(storageManager.expandMacros(storage.file())); - boolean fileExists = !onlyExisting || file.exists(); - if (fileExists || additionalExportFile != null) { - File[] files; - if (additionalExportFile == null) { - files = new File[]{file}; - } - else { - files = fileExists ? new File[]{file, additionalExportFile} : new File[]{additionalExportFile}; - } - ExportableComponentItem item = new ExportableComponentItem(files, - computePresentableNames - ? getComponentPresentableName(stateAnnotation, aClass, pluginDescriptor) - : "", - storage.roamingType()); - result.putValue(file, item); - if (additionalExportFile != null) { - result.putValue(additionalExportFile, item); - } - } - } - } - return true; - } - }); - return result; - } - - @NotNull - private static String getComponentPresentableName(@NotNull State state, @NotNull Class aClass, @Nullable PluginDescriptor pluginDescriptor) { - if (state.presentableName() != State.NameGetter.class) { - try { - return ReflectionUtil.newInstance(state.presentableName()).get(); - } - catch (Exception e) { - LOG.error(e); - } - } - - String defaultName = state.name(); - String resourceBundleName; - if (pluginDescriptor != null && pluginDescriptor instanceof IdeaPluginDescriptor && !"com.intellij".equals(pluginDescriptor.getPluginId().getIdString())) { - resourceBundleName = ((IdeaPluginDescriptor)pluginDescriptor).getResourceBundleBaseName(); - } - else { - resourceBundleName = OptionsBundle.PATH_TO_BUNDLE; - } - - if (resourceBundleName == null) { - return defaultName; - } - - ClassLoader classLoader = pluginDescriptor == null ? null : pluginDescriptor.getPluginClassLoader(); - classLoader = classLoader == null ? aClass.getClassLoader() : classLoader; - if (classLoader != null) { - String message = messageOrDefault(classLoader, resourceBundleName, defaultName); - if (message != defaultName) { - return message; - } - - if (PlatformUtils.isRubyMine()) { - // ruby plugin in RubyMine has id "com.intellij", so, we cannot set "resource-bundle" in plugin.xml - return messageOrDefault(classLoader, "org.jetbrains.plugins.ruby.RBundle", defaultName); - } - } - return defaultName; - } - - @NotNull - private static String messageOrDefault(@NotNull ClassLoader classLoader, @NotNull String bundleName, @NotNull String defaultName) { - ResourceBundle bundle = AbstractBundle.getResourceBundle(bundleName, classLoader); - return bundle == null ? defaultName : CommonBundle.messageOrDefault(bundle, "exportable." + defaultName + ".presentable.name", defaultName); - } - - public static final class ExportableComponentItem implements ExportableComponent { - private final File[] files; - private final String name; - private final RoamingType roamingType; - - public ExportableComponentItem(@NotNull File[] files, @NotNull String name, @NotNull RoamingType roamingType) { - this.files = files; - this.name = name; - this.roamingType = roamingType; - } - - @NotNull - @Override - public File[] getExportFiles() { - return files; - } - - @NotNull - @Override - public String getPresentableName() { - return name; - } - - @NotNull - public RoamingType getRoamingType() { - return roamingType; + catch (e1: IOException) { + Messages.showErrorDialog(IdeBundle.message("error.writing.settings", e1.toString()), IdeBundle.message("title.error.writing.file")) } } } +private class MyZipOutputStream(out: OutputStream) : ZipOutputStream(out) { + override fun close() { + } + + fun doClose() { + super.close() + } +} + +class ExportableComponentItem(private val files: Array, private val name: String, val roamingType: RoamingType) : ExportableComponent { + override fun getExportFiles() = files + + override fun getPresentableName() = name +} + +private val LOG = Logger.getInstance(ExportSettingsAction::class.java) + +private fun exportInstalledPlugins(zipOut: MyZipOutputStream) { + val plugins = ArrayList() + for (descriptor in PluginManagerCore.getPlugins()) { + if (!descriptor.isBundled && descriptor.isEnabled) { + plugins.add(descriptor.pluginId.idString) + } + } + if (plugins.isEmpty()) { + return + } + + val e = ZipEntry(PluginManager.INSTALLED_TXT) + zipOut.putNextEntry(e) + try { + PluginManagerCore.writePluginsList(plugins, OutputStreamWriter(zipOut, CharsetToolkit.UTF8_CHARSET)) + } + finally { + zipOut.closeEntry() + } +} + +fun getExportableComponentsMap(onlyExisting: Boolean, computePresentableNames: Boolean, storageManager: StateStorageManager = ApplicationManager.getApplication().stateStore.stateStorageManager): MultiMap { + val result = MultiMap.createLinkedSet() + val processor = { component: ExportableComponent -> + for (exportFile in component.exportFiles) { + result.putValue(exportFile, component) + } + } + + @Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE") + ApplicationManager.getApplication().getComponents(ExportableApplicationComponent::class.java).forEach(processor) + ServiceBean.loadServicesFromBeans(ExportableComponent.EXTENSION_POINT, ExportableComponent::class.java).forEach(processor) + + if (onlyExisting) { + val it = result.keySet().iterator() + while (it.hasNext()) { + if (!it.next().exists()) { + it.remove() + } + } + } + + ServiceManagerImpl.processAllImplementationClasses(ApplicationManager.getApplication() as ApplicationImpl, object : PairProcessor, PluginDescriptor> { + override fun process(aClass: Class<*>, pluginDescriptor: PluginDescriptor?): Boolean { + val stateAnnotation = StoreUtil.getStateSpec(aClass) + if (stateAnnotation != null && !StringUtil.isEmpty(stateAnnotation.name)) { + if (ExportableComponent::class.java.isAssignableFrom(aClass)) { + return true + } + + val storageIndex: Int + val storages = stateAnnotation.storages + if (storages.size() == 1) { + storageIndex = 0 + } + else { + return true + } + + val storage = storages[storageIndex] + if (storage.roamingType != RoamingType.DISABLED && storage.storageClass == StateStorage::class.java && storage.scheme == StorageScheme.DEFAULT && !StringUtil.isEmpty(storage.file) && storage.file.startsWith(StoragePathMacros.APP_CONFIG)) { + var additionalExportFile: File? = null + if (!StringUtil.isEmpty(stateAnnotation.additionalExportFile)) { + val expandedPath = storageManager.expandMacros(stateAnnotation.additionalExportFile) + additionalExportFile = File(expandedPath) + if (!additionalExportFile.exists()) { + //noinspection deprecation + additionalExportFile = File(storageManager.expandMacros(StoragePathMacros.ROOT_CONFIG) + '/' + expandedPath) + } + + if (onlyExisting && !additionalExportFile.exists()) { + additionalExportFile = null + } + } + + val file = File(storageManager.expandMacros(storage.file)) + val fileExists = !onlyExisting || file.exists() + if (fileExists || additionalExportFile != null) { + val files = if (additionalExportFile == null) { + arrayOf(file) + } + else { + if (fileExists) arrayOf(file, additionalExportFile) else arrayOf(additionalExportFile) + } + val item = ExportableComponentItem(files, if (computePresentableNames) getComponentPresentableName(stateAnnotation, aClass, pluginDescriptor) else "", storage.roamingType) + result.putValue(file, item) + if (additionalExportFile != null) { + result.putValue(additionalExportFile, item) + } + } + } + } + return true + } + }) + return result +} + +private fun getComponentPresentableName(state: State, aClass: Class<*>, pluginDescriptor: PluginDescriptor?): String { + val presentableName = state.presentableName.java + if (presentableName != State.NameGetter::class.java) { + try { + return ReflectionUtil.newInstance(presentableName).get() + } + catch (e: Exception) { + LOG.error(e) + } + } + + val defaultName = state.name + val resourceBundleName = (if (pluginDescriptor is IdeaPluginDescriptor && "com.intellij" != pluginDescriptor.pluginId.idString) { + pluginDescriptor.resourceBundleBaseName + } + else { + OptionsBundle.PATH_TO_BUNDLE + }) ?: return defaultName + + var classLoader = pluginDescriptor?.pluginClassLoader ?: aClass.classLoader + if (classLoader != null) { + val message = messageOrDefault(classLoader, resourceBundleName, defaultName) + if (message !== defaultName) { + return message + } + + if (PlatformUtils.isRubyMine()) { + // ruby plugin in RubyMine has id "com.intellij", so, we cannot set "resource-bundle" in plugin.xml + return messageOrDefault(classLoader, "org.jetbrains.plugins.ruby.RBundle", defaultName) + } + } + return defaultName +} + +private fun messageOrDefault(classLoader: ClassLoader, bundleName: String, defaultName: String): String { + val bundle = AbstractBundle.getResourceBundle(bundleName, classLoader) ?: return defaultName + return CommonBundle.messageOrDefault(bundle, "exportable.$defaultName.presentable.name", defaultName) +} + diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java index db61dbc06aaa..e3f5aaf13b8f 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java @@ -13,168 +13,141 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.intellij.ide.actions -/** - * @author cdr - */ -package com.intellij.ide.actions; +import com.intellij.ide.IdeBundle +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.actionSystem.PlatformDataKeys +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.ExportableComponent +import com.intellij.openapi.project.DumbAware +import com.intellij.openapi.ui.Messages +import com.intellij.openapi.updateSettings.impl.UpdateSettings +import com.intellij.openapi.util.io.FileUtil +import com.intellij.openapi.util.io.FileUtilRt +import com.intellij.util.Consumer +import gnu.trove.THashSet +import java.io.File +import java.io.IOException +import java.util.* +import java.util.zip.ZipException +import java.util.zip.ZipFile -import com.intellij.ide.IdeBundle; -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.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.PlatformDataKeys; -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.ExportableComponent; -import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.updateSettings.impl.UpdateSettings; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.io.FileUtilRt; -import com.intellij.util.Consumer; -import com.intellij.util.containers.MultiMap; -import gnu.trove.THashSet; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; -import java.io.File; -import java.io.IOException; -import java.util.*; -import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipFile; - -public class ImportSettingsAction extends AnAction implements DumbAware { - @Override - public void actionPerformed(@NotNull AnActionEvent e) { - final DataContext dataContext = e.getDataContext(); - final Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext); - ChooseComponentsToExportDialog.chooseSettingsFile(PathManager.getConfigPath(), component, IdeBundle.message("title.import.file.location"), IdeBundle.message("prompt.choose.import.file.path")).doWhenDone(new Consumer() { - @Override - public void consume(String path) { - File saveFile = new File(path); +private class ImportSettingsAction : AnAction(), DumbAware { + override fun actionPerformed(e: AnActionEvent) { + val dataContext = e.dataContext + val component = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext) + ChooseComponentsToExportDialog.chooseSettingsFile(PathManager.getConfigPath(), component, IdeBundle.message("title.import.file.location"), IdeBundle.message("prompt.choose.import.file.path")).doWhenDone(object : Consumer { + override fun consume(path: String) { + val saveFile = File(path) try { - doImport(saveFile); + doImport(saveFile) } - catch (ZipException e1) { + catch (e1: ZipException) { Messages.showErrorDialog( IdeBundle.message("error.reading.settings.file", presentableFileName(saveFile), e1.getMessage(), promptLocationMessage()), - IdeBundle.message("title.invalid.file")); + IdeBundle.message("title.invalid.file")) } - catch (IOException e1) { + catch (e1: IOException) { Messages.showErrorDialog(IdeBundle.message("error.reading.settings.file.2", presentableFileName(saveFile), e1.getMessage()), - IdeBundle.message("title.error.reading.file")); + IdeBundle.message("title.error.reading.file")) } } - }); + }) } - private static void doImport(@NotNull File saveFile) throws IOException { + private fun doImport(saveFile: File) { if (!saveFile.exists()) { Messages.showErrorDialog(IdeBundle.message("error.cannot.find.file", presentableFileName(saveFile)), - IdeBundle.message("title.file.not.found")); - return; + IdeBundle.message("title.file.not.found")) + return } @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") - final ZipEntry magicEntry = new ZipFile(saveFile).getEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER); + val magicEntry = ZipFile(saveFile).getEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER) if (magicEntry == null) { Messages.showErrorDialog( IdeBundle.message("error.file.contains.no.settings.to.import", presentableFileName(saveFile), promptLocationMessage()), - IdeBundle.message("title.invalid.file")); - return; + IdeBundle.message("title.invalid.file")) + return } - MultiMap fileToComponents = ExportSettingsAction.getExportableComponentsMap(false, true); - List components = getComponentsStored(saveFile, fileToComponents.values()); - fileToComponents.values().retainAll(components); - final ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(fileToComponents, false, - IdeBundle.message("title.select.components.to.import"), - IdeBundle.message("prompt.check.components.to.import")); + val fileToComponents = getExportableComponentsMap(false, true) + val components = getComponentsStored(saveFile, fileToComponents.values()) + fileToComponents.values().retainAll(components) + val dialog = ChooseComponentsToExportDialog(fileToComponents, false, + IdeBundle.message("title.select.components.to.import"), + IdeBundle.message("prompt.check.components.to.import")) if (!dialog.showAndGet()) { - return; + return } - final Set chosenComponents = dialog.getExportableComponents(); - Set relativeNamesToExtract = new THashSet(); - for (ExportableComponent chosenComponent : chosenComponents) { - for (File exportFile : chosenComponent.getExportFiles()) { - String rPath = FileUtilRt.getRelativePath(new File(PathManager.getConfigPath()), exportFile); - assert rPath != null; - relativeNamesToExtract.add(FileUtil.toSystemIndependentName(rPath)); + val chosenComponents = dialog.exportableComponents + val relativeNamesToExtract = THashSet() + for (chosenComponent in chosenComponents) { + for (exportFile in chosenComponent.exportFiles) { + relativeNamesToExtract.add(FileUtil.toSystemIndependentName(FileUtilRt.getRelativePath(File(PathManager.getConfigPath()), exportFile)!!)) } } - relativeNamesToExtract.add(PluginManager.INSTALLED_TXT); + 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.addActionCommand(new StartupActionScriptManager.UnzipCommand(tempFile, outDir, filenameFilter)); + val tempFile = File(PathManager.getPluginTempPath(), saveFile.name) + FileUtil.copy(saveFile, tempFile) + val outDir = File(PathManager.getConfigPath()) + val filenameFilter = ImportSettingsFilenameFilter(relativeNamesToExtract) + StartupActionScriptManager.addActionCommand(StartupActionScriptManager.UnzipCommand(tempFile, outDir, filenameFilter)) // remove temp file - StartupActionScriptManager.addActionCommand(new StartupActionScriptManager.DeleteCommand(tempFile)); + StartupActionScriptManager.addActionCommand(StartupActionScriptManager.DeleteCommand(tempFile)) - UpdateSettings.getInstance().forceCheckForUpdateAfterRestart(); + UpdateSettings.getInstance().forceCheckForUpdateAfterRestart() - String key = ApplicationManager.getApplication().isRestartCapable() - ? "message.settings.imported.successfully.restart" - : "message.settings.imported.successfully"; + val key = if (ApplicationManager.getApplication().isRestartCapable) + "message.settings.imported.successfully.restart" + else + "message.settings.imported.successfully" if (Messages.showOkCancelDialog(IdeBundle.message(key, - ApplicationNamesInfo.getInstance().getProductName(), - ApplicationNamesInfo.getInstance().getFullProductName()), - IdeBundle.message("title.restart.needed"), Messages.getQuestionIcon()) == Messages.OK) { - ((ApplicationEx)ApplicationManager.getApplication()).restart(true); + ApplicationNamesInfo.getInstance().productName, + ApplicationNamesInfo.getInstance().fullProductName), + IdeBundle.message("title.restart.needed"), Messages.getQuestionIcon()) == Messages.OK) { + (ApplicationManager.getApplication() as ApplicationEx).restart(true) } } - private static String presentableFileName(@NotNull File file) { - return "'" + FileUtil.toSystemDependentName(file.getPath()) + "'"; - } + private fun presentableFileName(file: File) = "'" + FileUtil.toSystemDependentName(file.path) + "'" - private static String promptLocationMessage() { - return IdeBundle.message("message.please.ensure.correct.settings"); - } + private fun promptLocationMessage() = IdeBundle.message("message.please.ensure.correct.settings") - @NotNull - private static List getComponentsStored(@NotNull File settings, - @NotNull Collection registeredComponents) throws IOException { - THashSet zipEntries = new THashSet(); - ZipFile zip = new ZipFile(settings); - try { - Enumeration enumeration = zip.entries(); + private fun getComponentsStored(settings: File, registeredComponents: Collection): List { + val zipEntries = THashSet() + ZipFile(settings).use { + val enumeration = it.entries() while (enumeration.hasMoreElements()) { - ZipEntry zipEntry = (ZipEntry)enumeration.nextElement(); - zipEntries.add(zipEntry.getName()); + zipEntries.add(enumeration.nextElement().name) } } - finally { - zip.close(); - } - File configPath = new File(PathManager.getConfigPath()); - List components = new ArrayList(); - - for (ExportableComponent component : registeredComponents) { - for (File exportFile : component.getExportFiles()) { - String relativePath = FileUtilRt.getRelativePath(configPath, exportFile); - assert relativePath != null; - relativePath = FileUtilRt.toSystemIndependentName(relativePath); - if (exportFile.getName().indexOf('.') == -1 && !exportFile.isFile()) { - relativePath += '/'; + val configPath = File(PathManager.getConfigPath()) + val components = ArrayList() + for (component in registeredComponents) { + for (exportFile in component.exportFiles) { + var relativePath = FileUtilRt.getRelativePath(configPath, exportFile)!! + relativePath = FileUtilRt.toSystemIndependentName(relativePath) + if (exportFile.name.indexOf('.') == -1 && !exportFile.isFile) { + relativePath += '/' } if (zipEntries.contains(relativePath)) { - components.add(component); - break; + components.add(component) + break } } } - return components; + return components } } diff --git a/plugins/settings-repository/src/copyAppSettingsToRepository.kt b/plugins/settings-repository/src/copyAppSettingsToRepository.kt index d638b61f4303..520355b69a1d 100644 --- a/plugins/settings-repository/src/copyAppSettingsToRepository.kt +++ b/plugins/settings-repository/src/copyAppSettingsToRepository.kt @@ -17,7 +17,8 @@ package org.jetbrains.settingsRepository import com.intellij.configurationStore.ROOT_CONFIG import com.intellij.configurationStore.StateStorageManagerImpl -import com.intellij.ide.actions.ExportSettingsAction +import com.intellij.ide.actions.ExportableComponentItem +import com.intellij.ide.actions.getExportableComponentsMap import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.* import com.intellij.openapi.util.io.FileUtil @@ -27,7 +28,7 @@ import java.io.File fun copyLocalConfig(storageManager: StateStorageManagerImpl = ApplicationManager.getApplication()!!.stateStore.stateStorageManager as StateStorageManagerImpl) { val streamProvider = storageManager.streamProvider!! as IcsManager.IcsStreamProvider - val fileToComponents = ExportSettingsAction.getExportableComponentsMap(true, false, storageManager) + val fileToComponents = getExportableComponentsMap(true, false, storageManager) for (file in fileToComponents.keySet()) { val absolutePath = FileUtilRt.toSystemIndependentName(file.absolutePath) var fileSpec = storageManager.collapseMacros(absolutePath) @@ -69,7 +70,7 @@ private fun saveDirectory(parent: File, parentFileSpec: String, roamingType: Roa private fun getRoamingType(components: Collection): RoamingType { for (component in components) { - if (component is ExportSettingsAction.ExportableComponentItem) { + if (component is ExportableComponentItem) { return component.roamingType } else if (component is PersistentStateComponent<*>) {