quick fix: IDEA-136382 Bundled custom file types disappear

This commit is contained in:
Vladimir Krivosheev
2015-02-18 18:54:39 +01:00
parent 70d9f44058
commit f8ae94b167
4 changed files with 93 additions and 19 deletions
@@ -8,6 +8,7 @@ import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.components.*;
import com.intellij.openapi.components.impl.stores.ComponentStoreImpl;
import com.intellij.openapi.components.impl.stores.StateStorageManager;
import com.intellij.openapi.components.impl.stores.StoreUtil;
import com.intellij.openapi.fileTypes.FileTypeManager;
@@ -65,6 +66,12 @@ public class CompilerTestUtil {
}
public static void saveApplicationComponent(Object appComponent) {
//noinspection ConstantConditions
if (true) {
//noinspection TestOnlyProblems
((ComponentStoreImpl)((ApplicationImpl)ApplicationManager.getApplication()).getStateStore()).saveApplicationComponent(appComponent);
}
try {
final File file;
String componentName;
@@ -24,15 +24,14 @@ import com.intellij.openapi.components.impl.stores.StateStorageManager.Externali
import com.intellij.openapi.components.store.ReadOnlyModificationException;
import com.intellij.openapi.components.store.StateStorageBase;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.containers.ContainerUtil;
@@ -45,7 +44,9 @@ import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.*;
@@ -98,12 +99,7 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable {
Arrays.sort(names);
for (String name : names) {
Object component = myComponents.get(name);
if (component instanceof PersistentStateComponent) {
commitPersistentComponent((PersistentStateComponent<?>)component, externalizationSession);
}
else if (component instanceof JDOMExternalizable) {
externalizationSession.setStateInOldStorage(component, ComponentManagerImpl.getComponentName(component), component);
}
commitComponent(externalizationSession, component);
}
}
@@ -119,6 +115,64 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable {
doSave(externalizationSession == null ? null : externalizationSession.createSaveSessions(), readonlyFiles);
}
@TestOnly
public void saveApplicationComponent(@NotNull Object component) {
StateStorageManager.ExternalizationSession externalizationSession = getStateStorageManager().startExternalization();
if (externalizationSession == null) {
return;
}
commitComponent(externalizationSession, component);
List<SaveSession> sessions = externalizationSession.createSaveSessions();
if (sessions.isEmpty()) {
return;
}
final File file;
State state = StoreUtil.getStateSpec(component.getClass());
if (state != null) {
file = new File(getStateStorageManager().expandMacros(findNonDeprecated(state.storages()).file()));
}
else if (component instanceof ExportableApplicationComponent && component instanceof NamedJDOMExternalizable) {
file = PathManager.getOptionsFile((NamedJDOMExternalizable)component);
}
else {
throw new AssertionError(component.getClass() + " doesn't have @State annotation and doesn't implement ExportableApplicationComponent");
}
AccessToken token = WriteAction.start();
try {
VfsRootAccess.allowRootAccess(file.getAbsolutePath());
doSave(sessions, Collections.<Pair<SaveSession, VirtualFile>>emptyList());
}
finally {
try {
VfsRootAccess.disallowRootAccess(file.getAbsolutePath());
}
finally {
token.finish();
}
}
}
private static Storage findNonDeprecated(Storage[] storages) {
for (Storage storage : storages) {
if (!storage.deprecated()) {
return storage;
}
}
throw new AssertionError("All storages are deprecated");
}
private void commitComponent(ExternalizationSession externalizationSession, Object component) {
if (component instanceof PersistentStateComponent) {
commitPersistentComponent((PersistentStateComponent<?>)component, externalizationSession);
}
else if (component instanceof JDOMExternalizable) {
externalizationSession.setStateInOldStorage(component, ComponentManagerImpl.getComponentName(component), component);
}
}
protected void doSave(@Nullable List<SaveSession> saveSessions, @NotNull List<Pair<SaveSession, VirtualFile>> readonlyFiles) {
if (saveSessions != null) {
for (SaveSession session : saveSessions) {
@@ -137,12 +191,19 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable {
}
}
private <T> void commitPersistentComponent(@NotNull PersistentStateComponent<T> persistentStateComponent,
@NotNull ExternalizationSession session) {
T state = persistentStateComponent.getState();
private <T> void commitPersistentComponent(@NotNull PersistentStateComponent<T> component, @NotNull ExternalizationSession session) {
T state = component.getState();
if (state != null) {
Storage[] storageSpecs = getComponentStorageSpecs(persistentStateComponent, StoreUtil.getStateSpec(persistentStateComponent), StateStorageOperation.WRITE);
session.setState(storageSpecs, persistentStateComponent, getComponentName(persistentStateComponent), state);
Storage[] storageSpecs = getComponentStorageSpecs(component, StoreUtil.getStateSpec(component), StateStorageOperation.WRITE);
String componentName = getComponentName(component);
//if (state instanceof Element) {
// Element defaultState = getDefaultState(component, componentName, Element.class);
// if (defaultState != null && JDOMUtil.areElementsEqual(defaultState, (Element)state)) {
// session.setState(storageSpecs, component, componentName, new Element("empty"));
// return;
// }
//}
session.setState(storageSpecs, component, componentName, state);
}
}
@@ -230,7 +291,8 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable {
}
Class<T> stateClass = ComponentSerializationUtil.getStateClass(component.getClass());
T state = getDefaultState(component, name, stateClass);
T defaultState = getDefaultState(component, name, stateClass);
T state = defaultState;
Storage[] storageSpecs = getComponentStorageSpecs(component, stateSpec, StateStorageOperation.READ);
for (Storage storageSpec : storageSpecs) {
@@ -243,6 +305,10 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable {
}
if (state != null) {
// quick dirty fix IDEA-136382 Bundled custom file types disappear
if (defaultState != state && component instanceof FileTypeManager) {
component.loadState(defaultState);
}
component.loadState(state);
}
@@ -74,6 +74,7 @@ import java.util.concurrent.atomic.AtomicLong;
public class FileTypeManagerImpl extends FileTypeManagerEx implements PersistentStateComponent<Element>, ApplicationComponent, Disposable {
private static final Logger LOG = Logger.getInstance(FileTypeManagerImpl.class);
// You must update all existing default configurations accordingly
private static final int VERSION = 12;
private static final Key<FileType> FILE_TYPE_KEY = Key.create("FILE_TYPE_KEY");
// cached auto-detected file type. If the file was auto-detected as plain text or binary
@@ -361,7 +362,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
}
}
// Resolve unresolved mappings initialized before certain plugin initialized.
for (final StandardFileType pair : myStandardFileTypes.values()) {
for (StandardFileType pair : myStandardFileTypes.values()) {
bindUnresolvedMappings(pair.fileType);
}
@@ -1,5 +1,5 @@
<component version="2">
<ignoreFiles list="CVS;SCCS;RCS;rcs;.DS_Store;.svn;.pyc;.pyo"/>
<component version="12">
<ignoreFiles list="CVS;SCCS;RCS;rcs;.DS_Store;.svn;.git;.pyc;.pyo;*.hprof;_svn;.hg;*.lib;*~;__pycache__;.bundle;*.rbc"/>
<filetypes>
<filetype name = "IDL" description = "IDL files"