IDEA-129939 IDEA tries to perform 'clear read-only status' on start on all .iml files

This commit is contained in:
Vladimir Krivosheev
2014-09-26 18:32:36 +02:00
parent d7bf706534
commit d49767206d
20 changed files with 220 additions and 187 deletions
@@ -27,7 +27,6 @@ import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -52,7 +51,7 @@ public class Convertor34 {
private static final String JAVA_DOC_ROOTS_CANNOT_BE_CONVERTED = ProjectBundle.message("project.convert.javadoc.paths.error");
private static final String MULTIPLE_OUTPUT_PATHS = ProjectBundle.message("project.convert.multiple.output.paths.error");
public static void execute(Element root, String filePath, @Nullable ArrayList<String> conversionProblems) {
public static void execute(Element root, String filePath, @Nullable List<String> conversionProblems) {
if (filePath == null) return;
if (conversionProblems == null) {
@@ -122,7 +121,7 @@ public class Convertor34 {
}
@SuppressWarnings({"HardCodedStringLiteral"})
private static void convertProjectFile(Element root, String filePath, ArrayList<String> conversionProblems) {
private static void convertProjectFile(Element root, String filePath, List<String> conversionProblems) {
Element rootComponent = null;
List components = root.getChildren("component");
for (final Object component1 : components) {
@@ -184,7 +183,7 @@ public class Convertor34 {
String name = root.getAttributeValue("name");
String url = root.getAttributeValue("url");
if(name == null || url == null) continue;
if (name == null || url == null) continue;
String filepath = VirtualFileManager.extractPath(url);
@@ -203,7 +202,7 @@ public class Convertor34 {
module.addContent(moduleProperties);
Document moduleDocument = new Document(module);
String moduleName = (!"".equals(name) ? name : moduleDirectory.getName());
String moduleName = (!name.isEmpty() ? name : moduleDirectory.getName());
if(moduleName.equals(mainModule)) moduleName = "web" + moduleName;
try {
final String modulePath = moduleDirectory.getPath() + "/" + moduleName + ModuleFileType.DOT_DEFAULT_EXTENSION;
@@ -305,14 +304,14 @@ public class Convertor34 {
VirtualFile classesDir = moduleDirectory.findFileByRelativePath("WEB-INF/classes");
if(classesDir != null) {
Element classes = createLibraryEntry(classesDir, module, moduleDirectory);
Element classes = createLibraryEntry(classesDir, moduleDirectory);
newModuleRootManager.addContent(classes);
}
VirtualFile lib = moduleDirectory.findFileByRelativePath("WEB-INF/lib");
if(lib != null) {
for (VirtualFile virtualFile : lib.getChildren()) {
Element libEntry = createLibraryEntry(virtualFile, module, moduleDirectory);
Element libEntry = createLibraryEntry(virtualFile, moduleDirectory);
newModuleRootManager.addContent(libEntry);
}
}
@@ -321,10 +320,10 @@ public class Convertor34 {
}
@SuppressWarnings({"HardCodedStringLiteral"})
private static Element createLibraryEntry(VirtualFile file, Element module, VirtualFile moduleDirectory) {
private static Element createLibraryEntry(VirtualFile file, VirtualFile moduleDirectory) {
String path = file.getPath().substring(moduleDirectory.getPath().length() + 1);
if(file.getFileSystem() instanceof JarFileSystem) {
path = path + "!/";
path += "!/";
}
Element orderEntry = new Element("orderEntry");
@@ -340,7 +339,7 @@ public class Convertor34 {
}
private static String getModulePath(String path, String moduleDirectory) {
return "".equals(path) ? moduleDirectory : moduleDirectory + "/" + path;
return path != null && path.isEmpty() ? moduleDirectory : moduleDirectory + "/" + path;
}
@SuppressWarnings({"HardCodedStringLiteral"})
@@ -357,11 +356,11 @@ public class Convertor34 {
modulesEntry.addContent(moduleEntry);
}
private static Element convertProjectRootManager(Element projectRootManager, ArrayList<String> conversionProblems) {
private static Element convertProjectRootManager(Element projectRootManager, List<String> conversionProblems) {
return new ProjectToModuleConverter(projectRootManager, conversionProblems).getModuleRootManager();
}
private static interface RootElementProcessor {
private interface RootElementProcessor {
void processSimpleRoot(Element root);
void processJdkRoot(Element root);
@@ -468,9 +467,9 @@ public class Convertor34 {
private final ArrayList<String> myProjectRoots;
private final List<String> mySourceFolders;
private final ArrayList<String> myExcludeFolders;
private final ArrayList<String> myDetectedProblems;
private final List<String> myDetectedProblems;
private ProjectToModuleConverter(Element projectRootManager, ArrayList<String> problems) {
private ProjectToModuleConverter(Element projectRootManager, List<String> problems) {
myProjectRootManager = projectRootManager;
myModuleRootManager = new Element("component");
myModuleRootManager.setAttribute("name", "NewModuleRootManager");
@@ -553,10 +552,10 @@ public class Convertor34 {
}
private static void createFolders(final Element contentElement,
final Element patternFolderElement,
final List<String> folders) {
final Element patternFolderElement,
final List<String> folders) {
for (String folder : folders) {
Element folderElement = (Element)patternFolderElement.clone();
Element folderElement = patternFolderElement.clone();
folderElement.setAttribute("url", folder);
contentElement.addContent(folderElement);
}
@@ -708,7 +707,7 @@ public class Convertor34 {
final Element libraryElement = new Element("library");
final Element classesElement = new Element("CLASSES");
final Element rootElement = new Element("root");
rootElement.setAttribute((Attribute)root.getAttribute("url").clone());
rootElement.setAttribute(root.getAttribute("url").clone());
classesElement.addContent(rootElement);
libraryElement.addContent(classesElement);
orderEntry.addContent(libraryElement);
@@ -17,7 +17,8 @@ package com.intellij.openapi.editor;
import org.jetbrains.annotations.NotNull;
public class ReadOnlyModificationException extends RuntimeException {
public class
ReadOnlyModificationException extends RuntimeException {
private final Document myDocument;
public ReadOnlyModificationException(@NotNull Document document) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.components.impl.stores;
import com.intellij.openapi.application.ApplicationManager;
@@ -44,7 +43,7 @@ import java.util.Map;
import java.util.Set;
public class ModuleStoreImpl extends BaseFileConfigurableStoreImpl implements IModuleStore {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.ModuleStoreImpl");
private static final Logger LOG = Logger.getInstance(ModuleStoreImpl.class);
private final ModuleImpl myModule;
@@ -184,7 +183,7 @@ public class ModuleStoreImpl extends BaseFileConfigurableStoreImpl implements IM
}
@Override
public void setModuleFilePath(@NotNull final String filePath) {
public void setModuleFilePath(@NotNull String filePath) {
final String path = filePath.replace(File.separatorChar, '/');
LocalFileSystem.getInstance().refreshAndFindFileByPath(path);
final StateStorageManager storageManager = getStateStorageManager();
@@ -18,6 +18,7 @@ package com.intellij.openapi.components.impl.stores;
import com.intellij.openapi.components.StateStorage;
import com.intellij.openapi.components.StateStorageException;
import com.intellij.openapi.components.TrackingPathMacroSubstitutor;
import com.intellij.openapi.components.store.ComponentSaveSession;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.impl.ModuleImpl;
@@ -92,7 +93,7 @@ public class ProjectWithModulesStoreImpl extends ProjectStoreImpl {
}
private class ProjectWithModulesSaveSession extends ProjectSaveSession {
List<SaveSession> myModuleSaveSessions = new SmartList<SaveSession>();
List<ComponentSaveSession> myModuleSaveSessions = new SmartList<ComponentSaveSession>();
public ProjectWithModulesSaveSession() {
for (Module module : getPersistentModules()) {
@@ -105,7 +106,7 @@ public class ProjectWithModulesStoreImpl extends ProjectStoreImpl {
public List<File> getAllStorageFiles(boolean includingSubStructures) {
List<File> result = super.getAllStorageFiles(includingSubStructures);
if (includingSubStructures) {
for (SaveSession moduleSaveSession : myModuleSaveSessions) {
for (ComponentSaveSession moduleSaveSession : myModuleSaveSessions) {
result.addAll(moduleSaveSession.getAllStorageFiles(true));
}
}
@@ -121,7 +122,7 @@ public class ProjectWithModulesStoreImpl extends ProjectStoreImpl {
}
Set<String> result = superResult.isEmpty() ? null : new THashSet<String>(superResult);
for (SaveSession moduleSaveSession : myModuleSaveSessions) {
for (ComponentSaveSession moduleSaveSession : myModuleSaveSessions) {
Set<String> s = moduleSaveSession.analyzeExternalChanges(changedFiles);
if (s == null) {
return null;
@@ -140,7 +141,7 @@ public class ProjectWithModulesStoreImpl extends ProjectStoreImpl {
public void finishSave() {
try {
Throwable first = null;
for (SaveSession moduleSaveSession : myModuleSaveSessions) {
for (ComponentSaveSession moduleSaveSession : myModuleSaveSessions) {
try {
moduleSaveSession.finishSave();
}
@@ -163,7 +164,7 @@ public class ProjectWithModulesStoreImpl extends ProjectStoreImpl {
@Override
public void reset() {
try {
for (SaveSession moduleSaveSession : myModuleSaveSessions) {
for (ComponentSaveSession moduleSaveSession : myModuleSaveSessions) {
moduleSaveSession.reset();
}
}
@@ -173,16 +174,17 @@ public class ProjectWithModulesStoreImpl extends ProjectStoreImpl {
}
@Override
protected void beforeSave() {
super.beforeSave();
for (SaveSession moduleSaveSession : myModuleSaveSessions) {
moduleSaveSession.save();
protected void beforeSave(@NotNull List<Pair<StateStorageManager.SaveSession, VirtualFile>> readonlyFiles) {
super.beforeSave(readonlyFiles);
for (ComponentSaveSession moduleSaveSession : myModuleSaveSessions) {
moduleSaveSession.save(readonlyFiles);
}
}
@Override
protected void collectSubFilesToSave(@NotNull List<File> result) {
for (SaveSession moduleSaveSession : myModuleSaveSessions) {
for (ComponentSaveSession moduleSaveSession : myModuleSaveSessions) {
result.addAll(moduleSaveSession.getAllStorageFilesToSave(true));
}
}
@@ -410,7 +410,7 @@ public class ClasspathStorage implements StateStorage {
}
@Override
public void save() throws StateStorageException {
public void save() {
assert mySession == this;
ClasspathStorage.this.save();
}
@@ -17,31 +17,33 @@ package com.intellij.openapi.components.impl.stores;
import com.intellij.openapi.components.*;
import com.intellij.openapi.project.impl.ProjectManagerImpl;
import com.intellij.util.SmartList;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
abstract class BaseFileConfigurableStoreImpl extends ComponentStoreImpl {
@NonNls protected static final String VERSION_OPTION = "version";
@NonNls public static final String ATTRIBUTE_NAME = "name";
private static final List<String> ourConversionProblemsStorage = new SmartList<String>();
private final ComponentManager myComponentManager;
private static final ArrayList<String> ourConversionProblemsStorage = new ArrayList<String>();
private final DefaultsStateStorage myDefaultsStateStorage;
private StateStorageManager myStateStorageManager;
protected BaseFileConfigurableStoreImpl(final ComponentManager componentManager) {
protected BaseFileConfigurableStoreImpl(@NotNull ComponentManager componentManager) {
myComponentManager = componentManager;
final PathMacroManager pathMacroManager = PathMacroManager.getInstance(myComponentManager);
myDefaultsStateStorage = new DefaultsStateStorage(pathMacroManager);
myDefaultsStateStorage = new DefaultsStateStorage(PathMacroManager.getInstance(myComponentManager));
}
public synchronized ComponentManager getComponentManager() {
@NotNull
public ComponentManager getComponentManager() {
return myComponentManager;
}
@@ -109,7 +111,7 @@ abstract class BaseFileConfigurableStoreImpl extends ComponentStoreImpl {
protected abstract XmlElementStorage getMainStorage();
@Nullable
static ArrayList<String> getConversionProblemsStorage() {
static List<String> getConversionProblemsStorage() {
return ourConversionProblemsStorage;
}
@@ -22,6 +22,8 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.components.*;
import com.intellij.openapi.components.impl.ComponentManagerImpl;
import com.intellij.openapi.components.store.ComponentSaveSession;
import com.intellij.openapi.components.store.ReadOnlyModificationException;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.project.Project;
@@ -90,7 +92,7 @@ public abstract class ComponentStoreImpl implements IComponentStore {
@Override
@NotNull
public SaveSession startSave() {
public ComponentSaveSession startSave() {
SaveSessionImpl session = createSaveSession();
try {
session.commit();
@@ -118,7 +120,7 @@ public abstract class ComponentStoreImpl implements IComponentStore {
return new SaveSessionImpl();
}
public void finishSave(@NotNull final SaveSession saveSession) {
public void finishSave(@NotNull final ComponentSaveSession saveSession) {
assert mySession == saveSession;
mySession.finishSave();
mySession = null;
@@ -336,7 +338,16 @@ public abstract class ComponentStoreImpl implements IComponentStore {
return null;
}
protected class SaveSessionImpl implements SaveSession {
protected static void executeSave(@NotNull StateStorageManager.SaveSession saveSession, @NotNull List<Pair<StateStorageManager.SaveSession, VirtualFile>> readonlyFiles) {
try {
saveSession.save();
}
catch (ReadOnlyModificationException e) {
readonlyFiles.add(Pair.create(saveSession, e.getFile()));
}
}
protected class SaveSessionImpl implements ComponentSaveSession {
protected StateStorageManager.SaveSession myStorageManagerSaveSession;
public SaveSessionImpl() {
@@ -351,7 +362,7 @@ public abstract class ComponentStoreImpl implements IComponentStore {
@NotNull
@Override
public SaveSession save() {
public ComponentSaveSession save(@NotNull List<Pair<StateStorageManager.SaveSession, VirtualFile>> readonlyFiles) {
SettingsSavingComponent[] settingsComponents =
mySettingsSavingComponents.toArray(new SettingsSavingComponent[mySettingsSavingComponents.size()]);
for (SettingsSavingComponent settingsSavingComponent : settingsComponents) {
@@ -363,7 +374,7 @@ public abstract class ComponentStoreImpl implements IComponentStore {
}
}
myStorageManagerSaveSession.save();
executeSave(myStorageManagerSaveSession, readonlyFiles);
return this;
}
@@ -391,7 +402,7 @@ public abstract class ComponentStoreImpl implements IComponentStore {
}
}
protected void commit() throws StateStorageException {
protected void commit() {
final StateStorageManager storageManager = getStateStorageManager();
final StateStorageManager.ExternalizationSession session = storageManager.startExternalization();
@@ -471,7 +482,7 @@ public abstract class ComponentStoreImpl implements IComponentStore {
@Nullable
protected final Collection<String> reload(@NotNull Set<Pair<VirtualFile, StateStorage>> changedFiles, @NotNull MessageBus messageBus) {
SaveSession saveSession = startSave();
ComponentSaveSession saveSession = startSave();
Set<String> componentNames;
try {
componentNames = saveSession.analyzeExternalChanges(changedFiles);
@@ -162,7 +162,7 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
@NotNull
@Override
public SaveSession startSave(@NotNull final ExternalizationSession externalizationSession) {
public SaveSession startSave(@NotNull ExternalizationSession externalizationSession) {
return new MySaveSession(storage, externalizationSession);
}
@@ -25,7 +25,10 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.util.text.StringUtilRt;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileAdapter;
import com.intellij.openapi.vfs.VirtualFileEvent;
import com.intellij.openapi.vfs.tracker.VirtualFileTracker;
import com.intellij.util.SmartList;
import com.intellij.util.containers.SmartHashSet;
@@ -168,7 +171,7 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
public void dispose() {
}
private class MySaveSession implements SaveSession, SafeWriteRequestor {
private class MySaveSession implements SaveSession {
private final DirectoryStorageData myStorageData;
private final TrackingPathMacroSubstitutor myPathMacroSubstitutor;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -15,17 +15,12 @@
*/
package com.intellij.openapi.components.impl.stores;
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.openapi.components.store.ComponentSaveSession;
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.List;
import java.util.Set;
public interface IComponentStore {
@@ -55,23 +50,5 @@ public interface IComponentStore {
}
@NotNull
SaveSession startSave();
interface SaveSession {
@NotNull
List<File> getAllStorageFilesToSave(boolean includingSubStructures);
@NotNull
SaveSession save();
void finishSave();
void reset();
@Nullable
Set<String> analyzeExternalChanges(@NotNull Set<Pair<VirtualFile, StateStorage>> changedFiles);
@NotNull
List<File> getAllStorageFiles(final boolean includingSubStructures);
}
ComponentSaveSession startSave();
}
@@ -20,8 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface IModuleStore extends IComponentStore {
void setModuleFilePath(final String filePath);
void setModuleFilePath(@NotNull String filePath);
@Nullable
VirtualFile getModuleFile();
@@ -19,10 +19,9 @@ import com.intellij.CommonBundle;
import com.intellij.ide.highlighter.ProjectFileType;
import com.intellij.ide.highlighter.WorkspaceFileType;
import com.intellij.notification.NotificationsManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.*;
import com.intellij.openapi.components.*;
import com.intellij.openapi.components.store.ComponentSaveSession;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
@@ -32,7 +31,6 @@ import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.project.impl.ProjectImpl;
import com.intellij.openapi.project.impl.ProjectManagerImpl;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
@@ -51,7 +49,6 @@ import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -87,7 +84,7 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
name + OLD_PROJECT_SUFFIX + projectFile.getExtension());
if (Messages.showYesNoDialog(message, CommonBundle.getWarningTitle(), Messages.getWarningIcon()) != Messages.YES) return false;
final ArrayList<String> conversionProblems = getConversionProblemsStorage();
List<String> conversionProblems = getConversionProblemsStorage();
if (conversionProblems != null && !conversionProblems.isEmpty()) {
StringBuilder buffer = new StringBuilder();
buffer.append(ProjectBundle.message("project.convert.problems.detected"));
@@ -494,97 +491,57 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
@NotNull
@Override
public SaveSession save() {
public ComponentSaveSession save(@NotNull List<Pair<StateStorageManager.SaveSession, VirtualFile>> readonlyFiles) {
ProjectImpl.UnableToSaveProjectNotification[] notifications =
NotificationsManager.getNotificationsManager().getNotificationsOfType(ProjectImpl.UnableToSaveProjectNotification.class, myProject);
if (notifications.length > 0) {
throw new SaveCancelledException();
}
ReadonlyStatusHandler.OperationStatus operationStatus = ensureConfigFilesWritable();
if (operationStatus == null) {
throw new StateStorageException();
}
else if (operationStatus.hasReadonlyFiles()) {
ProjectImpl.dropUnableToSaveProjectNotification(myProject, operationStatus.getReadonlyFiles());
throw new SaveCancelledException();
beforeSave(readonlyFiles);
super.save(readonlyFiles);
if (!readonlyFiles.isEmpty()) {
ReadonlyStatusHandler.OperationStatus status;
AccessToken token = ReadAction.start();
try {
status = ReadonlyStatusHandler.getInstance(myProject).ensureFilesWritable(getFilesList(readonlyFiles));
}
finally {
token.finish();
}
if (status.hasReadonlyFiles()) {
ProjectImpl.dropUnableToSaveProjectNotification(myProject, status.getReadonlyFiles());
throw new SaveCancelledException();
}
else {
readonlyFiles.clear();
for (Pair<StateStorageManager.SaveSession, VirtualFile> entry : readonlyFiles) {
executeSave(entry.first, readonlyFiles);
}
if (!readonlyFiles.isEmpty()) {
ProjectImpl.dropUnableToSaveProjectNotification(myProject, getFilesList(readonlyFiles));
throw new SaveCancelledException();
}
}
}
beforeSave();
super.save();
return this;
}
protected void beforeSave() {
@NotNull
private VirtualFile[] getFilesList(List<Pair<StateStorageManager.SaveSession, VirtualFile>> readonlyFiles) {
final VirtualFile[] files = new VirtualFile[readonlyFiles.size()];
for (int i = 0, size = readonlyFiles.size(); i < size; i++) {
files[i] = readonlyFiles.get(i).second;
}
return files;
}
private ReadonlyStatusHandler.OperationStatus ensureConfigFilesWritable() {
return ApplicationManager.getApplication().runReadAction(new Computable<ReadonlyStatusHandler.OperationStatus>() {
@Override
public ReadonlyStatusHandler.OperationStatus compute() {
List<File> filesToSave;
try {
filesToSave = getAllStorageFilesToSave(true);
Iterator<File> iterator = filesToSave.iterator();
while (iterator.hasNext()) {
if (!iterator.next().exists()) {
iterator.remove();
}
}
}
catch (Exception e) {
LOG.error(e);
return null;
}
List<VirtualFile> readonlyFiles = new ArrayList<VirtualFile>();
if (myProject.isToSaveProjectName()) {
final VirtualFile baseDir = getProjectBaseDir();
if (baseDir != null && baseDir.isValid()) {
filesToSave.add(new File(new File(baseDir.getPath(), Project.DIRECTORY_STORE_FOLDER), ProjectImpl.NAME_FILE));
}
}
for (File file : filesToSave) {
final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(file);
if (virtualFile != null) {
virtualFile.refresh(false, false);
if (virtualFile.isValid() && !virtualFile.isWritable()) {
readonlyFiles.add(virtualFile);
}
}
}
if (readonlyFiles.isEmpty()) {
final VirtualFile projectBaseDir = getProjectBaseDir();
if (projectBaseDir != null && projectBaseDir.isValid()) {
if (!projectBaseDir.isWritable()) {
readonlyFiles.add(projectBaseDir);
}
final LocalFileSystem instance = LocalFileSystem.getInstance();
final VirtualFile ideaDir1 =
instance.findFileByIoFile(new File(projectBaseDir.getPath(), Project.DIRECTORY_STORE_FOLDER));
if (ideaDir1 != null && ideaDir1.isValid()) {
if (!ideaDir1.isWritable()) {
readonlyFiles.add(ideaDir1);
}
} else {
final VirtualFile ideaDir2 =
instance.findFileByIoFile(new File(new File(projectBaseDir.getPath()).getParent(), Project.DIRECTORY_STORE_FOLDER));
if (ideaDir2 != null && ideaDir2.isValid()) {
if (!ideaDir2.isWritable()) {
readonlyFiles.add(ideaDir2);
}
}
}
}
}
return ReadonlyStatusHandler.getInstance(myProject).ensureFilesWritable(readonlyFiles);
}
});
protected void beforeSave(@NotNull List<Pair<StateStorageManager.SaveSession, VirtualFile>> readonlyFiles) {
}
}
@@ -21,6 +21,7 @@ import com.intellij.notification.NotificationType;
import com.intellij.notification.NotificationsManager;
import com.intellij.openapi.application.*;
import com.intellij.openapi.components.*;
import com.intellij.openapi.components.store.ReadOnlyModificationException;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.DocumentRunnable;
import com.intellij.openapi.project.Project;
@@ -173,6 +174,14 @@ public class StorageUtil {
}
return virtualFile;
}
catch (FileNotFoundException e) {
if (virtualFile == null) {
throw e;
}
else {
throw new ReadOnlyModificationException(virtualFile);
}
}
finally {
token.finish();
}
@@ -15,8 +15,14 @@
*/
package com.intellij.openapi.components.impl.stores;
import com.intellij.openapi.components.store.ComponentSaveSession;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author yole
*/
@@ -25,10 +31,11 @@ public class StoreUtil {
}
public static void doSave(@NotNull IComponentStore stateStore) {
IComponentStore.SaveSession session = null;
ComponentSaveSession session = null;
try {
session = stateStore.startSave();
session.save();
List<Pair<StateStorageManager.SaveSession, VirtualFile>> readonlyFiles = new SmartList<Pair<StateStorageManager.SaveSession, VirtualFile>>();
session.save(readonlyFiles);
}
finally {
if (session != null) {
@@ -23,7 +23,6 @@ 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 gnu.trove.THashMap;
import gnu.trove.THashSet;
@@ -217,7 +216,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
private static SaveSession createNullSession() {
return new SaveSession(){
@Override
public void save() throws StateStorageException {
public void save() {
}
@Override
@@ -320,7 +319,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
return element;
}
protected abstract class MySaveSession implements SaveSession, SafeWriteRequestor {
protected abstract class MySaveSession implements SaveSession {
final StorageData myStorageData;
private Element myElementToSave;
@@ -380,7 +379,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
}
@Override
public final void save() throws StateStorageException {
public final void save() {
assert mySession == this;
if (myBlockSavingTheContent) {
@@ -392,27 +391,17 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
if (myStreamProvider != null && myStreamProvider.isEnabled() && (myProviderUpToDateHash == -1 || myProviderUpToDateHash != hash)) {
try {
saveForProvider();
}
catch (IOException e) {
LOG.warn(e);
}
finally {
myProviderUpToDateHash = hash;
}
catch (Throwable e) {
LOG.error(e);
}
}
}
finally {
saveLocally(hash);
}
}
private void saveLocally(int hash) {
try {
if (!(myUpToDateHash != -1 && myUpToDateHash == hash) && _needsSave(hash)) {
doSave();
}
}
finally {
myUpToDateHash = hash;
}
}
@@ -0,0 +1,45 @@
/*
* Copyright 2000-2014 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.store;
import com.intellij.openapi.components.StateStorage;
import com.intellij.openapi.components.impl.stores.StateStorageManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.List;
import java.util.Set;
public interface ComponentSaveSession {
@NotNull
List<File> getAllStorageFilesToSave(boolean includingSubStructures);
@NotNull
ComponentSaveSession save(@NotNull List<Pair<StateStorageManager.SaveSession, VirtualFile>> readonlyFiles);
void finishSave();
void reset();
@Nullable
Set<String> analyzeExternalChanges(@NotNull Set<Pair<VirtualFile, StateStorage>> changedFiles);
@NotNull
List<File> getAllStorageFiles(final boolean includingSubStructures);
}
@@ -0,0 +1,32 @@
/*
* Copyright 2000-2014 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.store;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
public final class ReadOnlyModificationException extends RuntimeException {
private final VirtualFile myFile;
public ReadOnlyModificationException(@NotNull VirtualFile file) {
myFile = file;
}
@NotNull
public VirtualFile getFile() {
return myFile;
}
}
@@ -32,9 +32,9 @@ import com.intellij.openapi.components.ExportableApplicationComponent;
import com.intellij.openapi.components.StateStorage;
import com.intellij.openapi.components.StateStorageException;
import com.intellij.openapi.components.TrackingPathMacroSubstitutor;
import com.intellij.openapi.components.impl.stores.IComponentStore;
import com.intellij.openapi.components.impl.stores.StorageUtil;
import com.intellij.openapi.components.impl.stores.XmlElementStorage;
import com.intellij.openapi.components.store.ComponentSaveSession;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.progress.*;
@@ -918,7 +918,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
final String location = projectImpl.getPresentableUrl();
final List<File> original;
try {
IComponentStore.SaveSession saveSession = projectImpl.getStateStore().startSave();
ComponentSaveSession saveSession = projectImpl.getStateStore().startSave();
original = saveSession.getAllStorageFiles(true);
saveSession.finishSave();
}
@@ -51,7 +51,7 @@ public interface StateStorage {
}
interface SaveSession {
void save() throws StateStorageException;
void save();
/**
* Get changed component names
@@ -20,6 +20,7 @@ import com.intellij.openapi.components.StorageScheme;
import com.intellij.openapi.components.TrackingPathMacroSubstitutor;
import com.intellij.openapi.components.impl.stores.IProjectStore;
import com.intellij.openapi.components.impl.stores.StateStorageManager;
import com.intellij.openapi.components.store.ComponentSaveSession;
import com.intellij.openapi.project.impl.ProjectImpl;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.Pair;
@@ -138,7 +139,7 @@ public class MockProjectStore implements IProjectStore {
@Override
@NotNull
public SaveSession startSave() {
public ComponentSaveSession startSave() {
throw new UnsupportedOperationException("Method startSave not implemented in " + getClass());
}