summaryrefslogtreecommitdiff
path: root/platform/platform-impl/src/com/intellij/openapi/components/impl
diff options
context:
space:
mode:
Diffstat (limited to 'platform/platform-impl/src/com/intellij/openapi/components/impl')
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java8
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java36
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/CompoundSaveSession.java10
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java44
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultsStateStorage.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java95
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java134
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IApplicationStore.java10
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IComponentStore.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/OldStreamProviderAdapter.java6
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStateStorageManager.java13
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java126
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/RoamingTypeExtensionPointBean.java29
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java20
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java129
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java214
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java6
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java304
19 files changed, 593 insertions, 619 deletions
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java
index a00533d3244b..bf03cb11f1d6 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java
@@ -36,7 +36,6 @@ class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationSto
private static final String XML_EXTENSION = ".xml";
private static final String DEFAULT_STORAGE_SPEC = StoragePathMacros.APP_CONFIG + "/" + PathManager.DEFAULT_OPTIONS_FILE_NAME + XML_EXTENSION;
- private static final String OPTIONS_MACRO = "OPTIONS";
private static final String ROOT_ELEMENT_NAME = "application";
private final ApplicationImpl myApplication;
@@ -93,14 +92,13 @@ class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationSto
}
@Override
- public void setOptionsPath(final String path) {
- myStateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.APP_CONFIG), path);
- myStateStorageManager.addMacro(OPTIONS_MACRO, path);
+ public void setOptionsPath(@NotNull String path) {
+ myStateStorageManager.addMacro(StoragePathMacros.APP_CONFIG, path);
}
@Override
public void setConfigPath(@NotNull final String configPath) {
- myStateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.ROOT_CONFIG), configPath);
+ myStateStorageManager.addMacro(StoragePathMacros.ROOT_CONFIG, configPath);
myConfigPath = configPath;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java
index 25dd8a05cab3..dc07fee151e2 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java
@@ -59,8 +59,8 @@ abstract class BaseFileConfigurableStoreImpl extends ComponentStoreImpl {
}
@Override
- public void load(@NotNull final Element rootElement) throws IOException {
- super.load(rootElement);
+ public void load(@NotNull Element rootElement, @Nullable PathMacroSubstitutor pathMacroSubstitutor, boolean intern) {
+ super.load(rootElement, pathMacroSubstitutor, intern);
final String v = rootElement.getAttributeValue(VERSION_OPTION);
if (v != null) {
@@ -74,7 +74,11 @@ abstract class BaseFileConfigurableStoreImpl extends ComponentStoreImpl {
@Override
@NotNull
protected Element save() {
- final Element root = super.save();
+ Element root = super.save();
+ if (root == null) {
+ root = new Element(myRootElementName);
+ }
+
root.setAttribute(VERSION_OPTION, Integer.toString(myVersion));
return root;
}
@@ -113,7 +117,7 @@ abstract class BaseFileConfigurableStoreImpl extends ComponentStoreImpl {
}
public BaseStorageData getMainStorageData() throws StateStorageException {
- return (BaseStorageData) getMainStorage().getStorageData(false);
+ return (BaseStorageData)getMainStorage().getStorageData();
}
@Nullable
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
index fc2017b57a4a..ed63bf12d4c4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
@@ -29,12 +29,12 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ReflectionUtil;
-import com.intellij.util.io.fs.IFile;
import gnu.trove.THashMap;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.*;
@@ -46,12 +46,6 @@ public abstract class ComponentStoreImpl implements IComponentStore {
private final List<SettingsSavingComponent> mySettingsSavingComponents = Collections.synchronizedList(new ArrayList<SettingsSavingComponent>());
@Nullable private SaveSessionImpl mySession;
- @Deprecated
- @Nullable
- private StateStorage getStateStorage(@NotNull final Storage storageSpec) throws StateStorageException {
- return getStateStorageManager().getStateStorage(storageSpec);
- }
-
@Nullable
protected abstract StateStorage getDefaultsStorage();
@@ -255,9 +249,10 @@ public abstract class ComponentStoreImpl implements IComponentStore {
Storage[] storageSpecs = getComponentStorageSpecs(component, StateStorageOperation.READ);
for (Storage storageSpec : storageSpecs) {
- StateStorage stateStorage = getStateStorage(storageSpec);
- if (stateStorage == null || !stateStorage.hasState(component, name, stateClass, reloadData)) continue;
- state = stateStorage.getState(component, name, stateClass, state);
+ StateStorage stateStorage = getStateStorageManager().getStateStorage(storageSpec);
+ if (stateStorage != null && stateStorage.hasState(component, name, stateClass, reloadData)) {
+ state = stateStorage.getState(component, name, stateClass, state);
+ }
}
if (state != null) {
@@ -320,17 +315,15 @@ public abstract class ComponentStoreImpl implements IComponentStore {
}
assert storages.length > 0;
- final Class<StorageAnnotationsDefaultValues.NullStateStorageChooser> defaultClass =
- StorageAnnotationsDefaultValues.NullStateStorageChooser.class;
-
final Class<? extends StateStorageChooser> storageChooserClass = stateSpec.storageChooser();
- final StateStorageChooser<PersistentStateComponent<?>> defaultStateStorageChooser = getDefaultStateStorageChooser();
- assert storageChooserClass != defaultClass || defaultStateStorageChooser != null : "State chooser not specified for: " +
- persistentStateComponent.getClass();
-
- if (storageChooserClass == defaultClass) {
+ if (storageChooserClass == StateStorageChooser.class) {
+ StateStorageChooser<PersistentStateComponent<?>> defaultStateStorageChooser = getDefaultStateStorageChooser();
+ assert defaultStateStorageChooser != null : "State chooser not specified for: " + persistentStateComponent.getClass();
return defaultStateStorageChooser.selectStorages(storages, persistentStateComponent, operation);
}
+ else if (storageChooserClass == LastStorageChooserForWrite.class) {
+ return LastStorageChooserForWrite.INSTANCE.selectStorages(storages, persistentStateComponent, operation);
+ }
else {
try {
@SuppressWarnings("unchecked")
@@ -361,7 +354,7 @@ public abstract class ComponentStoreImpl implements IComponentStore {
@NotNull
@Override
- public List<IFile> getAllStorageFilesToSave(final boolean includingSubStructures) throws IOException {
+ public List<File> getAllStorageFilesToSave(final boolean includingSubStructures) throws IOException {
try {
return myStorageManagerSaveSession.getAllStorageFilesToSave();
}
@@ -426,12 +419,10 @@ public abstract class ComponentStoreImpl implements IComponentStore {
protected void commit() throws StateStorageException {
final StateStorageManager storageManager = getStateStorageManager();
-
final StateStorageManager.ExternalizationSession session = storageManager.startExternalization();
String[] names = ArrayUtil.toStringArray(myComponents.keySet());
Arrays.sort(names);
-
for (String name : names) {
Object component = myComponents.get(name);
if (component instanceof PersistentStateComponent) {
@@ -452,10 +443,9 @@ public abstract class ComponentStoreImpl implements IComponentStore {
@NotNull
@Override
- public List<IFile> getAllStorageFiles(final boolean includingSubStructures) {
+ public List<File> getAllStorageFiles(final boolean includingSubStructures) {
return myStorageManagerSaveSession.getAllStorageFiles();
}
-
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/CompoundSaveSession.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/CompoundSaveSession.java
index 51cc717726f3..aacdb58aeeec 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/CompoundSaveSession.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/CompoundSaveSession.java
@@ -18,9 +18,9 @@ package com.intellij.openapi.components.impl.stores;
import com.intellij.openapi.components.StateStorage;
import com.intellij.openapi.components.StateStorageException;
import com.intellij.util.SmartList;
-import com.intellij.util.io.fs.IFile;
import gnu.trove.THashMap;
+import java.io.File;
import java.util.List;
import java.util.Map;
@@ -36,8 +36,8 @@ public class CompoundSaveSession {
}
}
- public List<IFile> getAllStorageFilesToSave() throws StateStorageException {
- List<IFile> result = new SmartList<IFile>();
+ public List<File> getAllStorageFilesToSave() throws StateStorageException {
+ List<File> result = new SmartList<File>();
for (StateStorage.SaveSession saveSession : mySaveSessions.values()) {
result.addAll(saveSession.getStorageFilesToSave());
}
@@ -70,8 +70,8 @@ public class CompoundSaveSession {
return mySaveSessions.get(storage);
}
- public List<IFile> getAllStorageFiles() {
- List<IFile> result = new SmartList<IFile>();
+ public List<File> getAllStorageFiles() {
+ List<File> result = new SmartList<File>();
for (StateStorage.SaveSession saveSession : mySaveSessions.values()) {
result.addAll(saveSession.getAllStorageFiles());
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java
index 6f0c3b8122cf..fad17c8d2889 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java
@@ -21,13 +21,12 @@ import com.intellij.openapi.project.impl.ProjectImpl;
import com.intellij.openapi.project.impl.ProjectManagerImpl;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.io.fs.IFile;
-import org.jdom.Document;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
@@ -40,10 +39,10 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
private final ProjectManagerImpl myProjectManager;
@NonNls private static final String ROOT_TAG_NAME = "defaultProject";
- public DefaultProjectStoreImpl(final ProjectImpl project, final ProjectManagerImpl projectManager) {
+ public DefaultProjectStoreImpl(@NotNull ProjectImpl project, final ProjectManagerImpl projectManager) {
super(project);
- myProjectManager = projectManager;
+ myProjectManager = projectManager;
myElement = projectManager.getDefaultProjectRootElement();
}
@@ -53,29 +52,28 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
return element != null ? element.clone() : null;
}
-
@NotNull
@Override
protected StateStorageManager createStateStorageManager() {
- Document _d = null;
+ Element _d = null;
if (myElement != null) {
myElement.detach();
- _d = new Document(myElement);
+ _d = myElement;
}
final ComponentManager componentManager = getComponentManager();
final PathMacroManager pathMacroManager = PathMacroManager.getInstance(componentManager);
- final Document document = _d;
+ final Element element = _d;
- final XmlElementStorage storage = new XmlElementStorage(pathMacroManager.createTrackingSubstitutor(), componentManager,
- ROOT_TAG_NAME, null, "", ComponentRoamingManager.getInstance(),
+ final XmlElementStorage storage = new XmlElementStorage("", RoamingType.DISABLED, pathMacroManager.createTrackingSubstitutor(), componentManager,
+ ROOT_TAG_NAME, null,
ComponentVersionProvider.EMPTY) {
@Override
@Nullable
- protected Document loadDocument() throws StateStorageException {
- return document;
+ protected Element loadLocalData() {
+ return element;
}
@Override
@@ -96,26 +94,28 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
@Override
protected void doSave() throws StateStorageException {
- myProjectManager.setDefaultProjectRootElement(getDocumentToSave().getRootElement());
+ Element element = getElementToSave();
+ myProjectManager.setDefaultProjectRootElement(element == null ? null : element);
}
@NotNull
@Override
- public Collection<IFile> getStorageFilesToSave() throws StateStorageException {
+ public Collection<File> getStorageFilesToSave() throws StateStorageException {
return Collections.emptyList();
}
@NotNull
@Override
- public List<IFile> getAllStorageFiles() {
+ public List<File> getAllStorageFiles() {
return Collections.emptyList();
}
}
};
+ //noinspection deprecation
return new StateStorageManager() {
@Override
- public void addMacro(String macro, String expansion) {
+ public void addMacro(@NotNull String macro, @NotNull String expansion) {
throw new UnsupportedOperationException("Method addMacro not implemented in " + getClass());
}
@@ -131,6 +131,12 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
return storage;
}
+ @Nullable
+ @Override
+ public StateStorage getStateStorage(@NotNull String fileSpec, @NotNull RoamingType roamingType) {
+ return storage;
+ }
+
@Override
@Nullable
public StateStorage getFileStateStorage(@NotNull String fileSpec) {
@@ -158,6 +164,7 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
storage.finishSave(((MySaveSession)saveSession).saveSession);
}
+ @NotNull
@Override
public String expandMacros(@NotNull String file) {
throw new UnsupportedOperationException("Method expandMacros not implemented in " + getClass());
@@ -186,6 +193,7 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
throw new UnsupportedOperationException("Method getStreamProviders not implemented in " + getClass());
}
+ @NotNull
@Override
public Collection<String> getStorageFileNames() {
throw new UnsupportedOperationException("Method getStorageFileNames not implemented in " + getClass());
@@ -238,13 +246,13 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
@NotNull
@Override
- public List<IFile> getAllStorageFilesToSave() throws StateStorageException {
+ public List<File> getAllStorageFilesToSave() throws StateStorageException {
return Collections.emptyList();
}
@NotNull
@Override
- public List<IFile> getAllStorageFiles() {
+ public List<File> getAllStorageFiles() {
return Collections.emptyList();
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultsStateStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultsStateStorage.java
index b62db63b73c2..9415aee49b09 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultsStateStorage.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultsStateStorage.java
@@ -65,12 +65,12 @@ class DefaultsStateStorage implements StateStorage {
}
@Nullable
- public <T> T getState(final Object component, final String componentName, final Class<T> stateClass, @Nullable final T mergeInto) throws
+ public <T> T getState(final Object component, @NotNull final String componentName, final Class<T> stateClass, @Nullable final T mergeInto) throws
StateStorageException {
return DefaultStateSerializer.deserializeState(getState(component, componentName), stateClass, mergeInto);
}
- public boolean hasState(final Object component, final String componentName, final Class<?> aClass, final boolean reloadData) throws StateStorageException {
+ public boolean hasState(final Object component, @NotNull final String componentName, final Class<?> aClass, final boolean reloadData) throws StateStorageException {
final URL url = DecodeDefaultsUtil.getDefaults(component, componentName);
return url != null;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java
index cda453be5cd2..912c239cffcb 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java
@@ -26,7 +26,8 @@ import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.tracker.VirtualFileTracker;
-import com.intellij.util.io.fs.IFile;
+import com.intellij.util.SmartList;
+import com.intellij.util.containers.SmartHashSet;
import com.intellij.util.messages.MessageBus;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
@@ -37,16 +38,13 @@ import java.io.File;
import java.io.IOException;
import java.util.*;
-import static com.intellij.util.io.fs.FileSystem.FILE_SYSTEM;
-
//todo: support missing plugins
//todo: support storage data
public class DirectoryBasedStorage implements StateStorage, Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.DirectoryBasedStorage");
- private static final IFile[] EMPTY_FILES = new IFile[0];
private final TrackingPathMacroSubstitutor myPathMacroSubstitutor;
- private final IFile myDir;
+ private final File myDir;
private final StateSplitter mySplitter;
private final FileTypeManager myFileTypeManager;
@@ -59,7 +57,7 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
@NotNull Disposable parentDisposable,
@NotNull PicoContainer picoContainer) {
myPathMacroSubstitutor = pathMacroSubstitutor;
- myDir = FILE_SYSTEM.createFile(dir);
+ myDir = new File(dir);
mySplitter = splitter;
Disposer.register(parentDisposable, this);
@@ -96,7 +94,7 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
@Override
@Nullable
- public <T> T getState(final Object component, final String componentName, Class<T> stateClass, @Nullable T mergeInto)
+ public <T> T getState(final Object component, @NotNull final String componentName, Class<T> stateClass, @Nullable T mergeInto)
throws StateStorageException {
if (myStorageData == null) myStorageData = loadState();
@@ -116,7 +114,7 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
@Override
- public boolean hasState(final Object component, final String componentName, final Class<?> aClass, final boolean reloadData) throws StateStorageException {
+ public boolean hasState(final Object component, @NotNull String componentName, final Class<?> aClass, final boolean reloadData) throws StateStorageException {
if (!myDir.exists()) return false;
if (reloadData) myStorageData = null;
return true;
@@ -180,32 +178,28 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
@Override
public void save() throws StateStorageException {
assert mySession == this;
- final Set<String> currentNames = new HashSet<String>();
-
- IFile[] children = myDir.exists() ? myDir.listFiles() : EMPTY_FILES;
- for (IFile child : children) {
- final String fileName = child.getName();
- if (!myFileTypeManager.isFileIgnored(fileName) && StringUtil.endsWithIgnoreCase(fileName, ".xml")) {
- currentNames.add(fileName);
+ final Set<String> currentNames = new SmartHashSet<String>();
+ File[] children = myDir.listFiles();
+ if (children != null) {
+ for (File child : children) {
+ final String fileName = child.getName();
+ if (!myFileTypeManager.isFileIgnored(fileName) && StringUtil.endsWithIgnoreCase(fileName, ".xml")) {
+ currentNames.add(fileName);
+ }
}
}
myStorageData.process(new DirectoryStorageData.StorageDataProcessor() {
@Override
- public void process(final String componentName, final IFile file, final Element element) {
+ public void process(final String componentName, final File file, final Element element) {
currentNames.remove(file.getName());
if (myPathMacroSubstitutor != null) {
myPathMacroSubstitutor.collapsePaths(element);
}
- if (file.getTimeStamp() <= myStorageData.getLastTimeStamp()) {
- if (!myDir.exists()) {
- myDir.createParentDirs();
- myDir.mkDir();
- }
-
- StorageUtil.save(file, element, MySaveSession.this);
+ if (file.lastModified() <= myStorageData.getLastTimeStamp()) {
+ StorageUtil.save(file, element, MySaveSession.this, false, null);
myStorageData.updateLastTimestamp(file);
}
}
@@ -217,15 +211,14 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
public void run() {
if (myDir.exists()) {
for (String name : currentNames) {
- IFile child = myDir.getChild(name);
-
- if (child.getTimeStamp() > myStorageData.getLastTimeStamp()) {
+ File child = new File(myDir, name);
+ if (child.lastModified() > myStorageData.getLastTimeStamp()) {
// do not touch new files during VC update (which aren't read yet)
// now got an opposite problem: file is recreated if was removed by VC during update.
return;
}
- final VirtualFile virtualFile = StorageUtil.getVirtualFile(child);
+ final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(child);
if (virtualFile != null) {
try {
LOG.debug("Removing configuration file: " + virtualFile.getPresentableUrl());
@@ -272,23 +265,26 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
@Override
@NotNull
- public Collection<IFile> getStorageFilesToSave() throws StateStorageException {
+ public Collection<File> getStorageFilesToSave() throws StateStorageException {
assert mySession == this;
if (!myDir.exists()) return getAllStorageFiles();
assert myDir.isDirectory() : myDir.getPath();
- final List<IFile> filesToSave = new ArrayList<IFile>();
-
- IFile[] children = myDir.listFiles();
- final Set<String> currentChildNames = new HashSet<String>();
- for (IFile child : children) {
- if (!myFileTypeManager.isFileIgnored(child.getName())) currentChildNames.add(child.getName());
+ final List<File> filesToSave = new ArrayList<File>();
+ final Set<String> currentChildNames = new SmartHashSet<String>();
+ File[] children = myDir.listFiles();
+ if (children != null) {
+ for (File child : children) {
+ if (!myFileTypeManager.isFileIgnored(child.getName())) {
+ currentChildNames.add(child.getName());
+ }
+ }
}
myStorageData.process(new DirectoryStorageData.StorageDataProcessor() {
@Override
- public void process(final String componentName, final IFile file, final Element element) {
+ public void process(final String componentName, final File file, final Element element) {
if (currentChildNames.contains(file.getName())) {
currentChildNames.remove(file.getName());
@@ -301,13 +297,11 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
filesToSave.add(file);
}
}
-
}
});
for (String childName : currentChildNames) {
- final IFile child = myDir.getChild(childName);
- filesToSave.add(child);
+ filesToSave.add(new File(myDir, childName));
}
return filesToSave;
@@ -315,8 +309,8 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
@Override
@NotNull
- public List<IFile> getAllStorageFiles() {
- return new ArrayList<IFile>(myStorageData.getAllStorageFiles().keySet());
+ public List<File> getAllStorageFiles() {
+ return new SmartList<File>(myStorageData.getAllStorageFiles().keySet());
}
}
@@ -328,24 +322,25 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
}
@Override
- public void setState(@NotNull final Object component, final String componentName, @NotNull final Object state, final Storage storageSpec)
- throws StateStorageException {
+ public void setState(@NotNull final Object component, final String componentName, @NotNull final Object state, final Storage storageSpec) {
assert mySession == this;
setState(componentName, state, storageSpec);
}
- private void setState(final String componentName, @NotNull Object state, final Storage storageSpec) throws StateStorageException {
+ private void setState(final String componentName, @NotNull Object state, final Storage storageSpec) {
try {
final Element element = DefaultStateSerializer.serializeState(state, storageSpec);
- for (Pair<Element, String> pair : mySplitter.splitState(element)) {
- Element e = pair.first;
- String name = pair.second;
+ if (element != null) {
+ for (Pair<Element, String> pair : mySplitter.splitState(element)) {
+ Element e = pair.first;
+ String name = pair.second;
- Element statePart = new Element(StorageData.COMPONENT);
- statePart.setAttribute(StorageData.NAME, componentName);
- statePart.addContent(e.detach());
+ Element statePart = new Element(StorageData.COMPONENT);
+ statePart.setAttribute(StorageData.NAME, componentName);
+ statePart.addContent(e.detach());
- myStorageData.put(componentName, myDir.getChild(name), statePart, false);
+ myStorageData.put(componentName, new File(myDir, name), statePart, false);
+ }
}
}
catch (WriteExternalException e) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java
index 923072d4fb1d..54fd9d65cb92 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java
@@ -22,19 +22,14 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
-import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.components.StateStorageException;
-import com.intellij.openapi.components.StoragePathMacros;
-import com.intellij.openapi.components.TrackingPathMacroSubstitutor;
+import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.JDOMUtil;
+import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.tracker.VirtualFileTracker;
-import com.intellij.util.io.fs.FileSystem;
-import com.intellij.util.io.fs.IFile;
import com.intellij.util.messages.MessageBus;
-import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NonNls;
@@ -44,46 +39,40 @@ import org.picocontainer.PicoContainer;
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class FileBasedStorage extends XmlElementStorage {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.FileBasedStorage");
+ private static final Logger LOG = Logger.getInstance(FileBasedStorage.class);
private static boolean ourConfigDirectoryRefreshed = false;
private final String myFilePath;
- private final IFile myFile;
- private final String myRootElementName;
+ private final File myFile;
private volatile VirtualFile myCachedVirtualFile;
- public FileBasedStorage(@Nullable TrackingPathMacroSubstitutor pathMacroManager,
- StreamProvider streamProvider,
- String filePath,
- String fileSpec,
- String rootElementName,
+ public FileBasedStorage(@NotNull String filePath,
+ @NotNull String fileSpec,
+ @Nullable RoamingType roamingType,
+ @Nullable TrackingPathMacroSubstitutor pathMacroManager,
+ @NotNull String rootElementName,
@NotNull Disposable parentDisposable,
PicoContainer picoContainer,
- ComponentRoamingManager componentRoamingManager,
+ @Nullable StreamProvider streamProvider,
ComponentVersionProvider componentVersionProvider) {
- super(pathMacroManager, parentDisposable, rootElementName, streamProvider, fileSpec, componentRoamingManager, componentVersionProvider);
+ super(fileSpec, roamingType, pathMacroManager, parentDisposable, rootElementName, streamProvider, componentVersionProvider);
refreshConfigDirectoryOnce();
- myRootElementName = rootElementName;
myFilePath = filePath;
- myFile = FileSystem.FILE_SYSTEM.createFile(myFilePath);
+ myFile = new File(filePath);
VirtualFileTracker virtualFileTracker = ServiceManager.getService(VirtualFileTracker.class);
MessageBus messageBus = (MessageBus)picoContainer.getComponentInstanceOfType(MessageBus.class);
if (virtualFileTracker != null && messageBus != null) {
- final String path = myFile.getAbsolutePath();
- final String fileUrl = LocalFileSystem.PROTOCOL_PREFIX + path.replace(File.separatorChar, '/');
-
final Listener listener = messageBus.syncPublisher(STORAGE_TOPIC);
- virtualFileTracker.addTracker(fileUrl, new VirtualFileAdapter() {
+ virtualFileTracker.addTracker(LocalFileSystem.PROTOCOL_PREFIX + myFile.getAbsolutePath().replace(File.separatorChar, '/'), new VirtualFileAdapter() {
@Override
public void fileMoved(@NotNull VirtualFileMoveEvent event) {
myCachedVirtualFile = null;
@@ -95,6 +84,11 @@ public class FileBasedStorage extends XmlElementStorage {
}
@Override
+ public void fileCreated(@NotNull VirtualFileEvent event) {
+ myCachedVirtualFile = event.getFile();
+ }
+
+ @Override
public void contentsChanged(@NotNull final VirtualFileEvent event) {
if (!isDisposed()) {
listener.storageFileChanged(event, FileBasedStorage.this);
@@ -130,13 +124,6 @@ public class FileBasedStorage extends XmlElementStorage {
return new FileSaveSession(externalizationSession);
}
- public void resetProviderCache() {
- myProviderUpToDateHash = -1;
- if (myRemoteVersionProvider != null) {
- myRemoteVersionProvider.myProviderVersions = null;
- }
- }
-
private class FileSaveSession extends MySaveSession {
protected FileSaveSession(MyExternalizationSession externalizationSession) {
super(externalizationSession);
@@ -145,9 +132,11 @@ public class FileBasedStorage extends XmlElementStorage {
@Override
protected boolean physicalContentNeedsSave() {
VirtualFile file = getVirtualFile();
- if (file == null || !file.exists())
+ if (file == null || !file.exists()) {
return !myStorageData.isEmpty();
- return !StorageUtil.contentEquals(getDocumentToSave(), file);
+ }
+ Element element = getElementToSave();
+ return element == null || !StorageUtil.contentEquals(element, file);
}
@Override
@@ -169,14 +158,13 @@ public class FileBasedStorage extends XmlElementStorage {
}
LOG.assertTrue(myFile != null);
- myCachedVirtualFile = StorageUtil.save(myFile, getDocumentToSave(), this);
+ myCachedVirtualFile = StorageUtil.save(myFile, getElementToSave(), this, true, myCachedVirtualFile);
}
@NotNull
@Override
- public Collection<IFile> getStorageFilesToSave() throws StateStorageException {
- boolean needsSave = needsSave();
- if (needsSave) {
+ public Collection<File> getStorageFilesToSave() {
+ if (needsSave()) {
if (LOG.isDebugEnabled()) {
LOG.info("File " + myFileSpec + " needs save; hash=" + myUpToDateHash + "; currentHash=" + calcHash() + "; " +
"content needs save=" + physicalContentNeedsSave());
@@ -190,21 +178,17 @@ public class FileBasedStorage extends XmlElementStorage {
@NotNull
@Override
- public List<IFile> getAllStorageFiles() {
+ public List<File> getAllStorageFiles() {
return Collections.singletonList(myFile);
}
}
@Override
- protected void loadState(final StorageData result, final Element element) throws StateStorageException {
- ((FileStorageData)result).myFilePath = myFile.getAbsolutePath();
- super.loadState(result, element);
- }
-
- @Override
@NotNull
protected StorageData createStorageData() {
- return new FileStorageData(myRootElementName);
+ FileStorageData data = new FileStorageData(myRootElementName);
+ data.myFilePath = myFilePath;
+ return data;
}
public static class FileStorageData extends StorageData {
@@ -234,18 +218,24 @@ public class FileBasedStorage extends XmlElementStorage {
public VirtualFile getVirtualFile() {
VirtualFile virtualFile = myCachedVirtualFile;
if (virtualFile == null) {
- myCachedVirtualFile = virtualFile = StorageUtil.getVirtualFile(myFile);
+ myCachedVirtualFile = virtualFile = LocalFileSystem.getInstance().findFileByIoFile(myFile);
}
return virtualFile;
}
+ @NotNull
public File getFile() {
- return new File(myFile.getPath());
+ return myFile;
+ }
+
+ @NotNull
+ public String getFilePath() {
+ return myFilePath;
}
@Override
@Nullable
- protected Document loadDocument() throws StateStorageException {
+ protected Element loadLocalData() {
myBlockSavingTheContent = false;
try {
VirtualFile file = getVirtualFile();
@@ -256,7 +246,7 @@ public class FileBasedStorage extends XmlElementStorage {
if (file.getLength() == 0) {
return processReadException(null);
}
- return loadDocumentImpl(file);
+ return StorageData.load(file);
}
catch (final JDOMException e) {
return processReadException(e);
@@ -267,7 +257,7 @@ public class FileBasedStorage extends XmlElementStorage {
}
@Nullable
- private Document processReadException(@Nullable final Exception e) {
+ private Element processReadException(@Nullable final Exception e) {
boolean contentTruncated = e == null;
myBlockSavingTheContent = isProjectOrModuleOrWorkspaceFile() && !contentTruncated;
if (!ApplicationManager.getApplication().isUnitTestMode() && !ApplicationManager.getApplication().isHeadlessEnvironment()) {
@@ -291,45 +281,27 @@ public class FileBasedStorage extends XmlElementStorage {
return isProjectOrModuleOrWorkspaceFile() && !contentTruncated ? "Please correct the file content" : "File content will be recreated";
}
- private static Document loadDocumentImpl(final VirtualFile file) throws IOException, JDOMException {
- InputStream stream = file.getInputStream();
- try {
- return JDOMUtil.loadDocument(stream);
- }
- finally {
- stream.close();
- }
- }
-
- public String getFileName() {
- return myFile.getName();
- }
-
- public String getFilePath() {
- return myFilePath;
- }
-
@Override
public void setDefaultState(final Element element) {
element.setName(myRootElementName);
super.setDefaultState(element);
}
- protected boolean physicalContentNeedsSave(final Document doc) {
- VirtualFile file = getVirtualFile();
- return file == null || !file.exists() || !StorageUtil.contentEquals(doc, file);
- }
-
@Nullable
public File updateFileExternallyFromStreamProviders() throws IOException {
- StorageData loadedData = loadData(true);
- Document document = getDocument(loadedData);
- if (physicalContentNeedsSave(document)) {
- File file = new File(myFile.getAbsolutePath());
- JDOMUtil.writeDocument(document, file, "\n");
- return file;
+ Element element = getElement(loadData(true));
+ if (element == null) {
+ FileUtil.delete(myFile);
+ return null;
}
- return null;
+ BufferExposingByteArrayOutputStream out = StorageUtil.newContentIfDiffers(element, getVirtualFile());
+ if (out == null) {
+ return null;
+ }
+
+ File file = new File(myFile.getAbsolutePath());
+ FileUtil.writeToFile(file, out.getInternalBuffer(), 0, out.size());
+ return file;
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IApplicationStore.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IApplicationStore.java
index c669bd1f37be..0ebfae887771 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IApplicationStore.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IApplicationStore.java
@@ -15,18 +15,18 @@
*/
package com.intellij.openapi.components.impl.stores;
-import com.intellij.openapi.components.StateStorageException;
-import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.components.StateStorage;
+import com.intellij.openapi.components.StateStorageException;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
-import java.util.Set;
-import java.util.Collection;
import java.io.IOException;
+import java.util.Collection;
+import java.util.Set;
public interface IApplicationStore extends IComponentStore {
- void setOptionsPath(String path);
+ void setOptionsPath(@NotNull String path);
void setConfigPath(@NotNull String configPath);
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IComponentStore.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IComponentStore.java
index 0427a8be15ab..93a65a2eb50b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IComponentStore.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IComponentStore.java
@@ -19,10 +19,10 @@ import com.intellij.openapi.components.StateStorage;
import com.intellij.openapi.components.StateStorageException;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.io.fs.IFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;
@@ -54,17 +54,19 @@ public interface IComponentStore {
interface SaveSession {
@NotNull
- List<IFile> getAllStorageFilesToSave(final boolean includingSubStructures) throws IOException;
+ List<File> getAllStorageFilesToSave(final boolean includingSubStructures) throws IOException;
+
@NotNull
SaveSession save() throws IOException;
+
void finishSave();
+
void reset();
@Nullable
- Set<String> analyzeExternalChanges(@NotNull Set<Pair<VirtualFile,StateStorage>> changedFiles);
+ Set<String> analyzeExternalChanges(@NotNull Set<Pair<VirtualFile, StateStorage>> changedFiles);
@NotNull
- List<IFile> getAllStorageFiles(final boolean includingSubStructures);
+ List<File> getAllStorageFiles(final boolean includingSubStructures);
}
-
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/OldStreamProviderAdapter.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/OldStreamProviderAdapter.java
index 2120030db2c1..ac7bf84f6b3e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/OldStreamProviderAdapter.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/OldStreamProviderAdapter.java
@@ -12,6 +12,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+@SuppressWarnings("deprecation")
final class OldStreamProviderAdapter extends StreamProvider implements CurrentUserHolder {
final com.intellij.openapi.options.StreamProvider myProvider;
private final RoamingType myRoamingType;
@@ -32,9 +33,8 @@ final class OldStreamProviderAdapter extends StreamProvider implements CurrentUs
}
@Override
- public boolean saveContent(@NotNull String fileSpec, @NotNull byte[] content, int size, @NotNull RoamingType roamingType, boolean async) throws IOException {
+ public void saveContent(@NotNull String fileSpec, @NotNull byte[] content, int size, @NotNull RoamingType roamingType, boolean async) throws IOException {
myProvider.saveContent(fileSpec, new BufferExposingByteArrayInputStream(content, size), size, roamingType, async);
- return false;
}
@Nullable
@@ -65,4 +65,4 @@ final class OldStreamProviderAdapter extends StreamProvider implements CurrentUs
public String getCurrentUserName() {
return myProvider instanceof CurrentUserHolder ? ((CurrentUserHolder)myProvider).getCurrentUserName() : null;
}
-} \ No newline at end of file
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStateStorageManager.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStateStorageManager.java
index 0eed50a65131..c7b93afbe8d8 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStateStorageManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStateStorageManager.java
@@ -56,17 +56,12 @@ class ProjectStateStorageManager extends StateStorageManagerImpl {
assert config != null : "Couldn't find old storage for " + component.getClass().getName();
final boolean workspace = isWorkspace(config.options);
- String macro = StoragePathMacros.getMacroName(workspace ? StoragePathMacros.WORKSPACE_FILE : StoragePathMacros.PROJECT_FILE);
-
- String name = "$" + macro + "$";
-
- StateStorage storage = getFileStateStorage(name);
-
+ String fileSpec = workspace ? StoragePathMacros.WORKSPACE_FILE : StoragePathMacros.PROJECT_FILE;
+ StateStorage storage = getStateStorage(fileSpec, workspace ? RoamingType.DISABLED : RoamingType.PER_USER);
if (operation == StateStorageOperation.READ && storage != null && workspace && !storage.hasState(component, componentName, Element.class, false)) {
- name = StoragePathMacros.PROJECT_FILE;
+ fileSpec = StoragePathMacros.PROJECT_FILE;
}
-
- return name;
+ return fileSpec;
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java
index 6288c62ab9e5..01e2f9e036d0 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java
@@ -39,13 +39,14 @@ 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.*;
+import com.intellij.util.PathUtilRt;
+import com.intellij.util.SmartList;
import com.intellij.util.containers.OrderedSet;
-import com.intellij.util.io.fs.FileSystem;
-import com.intellij.util.io.fs.IFile;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.lang.annotation.Annotation;
@@ -55,23 +56,21 @@ import java.util.List;
import java.util.Set;
class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProjectStore {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.ProjectStoreImpl");
+ private static final Logger LOG = Logger.getInstance(ProjectStoreImpl.class);
@NonNls private static final String OLD_PROJECT_SUFFIX = "_old.";
@NonNls static final String OPTION_WORKSPACE = "workspace";
- @NonNls static final String DEFAULT_STATE_STORAGE = StoragePathMacros.PROJECT_FILE;
-
static final Storage DEFAULT_STORAGE_ANNOTATION = new MyStorage();
private static int originalVersion = -1;
protected ProjectImpl myProject;
private StorageScheme myScheme = StorageScheme.DEFAULT;
- private String myCachedLocation;
private String myPresentableUrl;
- ProjectStoreImpl(final ProjectImpl project) {
+ ProjectStoreImpl(@NotNull ProjectImpl project) {
super(project);
+
myProject = project;
}
@@ -169,15 +168,15 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
final File dirStore = file.isDirectory() ? new File(file, Project.DIRECTORY_STORE_FOLDER)
: new File(file.getParentFile(), Project.DIRECTORY_STORE_FOLDER);
- stateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.PROJECT_FILE), new File(dirStore, "misc.xml").getPath());
+ stateStorageManager.addMacro(StoragePathMacros.PROJECT_FILE, new File(dirStore, "misc.xml").getPath());
final File ws = new File(dirStore, "workspace.xml");
- stateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.WORKSPACE_FILE), ws.getPath());
+ stateStorageManager.addMacro(StoragePathMacros.WORKSPACE_FILE, ws.getPath());
if (!ws.exists() && !file.isDirectory()) {
useOldWsContent(filePath, ws);
}
- stateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.PROJECT_CONFIG_DIR), dirStore.getPath());
+ stateStorageManager.addMacro(StoragePathMacros.PROJECT_CONFIG_DIR, dirStore.getPath());
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
@@ -189,10 +188,10 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
else {
myScheme = StorageScheme.DEFAULT;
- stateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.PROJECT_FILE), filePath);
+ stateStorageManager.addMacro(StoragePathMacros.PROJECT_FILE, filePath);
final String workspacePath = composeWsPath(filePath);
- stateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.WORKSPACE_FILE), workspacePath);
+ stateStorageManager.addMacro(StoragePathMacros.WORKSPACE_FILE, workspacePath);
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
@@ -202,7 +201,6 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
}, ModalityState.defaultModalityState());
}
- myCachedLocation = null;
myPresentableUrl = null;
}
@@ -258,18 +256,26 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
final String path = getProjectFilePath();
if (!StringUtil.isEmptyOrSpaces(path)) {
- return myScheme == StorageScheme.DEFAULT ? new File(path).getParent() : new File(path).getParentFile().getParent();
+ return getBasePath(new File(path));
}
//we are not yet initialized completely ("open directory", etc)
- final StateStorage s = getStateStorageManager().getFileStateStorage(StoragePathMacros.PROJECT_FILE);
- if (!(s instanceof FileBasedStorage)) return null;
- final FileBasedStorage storage = (FileBasedStorage)s;
+ StateStorage storage = getStateStorageManager().getStateStorage(StoragePathMacros.PROJECT_FILE, RoamingType.PER_USER);
+ if (!(storage instanceof FileBasedStorage)) {
+ return null;
+ }
- final File file = storage.getFile();
- if (file == null) return null;
+ return getBasePath(((FileBasedStorage)storage).getFile());
+ }
- return myScheme == StorageScheme.DEFAULT ? file.getParent() : file.getParentFile().getParent();
+ private String getBasePath(@NotNull File file) {
+ if (myScheme == StorageScheme.DEFAULT) {
+ return file.getParent();
+ }
+ else {
+ File parentFile = file.getParentFile();
+ return parentFile == null ? null : parentFile.getParent();
+ }
}
@NotNull
@@ -302,7 +308,7 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
return baseDir.getName().replace(":", "");
}
else {
- String temp = getProjectFileName();
+ String temp = PathUtilRt.getFileName(((FileBasedStorage)getProjectFileStorage()).getFilePath());
FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(temp);
if (fileType instanceof ProjectFileType) {
temp = temp.substring(0, temp.length() - fileType.getDefaultExtension().length() - 1);
@@ -316,13 +322,6 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
}
@NotNull
- private String getProjectFileName() {
- final FileBasedStorage storage = (FileBasedStorage)getStateStorageManager().getFileStateStorage(StoragePathMacros.PROJECT_FILE);
- assert storage != null;
- return storage.getFileName();
- }
-
- @NotNull
@Override
public StorageScheme getStorageScheme() {
return myScheme;
@@ -349,26 +348,28 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
@Override
public VirtualFile getProjectFile() {
- if (myProject.isDefault()) return null;
- final FileBasedStorage storage = (FileBasedStorage)getStateStorageManager().getFileStateStorage(StoragePathMacros.PROJECT_FILE);
+ return myProject.isDefault() ? null : ((FileBasedStorage)getProjectFileStorage()).getVirtualFile();
+ }
+
+ @NotNull
+ private XmlElementStorage getProjectFileStorage() {
+ // XmlElementStorage if default project, otherwise FileBasedStorage
+ XmlElementStorage storage = (XmlElementStorage)getStateStorageManager().getStateStorage(StoragePathMacros.PROJECT_FILE, RoamingType.PER_USER);
assert storage != null;
- return storage.getVirtualFile();
+ return storage;
}
@Override
public VirtualFile getWorkspaceFile() {
if (myProject.isDefault()) return null;
- final FileBasedStorage storage = (FileBasedStorage)getStateStorageManager().getFileStateStorage(StoragePathMacros.WORKSPACE_FILE);
+ final FileBasedStorage storage = (FileBasedStorage)getStateStorageManager().getStateStorage(StoragePathMacros.WORKSPACE_FILE, RoamingType.DISABLED);
assert storage != null;
return storage.getVirtualFile();
}
@Override
public void loadProjectFromTemplate(@NotNull final ProjectImpl defaultProject) {
- final StateStorage stateStorage = getStateStorageManager().getFileStateStorage(DEFAULT_STATE_STORAGE);
-
- assert stateStorage instanceof XmlElementStorage;
- XmlElementStorage xmlElementStorage = (XmlElementStorage)stateStorage;
+ XmlElementStorage stateStorage = getProjectFileStorage();
defaultProject.save();
final IProjectStore projectStore = defaultProject.getStateStore();
@@ -376,24 +377,19 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
DefaultProjectStoreImpl defaultProjectStore = (DefaultProjectStoreImpl)projectStore;
final Element element = defaultProjectStore.getStateCopy();
if (element != null) {
- xmlElementStorage.setDefaultState(element);
+ stateStorage.setDefaultState(element);
}
}
@NotNull
@Override
public String getProjectFilePath() {
- if (myProject.isDefault()) return "";
- final FileBasedStorage storage = (FileBasedStorage)getStateStorageManager().getFileStateStorage(StoragePathMacros.PROJECT_FILE);
- assert storage != null;
- return storage.getFilePath();
+ return myProject.isDefault() ? "" : ((FileBasedStorage)getProjectFileStorage()).getFilePath();
}
@Override
protected XmlElementStorage getMainStorage() {
- final XmlElementStorage storage = (XmlElementStorage)getStateStorageManager().getFileStateStorage(DEFAULT_STATE_STORAGE);
- assert storage != null;
- return storage;
+ return getProjectFileStorage();
}
@NotNull
@@ -402,7 +398,6 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
return new ProjectStateStorageManager(PathMacroManager.getInstance(getComponentManager()).createTrackingSubstitutor(), myProject);
}
-
static class ProjectStorageData extends BaseStorageData {
protected final Project myProject;
@@ -447,16 +442,16 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
}
@Override
- public void load(@NotNull final Element root) throws IOException {
- final String v = root.getAttributeValue(VERSION_OPTION);
+ public void load(@NotNull Element rootElement, @Nullable PathMacroSubstitutor pathMacroSubstitutor, boolean intern) {
+ final String v = rootElement.getAttributeValue(VERSION_OPTION);
//noinspection AssignmentToStaticFieldFromInstanceMethod
originalVersion = v != null ? Integer.parseInt(v) : 0;
if (originalVersion != ProjectManagerImpl.CURRENT_FORMAT_VERSION) {
- convert(root, originalVersion);
+ convert(rootElement, originalVersion);
}
- super.load(root);
+ super.load(rootElement, pathMacroSubstitutor, intern);
}
protected void convert(final Element root, final int originalVersion) {
@@ -479,19 +474,16 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
@NotNull
@Override
- public List<IFile> getAllStorageFilesToSave(final boolean includingSubStructures) throws IOException {
- List<IFile> result = new ArrayList<IFile>();
-
+ public List<File> getAllStorageFilesToSave(final boolean includingSubStructures) throws IOException {
+ List<File> result = new SmartList<File>();
if (includingSubStructures) {
- collectSubfilesToSave(result);
+ collectSubFilesToSave(result);
}
-
result.addAll(super.getAllStorageFilesToSave(false));
-
return result;
}
- protected void collectSubfilesToSave(final List<IFile> result) throws IOException { }
+ protected void collectSubFilesToSave(final List<File> result) throws IOException { }
@NotNull
@Override
@@ -523,10 +515,10 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
return ApplicationManager.getApplication().runReadAction(new Computable<ReadonlyStatusHandler.OperationStatus>() {
@Override
public ReadonlyStatusHandler.OperationStatus compute() {
- final List<IFile> filesToSave;
+ final List<File> filesToSave;
try {
filesToSave = getAllStorageFilesToSave(true);
- final Iterator<IFile> iterator = filesToSave.iterator();
+ final Iterator<File> iterator = filesToSave.iterator();
while (iterator.hasNext()) {
if (!iterator.next().exists()) {
iterator.remove();
@@ -543,14 +535,12 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
if (myProject.isToSaveProjectName()) {
final VirtualFile baseDir = getProjectBaseDir();
if (baseDir != null && baseDir.isValid()) {
- filesToSave.add(FileSystem.FILE_SYSTEM
- .createFile(new File(new File(baseDir.getPath(), Project.DIRECTORY_STORE_FOLDER), ProjectImpl.NAME_FILE).getPath()));
+ filesToSave.add(new File(new File(baseDir.getPath(), Project.DIRECTORY_STORE_FOLDER), ProjectImpl.NAME_FILE));
}
}
- for (IFile file : filesToSave) {
+ for (File file : filesToSave) {
final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(file);
-
if (virtualFile != null) {
virtualFile.refresh(false, false);
if (virtualFile.isValid() && !virtualFile.isWritable()) {
@@ -670,7 +660,7 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
@Override
public String file() {
- return DEFAULT_STATE_STORAGE;
+ return StoragePathMacros.PROJECT_FILE;
}
@Override
@@ -679,15 +669,21 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
}
@Override
+ public RoamingType roamingType() {
+ return RoamingType.PER_USER;
+ }
+
+ @Override
public Class<? extends StateStorage> storageClass() {
- return StorageAnnotationsDefaultValues.NullStateStorage.class;
+ return StateStorage.class;
}
@Override
public Class<? extends StateSplitter> stateSplitter() {
- return StorageAnnotationsDefaultValues.NullStateSplitter.class;
+ return StateSplitter.class;
}
+ @NotNull
@Override
public Class<? extends Annotation> annotationType() {
throw new UnsupportedOperationException("Method annotationType not implemented in " + getClass());
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/RoamingTypeExtensionPointBean.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/RoamingTypeExtensionPointBean.java
deleted file mode 100644
index ff5d16361228..000000000000
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/RoamingTypeExtensionPointBean.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.openapi.components.impl.stores;
-
-import com.intellij.util.xmlb.annotations.Attribute;
-
-/**
- * @deprecated use {@link com.intellij.openapi.components.RoamingType#DISABLED}
- */
-@Deprecated
-public class RoamingTypeExtensionPointBean {
- @Attribute("component")
- public String componentName;
- @Attribute("type")
- public String roamingType;
-}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
index 68d882d2b204..d3e9d1c03d2e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
@@ -19,10 +19,10 @@ import com.intellij.openapi.components.*;
import com.intellij.openapi.options.StreamProvider;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.io.fs.IFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Set;
@@ -31,7 +31,7 @@ import java.util.Set;
* @author mike
*/
public interface StateStorageManager {
- void addMacro(String macro, String expansion);
+ void addMacro(@NotNull String macro, @NotNull String expansion);
@Nullable
TrackingPathMacroSubstitutor getMacroSubstitutor();
@@ -40,8 +40,16 @@ public interface StateStorageManager {
StateStorage getStateStorage(@NotNull Storage storageSpec) throws StateStorageException;
@Nullable
+ StateStorage getStateStorage(@NotNull String fileSpec, @NotNull RoamingType roamingType);
+
+ @Deprecated
+ @Nullable
+ /**
+ * @deprecated Use {@link #getStateStorage(String, com.intellij.openapi.components.RoamingType)}
+ */
StateStorage getFileStateStorage(@NotNull String fileSpec);
+ @NotNull
Collection<String> getStorageFileNames();
void clearStateStorage(@NotNull String file);
@@ -57,7 +65,7 @@ public interface StateStorageManager {
@Nullable
StateStorage getOldStorage(Object component, String componentName, StateStorageOperation operation) throws StateStorageException;
- @Nullable
+ @NotNull
String expandMacros(@NotNull String file);
@Deprecated
@@ -81,11 +89,11 @@ public interface StateStorageManager {
Set<String> analyzeExternalChanges(@NotNull Set<Pair<VirtualFile, StateStorage>> files);
@NotNull
- List<IFile> getAllStorageFilesToSave() throws StateStorageException;
+ List<File> getAllStorageFilesToSave() throws StateStorageException;
@NotNull
- List<IFile> getAllStorageFiles();
+ List<File> getAllStorageFiles();
void save() throws StateStorageException;
}
-} \ No newline at end of file
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
index 431c9a97820c..651acce271c0 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
@@ -24,12 +24,14 @@ import com.intellij.openapi.options.CurrentUserHolder;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.RoamingTypeDisabled;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ObjectUtils;
+import com.intellij.util.PathUtilRt;
+import com.intellij.util.ReflectionUtil;
import com.intellij.util.SmartList;
-import com.intellij.util.io.fs.IFile;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import gnu.trove.TObjectLongHashMap;
@@ -99,9 +101,14 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
}
@Override
- public synchronized void addMacro(String macro, String expansion) {
- // avoid hundreds of $MODULE_FILE$ instances
- myMacros.put(("$" + macro + "$").intern(), expansion);
+ public synchronized void addMacro(@NotNull String macro, @NotNull String expansion) {
+ assert !macro.isEmpty();
+ // backward compatibility
+ if (macro.charAt(0) != '$') {
+ LOG.warn("Add macros instead of macro name: " + macro);
+ expansion = '$' + macro + '$';
+ }
+ myMacros.put(macro, expansion);
}
@Override
@@ -123,15 +130,15 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
}
}
- @Override
@Nullable
- public StateStorage getFileStateStorage(@NotNull String fileName) {
+ @Override
+ public StateStorage getStateStorage(@NotNull String fileSpec, @NotNull RoamingType roamingType) {
myStorageLock.lock();
try {
- StateStorage stateStorage = myStorages.get(fileName);
+ StateStorage stateStorage = myStorages.get(fileSpec);
if (stateStorage == null) {
- stateStorage = createFileStateStorage(fileName);
- putStorageToMap(fileName, stateStorage);
+ stateStorage = createFileStateStorage(fileSpec, roamingType);
+ putStorageToMap(fileSpec, stateStorage);
}
return stateStorage;
}
@@ -141,6 +148,13 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
}
@Override
+ @Nullable
+ public StateStorage getFileStateStorage(@NotNull String fileSpec) {
+ return getStateStorage(fileSpec, RoamingType.PER_USER);
+ }
+
+ @NotNull
+ @Override
public Collection<String> getStorageFileNames() {
myStorageLock.lock();
try {
@@ -176,19 +190,19 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
@Nullable
private StateStorage createStateStorage(Storage storageSpec) throws StateStorageException {
- if (!storageSpec.storageClass().equals(StorageAnnotationsDefaultValues.NullStateStorage.class)) {
+ if (!storageSpec.storageClass().equals(StateStorage.class)) {
String key = UUID.randomUUID().toString();
((MutablePicoContainer)myPicoContainer).registerComponentImplementation(key, storageSpec.storageClass());
return (StateStorage)myPicoContainer.getComponentInstance(key);
}
- if (!storageSpec.stateSplitter().equals(StorageAnnotationsDefaultValues.NullStateSplitter.class)) {
+ if (!storageSpec.stateSplitter().equals(StateSplitter.class)) {
return createDirectoryStateStorage(storageSpec.file(), storageSpec.stateSplitter());
}
- return createFileStateStorage(storageSpec.file());
+ return createFileStateStorage(storageSpec.file(), storageSpec.roamingType());
}
private static String getStorageSpecId(Storage storageSpec) {
- if (!storageSpec.storageClass().equals(StorageAnnotationsDefaultValues.NullStateStorage.class)) {
+ if (!storageSpec.storageClass().equals(StateStorage.class)) {
return storageSpec.storageClass().getName();
}
else {
@@ -209,41 +223,30 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
@Nullable
private StateStorage createDirectoryStateStorage(String file, Class<? extends StateSplitter> splitterClass) throws StateStorageException {
- String expandedFile = expandMacros(file);
- if (expandedFile == null) {
- myStorages.put(file, null);
- return null;
- }
-
final StateSplitter splitter;
try {
- splitter = splitterClass.newInstance();
+ splitter = ReflectionUtil.newInstance(splitterClass);
}
- catch (InstantiationException e) {
+ catch (RuntimeException e) {
throw new StateStorageException(e);
}
- catch (IllegalAccessException e) {
- throw new StateStorageException(e);
- }
-
- return new DirectoryBasedStorage(myPathMacroSubstitutor, expandedFile, splitter, this, myPicoContainer);
+ return new DirectoryBasedStorage(myPathMacroSubstitutor, expandMacros(file), splitter, this, myPicoContainer);
}
@Nullable
- private StateStorage createFileStateStorage(@NotNull final String fileSpec) {
+ private StateStorage createFileStateStorage(@NotNull final String fileSpec, @Nullable RoamingType roamingType) {
String expandedFile = expandMacros(fileSpec);
- if (expandedFile == null) {
- myStorages.put(fileSpec, null);
- return null;
- }
- String extension = FileUtilRt.getExtension(new File(expandedFile).getName());
- if (!ourHeadlessEnvironment && extension.isEmpty()) {
+ if (!ourHeadlessEnvironment && PathUtilRt.getFileName(expandedFile).lastIndexOf('.') < 0) {
throw new IllegalArgumentException("Extension is missing for storage file: " + expandedFile);
}
- return new FileBasedStorage(getMacroSubstitutor(fileSpec), getStreamProvider(), expandedFile, fileSpec, myRootTagName, this,
- myPicoContainer, ComponentRoamingManager.getInstance(), this) {
+ if (roamingType != RoamingType.PER_USER && fileSpec.equals(StoragePathMacros.WORKSPACE_FILE)) {
+ roamingType = RoamingType.DISABLED;
+ }
+
+ return new FileBasedStorage(expandedFile, fileSpec, roamingType, getMacroSubstitutor(fileSpec), myRootTagName, this,
+ myPicoContainer, getStreamProvider(), this) {
@Override
@NotNull
protected StorageData createStorageData() {
@@ -271,8 +274,7 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
String filePath = getNotNullVersionsFilePath();
if (filePath != null) {
try {
- Document document = JDOMUtil.loadDocument(new File(filePath));
- loadComponentVersions(result, document);
+ loadComponentVersions(result, JDOMUtil.loadDocument(new File(filePath)));
}
catch (JDOMException e) {
LOG.debug(e);
@@ -294,6 +296,7 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
public static void loadComponentVersions(TObjectLongHashMap<String> result, Document document) {
List<Element> componentObjects = document.getRootElement().getChildren("component");
+ result.ensureCapacity(componentObjects.size());
for (Element component : componentObjects) {
String name = component.getAttributeValue("name");
String version = component.getAttributeValue("version");
@@ -330,26 +333,21 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
private static final Pattern MACRO_PATTERN = Pattern.compile("(\\$[^\\$]*\\$)");
@Override
- @Nullable
+ @NotNull
public synchronized String expandMacros(@NotNull String file) {
- final Matcher matcher = MACRO_PATTERN.matcher(file);
+ Matcher matcher = MACRO_PATTERN.matcher(file);
while (matcher.find()) {
String m = matcher.group(1);
- if (!myMacros.containsKey(m) || !ApplicationManager.getApplication().isUnitTestMode() && myMacros.get(m) == null) {
- throw new IllegalArgumentException("Unknown macro: " + m + " in storage spec: " + file);
+ if (!myMacros.containsKey(m)) {
+ throw new IllegalArgumentException("Unknown macro: " + m + " in storage file spec: " + file);
}
}
- String actualFile = file;
-
+ String expanded = file;
for (String macro : myMacros.keySet()) {
- final String replacement = myMacros.get(macro);
- if (replacement != null) {
- actualFile = StringUtil.replace(actualFile, macro, replacement);
- }
+ expanded = StringUtil.replace(expanded, macro, myMacros.get(macro));
}
-
- return actualFile;
+ return expanded;
}
@NotNull
@@ -424,7 +422,9 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
@Override
@Nullable
public StateStorage getOldStorage(Object component, String componentName, StateStorageOperation operation) throws StateStorageException {
- return getFileStateStorage(getOldStorageSpec(component, componentName, operation));
+ String oldStorageSpec = getOldStorageSpec(component, componentName, operation);
+ //noinspection deprecation
+ return oldStorageSpec == null ? null : getStateStorage(oldStorageSpec, component instanceof RoamingTypeDisabled ? RoamingType.DISABLED : RoamingType.PER_USER);
}
@Nullable
@@ -440,14 +440,14 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
@Override
@NotNull
- public List<IFile> getAllStorageFilesToSave() throws StateStorageException {
+ public List<File> getAllStorageFilesToSave() throws StateStorageException {
assert mySession == this;
return myCompoundSaveSession.getAllStorageFilesToSave();
}
@Override
@NotNull
- public List<IFile> getAllStorageFiles() {
+ public List<File> getAllStorageFiles() {
return myCompoundSaveSession.getAllStorageFiles();
}
@@ -503,15 +503,16 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
}
public void save() {
- if (!isDirty) return;
+ if (!isDirty) {
+ return;
+ }
+
String filePath = getNotNullVersionsFilePath();
if (filePath != null) {
- File dir = new File(filePath).getParentFile();
- if (!dir.isDirectory() && !dir.mkdirs()) {
- LOG.warn("Unable to create: " + dir);
- }
+ File file = new File(filePath);
+ FileUtilRt.createParentDirs(file);
try {
- JDOMUtil.writeDocument(new Document(createComponentVersionsXml(getComponentVersions())), filePath, "\n");
+ JDOMUtil.writeParent(createComponentVersionsXml(getComponentVersions()), file, "\n");
isDirty = false;
}
catch (IOException e) {
@@ -546,6 +547,7 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
return root;
}
+ @SuppressWarnings("deprecation")
private static class OldStreamProviderManager extends StreamProvider implements CurrentUserHolder {
private final List<OldStreamProviderAdapter> myStreamProviders = new SmartList<OldStreamProviderAdapter>();
@@ -575,22 +577,17 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
}
@Override
- public boolean saveContent(@NotNull String fileSpec, @NotNull byte[] content, int size, @NotNull RoamingType roamingType, boolean async) throws IOException {
- boolean result = false;
+ public void saveContent(@NotNull String fileSpec, @NotNull byte[] content, int size, @NotNull RoamingType roamingType, boolean async) throws IOException {
for (StreamProvider streamProvider : myStreamProviders) {
try {
- if (streamProvider.isEnabled() && streamProvider.isApplicable(fileSpec, roamingType) && streamProvider.saveContent(fileSpec, content, size, roamingType, async)) {
- result = true;
+ if (streamProvider.isEnabled() && streamProvider.isApplicable(fileSpec, roamingType)) {
+ streamProvider.saveContent(fileSpec, content, size, roamingType, async);
}
}
- catch (ConnectException e) {
- LOG.debug("Cannot send user profile to server: " + e.getLocalizedMessage());
- }
catch (Exception e) {
LOG.debug(e);
}
}
- return result;
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java
index bd732705446a..2344c8526b0a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java
@@ -26,7 +26,6 @@ import com.intellij.openapi.editor.DocumentRunnable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.project.ex.ProjectEx;
-import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
@@ -38,7 +37,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.SystemProperties;
import com.intellij.util.UniqueFileNamesProvider;
import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.io.fs.IFile;
import com.intellij.util.ui.UIUtil;
import org.jdom.Document;
import org.jdom.Element;
@@ -59,11 +57,12 @@ import java.util.Set;
* @author mike
*/
public class StorageUtil {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.StorageUtil");
+ private static final Logger LOG = Logger.getInstance(StorageUtil.class);
private static final boolean DUMP_COMPONENT_STATES = SystemProperties.getBooleanProperty("idea.log.externally.changed.component.states", false);
@SuppressWarnings("SpellCheckingInspection")
private static final SimpleDateFormat LOG_DIR_FORMAT = new SimpleDateFormat("yyyyMMdd-HHmmss");
+ private static final Pair<byte[], String> NON_EXISTENT_FILE_DATA = Pair.create(null, SystemProperties.getLineSeparator());
private StorageUtil() { }
@@ -110,34 +109,86 @@ public class StorageUtil {
return notified;
}
+
+ public static boolean isEmpty(@Nullable Parent element) {
+ if (element == null) {
+ return true;
+ }
+ else if (element instanceof Element) {
+ return JDOMUtil.isEmpty((Element)element);
+ }
+ else {
+ Document document = (Document)element;
+ return !document.hasRootElement() || JDOMUtil.isEmpty(document.getRootElement());
+ }
+ }
+
+ /**
+ * Due to historical reasons files in ROOT_CONFIG don’t wrapped into document (xml prolog) opposite to files in APP_CONFIG
+ */
@Nullable
- static VirtualFile save(@NotNull IFile file, Parent element, Object requestor) throws StateStorageException {
- try {
- String lineSeparator;
- String oldText;
- if (file.exists()) {
- VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(file);
- Couple<String> pair = loadFile(vFile);
- lineSeparator = pair.second;
- oldText = pair.first;
+ static VirtualFile save(@NotNull File file, @Nullable Parent element, Object requestor, boolean wrapAsDocument, @Nullable VirtualFile cachedVirtualFile) throws StateStorageException {
+ if (isEmpty(element)) {
+ if (!file.exists()) {
+ return null;
+ }
+
+ VirtualFile virtualFile = cachedVirtualFile;
+ if (virtualFile == null || !virtualFile.isValid()) {
+ virtualFile = LocalFileSystem.getInstance().findFileByIoFile(file);
+ }
+ if (virtualFile == null) {
+ LOG.info("Cannot find virtual file " + file.getAbsolutePath());
+ FileUtil.delete(file);
}
else {
- oldText = null;
- lineSeparator = SystemProperties.getLineSeparator();
- file.createParentDirs();
+ AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(DocumentRunnable.IgnoreDocumentRunnable.class);
+ try {
+ virtualFile.delete(requestor);
+ }
+ catch (IOException e) {
+ throw new StateStorageException(e);
+ }
+ finally {
+ token.finish();
+ }
}
+ return null;
+ }
- String text = JDOMUtil.writeParent(element, lineSeparator);
- if (text.equals(oldText)) {
- return null;
+ VirtualFile virtualFile = cachedVirtualFile == null || !cachedVirtualFile.isValid() ? null : cachedVirtualFile;
+ Parent document = !wrapAsDocument || element instanceof Document ? element : new Document((Element)element);
+ try {
+ BufferExposingByteArrayOutputStream byteOut;
+ if (file.exists()) {
+ if (virtualFile == null) {
+ virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
+ }
+
+ Pair<byte[], String> pair = loadFile(virtualFile);
+ byteOut = writeToBytes(document, pair.second);
+ if (equal(pair.first, byteOut)) {
+ return null;
+ }
+ }
+ else {
+ FileUtil.createParentDirs(file);
+ byteOut = writeToBytes(document, SystemProperties.getLineSeparator());
}
// mark this action as modifying the file which daemon analyzer should ignore
AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(DocumentRunnable.IgnoreDocumentRunnable.class);
try {
- VirtualFile virtualFile = getOrCreateVirtualFile(requestor, file);
- byte[] bytes = text.getBytes(CharsetToolkit.UTF8);
- virtualFile.setBinaryContent(bytes, -1, -1, requestor);
+ if (virtualFile == null) {
+ virtualFile = getOrCreateVirtualFile(requestor, file);
+ }
+ OutputStream virtualFileOut = virtualFile.getOutputStream(requestor);
+ try {
+ byteOut.writeTo(virtualFileOut);
+ }
+ finally {
+ virtualFileOut.close();
+ }
return virtualFile;
}
finally {
@@ -150,70 +201,78 @@ public class StorageUtil {
}
@NotNull
- static VirtualFile getOrCreateVirtualFile(final Object requestor, final IFile ioFile) throws IOException {
- VirtualFile vFile = getVirtualFile(ioFile);
-
- if (vFile == null) {
- vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioFile);
- }
+ private static BufferExposingByteArrayOutputStream writeToBytes(@NotNull Parent element, @NotNull String lineSeparator) throws IOException {
+ BufferExposingByteArrayOutputStream out = new BufferExposingByteArrayOutputStream(512);
+ JDOMUtil.writeParent(element, out, lineSeparator);
+ return out;
+ }
- if (vFile == null) {
- final IFile parentFile = ioFile.getParentFile();
- final VirtualFile parentVFile =
- LocalFileSystem.getInstance().refreshAndFindFileByIoFile(parentFile); // need refresh if the directory has just been created
- if (parentVFile == null) {
- throw new IOException(ProjectBundle.message("project.configuration.save.file.not.found", parentFile.getPath()));
+ @NotNull
+ static VirtualFile getOrCreateVirtualFile(@Nullable Object requestor, @NotNull File ioFile) throws IOException {
+ VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioFile);
+ if (virtualFile == null) {
+ File parentFile = ioFile.getParentFile();
+ // need refresh if the directory has just been created
+ VirtualFile parentVirtualFile = parentFile == null ? null : LocalFileSystem.getInstance().refreshAndFindFileByIoFile(parentFile);
+ if (parentVirtualFile == null) {
+ throw new IOException(ProjectBundle.message("project.configuration.save.file.not.found", parentFile == null ? "" : parentFile.getPath()));
}
- vFile = parentVFile.createChildData(requestor, ioFile.getName());
+ virtualFile = parentVirtualFile.createChildData(requestor, ioFile.getName());
}
-
- return vFile;
- }
-
- @Nullable
- static VirtualFile getVirtualFile(final IFile ioFile) {
- return LocalFileSystem.getInstance().findFileByIoFile(ioFile);
+ return virtualFile;
}
/**
* @return pair.first - file contents (null if file does not exist), pair.second - file line separators
*/
- private static Couple<String> loadFile(@Nullable final VirtualFile file) throws IOException {
+ @NotNull
+ private static Pair<byte[], String> loadFile(@Nullable final VirtualFile file) throws IOException {
if (file == null || !file.exists()) {
- return Couple.of(null, SystemProperties.getLineSeparator());
+ return NON_EXISTENT_FILE_DATA;
}
- String fileText = new String(file.contentsToByteArray(), CharsetToolkit.UTF8);
- final int index = fileText.indexOf('\n');
- return Couple.of(fileText, index == -1
- ? SystemProperties.getLineSeparator()
- : index - 1 >= 0 ? fileText.charAt(index - 1) == '\r' ? "\r\n" : "\n" : "\n");
+ byte[] bytes = file.contentsToByteArray();
+ String lineSeparator = file.getDetectedLineSeparator();
+ if (lineSeparator == null) {
+ String fileText = new String(bytes, CharsetToolkit.UTF8);
+ final int index = fileText.indexOf('\n');
+ lineSeparator = index == -1
+ ? SystemProperties.getLineSeparator()
+ : index - 1 >= 0 ? fileText.charAt(index - 1) == '\r' ? "\r\n" : "\n" : "\n";
+ }
+ return Pair.create(bytes, lineSeparator);
}
- public static boolean contentEquals(@NotNull final Document document, @NotNull final VirtualFile file) {
+ public static boolean contentEquals(@NotNull Parent element, @NotNull VirtualFile file) {
+ return newContentIfDiffers(element, file) == null;
+ }
+
+ @Nullable
+ public static BufferExposingByteArrayOutputStream newContentIfDiffers(@NotNull Parent element, @Nullable VirtualFile file) {
try {
- final Couple<String> pair = loadFile(file);
- return pair.first != null && pair.first.equals(JDOMUtil.writeDocument(document, pair.second));
+ Pair<byte[], String> pair = loadFile(file);
+ BufferExposingByteArrayOutputStream out = writeToBytes(element, pair.second);
+ return pair.first != null && equal(pair.first, out) ? null : out;
}
catch (IOException e) {
LOG.debug(e);
- return false;
+ return null;
}
}
- public static boolean contentEquals(@NotNull final Element element, @NotNull final VirtualFile file) {
- try {
- final Couple<String> pair = loadFile(file);
- return pair.first != null && pair.first.equals(printElement(element, pair.second));
- }
- catch (IOException e) {
- LOG.debug(e);
+ public static boolean equal(byte[] a1, @NotNull BufferExposingByteArrayOutputStream out) {
+ int length = out.size();
+ if (a1.length != length) {
return false;
}
- }
- static String printElement(final Element element, final String lineSeparator) throws StateStorageException {
- return JDOMUtil.writeElement(element, lineSeparator);
+ byte[] internalBuffer = out.getInternalBuffer();
+ for (int i = 0; i < length; i++) {
+ if (a1[i] != internalBuffer[i]) {
+ return false;
+ }
+ }
+ return true;
}
@Nullable
@@ -229,6 +288,7 @@ public class StorageUtil {
}
}
+ @SuppressWarnings("Contract")
@Nullable
public static Document loadDocument(@Nullable InputStream stream) {
if (stream == null) {
@@ -252,29 +312,20 @@ public class StorageUtil {
}
@NotNull
- public static BufferExposingByteArrayOutputStream documentToBytes(@NotNull Document document, boolean useSystemLineSeparator) throws IOException {
- BufferExposingByteArrayOutputStream out = new BufferExposingByteArrayOutputStream(512);
- OutputStreamWriter writer = new OutputStreamWriter(out, CharsetToolkit.UTF8_CHARSET);
- try {
- JDOMUtil.writeDocument(document, writer, useSystemLineSeparator ? SystemProperties.getLineSeparator() : "\n");
- return out;
- }
- finally {
- writer.close();
- }
+ public static BufferExposingByteArrayOutputStream elementToBytes(@NotNull Parent element, boolean useSystemLineSeparator) throws IOException {
+ return writeToBytes(element, useSystemLineSeparator ? SystemProperties.getLineSeparator() : "\n");
}
- public static boolean sendContent(@NotNull StreamProvider provider, @NotNull String fileSpec, @NotNull Document copy, @NotNull RoamingType type, boolean async) {
+ public static void sendContent(@NotNull StreamProvider provider, @NotNull String fileSpec, @NotNull Parent element, @NotNull RoamingType type, boolean async) {
if (!provider.isApplicable(fileSpec, type)) {
- return false;
+ return;
}
try {
- return doSendContent(provider, fileSpec, copy, type, async);
+ doSendContent(provider, fileSpec, element, type, async);
}
catch (IOException e) {
LOG.warn(e);
- return false;
}
}
@@ -287,10 +338,10 @@ public class StorageUtil {
/**
* You must call {@link StreamProvider#isApplicable(String, com.intellij.openapi.components.RoamingType)} before
*/
- public static boolean doSendContent(StreamProvider provider, String fileSpec, Document copy, RoamingType type, boolean async) throws IOException {
+ public static void doSendContent(@NotNull StreamProvider provider, @NotNull String fileSpec, @NotNull Parent element, @NotNull RoamingType type, boolean async) throws IOException {
// we should use standard line-separator (\n) - stream provider can share file content on any OS
- BufferExposingByteArrayOutputStream content = documentToBytes(copy, false);
- return provider.saveContent(fileSpec, content.getInternalBuffer(), content.size(), type, async);
+ BufferExposingByteArrayOutputStream content = elementToBytes(element, false);
+ provider.saveContent(fileSpec, content.getInternalBuffer(), content.size(), type, async);
}
public static void logStateDiffInfo(Set<Pair<VirtualFile, StateStorage>> changedFiles, Set<String> componentNames) {
@@ -309,10 +360,9 @@ public class StorageUtil {
StateStorage storage = pair.second;
if (storage instanceof XmlElementStorage) {
- Document state = ((XmlElementStorage)storage).logComponents();
+ Element state = ((XmlElementStorage)storage).logComponents();
if (state != null) {
- File logFile = new File(logDirectory, "prev_" + file.getName());
- JDOMUtil.writeDocument(state, logFile, "\n");
+ JDOMUtil.writeParent(state, new File(logDirectory, "prev_" + file.getName()), "\n");
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java
index ec57d8c63601..cf49b927ad0e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java
@@ -12,7 +12,9 @@ import java.util.Collections;
public abstract class StreamProvider {
public static final StreamProvider[] EMPTY_ARRAY = new StreamProvider[0];
- public abstract boolean isEnabled();
+ public boolean isEnabled() {
+ return true;
+ }
/**
* If true, special version file per storage file will keep version of component.
@@ -37,7 +39,7 @@ public abstract class StreamProvider {
* @param roamingType
* @param async
*/
- public abstract boolean saveContent(@NotNull String fileSpec, @NotNull byte[] content, int size, @NotNull RoamingType roamingType, boolean async) throws IOException;
+ public abstract void saveContent(@NotNull String fileSpec, @NotNull byte[] content, int size, @NotNull RoamingType roamingType, boolean async) throws IOException;
@Nullable
public abstract InputStream loadContent(@NotNull String fileSpec, @NotNull RoamingType roamingType) throws IOException;
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java
index b028676168d5..76f47db77533 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java
@@ -15,44 +15,48 @@
*/
package com.intellij.openapi.components.impl.stores;
-import com.intellij.ide.plugins.IdeaPluginDescriptorImpl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.options.CurrentUserHolder;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.vfs.SafeWriteRequestor;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.io.fs.IFile;
import gnu.trove.THashMap;
+import gnu.trove.THashSet;
import gnu.trove.TObjectLongHashMap;
import org.jdom.Document;
import org.jdom.Element;
+import org.jdom.JDOMException;
import org.jdom.filter.ElementFilter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.util.*;
public abstract class XmlElementStorage implements StateStorage, Disposable {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.XmlElementStorage");
+ private static final Logger LOG = Logger.getInstance(XmlElementStorage.class);
+
+ private final static RoamingElementFilter DISABLED_ROAMING_ELEMENT_FILTER = new RoamingElementFilter(RoamingType.DISABLED);
private static final String ATTR_NAME = "name";
private static final String VERSION_FILE_SUFFIX = ".ver";
protected TrackingPathMacroSubstitutor myPathMacroSubstitutor;
- @NotNull private final String myRootElementName;
+ @NotNull protected final String myRootElementName;
private Object mySession;
private StorageData myLoadedData;
protected final StreamProvider myStreamProvider;
protected final String myFileSpec;
- private final ComponentRoamingManager myComponentRoamingManager;
protected boolean myBlockSavingTheContent = false;
protected int myUpToDateHash = -1;
- protected int myProviderUpToDateHash = -1;
+ private int myProviderUpToDateHash = -1;
private boolean mySavingDisabled = false;
private final Map<String, Object> myStorageComponentStates = new THashMap<String, Object>(); // at load we store Element, on setState Integer of hash
@@ -60,6 +64,8 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
private final ComponentVersionProvider myLocalVersionProvider;
protected final RemoteComponentVersionProvider myRemoteVersionProvider;
+ private final RoamingType myRoamingType;
+
protected ComponentVersionListener myListener = new ComponentVersionListener(){
@Override
public void componentStateChanged(String componentName) {
@@ -69,18 +75,18 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
private boolean myDisposed;
- protected XmlElementStorage(@Nullable TrackingPathMacroSubstitutor pathMacroSubstitutor,
+ protected XmlElementStorage(@NotNull String fileSpec,
+ @Nullable RoamingType roamingType,
+ @Nullable TrackingPathMacroSubstitutor pathMacroSubstitutor,
@NotNull Disposable parentDisposable,
@NotNull String rootElementName,
@Nullable StreamProvider streamProvider,
- String fileSpec,
- ComponentRoamingManager componentRoamingManager,
ComponentVersionProvider componentVersionProvider) {
+ myFileSpec = fileSpec;
+ myRoamingType = roamingType == null ? RoamingType.PER_USER : roamingType;
myPathMacroSubstitutor = pathMacroSubstitutor;
myRootElementName = rootElementName;
- myStreamProvider = streamProvider;
- myFileSpec = fileSpec;
- myComponentRoamingManager = componentRoamingManager;
+ myStreamProvider = myRoamingType == RoamingType.DISABLED ? null : streamProvider;
Disposer.register(parentDisposable, this);
myLocalVersionProvider = componentVersionProvider;
@@ -92,36 +98,39 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
}
@Nullable
- protected abstract Document loadDocument() throws StateStorageException;
+ protected abstract Element loadLocalData();
@Nullable
- public synchronized Element getState(final String componentName) throws StateStorageException {
+ public synchronized Element getState(@NotNull String componentName) {
final StorageData storageData = getStorageData(false);
final Element state = storageData.getState(componentName);
-
if (state != null) {
if (!myStorageComponentStates.containsKey(componentName)) {
myStorageComponentStates.put(componentName, state);
}
storageData.removeState(componentName);
}
-
return state;
}
@Override
- public boolean hasState(final Object component, final String componentName, final Class<?> aClass, final boolean reloadData) throws StateStorageException {
+ public boolean hasState(final Object component, @NotNull String componentName, final Class<?> aClass, final boolean reloadData) throws StateStorageException {
return getStorageData(reloadData).hasState(componentName);
}
@Override
@Nullable
- public <T> T getState(final Object component, final String componentName, Class<T> stateClass, @Nullable T mergeInto) throws StateStorageException {
+ public <T> T getState(final Object component, @NotNull String componentName, Class<T> stateClass, @Nullable T mergeInto) throws StateStorageException {
return DefaultStateSerializer.deserializeState(getState(componentName), stateClass, mergeInto);
}
@NotNull
- protected StorageData getStorageData(final boolean reloadData) throws StateStorageException {
+ protected StorageData getStorageData() {
+ return getStorageData(false);
+ }
+
+ @NotNull
+ private StorageData getStorageData(boolean reloadData) {
if (myLoadedData != null && !reloadData) {
return myLoadedData;
}
@@ -131,48 +140,48 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
}
@NotNull
- protected StorageData loadData(boolean useProvidersData) throws StateStorageException {
- Document document = loadDocument();
+ protected StorageData loadData(boolean useProvidersData) {
StorageData result = createStorageData();
- if (document != null) {
- loadState(result, document.getRootElement());
- }
-
if (useProvidersData && myStreamProvider != null && myStreamProvider.isEnabled()) {
- for (RoamingType roamingType : RoamingType.values()) {
- if (roamingType != RoamingType.DISABLED && roamingType != RoamingType.GLOBAL) {
- try {
- Document sharedDocument = StorageUtil.loadDocument(myStreamProvider.loadContent(myFileSpec, roamingType));
- if (sharedDocument != null) {
- filterOutOfDate(sharedDocument.getRootElement());
- loadState(result, sharedDocument.getRootElement());
- }
- }
- catch (Exception e) {
- LOG.warn(e);
- }
- }
+ boolean wasLoaded = false;
+ try {
+ wasLoaded = loadDataFromStreamProvider(result);
+ }
+ catch (Exception e) {
+ LOG.warn(e);
+ }
+
+ //noinspection deprecation
+ if (wasLoaded && !myStreamProvider.isVersioningRequired() && !(myStreamProvider instanceof OldStreamProviderAdapter || myStreamProvider instanceof CurrentUserHolder)) {
+ // we don't use local data if stream provider has one (to preserve backward compatibility, we don't use this logic for old stream providers)
+ return result;
}
}
+ Element element = loadLocalData();
+ if (element != null) {
+ loadState(result, element);
+ }
+
return result;
}
- protected void loadState(final StorageData result, final Element element) throws StateStorageException {
- if (myPathMacroSubstitutor != null) {
- myPathMacroSubstitutor.expandPaths(element);
+ private boolean loadDataFromStreamProvider(@NotNull StorageData result) throws IOException, JDOMException {
+ assert myStreamProvider != null;
+ InputStream inputStream = myStreamProvider.loadContent(myFileSpec, myRoamingType);
+ if (inputStream == null) {
+ return false;
}
- IdeaPluginDescriptorImpl.internJDOMElement(element);
+ Element element = JDOMUtil.loadDocument(inputStream).getRootElement();
+ filterOutOfDate(element);
+ loadState(result, element);
+ return true;
+ }
- try {
- result.load(element);
- result.checkUnknownMacros(myPathMacroSubstitutor);
- }
- catch (IOException e) {
- throw new StateStorageException(e);
- }
+ private void loadState(@NotNull StorageData result, @NotNull Element element) {
+ result.load(element, myPathMacroSubstitutor, true);
}
@NotNull
@@ -182,25 +191,15 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
public void setDefaultState(final Element element) {
myLoadedData = createStorageData();
- try {
- loadState(myLoadedData, element);
- }
- catch (StateStorageException e) {
- LOG.error(e);
- }
+ loadState(myLoadedData, element);
}
@Override
@NotNull
public ExternalizationSession startExternalization() {
- try {
- final ExternalizationSession session = new MyExternalizationSession(getStorageData(false).clone(), myListener);
- mySession = session;
- return session;
- }
- catch (StateStorageException e) {
- throw new RuntimeException(e);
- }
+ ExternalizationSession session = new MyExternalizationSession(getStorageData().clone(), myListener);
+ mySession = session;
+ return session;
}
@Override
@@ -226,19 +225,19 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
@NotNull
@Override
- public Collection<IFile> getStorageFilesToSave() throws StateStorageException {
+ public Collection<File> getStorageFilesToSave() throws StateStorageException {
return Collections.emptySet();
}
@NotNull
@Override
- public List<IFile> getAllStorageFiles() {
+ public List<File> getAllStorageFiles() {
return Collections.emptyList();
}
};
}
- protected abstract MySaveSession createSaveSession(final MyExternalizationSession externalizationSession);
+ protected abstract MySaveSession createSaveSession(MyExternalizationSession externalizationSession);
@Override
public void finishSave(@NotNull final SaveSession saveSession) {
@@ -265,22 +264,26 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
}
@Override
- public void setState(@NotNull final Object component, final String componentName, @NotNull final Object state, final Storage storageSpec) throws StateStorageException {
+ public void setState(@NotNull Object component, @NotNull String componentName, @NotNull Object state, @Nullable Storage storageSpec) {
assert mySession == this;
+ Element element;
try {
- setState(componentName, DefaultStateSerializer.serializeState(state, storageSpec));
+ element = DefaultStateSerializer.serializeState(state, storageSpec);
}
catch (WriteExternalException e) {
LOG.debug(e);
+ return;
}
- }
- private synchronized void setState(final String componentName, final Element element) {
- if (element.getAttributes().isEmpty() && element.getChildren().isEmpty()) {
+ if (element == null || JDOMUtil.isEmpty(element)) {
return;
}
+ setState(componentName, element);
+ }
+
+ private synchronized void setState(@NotNull String componentName, @NotNull Element element) {
myStorageData.setState(componentName, element);
int hash = JDOMUtil.getTreeHash(element);
try {
@@ -296,8 +299,12 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
}
}
- protected Document getDocument(StorageData data) {
- final Element element = data.save();
+ @Nullable
+ protected Element getElement(@NotNull StorageData data) {
+ Element element = data.save();
+ if (element == null || JDOMUtil.isEmpty(element)) {
+ return null;
+ }
if (myPathMacroSubstitutor != null) {
try {
@@ -308,18 +315,18 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
}
}
- return new Document(element);
+ return element;
}
protected abstract class MySaveSession implements SaveSession, SafeWriteRequestor {
final StorageData myStorageData;
- private Document myDocumentToSave;
+ private Element myElementToSave;
public MySaveSession(MyExternalizationSession externalizationSession) {
myStorageData = externalizationSession.myStorageData;
}
- public final boolean needsSave() throws StateStorageException {
+ public final boolean needsSave() {
assert mySession == this;
return _needsSave(calcHash());
}
@@ -382,11 +389,10 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
try {
if (myStreamProvider != null && myStreamProvider.isEnabled() && (myProviderUpToDateHash == -1 || myProviderUpToDateHash != hash)) {
try {
- //noinspection IfStatementWithIdenticalBranches
- if (saveForProvider(myStreamProvider)) {
- //noinspection UnnecessaryReturnStatement
- return;
- }
+ saveForProvider();
+ }
+ catch (IOException e) {
+ LOG.warn(e);
}
finally {
myProviderUpToDateHash = hash;
@@ -398,9 +404,9 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
}
}
- private void saveLocally(final Integer hash) {
+ private void saveLocally(int hash) {
try {
- if (!isHashUpToDate(hash) && _needsSave(hash)) {
+ if (!(myUpToDateHash != -1 && myUpToDateHash == hash) && _needsSave(hash)) {
doSave();
}
}
@@ -409,15 +415,15 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
}
}
- private boolean saveForProvider(@NotNull StreamProvider streamProvider) {
- if (!streamProvider.isApplicable(myFileSpec, RoamingType.PER_USER)) {
- return false;
+ private void saveForProvider() throws IOException {
+ if (!myStreamProvider.isApplicable(myFileSpec, myRoamingType)) {
+ return;
}
- Document document = getDocumentToSave();
- Element rootElement = document.getRootElement();
- if (rootElement.getChildren().isEmpty()) {
- return false;
+ Element element = getElementToSave();
+ if (element == null || element.getChildren().isEmpty()) {
+ myStreamProvider.delete(myFileSpec, myRoamingType);
+ return;
}
// skip the whole document if some component has disabled roaming type
@@ -425,59 +431,34 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
// one exclusion: workspace file (you don't have choice in this case)
// for example, it is important for ICS ProjectId - we cannot keep project in another place,
// but this project id must not be shared
- if (!myFileSpec.equals(StoragePathMacros.WORKSPACE_FILE) &&
- rootElement.getContent(new RoamingElementFilter(RoamingType.DISABLED)).iterator().hasNext()) {
- return false;
- }
-
- RoamingElementFilter perPlatformFilter = new RoamingElementFilter(RoamingType.PER_PLATFORM);
- if (rootElement.getContent(perPlatformFilter).iterator().hasNext()) {
- return doSaveForProvider(rootElement, new RoamingElementFilter(RoamingType.PER_USER)) ||
- doSaveForProvider(rootElement, perPlatformFilter);
+ if (myFileSpec.equals(StoragePathMacros.WORKSPACE_FILE)) {
+ Element copiedElement = JDOMUtil.cloneElement(element, DISABLED_ROAMING_ELEMENT_FILTER);
+ if (copiedElement != null) {
+ doSaveForProvider(copiedElement, DISABLED_ROAMING_ELEMENT_FILTER.myRoamingType, myStreamProvider);
+ }
}
else {
- return doSaveForProvider(document, RoamingType.PER_USER, streamProvider);
+ doSaveForProvider(element, myRoamingType, myStreamProvider);
}
}
- private boolean doSaveForProvider(Element element, RoamingElementFilter filter) {
- Element copiedElement = JDOMUtil.cloneElement(element, filter);
- return copiedElement != null && doSaveForProvider(new Document(copiedElement), filter.myRoamingType, myStreamProvider);
- }
-
- private boolean doSaveForProvider(Document actualDocument, RoamingType roamingType, StreamProvider streamProvider) {
- try {
- boolean result = StorageUtil.doSendContent(streamProvider, myFileSpec, actualDocument, roamingType, true);
- if (streamProvider.isVersioningRequired()) {
- TObjectLongHashMap<String> versions = loadVersions(actualDocument.getRootElement().getChildren(StorageData.COMPONENT));
- if (!versions.isEmpty()) {
- Document versionDoc = new Document(StateStorageManagerImpl.createComponentVersionsXml(versions));
- StorageUtil.doSendContent(streamProvider, myFileSpec + VERSION_FILE_SUFFIX, versionDoc, roamingType, true);
- }
+ private void doSaveForProvider(@NotNull Element element, @NotNull RoamingType roamingType, @NotNull StreamProvider streamProvider) throws IOException {
+ StorageUtil.doSendContent(streamProvider, myFileSpec, element, roamingType, true);
+ if (streamProvider.isVersioningRequired()) {
+ TObjectLongHashMap<String> versions = loadVersions(element.getChildren(StorageData.COMPONENT));
+ if (!versions.isEmpty()) {
+ Element versionDoc = StateStorageManagerImpl.createComponentVersionsXml(versions);
+ StorageUtil.doSendContent(streamProvider, myFileSpec + VERSION_FILE_SUFFIX, versionDoc, roamingType, true);
}
- return result;
- }
- catch (IOException e) {
- LOG.warn(e);
- return false;
}
}
- private boolean isHashUpToDate(final Integer hash) {
- return myUpToDateHash != -1 && myUpToDateHash == hash;
- }
-
- protected Document getDocumentToSave() {
- if (myDocumentToSave != null) return myDocumentToSave;
-
- final Element element = myStorageData.save();
- myDocumentToSave = new Document(element);
-
- if (myPathMacroSubstitutor != null) {
- myPathMacroSubstitutor.collapsePaths(element);
+ @Nullable
+ protected Element getElementToSave() {
+ if (myElementToSave == null) {
+ myElementToSave = getElement(myStorageData);
}
-
- return myDocumentToSave;
+ return myElementToSave;
}
public StorageData getData() {
@@ -488,12 +469,12 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
@Nullable
public Set<String> analyzeExternalChanges(@NotNull final Set<Pair<VirtualFile,StateStorage>> changedFiles) {
try {
- Document document = loadDocument();
+ Element element = loadLocalData();
StorageData storageData = createStorageData();
- if (document == null) {
+ if (element == null) {
return Collections.emptySet();
}
- loadState(storageData, document.getRootElement());
+ loadState(storageData, element);
return storageData.getDifference(myStorageData, myPathMacroSubstitutor);
}
catch (StateStorageException e) {
@@ -502,21 +483,6 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
return null;
}
-
- private class RoamingElementFilter extends ElementFilter {
- final RoamingType myRoamingType;
-
- public RoamingElementFilter(RoamingType roamingType) {
- super(StorageData.COMPONENT);
-
- myRoamingType = roamingType;
- }
-
- @Override
- public boolean matches(Object obj) {
- return super.matches(obj) && myComponentRoamingManager.getRoamingType(((Element)obj).getAttributeValue(StorageData.NAME)) == myRoamingType;
- }
- }
}
private TObjectLongHashMap<String> loadVersions(List<Element> elements) {
@@ -545,11 +511,9 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
@Override
public void reload(@NotNull final Set<String> changedComponents) throws StateStorageException {
final StorageData storageData = loadData(false);
-
final StorageData oldLoadedData = myLoadedData;
-
if (oldLoadedData != null) {
- Set<String> componentsToRetain = new HashSet<String>(oldLoadedData.myComponentStates.keySet());
+ Set<String> componentsToRetain = new THashSet<String>(oldLoadedData.myComponentStates.keySet());
componentsToRetain.addAll(changedComponents);
// add empty configuration tags for removed components
@@ -568,7 +532,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
myLoadedData = storageData;
}
- private void filterOutOfDate(Element element) {
+ private void filterOutOfDate(@NotNull Element element) {
if (myRemoteVersionProvider == null) {
return;
}
@@ -587,12 +551,19 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
}
@Nullable
- Document logComponents() throws StateStorageException {
- return mySession instanceof MySaveSession ? getDocument(((MySaveSession)mySession).myStorageData) : null;
+ Element logComponents() {
+ return mySession instanceof MySaveSession ? getElement(((MySaveSession)mySession).myStorageData) : null;
}
- protected class RemoteComponentVersionProvider implements ComponentVersionProvider {
- protected TObjectLongHashMap<String> myProviderVersions;
+ public void resetProviderCache() {
+ myProviderUpToDateHash = -1;
+ if (myRemoteVersionProvider != null) {
+ myRemoteVersionProvider.myProviderVersions = null;
+ }
+ }
+
+ private final class RemoteComponentVersionProvider implements ComponentVersionProvider {
+ private TObjectLongHashMap<String> myProviderVersions;
@Override
public long getVersion(String name) {
@@ -632,4 +603,19 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
}
}
}
+
+ private static class RoamingElementFilter extends ElementFilter {
+ final RoamingType myRoamingType;
+
+ public RoamingElementFilter(RoamingType roamingType) {
+ super(StorageData.COMPONENT);
+
+ myRoamingType = roamingType;
+ }
+
+ @Override
+ public boolean matches(Object obj) {
+ return super.matches(obj) && ComponentRoamingManager.getInstance().getRoamingType(((Element)obj).getAttributeValue(StorageData.NAME)) == myRoamingType;
+ }
+ }
}