mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
more robust project reloading (instead of revert bad changes (our state storage can overwritte new (FS) changes), we just disable saving until we are not ready to reinit/reload component store)
This commit is contained in:
@@ -22,7 +22,6 @@ import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.project.impl.ProjectManagerImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -33,7 +32,7 @@ public class ReloadProjectAction extends AnAction implements DumbAware {
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
|
||||
if (project != null) {
|
||||
((ProjectManagerImpl)ProjectManager.getInstance()).reloadProjectImpl(project, null);
|
||||
ProjectManager.getInstance().reloadProject(project);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+33
-16
@@ -52,7 +52,7 @@ import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
@SuppressWarnings({"deprecation"})
|
||||
public abstract class ComponentStoreImpl implements IComponentStore {
|
||||
public abstract class ComponentStoreImpl implements IComponentStore.Reloadable {
|
||||
private static final Logger LOG = Logger.getInstance(ComponentStoreImpl.class);
|
||||
private final Map<String, Object> myComponents = Collections.synchronizedMap(new THashMap<String, Object>());
|
||||
private final List<SettingsSavingComponent> mySettingsSavingComponents = new CopyOnWriteArrayList<SettingsSavingComponent>();
|
||||
@@ -101,6 +101,9 @@ public abstract class ComponentStoreImpl implements IComponentStore {
|
||||
|
||||
StateStorageManager storageManager = getStateStorageManager();
|
||||
StateStorageManager.ExternalizationSession externalizationSession = storageManager.startExternalization();
|
||||
if (externalizationSession == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] names = ArrayUtilRt.toStringArray(myComponents.keySet());
|
||||
Arrays.sort(names);
|
||||
@@ -429,6 +432,7 @@ public abstract class ComponentStoreImpl implements IComponentStore {
|
||||
@NotNull
|
||||
protected abstract MessageBus getMessageBus();
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public final Collection<String> reload(@NotNull Collection<Pair<VirtualFile, StateStorage>> changedFiles) {
|
||||
Set<String> componentNames = new SmartHashSet<String>();
|
||||
@@ -470,7 +474,7 @@ public abstract class ComponentStoreImpl implements IComponentStore {
|
||||
}
|
||||
|
||||
public enum ReloadComponentStoreStatus {
|
||||
RESTART_REQUIRED,
|
||||
RESTART_AGREED,
|
||||
RESTART_CANCELLED,
|
||||
ERROR,
|
||||
SUCCESS,
|
||||
@@ -479,24 +483,37 @@ public abstract class ComponentStoreImpl implements IComponentStore {
|
||||
@NotNull
|
||||
public static ReloadComponentStoreStatus reloadStore(@NotNull Collection<Pair<VirtualFile, StateStorage>> causes, @NotNull IComponentStore.Reloadable store) {
|
||||
Collection<String> notReloadableComponents;
|
||||
AccessToken token = WriteAction.start();
|
||||
boolean willBeReloaded = false;
|
||||
try {
|
||||
notReloadableComponents = store.reload(causes);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
Messages.showWarningDialog(ProjectBundle.message("project.reload.failed", e.getMessage()),
|
||||
ProjectBundle.message("project.reload.failed.title"));
|
||||
return ReloadComponentStoreStatus.ERROR;
|
||||
AccessToken token = WriteAction.start();
|
||||
try {
|
||||
notReloadableComponents = store.reload(causes);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
Messages.showWarningDialog(ProjectBundle.message("project.reload.failed", e.getMessage()),
|
||||
ProjectBundle.message("project.reload.failed.title"));
|
||||
return ReloadComponentStoreStatus.ERROR;
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
|
||||
if (ContainerUtil.isEmpty(notReloadableComponents)) {
|
||||
return ReloadComponentStoreStatus.SUCCESS;
|
||||
}
|
||||
|
||||
willBeReloaded = askToRestart(store, notReloadableComponents, causes);
|
||||
return willBeReloaded ? ReloadComponentStoreStatus.RESTART_AGREED : ReloadComponentStoreStatus.RESTART_CANCELLED;
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
if (!willBeReloaded) {
|
||||
for (Pair<VirtualFile, StateStorage> cause : causes) {
|
||||
if (cause.second instanceof XmlElementStorage) {
|
||||
((XmlElementStorage)cause.second).enableSaving();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ContainerUtil.isEmpty(notReloadableComponents)) {
|
||||
return ReloadComponentStoreStatus.SUCCESS;
|
||||
}
|
||||
|
||||
return askToRestart(store, notReloadableComponents, causes) ? ReloadComponentStoreStatus.RESTART_REQUIRED : ReloadComponentStoreStatus.RESTART_CANCELLED;
|
||||
}
|
||||
|
||||
// used in settings repository plugin
|
||||
|
||||
+5
-4
@@ -137,10 +137,11 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
|
||||
public void clearStateStorage(@NotNull String file) {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nullable
|
||||
@Override
|
||||
public ExternalizationSession startExternalization() {
|
||||
return new MyExternalizationSession(storage);
|
||||
StateStorage.ExternalizationSession externalizationSession = storage.startExternalization();
|
||||
return externalizationSession == null ? null : new MyExternalizationSession(externalizationSession);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -204,8 +205,8 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
|
||||
private static class MyExternalizationSession implements StateStorageManager.ExternalizationSession {
|
||||
@NotNull final StateStorage.ExternalizationSession externalizationSession;
|
||||
|
||||
public MyExternalizationSession(@NotNull XmlElementStorage storage) {
|
||||
externalizationSession = storage.startExternalization();
|
||||
public MyExternalizationSession(@NotNull StateStorage.ExternalizationSession externalizationSession) {
|
||||
this.externalizationSession = externalizationSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ public interface StateStorageManager {
|
||||
|
||||
void clearStateStorage(@NotNull String file);
|
||||
|
||||
@NotNull
|
||||
@Nullable
|
||||
ExternalizationSession startExternalization();
|
||||
|
||||
/**
|
||||
|
||||
+23
-19
@@ -414,22 +414,17 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
|
||||
@Override
|
||||
public SaveSession startSave(@NotNull ExternalizationSession externalizationSession) {
|
||||
StateStorageManagerExternalizationSession myExternalizationSession = (StateStorageManagerExternalizationSession)externalizationSession;
|
||||
Map<StateStorage, SaveSession> saveSessions = null;
|
||||
List<SaveSession> saveSessions = null;
|
||||
for (StateStorage stateStorage : myExternalizationSession.mySessions.keySet()) {
|
||||
SaveSession saveSession = stateStorage.startSave(myExternalizationSession.getExternalizationSession(stateStorage));
|
||||
SaveSession saveSession = stateStorage.startSave(myExternalizationSession.mySessions.get(stateStorage));
|
||||
if (saveSession != null) {
|
||||
if (saveSessions == null) {
|
||||
saveSessions = new SmartHashMap<StateStorage, SaveSession>();
|
||||
saveSessions = new SmartList<SaveSession>();
|
||||
}
|
||||
saveSessions.put(stateStorage, saveSession);
|
||||
saveSessions.add(saveSession);
|
||||
}
|
||||
}
|
||||
|
||||
if (saveSessions == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new StateStorageSaveSession(saveSessions);
|
||||
return saveSessions == null ? null : new StateStorageSaveSession(saveSessions);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -463,7 +458,10 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
|
||||
continue;
|
||||
}
|
||||
|
||||
getExternalizationSession(stateStorage).setState(component, componentName, state, storageSpec);
|
||||
StateStorage.ExternalizationSession session = getExternalizationSession(stateStorage);
|
||||
if (session != null) {
|
||||
session.setState(component, componentName, state, storageSpec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,15 +469,21 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
|
||||
public void setStateInOldStorage(@NotNull Object component, @NotNull String componentName, @NotNull Object state) {
|
||||
StateStorage stateStorage = getOldStorage(component, componentName, StateStorageOperation.WRITE);
|
||||
if (stateStorage != null) {
|
||||
getExternalizationSession(stateStorage).setState(component, componentName, state, null);
|
||||
StateStorage.ExternalizationSession session = getExternalizationSession(stateStorage);
|
||||
if (session != null) {
|
||||
session.setState(component, componentName, state, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private StateStorage.ExternalizationSession getExternalizationSession(@NotNull StateStorage stateStore) {
|
||||
StateStorage.ExternalizationSession session = mySessions.get(stateStore);
|
||||
@Nullable
|
||||
private StateStorage.ExternalizationSession getExternalizationSession(@NotNull StateStorage stateStorage) {
|
||||
StateStorage.ExternalizationSession session = mySessions.get(stateStorage);
|
||||
if (session == null) {
|
||||
mySessions.put(stateStore, session = stateStore.startExternalization());
|
||||
session = stateStorage.startExternalization();
|
||||
if (session != null) {
|
||||
mySessions.put(stateStorage, session);
|
||||
}
|
||||
}
|
||||
return session;
|
||||
}
|
||||
@@ -497,15 +501,15 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
|
||||
protected abstract String getOldStorageSpec(@NotNull Object component, @NotNull String componentName, @NotNull StateStorageOperation operation);
|
||||
|
||||
private final static class StateStorageSaveSession implements SaveSession {
|
||||
private final Map<StateStorage, SaveSession> mySaveSessions;
|
||||
private final List<SaveSession> mySaveSessions;
|
||||
|
||||
public StateStorageSaveSession(@NotNull Map<StateStorage, SaveSession> saveSessions) {
|
||||
public StateStorageSaveSession(@NotNull List<SaveSession> saveSessions) {
|
||||
mySaveSessions = saveSessions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
for (SaveSession saveSession : mySaveSessions.values()) {
|
||||
for (SaveSession saveSession : mySaveSessions) {
|
||||
saveSession.save();
|
||||
}
|
||||
}
|
||||
|
||||
+6
-2
@@ -172,9 +172,9 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@Nullable
|
||||
public final ExternalizationSession startExternalization() {
|
||||
return createSaveSession(getStorageData());
|
||||
return mySavingDisabled ? null : createSaveSession(getStorageData());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -195,6 +195,10 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
|
||||
mySavingDisabled = true;
|
||||
}
|
||||
|
||||
public void enableSaving() {
|
||||
mySavingDisabled = false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected final Element getElement(@NotNull StorageData data, boolean collapsePaths, @NotNull Map<String, Element> newLiveStates) {
|
||||
Element element = data.save(newLiveStates);
|
||||
|
||||
+63
-146
@@ -29,11 +29,8 @@ import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx;
|
||||
import com.intellij.openapi.application.impl.ApplicationImpl;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.components.impl.stores.ComponentStoreImpl;
|
||||
import com.intellij.openapi.components.impl.stores.*;
|
||||
import com.intellij.openapi.components.impl.stores.ComponentStoreImpl.ReloadComponentStoreStatus;
|
||||
import com.intellij.openapi.components.impl.stores.FileBasedStorage;
|
||||
import com.intellij.openapi.components.impl.stores.StateStorageManager;
|
||||
import com.intellij.openapi.components.impl.stores.StorageUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.progress.*;
|
||||
@@ -46,7 +43,11 @@ import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileEvent;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.ex.VirtualFileManagerAdapter;
|
||||
import com.intellij.openapi.vfs.impl.local.FileWatcher;
|
||||
import com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl;
|
||||
import com.intellij.openapi.wm.impl.welcomeScreen.WelcomeFrame;
|
||||
@@ -96,13 +97,23 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
|
||||
private final Set<Project> myTestProjects = new THashSet<Project>();
|
||||
|
||||
private final MultiMap<Project, ChangedFileEntry> myChangedProjectFiles = MultiMap.createSet();
|
||||
private final MultiMap<Project, Pair<VirtualFile, StateStorage>> myChangedProjectFiles = MultiMap.createSet();
|
||||
private final SingleAlarm myChangedFilesAlarm;
|
||||
private final List<Pair<VirtualFile, StateStorage>> myChangedApplicationFiles = new SmartList<Pair<VirtualFile, StateStorage>>();
|
||||
private final AtomicInteger myReloadBlockCount = new AtomicInteger(0);
|
||||
|
||||
private final ProgressManager myProgressManager;
|
||||
private volatile boolean myDefaultProjectWasDisposed = false;
|
||||
|
||||
private final Runnable restartApplicationOrReloadProjectTask = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isReloadUnblocked() && tryToReloadApplication()) {
|
||||
askToReloadProjectIfConfigFilesChangedExternally();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
private static List<ProjectManagerListener> getListeners(Project project) {
|
||||
List<ProjectManagerListener> array = project.getUserData(LISTENERS_IN_PROJECT_KEY);
|
||||
@@ -111,7 +122,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
}
|
||||
|
||||
/** @noinspection UnusedParameters*/
|
||||
public ProjectManagerImpl(VirtualFileManager virtualFileManager,
|
||||
public ProjectManagerImpl(@NotNull VirtualFileManager virtualFileManager,
|
||||
RecentProjectsManagerBase recentProjectsManager,
|
||||
ProgressManager progressManager) {
|
||||
myProgressManager = progressManager;
|
||||
@@ -171,48 +182,18 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
}
|
||||
);
|
||||
|
||||
registerExternalProjectFileListener(virtualFileManager);
|
||||
myChangedFilesAlarm = new SingleAlarm(new Runnable() {
|
||||
virtualFileManager.addVirtualFileManagerListener(new VirtualFileManagerAdapter() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("[RELOAD] Scheduling reload application & project, myReloadBlockCount = " + myReloadBlockCount.get());
|
||||
}
|
||||
if (myReloadBlockCount.get() == 0) {
|
||||
scheduleReloadApplicationAndProject();
|
||||
}
|
||||
public void beforeRefreshStart(boolean asynchronous) {
|
||||
blockReloadingProjectOnExternalChanges();
|
||||
}
|
||||
}, 444);
|
||||
}
|
||||
|
||||
static final class ChangedFileEntry {
|
||||
public VirtualFile file;
|
||||
public StateStorage storage;
|
||||
public long timestamp;
|
||||
public byte[] savedContent;
|
||||
|
||||
public ChangedFileEntry(@NotNull VirtualFile file, @NotNull StateStorage storage) throws IOException {
|
||||
this.file = file;
|
||||
this.storage = storage;
|
||||
timestamp = file.getTimeStamp();
|
||||
savedContent = file.contentsToByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
@Override
|
||||
public void afterRefreshFinish(boolean asynchronous) {
|
||||
unblockReloadingProjectOnExternalChanges();
|
||||
}
|
||||
if (o == null || !(o instanceof ChangedFileEntry)) {
|
||||
return false;
|
||||
}
|
||||
return file.equals(((ChangedFileEntry)o).file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return file.hashCode();
|
||||
}
|
||||
});
|
||||
myChangedFilesAlarm = new SingleAlarm(restartApplicationOrReloadProjectTask, 300);
|
||||
}
|
||||
|
||||
private void projectStorageFileChanged(@NotNull VirtualFileEvent event, @NotNull StateStorage storage, @Nullable Project project) {
|
||||
@@ -644,19 +625,6 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
WelcomeFrame.showIfNoProjectOpened();
|
||||
}
|
||||
|
||||
private void registerExternalProjectFileListener(@NotNull VirtualFileManager virtualFileManager) {
|
||||
virtualFileManager.addVirtualFileManagerListener(new VirtualFileManagerListener() {
|
||||
@Override
|
||||
public void beforeRefreshStart(boolean asynchronous) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterRefreshFinish(boolean asynchronous) {
|
||||
scheduleReloadApplicationAndProject();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void askToReloadProjectIfConfigFilesChangedExternally() {
|
||||
Set<Project> projects;
|
||||
synchronized (myChangedProjectFiles) {
|
||||
@@ -666,16 +634,15 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
projects = new THashSet<Project>(myChangedProjectFiles.keySet());
|
||||
}
|
||||
|
||||
List<Pair<Project, Collection<ChangedFileEntry>>> projectsToReload = new SmartList<Pair<Project, Collection<ChangedFileEntry>>>();
|
||||
List<Project> projectsToReload = new SmartList<Project>();
|
||||
for (Project project : projects) {
|
||||
Collection<ChangedFileEntry> changedFileEntries = shouldReloadProject(project);
|
||||
if (changedFileEntries != null) {
|
||||
projectsToReload.add(Pair.create(project, changedFileEntries));
|
||||
if (shouldReloadProject(project)) {
|
||||
projectsToReload.add(project);
|
||||
}
|
||||
}
|
||||
|
||||
for (Pair<Project, Collection<ChangedFileEntry>> projectToReload : projectsToReload) {
|
||||
reloadProjectImpl(projectToReload.first, projectToReload.second);
|
||||
for (Project project : projectsToReload) {
|
||||
doReloadProject(project);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -691,44 +658,43 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
myChangedApplicationFiles.clear();
|
||||
|
||||
ReloadComponentStoreStatus status = ComponentStoreImpl.reloadStore(causes, ((ApplicationImpl)ApplicationManager.getApplication()).getStateStore());
|
||||
if (status == ReloadComponentStoreStatus.RESTART_REQUIRED) {
|
||||
if (status == ReloadComponentStoreStatus.RESTART_AGREED) {
|
||||
ApplicationManagerEx.getApplicationEx().restart(true);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return status == ReloadComponentStoreStatus.SUCCESS;
|
||||
return status == ReloadComponentStoreStatus.SUCCESS || status == ReloadComponentStoreStatus.RESTART_CANCELLED;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Collection<ChangedFileEntry> shouldReloadProject(@NotNull Project project) {
|
||||
private boolean shouldReloadProject(@NotNull Project project) {
|
||||
if (project.isDisposed()) {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
Collection<Pair<VirtualFile, StateStorage>> causes = new SmartList<Pair<VirtualFile, StateStorage>>();
|
||||
Collection<ChangedFileEntry> changes;
|
||||
Collection<Pair<VirtualFile, StateStorage>> changes;
|
||||
synchronized (myChangedProjectFiles) {
|
||||
changes = myChangedProjectFiles.remove(project);
|
||||
if (!ContainerUtil.isEmpty(changes)) {
|
||||
for (ChangedFileEntry change : changes) {
|
||||
causes.add(Pair.create(change.file, change.storage));
|
||||
for (Pair<VirtualFile, StateStorage> change : changes) {
|
||||
causes.add(change);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (causes.isEmpty()) {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
ReloadComponentStoreStatus status = ComponentStoreImpl.reloadStore(causes, ((ProjectEx)project).getStateStore());
|
||||
return status == ReloadComponentStoreStatus.RESTART_REQUIRED ? changes : null;
|
||||
return status == ReloadComponentStoreStatus.RESTART_AGREED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFileSavedToBeReloaded(VirtualFile candidate) {
|
||||
for (ChangedFileEntry entry : myChangedProjectFiles.values()) {
|
||||
if (entry.file.equals(candidate)) {
|
||||
for (Pair<VirtualFile, StateStorage> entry : myChangedProjectFiles.values()) {
|
||||
if (entry.first.equals(candidate)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -742,36 +708,17 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
|
||||
@Override
|
||||
public void unblockReloadingProjectOnExternalChanges() {
|
||||
if (myReloadBlockCount.decrementAndGet() == 0) scheduleReloadApplicationAndProject();
|
||||
if (myReloadBlockCount.decrementAndGet() == 0 && myChangedFilesAlarm.isEmpty()) {
|
||||
ApplicationManager.getApplication().invokeLater(restartApplicationOrReloadProjectTask, ModalityState.NON_MODAL);
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleReloadApplicationAndProject() {
|
||||
// todo: commented due to "IDEA-61938 Libraries configuration is kept if switching branches"
|
||||
// because of save which may happen _before_ project reload ;(
|
||||
|
||||
//ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
// public void run() {
|
||||
//IdeEventQueue.getInstance().addIdleListener(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// IdeEventQueue.getInstance().removeIdleListener(this);
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("[RELOAD] myReloadBlockCount = " + myReloadBlockCount.get());
|
||||
}
|
||||
if (myReloadBlockCount.get() == 0) {
|
||||
if (tryToReloadApplication()) {
|
||||
askToReloadProjectIfConfigFilesChangedExternally();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, ModalityState.NON_MODAL);
|
||||
//}
|
||||
//}, 2000);
|
||||
//}
|
||||
//}, ModalityState.NON_MODAL);
|
||||
private boolean isReloadUnblocked() {
|
||||
int count = myReloadBlockCount.get();
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("[RELOAD] myReloadBlockCount = " + count);
|
||||
}
|
||||
return count == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -813,35 +760,27 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
myChangedApplicationFiles.add(Pair.create(cause, storage));
|
||||
}
|
||||
else if (cause.exists()) {
|
||||
try {
|
||||
myChangedProjectFiles.putValue(project, new ChangedFileEntry(cause, storage));
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
myChangedProjectFiles.putValue(project, Pair.create(cause, storage));
|
||||
}
|
||||
|
||||
myChangedFilesAlarm.cancelAndRequest();
|
||||
if (storage instanceof XmlElementStorage) {
|
||||
((XmlElementStorage)storage).disableSaving();
|
||||
}
|
||||
|
||||
if (isReloadUnblocked()) {
|
||||
myChangedFilesAlarm.cancelAndRequest();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadProject(@NotNull Project project) {
|
||||
myChangedProjectFiles.remove(project);
|
||||
reloadProjectImpl(project, Collections.<ChangedFileEntry>emptyList());
|
||||
doReloadProject(project);
|
||||
}
|
||||
|
||||
public void reloadProjectImpl(@NotNull Project p, @Nullable Collection<ChangedFileEntry> changedFileEntries) {
|
||||
final Collection<ChangedFileEntry> filesToRestore;
|
||||
if (changedFileEntries == null) {
|
||||
// our internal ReloadProjectAction
|
||||
filesToRestore = myChangedProjectFiles.remove(p);
|
||||
}
|
||||
else {
|
||||
filesToRestore = changedFileEntries;
|
||||
}
|
||||
|
||||
final Ref<Project> projectRef = Ref.create(p);
|
||||
ProjectReloadState.getInstance(p).onBeforeAutomaticProjectReload();
|
||||
private static void doReloadProject(@NotNull Project project) {
|
||||
final Ref<Project> projectRef = Ref.create(project);
|
||||
ProjectReloadState.getInstance(project).onBeforeAutomaticProjectReload();
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -860,28 +799,6 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ContainerUtil.isEmpty(filesToRestore)) {
|
||||
AccessToken token = WriteAction.start();
|
||||
try {
|
||||
for (ChangedFileEntry entry : filesToRestore) {
|
||||
if (!entry.file.isWritable()) {
|
||||
// IDEA was unable to save it as well. So no need to restore
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
entry.file.setBinaryContent(entry.savedContent, -1, entry.timestamp, ProjectManagerImpl.this);
|
||||
}
|
||||
catch (IOException e) {
|
||||
Messages.showWarningDialog(ProjectBundle.message("project.reload.write.failed", entry.file.getPresentableUrl()),
|
||||
ProjectBundle.message("project.reload.write.failed.title"));
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
}
|
||||
ProjectUtil.openProject(presentableUrl, null, true);
|
||||
}
|
||||
}, ModalityState.NON_MODAL);
|
||||
|
||||
@@ -37,7 +37,7 @@ public interface StateStorage {
|
||||
|
||||
boolean hasState(@Nullable Object component, @NotNull String componentName, final Class<?> aClass, final boolean reloadData) throws StateStorageException;
|
||||
|
||||
@NotNull
|
||||
@Nullable
|
||||
ExternalizationSession startExternalization();
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user