mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-137442 Problems on exit from Idea when a project in Perforce
This commit is contained in:
+1
-1
@@ -196,7 +196,7 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable {
|
||||
}
|
||||
catch (ReadOnlyModificationException e) {
|
||||
LOG.warn(e);
|
||||
readonlyFiles.add(Pair.create(session, e.getFile()));
|
||||
readonlyFiles.add(Pair.create(e.getSession() == null ? session : e.getSession(), e.getFile()));
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (errors == null) {
|
||||
|
||||
+7
-14
@@ -287,12 +287,17 @@ public class DirectoryBasedStorage extends StateStorageBase<DirectoryStorageData
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteFiles(@NotNull VirtualFile dir) {
|
||||
private void deleteFiles(@NotNull VirtualFile dir) throws IOException {
|
||||
AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(DocumentRunnable.IgnoreDocumentRunnable.class);
|
||||
try {
|
||||
for (VirtualFile file : dir.getChildren()) {
|
||||
if (removedFileNames.contains(file.getName())) {
|
||||
deleteFile(file, this);
|
||||
try {
|
||||
file.delete(this);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
throw new ReadOnlyModificationException(file, e, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -301,16 +306,4 @@ public class DirectoryBasedStorage extends StateStorageBase<DirectoryStorageData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteFile(@NotNull VirtualFile file, @NotNull Object requestor) {
|
||||
try {
|
||||
file.delete(requestor);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
throw new ReadOnlyModificationException(file, e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new StateStorageException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+63
-35
@@ -22,6 +22,7 @@ import com.intellij.notification.NotificationsManager;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.components.RoamingType;
|
||||
import com.intellij.openapi.components.StateStorage;
|
||||
import com.intellij.openapi.components.StoragePathMacros;
|
||||
@@ -121,46 +122,66 @@ public class StorageUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static VirtualFile writeFile(@Nullable final File file,
|
||||
@NotNull final Object requestor,
|
||||
@Nullable final VirtualFile virtualFile,
|
||||
@NotNull final BufferExposingByteArrayOutputStream content,
|
||||
@Nullable final LineSeparator lineSeparatorIfPrependXmlProlog) throws IOException {
|
||||
public static VirtualFile writeFile(@Nullable File file,
|
||||
@NotNull Object requestor,
|
||||
@Nullable VirtualFile virtualFile,
|
||||
@NotNull BufferExposingByteArrayOutputStream content,
|
||||
@Nullable LineSeparator lineSeparatorIfPrependXmlProlog) throws IOException {
|
||||
final VirtualFile result;
|
||||
if (file != null && (virtualFile == null || !virtualFile.isValid())) {
|
||||
result = getOrCreateVirtualFile(requestor, file);
|
||||
}
|
||||
else {
|
||||
result = virtualFile;
|
||||
assert result != null;
|
||||
}
|
||||
assert result != null;
|
||||
|
||||
boolean equals = isEqualContent(result, lineSeparatorIfPrependXmlProlog, content);
|
||||
if (equals) return result;
|
||||
return ApplicationManager.getApplication().runWriteAction(new ThrowableComputable<VirtualFile, IOException>() {
|
||||
@Override
|
||||
public VirtualFile compute() throws IOException {
|
||||
try {
|
||||
OutputStream out = result.getOutputStream(requestor);
|
||||
try {
|
||||
if (lineSeparatorIfPrependXmlProlog != null) {
|
||||
out.write(XML_PROLOG);
|
||||
out.write(lineSeparatorIfPrependXmlProlog.getSeparatorBytes());
|
||||
}
|
||||
content.writeTo(out);
|
||||
}
|
||||
finally {
|
||||
out.close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
if (virtualFile == null) {
|
||||
throw e;
|
||||
}
|
||||
throw new ReadOnlyModificationException(virtualFile, e);
|
||||
if (equals) {
|
||||
LOG.warn("Content equals, but it must be handled not on this level");
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
doWrite(requestor, result, virtualFile, content, lineSeparatorIfPrependXmlProlog);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static void doWrite(@NotNull final Object requestor,
|
||||
@NotNull final VirtualFile file,
|
||||
@Nullable final VirtualFile proposedFile,
|
||||
@NotNull final BufferExposingByteArrayOutputStream content,
|
||||
@Nullable final LineSeparator lineSeparatorIfPrependXmlProlog) throws IOException {
|
||||
AccessToken token = WriteAction.start();
|
||||
try {
|
||||
OutputStream out = file.getOutputStream(requestor);
|
||||
try {
|
||||
if (lineSeparatorIfPrependXmlProlog != null) {
|
||||
out.write(XML_PROLOG);
|
||||
out.write(lineSeparatorIfPrependXmlProlog.getSeparatorBytes());
|
||||
}
|
||||
content.writeTo(out);
|
||||
}
|
||||
});
|
||||
finally {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
if (proposedFile == null) {
|
||||
throw e;
|
||||
}
|
||||
else {
|
||||
throw new ReadOnlyModificationException(proposedFile, e, new StateStorage.SaveSession() {
|
||||
@Override
|
||||
public void save() throws IOException {
|
||||
doWrite(requestor, file, proposedFile, content, lineSeparatorIfPrependXmlProlog);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isEqualContent(VirtualFile result,
|
||||
@@ -187,7 +208,7 @@ public class StorageUtil {
|
||||
return equals;
|
||||
}
|
||||
|
||||
public static void deleteFile(@NotNull File file, @NotNull Object requestor, @Nullable VirtualFile virtualFile) throws IOException {
|
||||
public static void deleteFile(@NotNull File file, @NotNull final Object requestor, @Nullable final VirtualFile virtualFile) throws IOException {
|
||||
if (virtualFile == null) {
|
||||
LOG.warn("Cannot find virtual file " + file.getAbsolutePath());
|
||||
}
|
||||
@@ -198,7 +219,17 @@ public class StorageUtil {
|
||||
}
|
||||
}
|
||||
else if (virtualFile.exists()) {
|
||||
deleteFile(requestor, virtualFile);
|
||||
try {
|
||||
deleteFile(requestor, virtualFile);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
throw new ReadOnlyModificationException(virtualFile, e, new StateStorage.SaveSession() {
|
||||
@Override
|
||||
public void save() throws IOException {
|
||||
deleteFile(requestor, virtualFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,9 +238,6 @@ public class StorageUtil {
|
||||
try {
|
||||
virtualFile.delete(requestor);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
throw new ReadOnlyModificationException(virtualFile, e);
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
|
||||
+10
-1
@@ -15,20 +15,29 @@
|
||||
*/
|
||||
package com.intellij.openapi.components.store;
|
||||
|
||||
import com.intellij.openapi.components.StateStorage;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class ReadOnlyModificationException extends RuntimeException {
|
||||
private final VirtualFile myFile;
|
||||
private final StateStorage.SaveSession mySession;
|
||||
|
||||
public ReadOnlyModificationException(@NotNull VirtualFile file, @NotNull Throwable cause) {
|
||||
public ReadOnlyModificationException(@NotNull VirtualFile file, @Nullable Throwable cause, StateStorage.SaveSession session) {
|
||||
super(cause);
|
||||
|
||||
myFile = file;
|
||||
mySession = session;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VirtualFile getFile() {
|
||||
return myFile;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public StateStorage.SaveSession getSession() {
|
||||
return mySession;
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,6 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ex.DecodeDefaultsUtil;
|
||||
import com.intellij.openapi.components.RoamingType;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.components.StateStorageException;
|
||||
import com.intellij.openapi.components.impl.stores.DirectoryBasedStorage;
|
||||
import com.intellij.openapi.components.impl.stores.DirectoryStorageData;
|
||||
import com.intellij.openapi.components.impl.stores.StorageUtil;
|
||||
@@ -503,6 +502,7 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
|
||||
}
|
||||
}
|
||||
|
||||
List<Throwable> errors = null;
|
||||
VirtualFile dir = getVirtualDir();
|
||||
if (!hasSchemes) {
|
||||
myFilesToDelete.clear();
|
||||
@@ -510,14 +510,14 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
|
||||
try {
|
||||
StorageUtil.deleteFile(this, dir);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new StateStorageException(e);
|
||||
catch (Throwable e) {
|
||||
errors = new SmartList<Throwable>();
|
||||
errors.add(e);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
List<Throwable> errors = null;
|
||||
for (E scheme : schemesToSave) {
|
||||
try {
|
||||
saveScheme(scheme, nameGenerator);
|
||||
@@ -530,7 +530,7 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
|
||||
}
|
||||
}
|
||||
|
||||
deleteFiles(dir);
|
||||
errors = deleteFiles(dir, errors);
|
||||
|
||||
CompoundRuntimeException.doThrow(errors);
|
||||
}
|
||||
@@ -620,9 +620,10 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
|
||||
return !scheme.getName().equals(scheme.getExternalInfo().getPreviouslySavedName());
|
||||
}
|
||||
|
||||
private void deleteFiles(@Nullable VirtualFile dir) {
|
||||
@Nullable
|
||||
private List<Throwable> deleteFiles(@Nullable VirtualFile dir, List<Throwable> errors) {
|
||||
if (myFilesToDelete.isEmpty()) {
|
||||
return;
|
||||
return errors;
|
||||
}
|
||||
|
||||
if (myProvider != null && myProvider.isEnabled()) {
|
||||
@@ -639,7 +640,15 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
|
||||
try {
|
||||
for (VirtualFile file : dir.getChildren()) {
|
||||
if (myFilesToDelete.contains(file.getNameWithoutExtension())) {
|
||||
DirectoryBasedStorage.deleteFile(file, this);
|
||||
try {
|
||||
file.delete(this);
|
||||
}
|
||||
catch (IOException e) {
|
||||
if (errors == null) {
|
||||
errors = new SmartList<Throwable>();
|
||||
}
|
||||
errors.add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
myFilesToDelete.clear();
|
||||
@@ -648,6 +657,7 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
|
||||
token.finish();
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
Reference in New Issue
Block a user