test "import settings"

This commit is contained in:
Vladimir Krivosheev
2015-10-01 14:43:15 +02:00
parent ddfa6f74fa
commit 134b3c97f5
8 changed files with 255 additions and 152 deletions
@@ -16,24 +16,27 @@
package com.intellij.configurationStore
import com.intellij.ide.actions.ExportableItem
import com.intellij.ide.actions.exportSettings
import com.intellij.ide.actions.getExportableComponentsMap
import com.intellij.ide.actions.getPaths
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.*
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream
import com.intellij.openapi.vfs.CharsetToolkit
import com.intellij.testFramework.*
import com.intellij.util.SmartList
import com.intellij.util.xmlb.XmlSerializer
import com.intellij.util.xmlb.XmlSerializerUtil
import com.intellij.util.xmlb.annotations.Attribute
import com.intellij.util.xmlb.serialize
import gnu.trove.THashMap
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.data.MapEntry
import org.intellij.lang.annotations.Language
import org.jdom.Element
import org.junit.Before
import org.junit.ClassRule
import org.junit.Rule
import org.junit.Test
import org.picocontainer.MutablePicoContainer
import org.picocontainer.defaults.InstanceComponentAdapter
import java.io.ByteArrayInputStream
import java.io.File
import java.io.InputStream
@@ -113,14 +116,65 @@ internal class ApplicationStoreTest {
}
@Test fun `export settings`() {
testAppConfig.refreshVfs()
val storageManager = ApplicationManager.getApplication().stateStore.stateStorageManager
val optionsPath = storageManager.expandMacros(StoragePathMacros.APP_CONFIG)
val rootConfigPath = storageManager.expandMacros(ROOT_CONFIG)
val map = getExportableComponentsMap(false, true, storageManager)
assertThat(map.size()).isNotEqualTo(0)
assertThat(map).isNotEmpty()
val key = File(optionsPath, "filetypes.xml")
assertThat(map.get(key)).containsExactly(ExportableItem(listOf(key, File(rootConfigPath, "filetypes")), "File types", RoamingType.DEFAULT))
fun test(item: ExportableItem) {
val file = item.files.first()
assertThat(map.get(file)).containsExactly(item)
assertThat(file).doesNotExist()
}
test(ExportableItem(listOf(File(optionsPath, "filetypes.xml"), File(rootConfigPath, "filetypes")), "File types", RoamingType.DEFAULT))
test(ExportableItem(listOf(File(optionsPath, "customization.xml")), "Menus and toolbars customization", RoamingType.DEFAULT))
}
@Test fun `import settings`() {
testAppConfig.refreshVfs()
val component = A()
componentStore.initComponent(component, false)
component.options.foo = "new"
saveStore()
val storageManager = componentStore.storageManager
val configPath = storageManager.expandMacros(ROOT_CONFIG)
val configDir = Paths.get(configPath)
val componentPath = configDir.resolve("a.xml")
assertThat(componentPath).isRegularFile()
val componentFile = componentPath.toFile()
// additional export path
val additionalPath = configDir.resolve("foo")
additionalPath.writeChild("bar.icls", "")
val additionalFile = additionalPath.toFile()
val exportedData = BufferExposingByteArrayOutputStream()
exportSettings(setOf(componentFile, additionalFile), exportedData, configPath)
val relativePaths = getPaths(ByteArrayInputStream(exportedData.internalBuffer, 0, exportedData.size()))
assertThat(relativePaths).containsOnly("a.xml", "foo/", "foo/bar.icls", "IntelliJ IDEA Global Settings")
val list = listOf(ExportableItem(listOf(componentFile, additionalFile), ""))
fun <B> File.to(that: B) = MapEntry.entry(this, that)
val picoContainer = ApplicationManager.getApplication().picoContainer as MutablePicoContainer
val componentKey = A::class.java.name
picoContainer.registerComponent(InstanceComponentAdapter(componentKey, component))
try {
assertThat(getExportableComponentsMap(false, false, storageManager, relativePaths)).containsOnly(componentFile to list, additionalFile to list)
}
finally {
picoContainer.unregisterComponent(componentKey)
}
}
private fun createComponentData(foo: String) = """<component name="A" foo="$foo" />"""
@@ -146,16 +200,16 @@ internal class ApplicationStoreTest {
</application>""")
}
@State(name = "A", storages = arrayOf(Storage(file = "a.xml")))
private open class A : PersistentStateComponent<Element> {
@State(name = "A", storages = arrayOf(Storage(file = "a.xml")), additionalExportFile = "foo")
private open class A : PersistentStateComponent<A.State> {
data class State(@Attribute var foo: String = "", @Attribute var bar: String = "")
var state = State()
var options = State()
override fun getState() = state.serialize()
override fun getState() = options
override fun loadState(state: Element) {
this.state = XmlSerializer.deserialize(state, State::class.java)!!
override fun loadState(state: State) {
this.options = state
}
}
@@ -167,15 +221,15 @@ internal class ApplicationStoreTest {
val component = A()
componentStore.initComponent(component, false)
assertThat(component.state).isEqualTo(A.State("old"))
assertThat(component.options).isEqualTo(A.State("old"))
saveStore()
assertThat(file).hasContent(oldContent)
assertThat(oldModificationTime).isEqualTo(file.getLastModifiedTime())
component.state.bar = "2"
component.state.foo = "1"
component.options.bar = "2"
component.options.foo = "1"
saveStore()
assertThat(file).hasContent("<application>\n <component name=\"A\" foo=\"1\" bar=\"2\" />\n</application>")
@@ -191,7 +245,7 @@ internal class ApplicationStoreTest {
val component = AWorkspace()
componentStore.initComponent(component, false)
assertThat(component.state).isEqualTo(A.State("old"))
assertThat(component.options).isEqualTo(A.State("old"))
saveStore()
@@ -242,6 +296,8 @@ internal class ApplicationStoreTest {
override fun setPath(path: String) {
storageManager.addMacro(StoragePathMacros.APP_CONFIG, path)
// yes, in tests APP_CONFIG equals to ROOT_CONFIG (as ICS does)
storageManager.addMacro(ROOT_CONFIG, path)
}
}
@@ -365,9 +365,8 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
}
@Nullable
public final PluginId getConfig(@NotNull Class<?> componentImplementation) {
ComponentConfigComponentAdapter adapter = getComponentAdapter(componentImplementation);
return adapter == null ? null : adapter.myPluginId;
public final PluginId getConfig(@NotNull ComponentAdapter adapter) {
return adapter instanceof ComponentConfigComponentAdapter ? ((ComponentConfigComponentAdapter)adapter).myPluginId : null;
}
public final boolean isWorkspaceComponent(@NotNull Class<?> componentImplementation) {
@@ -33,7 +33,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.FieldPanel;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -57,19 +57,21 @@ public class ChooseComponentsToExportDialog extends DialogWrapper {
private final boolean myShowFilePath;
private final String myDescription;
public ChooseComponentsToExportDialog(@NotNull MultiMap<File, ExportableItem> fileToComponents,
public ChooseComponentsToExportDialog(@NotNull Map<File, List<ExportableItem>> fileToComponents,
boolean showFilePath, final String title, String description) {
super(false);
myDescription = description;
myShowFilePath = showFilePath;
Map<ExportableItem, ComponentElementProperties> componentToContainingListElement = new LinkedHashMap<ExportableItem, ComponentElementProperties>();
for (ExportableItem component : fileToComponents.values()) {
if (!addToExistingListElement(component, componentToContainingListElement, fileToComponents)) {
ComponentElementProperties componentElementProperties = new ComponentElementProperties();
componentElementProperties.addComponent(component);
for (List<ExportableItem> list : fileToComponents.values()) {
for (ExportableItem component : list) {
if (!addToExistingListElement(component, componentToContainingListElement, fileToComponents)) {
ComponentElementProperties componentElementProperties = new ComponentElementProperties();
componentElementProperties.addComponent(component);
componentToContainingListElement.put(component, componentElementProperties);
componentToContainingListElement.put(component, componentElementProperties);
}
}
}
myChooser = new ElementsChooser<ComponentElementProperties>(true);
@@ -149,21 +151,24 @@ public class ChooseComponentsToExportDialog extends DialogWrapper {
private static boolean addToExistingListElement(@NotNull ExportableItem component,
@NotNull Map<ExportableItem, ComponentElementProperties> componentToContainingListElement,
@NotNull MultiMap<File, ExportableItem> fileToComponents) {
@NotNull Map<File, List<ExportableItem>> fileToComponents) {
File file = null;
for (File exportFile : component.getFiles()) {
for (ExportableItem tiedComponent : fileToComponents.get(exportFile)) {
if (tiedComponent == component) {
continue;
}
List<ExportableItem> list = fileToComponents.get(exportFile);
if (!ContainerUtil.isEmpty(list)) {
for (ExportableItem tiedComponent : list) {
if (tiedComponent == component) {
continue;
}
final ComponentElementProperties elementProperties = componentToContainingListElement.get(tiedComponent);
if (elementProperties != null && !FileUtil.filesEqual(exportFile, file)) {
LOG.assertTrue(file == null, "Component " + component + " serialize itself into " + file + " and " + exportFile);
// found
elementProperties.addComponent(component);
componentToContainingListElement.put(component, elementProperties);
file = exportFile;
final ComponentElementProperties elementProperties = componentToContainingListElement.get(tiedComponent);
if (elementProperties != null && !FileUtil.filesEqual(exportFile, file)) {
LOG.assertTrue(file == null, "Component " + component + " serialize itself into " + file + " and " + exportFile);
// found
elementProperties.addComponent(component);
componentToContainingListElement.put(component, elementProperties);
file = exportFile;
}
}
}
}
@@ -37,15 +37,19 @@ 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.io.systemIndependentPath
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.MultiMap
import com.intellij.util.SmartList
import com.intellij.util.io.ZipUtil
import gnu.trove.THashSet
import java.io.*
import java.io.File
import java.io.IOException
import java.io.OutputStream
import java.io.OutputStreamWriter
import java.util.*
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
@@ -80,26 +84,7 @@ private class ExportSettingsAction : AnAction(), DumbAware {
return
}
val zipOut = MyZipOutputStream(BufferedOutputStream(FileOutputStream(saveFile)))
try {
val writtenItemRelativePaths = THashSet<String>()
val configRoot = FileUtilRt.toSystemIndependentName(PathManager.getConfigPath())
for (file in exportFiles) {
if (file.exists()) {
val relativePath = FileUtilRt.getRelativePath(configRoot, FileUtilRt.toSystemIndependentName(file.absolutePath), '/')!!
ZipUtil.addFileOrDirRecursively(zipOut, null, file, relativePath, null, writtenItemRelativePaths)
}
}
exportInstalledPlugins(zipOut)
val zipEntry = ZipEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER)
zipOut.putNextEntry(zipEntry)
zipOut.closeEntry()
}
finally {
zipOut.doClose()
}
exportSettings(exportFiles, saveFile.outputStream().buffered(), FileUtilRt.toSystemIndependentName(PathManager.getConfigPath()))
ShowFilePathAction.showDialog(AnAction.getEventProject(e), IdeBundle.message("message.settings.exported.successfully"),
IdeBundle.message("title.export.successful"), saveFile, null)
}
@@ -109,6 +94,29 @@ private class ExportSettingsAction : AnAction(), DumbAware {
}
}
// not internal only to test
fun exportSettings(exportFiles: Set<File>, out: OutputStream, configPath: String) {
val zipOut = MyZipOutputStream(out)
try {
val writtenItemRelativePaths = THashSet<String>()
for (file in exportFiles) {
if (file.exists()) {
val relativePath = FileUtilRt.getRelativePath(configPath, FileUtilRt.toSystemIndependentName(file.absolutePath), '/')!!
ZipUtil.addFileOrDirRecursively(zipOut, null, file, relativePath, null, writtenItemRelativePaths)
}
}
exportInstalledPlugins(zipOut)
val zipEntry = ZipEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER)
zipOut.putNextEntry(zipEntry)
zipOut.closeEntry()
}
finally {
zipOut.doClose()
}
}
private class MyZipOutputStream(out: OutputStream) : ZipOutputStream(out) {
override fun close() {
}
@@ -118,7 +126,7 @@ private class MyZipOutputStream(out: OutputStream) : ZipOutputStream(out) {
}
}
data class ExportableItem(val files: List<File>, val presentableName: String, val roamingType: RoamingType)
data class ExportableItem(val files: List<File>, val presentableName: String, val roamingType: RoamingType = RoamingType.DEFAULT)
private val LOG = Logger.getInstance(ExportSettingsAction::class.java)
@@ -143,8 +151,23 @@ private fun exportInstalledPlugins(zipOut: MyZipOutputStream) {
}
}
fun getExportableComponentsMap(onlyExisting: Boolean, computePresentableNames: Boolean, storageManager: StateStorageManager = ApplicationManager.getApplication().stateStore.stateStorageManager): MultiMap<File, ExportableItem> {
val result = MultiMap.createLinkedSet<File, ExportableItem>()
fun <K, V> MutableMap<K, MutableList<V>>.putValue(key: K, value: V) {
var list = get(key)
if (list == null) {
list = SmartList<V>(value)
put(key, list)
}
else {
list.add(value)
}
}
// onlyPaths - include only specified paths (relative to config dir, ends with "/" if directory)
fun getExportableComponentsMap(onlyExisting: Boolean,
computePresentableNames: Boolean,
storageManager: StateStorageManager = ApplicationManager.getApplication().stateStore.stateStorageManager,
onlyPaths: Set<String>? = null): Map<File, List<ExportableItem>> {
val result = LinkedHashMap<File, MutableList<ExportableItem>>()
val processor = { component: ExportableComponent ->
val item = ExportableItem(component.exportFiles.toList(), component.presentableName, RoamingType.DEFAULT)
for (exportFile in item.files) {
@@ -156,10 +179,27 @@ fun getExportableComponentsMap(onlyExisting: Boolean, computePresentableNames: B
ApplicationManager.getApplication().getComponents(ExportableApplicationComponent::class.java).forEach(processor)
ServiceBean.loadServicesFromBeans(ExportableComponent.EXTENSION_POINT, ExportableComponent::class.java).forEach(processor)
if (onlyExisting) {
@Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
val configPath = storageManager.expandMacros(StoragePathMacros.ROOT_CONFIG)
fun isSkipFile(file: File): Boolean {
if (onlyPaths != null) {
var relativePath = FileUtilRt.getRelativePath(configPath, file.systemIndependentPath, '/')!!
if (!file.name.contains('.') && !file.isFile) {
relativePath += '/'
}
if (!onlyPaths.contains(relativePath)) {
return true
}
}
return onlyExisting && !file.exists()
}
if (onlyExisting || onlyPaths != null) {
val it = result.keySet().iterator()
while (it.hasNext()) {
if (!it.next().exists()) {
if (isSkipFile(it.next())) {
it.remove()
}
}
@@ -183,30 +223,32 @@ fun getExportableComponentsMap(onlyExisting: Boolean, computePresentableNames: B
}
val storage = storages[storageIndex]
if (storage.roamingType != RoamingType.DISABLED && storage.storageClass == StateStorage::class && storage.scheme == StorageScheme.DEFAULT && !storage.file.isNullOrEmpty()) {
var additionalExportFile: File? = null
var additionalExportPath = stateAnnotation.additionalExportFile
if (additionalExportPath.isNotEmpty()) {
// backward compatibility - path can contain macro
@Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
if (additionalExportPath[0] != '$') {
additionalExportPath = StoragePathMacros.ROOT_CONFIG + "/" + additionalExportPath
}
additionalExportFile = File(storageManager.expandMacros(additionalExportPath))
if (onlyExisting && !additionalExportFile.exists()) {
additionalExportFile = null
}
}
if (!(storage.roamingType != RoamingType.DISABLED && storage.storageClass == StateStorage::class && storage.scheme == StorageScheme.DEFAULT && !storage.file.isNullOrEmpty())) {
return true
}
val file = File(storageManager.expandMacros(storage.file))
val fileExists = !onlyExisting || file.exists()
if (fileExists || additionalExportFile != null) {
val files = if (additionalExportFile == null) listOf(file) else if (fileExists) listOf(file, additionalExportFile) else listOf(additionalExportFile)
val item = ExportableItem(files, if (computePresentableNames) getComponentPresentableName(stateAnnotation, aClass, pluginDescriptor) else "", storage.roamingType)
result.putValue(file, item)
if (additionalExportFile != null) {
result.putValue(additionalExportFile, item)
}
var additionalExportFile: File? = null
var additionalExportPath = stateAnnotation.additionalExportFile
if (additionalExportPath.isNotEmpty()) {
// backward compatibility - path can contain macro
@Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
if (additionalExportPath[0] != '$') {
additionalExportPath = StoragePathMacros.ROOT_CONFIG + "/" + additionalExportPath
}
additionalExportFile = File(storageManager.expandMacros(additionalExportPath))
if (isSkipFile(additionalExportFile)) {
additionalExportFile = null
}
}
val file = File(storageManager.expandMacros(storage.file))
val isFileIncluded = !isSkipFile(file)
if (isFileIncluded || additionalExportFile != null) {
val files = if (additionalExportFile == null) listOf(file) else if (isFileIncluded) listOf(file, additionalExportFile) else listOf(additionalExportFile)
val item = ExportableItem(files, if (computePresentableNames) getComponentPresentableName(stateAnnotation, aClass, pluginDescriptor) else "", storage.roamingType)
result.putValue(file, item)
if (additionalExportFile != null) {
result.putValue(additionalExportFile, item)
}
}
}
@@ -30,13 +30,14 @@ 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.openapi.util.io.parentPath
import com.intellij.util.Consumer
import gnu.trove.THashSet
import java.io.File
import java.io.IOException
import java.util.*
import java.io.InputStream
import java.util.zip.ZipException
import java.util.zip.ZipFile
import java.util.zip.ZipInputStream
private class ImportSettingsAction : AnAction(), DumbAware {
override fun actionPerformed(e: AnActionEvent) {
@@ -68,40 +69,26 @@ private class ImportSettingsAction : AnAction(), DumbAware {
return
}
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
val magicEntry = ZipFile(saveFile).getEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER)
if (magicEntry == null) {
val relativePaths = getPaths(saveFile.inputStream())
if (!relativePaths.contains(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER)) {
Messages.showErrorDialog(
IdeBundle.message("error.file.contains.no.settings.to.import", presentableFileName(saveFile), promptLocationMessage()),
IdeBundle.message("title.invalid.file"))
return
}
val fileToComponents = getExportableComponentsMap(false, true)
val components = getComponentsStored(saveFile, fileToComponents.values())
fileToComponents.values().retainAll(components)
val dialog = ChooseComponentsToExportDialog(fileToComponents, false,
val configPath = FileUtil.toSystemIndependentName(PathManager.getConfigPath())
val dialog = ChooseComponentsToExportDialog(getExportableComponentsMap(false, true, onlyPaths = relativePaths), false,
IdeBundle.message("title.select.components.to.import"),
IdeBundle.message("prompt.check.components.to.import"))
if (!dialog.showAndGet()) {
return
}
val chosenComponents = dialog.exportableComponents
val relativeNamesToExtract = THashSet<String>()
for (chosenComponent in chosenComponents) {
for (exportFile in chosenComponent.files) {
relativeNamesToExtract.add(FileUtil.toSystemIndependentName(FileUtilRt.getRelativePath(File(PathManager.getConfigPath()), exportFile)!!))
}
}
relativeNamesToExtract.add(PluginManager.INSTALLED_TXT)
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))
val filenameFilter = ImportSettingsFilenameFilter(getRelativeNamesToExtract(dialog.exportableComponents))
StartupActionScriptManager.addActionCommand(StartupActionScriptManager.UnzipCommand(tempFile, File(configPath), filenameFilter))
// remove temp file
StartupActionScriptManager.addActionCommand(StartupActionScriptManager.DeleteCommand(tempFile))
@@ -119,38 +106,39 @@ private class ImportSettingsAction : AnAction(), DumbAware {
}
}
private fun getRelativeNamesToExtract(chosenComponents: Set<ExportableItem>): Set<String> {
val result = THashSet<String>()
for (chosenComponent in chosenComponents) {
for (exportFile in chosenComponent.files) {
result.add(FileUtil.toSystemIndependentName(FileUtilRt.getRelativePath(File(PathManager.getConfigPath()), exportFile)!!))
}
}
result.add(PluginManager.INSTALLED_TXT)
return result
}
private fun presentableFileName(file: File) = "'" + FileUtil.toSystemDependentName(file.path) + "'"
private fun promptLocationMessage() = IdeBundle.message("message.please.ensure.correct.settings")
}
private fun getComponentsStored(settings: File, registeredComponents: Collection<ExportableItem>): List<ExportableItem> {
val zipEntries = THashSet<String>()
val zipFile = ZipFile(settings)
try {
val enumeration = zipFile.entries()
while (enumeration.hasMoreElements()) {
zipEntries.add(enumeration.nextElement().name)
fun getPaths(input: InputStream): Set<String> {
val result = THashSet<String>()
val zipIn = ZipInputStream(input)
try {
while (true) {
val entry = zipIn.nextEntry ?: break
var path = entry.name
result.add(path)
while (true) {
path = path.parentPath ?: break
result.add("$path/")
}
}
finally {
zipFile.close()
}
val configPath = File(PathManager.getConfigPath())
val components = ArrayList<ExportableItem>()
for (component in registeredComponents) {
for (exportFile in component.files) {
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
}
}
}
return components
}
finally {
zipIn.close()
}
return result
}
@@ -40,6 +40,7 @@ import com.intellij.util.pico.ConstructorInjectionComponentAdapter;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.picocontainer.*;
import org.picocontainer.defaults.InstanceComponentAdapter;
import java.util.Arrays;
import java.util.Collection;
@@ -142,17 +143,18 @@ public class ServiceManagerImpl implements BaseComponent {
}
}
else if (o instanceof ComponentAdapter && !(o instanceof ExtensionComponentAdapter)) {
try {
aClass = ((ComponentAdapter)o).getComponentImplementation();
}
catch (Throwable e) {
LOG.error(e);
continue;
}
PluginId pluginId = componentManager.getConfig((ComponentAdapter)o);
// allow InstanceComponentAdapter without pluginId to test
if (pluginId != null || o instanceof InstanceComponentAdapter) {
try {
aClass = ((ComponentAdapter)o).getComponentImplementation();
}
catch (Throwable e) {
LOG.error(e);
continue;
}
PluginId pluginId = componentManager.getConfig(aClass);
if (pluginId != null) {
processor.process(aClass, PluginManager.getPlugin(pluginId));
processor.process(aClass, pluginId == null ? null : PluginManager.getPlugin(pluginId));
}
}
}
@@ -17,9 +17,20 @@ package com.intellij.openapi.util.io
import java.io.File
public val File.systemIndependentPath: String
get() = getPath().replace(File.separatorChar, '/')
val File.systemIndependentPath: String
get() = path.replace(File.separatorChar, '/')
val File.parentSystemIndependentPath: String
get() = getParent().replace(File.separatorChar, '/')
public val File.parentSystemIndependentPath: String
get() = getParent().replace(File.separatorChar, '/')
val String.parentPath: String?
get() {
if (isEmpty()) {
return null
}
var end = Math.max(lastIndexOf('/'), lastIndexOf('\\'))
if (end == length() - 1) {
end = Math.max(lastIndexOf('/', end - 1), lastIndexOf('\\', end - 1))
}
return if (end == -1) null else substring(0, end)
}
@@ -42,7 +42,7 @@ fun copyLocalConfig(storageManager: StateStorageManagerImpl = ApplicationManager
}
}
val roamingType = getRoamingType(fileToComponents.get(file))
val roamingType = getRoamingType(fileToComponents.get(file)!!)
if (file.isFile) {
val fileBytes = FileUtil.loadFileBytes(file)
streamProvider.doSave(fileSpec, fileBytes, fileBytes.size(), roamingType)