mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
ProjectManager — both lists are thread-safe (LockFreeCopyOnWriteArrayList), but ContainerUtil.concat cannot handle situation when list size is changed during iteration
This commit is contained in:
+30
-5
@@ -99,7 +99,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable {
|
||||
messageBus.connect().subscribe(ProjectManager.TOPIC, new ProjectManagerListener() {
|
||||
@Override
|
||||
public void projectOpened(@NotNull Project project) {
|
||||
for (ProjectManagerListener listener : ContainerUtil.concat(getListeners(project), myListeners)) {
|
||||
for (ProjectManagerListener listener : getAllListeners(project)) {
|
||||
try {
|
||||
listener.projectOpened(project);
|
||||
}
|
||||
@@ -111,7 +111,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable {
|
||||
|
||||
@Override
|
||||
public void projectClosed(Project project) {
|
||||
for (ProjectManagerListener listener : ContainerUtil.concat(getListeners(project), myListeners)) {
|
||||
for (ProjectManagerListener listener : getAllListeners(project)) {
|
||||
try {
|
||||
listener.projectClosed(project);
|
||||
}
|
||||
@@ -125,7 +125,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable {
|
||||
|
||||
@Override
|
||||
public void projectClosing(Project project) {
|
||||
for (ProjectManagerListener listener : ContainerUtil.concat(getListeners(project), myListeners)) {
|
||||
for (ProjectManagerListener listener : getAllListeners(project)) {
|
||||
try {
|
||||
listener.projectClosing(project);
|
||||
}
|
||||
@@ -137,7 +137,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable {
|
||||
|
||||
@Override
|
||||
public void projectClosingBeforeSave(@NotNull Project project) {
|
||||
for (ProjectManagerListener listener : ContainerUtil.concat(getListeners(project), myListeners)) {
|
||||
for (ProjectManagerListener listener : getAllListeners(project)) {
|
||||
try {
|
||||
listener.projectClosingBeforeSave(project);
|
||||
}
|
||||
@@ -697,6 +697,12 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable {
|
||||
LOG.assertTrue(removed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeProjectManagerListener(@NotNull VetoableProjectManagerListener listener) {
|
||||
boolean removed = myListeners.remove(listener);
|
||||
LOG.assertTrue(removed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProjectManagerListener(@NotNull Project project, @NotNull ProjectManagerListener listener) {
|
||||
List<ProjectManagerListener> listeners = project.getUserData(LISTENERS_IN_PROJECT_KEY);
|
||||
@@ -737,7 +743,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable {
|
||||
LOG.debug("enter: canClose()");
|
||||
}
|
||||
|
||||
for (ProjectManagerListener listener : ContainerUtil.concat(getListeners(project), myListeners)) {
|
||||
for (ProjectManagerListener listener : getAllListeners(project)) {
|
||||
try {
|
||||
//noinspection deprecation
|
||||
boolean canClose = listener instanceof VetoableProjectManagerListener ? ((VetoableProjectManagerListener)listener).canClose(project) : listener.canCloseProject(project);
|
||||
@@ -754,6 +760,25 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable {
|
||||
return true;
|
||||
}
|
||||
|
||||
// both lists are thread-safe (LockFreeCopyOnWriteArrayList), but ContainerUtil.concat cannot handle situation when list size is changed during iteration
|
||||
// so, we have to create list.
|
||||
@NotNull
|
||||
private List<ProjectManagerListener> getAllListeners(@NotNull Project project) {
|
||||
List<ProjectManagerListener> projectLevelListeners = getListeners(project);
|
||||
if (projectLevelListeners.isEmpty()) {
|
||||
return myListeners;
|
||||
}
|
||||
else if (myListeners.isEmpty()) {
|
||||
return projectLevelListeners;
|
||||
}
|
||||
|
||||
List<ProjectManagerListener> result = new ArrayList<>(projectLevelListeners.size() + myListeners.size());
|
||||
// order is critically important due to backward compatibility - project level listeners must be first
|
||||
result.addAll(projectLevelListeners);
|
||||
result.addAll(myListeners);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean ensureCouldCloseIfUnableToSave(@NotNull Project project) {
|
||||
UnableToSaveProjectNotification[] notifications =
|
||||
NotificationsManager.getNotificationsManager().getNotificationsOfType(UnableToSaveProjectNotification.class, project);
|
||||
|
||||
@@ -60,6 +60,8 @@ public abstract class ProjectManager {
|
||||
@Deprecated
|
||||
public abstract void removeProjectManagerListener(@NotNull ProjectManagerListener listener);
|
||||
|
||||
public abstract void removeProjectManagerListener(@NotNull VetoableProjectManagerListener listener);
|
||||
|
||||
/**
|
||||
* Adds listener to the specified project.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user