diff --git a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/dispatch/DispatchServiceManager.java b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/dispatch/DispatchServiceManager.java index f4e380cd75..26dacb4c09 100644 --- a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/dispatch/DispatchServiceManager.java +++ b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/dispatch/DispatchServiceManager.java @@ -6,6 +6,7 @@ import com.google.gwt.place.shared.Place; import com.google.gwt.place.shared.PlaceController; import com.google.gwt.user.client.Timer; +import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.rpc.InvocationException; import com.google.web.bindery.event.shared.EventBus; @@ -31,6 +32,7 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; +import java.util.logging.Level; import java.util.logging.Logger; import static com.google.common.base.Preconditions.checkNotNull; @@ -126,6 +128,7 @@ public , R extends Result> void execute(A action, final Disp callback.handleSubmittedForExecution(); if(action instanceof HasProjectId) { ProjectId projectId = ((HasProjectId) action).getProjectId(); + checkMakingACallForCurrentProject(projectId); ResultCache resultCache = getResultCache(projectId, eventBus); Optional result = resultCache.getCachedResult(action); if (result.isPresent()) { @@ -145,6 +148,24 @@ public , R extends Result> void execute(A action, final Disp // } } + private void checkMakingACallForCurrentProject(ProjectId projectId) { + Place place = placeController.getWhere(); + if(place instanceof HasProjectId) { + ProjectId placeProjectId = ((HasProjectId) place).getProjectId(); + if(!placeProjectId.equals(projectId)) { + logCurrentStack(); + } + } + } + + private static void logCurrentStack() { + try { + throw new RuntimeException("Mismatch"); + } catch (RuntimeException e) { + logger.log(Level.WARNING, "Mismatch of project Ids. If not deliberate this may indicated a bug somewhere.", e); + } + } + @SuppressWarnings("unchecked") private , R extends Result> void execAction(A action, DispatchServiceCallback callback) { requestCount++; diff --git a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/editor/ClassEditorPortletPresenter.java b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/editor/ClassEditorPortletPresenter.java index e0fd811f77..3ea8ad2274 100644 --- a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/editor/ClassEditorPortletPresenter.java +++ b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/editor/ClassEditorPortletPresenter.java @@ -49,4 +49,10 @@ public void startPortlet(PortletUi portletUi, WebProtegeEventBus eventBus) { protected void handleReloadRequest() { editorPresenter.handleReloadRequest(); } + + @Override + public void dispose() { + editorPresenter.dispose(); + super.dispose(); + } } diff --git a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/inject/ClientProjectComponent.java b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/inject/ClientProjectComponent.java index 8544565d9a..7633a5eb2d 100644 --- a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/inject/ClientProjectComponent.java +++ b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/inject/ClientProjectComponent.java @@ -10,8 +10,10 @@ import edu.stanford.bmir.protege.web.client.project.ProjectPresenter; import edu.stanford.bmir.protege.web.client.projectsettings.ProjectSettingsPresenter; import edu.stanford.bmir.protege.web.client.search.EntitySearchSettingsPresenter; +import edu.stanford.bmir.protege.web.client.selection.SelectionModel; import edu.stanford.bmir.protege.web.client.sharing.SharingSettingsPresenter; import edu.stanford.bmir.protege.web.client.tag.ProjectTagsPresenter; +import edu.stanford.bmir.protege.web.shared.HasDispose; import edu.stanford.bmir.protege.web.shared.inject.ProjectSingleton; import edu.stanford.bmir.protege.web.shared.project.ProjectId; @@ -28,7 +30,7 @@ } ) @ProjectSingleton -public interface ClientProjectComponent { +public interface ClientProjectComponent extends HasDispose { ProjectId getProjectId(); @@ -51,4 +53,11 @@ public interface ClientProjectComponent { EntitySearchSettingsPresenter getEntitySearchSettingsPresenter(); PerspectivesManagerPresenter getPerspectivesManagerPresenter(); + + SelectionModel getProjectSelectionModel(); + + default void dispose() { + getProjectPresenter().dispose(); + getProjectSelectionModel().dispose(); + } } diff --git a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/perspective/PerspectiveImpl.java b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/perspective/PerspectiveImpl.java index 110595ac51..3b28eb6569 100644 --- a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/perspective/PerspectiveImpl.java +++ b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/perspective/PerspectiveImpl.java @@ -141,6 +141,7 @@ public void onResize() { @Override public void dispose() { + widgetMapper.dispose(); } diff --git a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/perspective/PerspectivePresenter.java b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/perspective/PerspectivePresenter.java index 2d3b39522b..4490591e42 100644 --- a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/perspective/PerspectivePresenter.java +++ b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/perspective/PerspectivePresenter.java @@ -6,6 +6,7 @@ import com.google.gwt.user.client.ui.AcceptsOneWidget; import com.google.gwt.user.client.ui.Label; import com.google.web.bindery.event.shared.EventBus; +import com.google.web.bindery.event.shared.HandlerRegistration; import edu.stanford.bmir.protege.web.client.dispatch.DispatchServiceManager; import edu.stanford.bmir.protege.web.client.form.LanguageMapCurrentLocaleMapper; import edu.stanford.bmir.protege.web.client.library.msgbox.MessageBox; @@ -67,6 +68,9 @@ public class PerspectivePresenter implements HasDispose { private final LanguageMapCurrentLocaleMapper localeMapper; + private HandlerRegistration placeChangedHandlerRegistration; + + @Inject public PerspectivePresenter(final PerspectiveView perspectiveView, final LoggedInUserProvider loggedInUserProvider, @@ -91,8 +95,8 @@ public PerspectivePresenter(final PerspectiveView perspectiveView, public void start(AcceptsOneWidget container, EventBus eventBus, ProjectViewPlace place) { logger.fine("[PerspectivePresenter] Starting at place " + place); - eventBus.addHandler(PlaceChangeEvent.TYPE, event -> { - if(event.getNewPlace() instanceof ProjectViewPlace) { + placeChangedHandlerRegistration = eventBus.addHandler(PlaceChangeEvent.TYPE, event -> { + if (event.getNewPlace() instanceof ProjectViewPlace) { displayPerspective(((ProjectViewPlace) event.getNewPlace()).getPerspectiveId()); } }); @@ -218,6 +222,9 @@ private void savePerspectiveLayout(PerspectiveId perspectiveId, Optional n @Override public void dispose() { + if(placeChangedHandlerRegistration != null) { + placeChangedHandlerRegistration.removeHandler(); + } for(Perspective tab : perspectiveCache.values()) { tab.dispose(); } diff --git a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/perspective/PortletWidgetMapper.java b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/perspective/PortletWidgetMapper.java index 26e477d59e..3a67d44abc 100644 --- a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/perspective/PortletWidgetMapper.java +++ b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/perspective/PortletWidgetMapper.java @@ -4,6 +4,7 @@ import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Label; import edu.stanford.bmir.protege.web.client.portlet.*; +import edu.stanford.bmir.protege.web.shared.HasDispose; import edu.stanford.bmir.protege.web.shared.PortletId; import edu.stanford.bmir.protege.web.shared.event.WebProtegeEventBus; import edu.stanford.protege.widgetmap.client.HasFixedPrimaryAxisSize; @@ -13,14 +14,14 @@ import edu.stanford.protege.widgetmap.shared.node.NodeProperties; import edu.stanford.protege.widgetmap.shared.node.TerminalNode; import edu.stanford.protege.widgetmap.shared.node.TerminalNodeId; +import org.slf4j.LoggerFactory; import javax.annotation.Nonnull; import javax.inject.Inject; import javax.inject.Provider; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; +import java.util.*; import java.util.function.Consumer; +import java.util.logging.Logger; import static com.google.common.base.Preconditions.checkNotNull; @@ -29,7 +30,9 @@ * Stanford Center for Biomedical Informatics Research * 17/02/16 */ -public class PortletWidgetMapper implements WidgetMapper { +public class PortletWidgetMapper implements WidgetMapper, HasDispose { + + private final Logger logger = Logger.getLogger("PortletWidgetMapper"); private static final String DROP_ZONE = "drop-zone"; @@ -45,6 +48,8 @@ public class PortletWidgetMapper implements WidgetMapper { private Consumer nodePropertiesChangedHandler = node -> {}; + private List disposables = new ArrayList<>(); + @Inject public PortletWidgetMapper(@Nonnull PortletFactory portletFactory, Provider portletUiProvider, @@ -69,19 +74,19 @@ public void setNodePropertiesChangedHandler(Consumer nodePropertie @Override public IsWidget getWidget(TerminalNode terminalNode) { - GWT.log("[PortletWidgetMapper] Getting widget for TerminalNode: " + terminalNode); + logger.info("logger.infoGetting widget for TerminalNode: " + terminalNode); ViewHolder cachedViewHolder = nodeId2ViewHolderMap.get(terminalNode.getNodeId()); if (cachedViewHolder != null) { - GWT.log("[PortletWidgetMapper] Using cached view: " + terminalNode); + logger.info("logger.infoUsing cached view: " + terminalNode); return cachedViewHolder; } String portletClass = terminalNode.getNodeProperties().getPropertyValue("portlet", ""); - GWT.log("[PortletWidgetMapper] Instantiate portlet: " + portletClass); + logger.info("logger.infoInstantiate portlet: " + portletClass); ViewHolder viewHolder; if (!portletClass.isEmpty()) { Optional thePortlet = portletFactory.createPortlet(new PortletId(portletClass)); if (thePortlet.isPresent()) { - GWT.log("[PortletWidgetMapper] Created portlet from auto-generated factory"); + logger.info("logger.infoCreated portlet from auto-generated factory"); WebProtegePortletComponents portletComponents = thePortlet.get(); WebProtegePortletPresenter portletPresenter = portletComponents.getPresenter(); viewHolder = createViewHolder(terminalNode, @@ -115,8 +120,10 @@ private ViewHolder createViewHolder(@Nonnull TerminalNode node, nodePropertiesChangedHandler.accept(node); }); WebProtegeEventBus eventBus = eventBusProvider.get(); + disposables.add(eventBus); portletUi.setTitle(portlet.getPortletDescriptor().getTitle()); WebProtegePortletPresenter portletPresenter = portlet.getPresenter(); + disposables.add(portletPresenter); portletPresenter.start(portletUi, eventBus); ViewHolder viewHolder; if (portletPresenter instanceof HasFixedPrimaryAxisSize) { @@ -127,10 +134,17 @@ private ViewHolder createViewHolder(@Nonnull TerminalNode node, } viewHolder.addStyleName(DROP_ZONE); viewHolder.addCloseHandler(event -> { + disposables.remove(eventBus); eventBus.dispose(); + disposables.remove(portletPresenter); portletPresenter.dispose(); nodeId2ViewHolderMap.remove(node.getNodeId()); }); return viewHolder; } + + @Override + public void dispose() { + disposables.forEach(HasDispose::dispose); + } } diff --git a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/place/WebProtegeActivityMapper.java b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/place/WebProtegeActivityMapper.java index 9af091a426..a2501c0afe 100644 --- a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/place/WebProtegeActivityMapper.java +++ b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/place/WebProtegeActivityMapper.java @@ -22,6 +22,7 @@ import edu.stanford.bmir.protege.web.client.projectsettings.ProjectSettingsActivity; import edu.stanford.bmir.protege.web.client.search.EntitySearchSettingsActivity; import edu.stanford.bmir.protege.web.client.search.EntitySearchSettingsPresenter; +import edu.stanford.bmir.protege.web.client.selection.SelectionModel; import edu.stanford.bmir.protege.web.client.sharing.SharingSettingsActivity; import edu.stanford.bmir.protege.web.client.sharing.SharingSettingsPresenter; import edu.stanford.bmir.protege.web.client.signup.SignUpPresenter; @@ -44,6 +45,7 @@ * 12/02/16 */ public class WebProtegeActivityMapper implements ActivityMapper { + Logger logger = Logger.getLogger("WebProtegeActivityMapper"); private final ClientApplicationComponent applicationComponent; @@ -86,9 +88,9 @@ public WebProtegeActivityMapper(LoggedInUserProvider loggedInUserProvider, } public void start() { - GWT.log("[WebProtegeActivityMapper] Started activity mapper."); + logger.info("Started activity mapper."); eventBus.addHandler(UserLoggedOutEvent.ON_USER_LOGGED_OUT, event -> { - GWT.log("[WebProtegeActivityMapper] User logged out. Going to the Login Place."); + logger.info("User logged out. Going to the Login Place."); LoginPlace loginPlace; Place currentPlace = placeController.getWhere(); if (!(currentPlace instanceof LoginPlace)) { @@ -102,16 +104,18 @@ public void start() { } private ClientProjectComponent getClientProjectComponentForProjectAndLoggedInUser(@Nonnull ProjectId projectId) { + logger.info("Getting project component for " + projectId + ". The current project is " + currentClientProjectComponent); if(currentClientProjectComponent.isPresent()) { ClientProjectComponent projectComponent = currentClientProjectComponent.get(); if(isProjectComponentForProject(projectComponent, projectId) && isLastUserSameAsLoggedInUser()) { return projectComponent; } - projectComponent.getProjectPresenter().dispose(); + logger.info("Disposing of project component for " + projectComponent.getProjectId()); + projectComponent.dispose(); } ClientProjectComponent nextProjectComponent = instantiateClientProjectComponent(projectId); // Reset project component and user - GWT.log("[WebProtegeActivityMapper] Instantiating new project component"); + logger.info("Instantiating new project component"); lastUser = Optional.of(loggedInUserProvider.getCurrentUserId()); currentClientProjectComponent = Optional.of(nextProjectComponent); return nextProjectComponent; @@ -131,10 +135,10 @@ private ClientProjectComponent instantiateClientProjectComponent(@Nonnull Projec } public Activity getActivity(final Place place) { - GWT.log("[WebProtegeActivityMapper] Map place: " + place); + logger.info("Map place: " + place); if (shouldRedirectToLogin(place)) { - GWT.log("[WebProtegeActivityMapper] User is not logged in. Redirecting to login."); - logger.info("[WebProtegeActivityMapper] User is not logged in. Redirecting to login."); + logger.info("User is not logged in. Redirecting to login."); + logger.info("User is not logged in. Redirecting to login."); loginPresenter.setNextPlace(place); Scheduler.get().scheduleFinally(() -> placeController.goTo(new LoginPlace(place))); return new LoginActivity(loginPresenter); @@ -168,7 +172,7 @@ public Activity getActivity(final Place place) { } if (place instanceof LoginPlace) { if (!loggedInUserProvider.getCurrentUserId().isGuest()) { - logger.info("[WebProtegeActivityMapper] Schedule to project list after login."); + logger.info("Schedule to project list after login."); Scheduler.get().scheduleFinally(() -> placeController.goTo(new ProjectListPlace())); } @@ -193,7 +197,7 @@ public Activity getActivity(final Place place) { } if (place instanceof ProjectListPlace) { - logger.info("[WebProtegeActivityMapper] Route to project list activity"); + logger.info("Route to project list activity"); return new ProjectListActivity(projectManagerPresenter); } diff --git a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/portlet/AbstractWebProtegePortletPresenter.java b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/portlet/AbstractWebProtegePortletPresenter.java index 64c0e16f1c..aff05aa0cb 100644 --- a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/portlet/AbstractWebProtegePortletPresenter.java +++ b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/portlet/AbstractWebProtegePortletPresenter.java @@ -17,6 +17,7 @@ import edu.stanford.bmir.protege.web.shared.lang.DisplayNameSettingsChangedEvent; import edu.stanford.bmir.protege.web.shared.place.ProjectViewPlace; import edu.stanford.bmir.protege.web.shared.project.ProjectId; +import edu.stanford.protege.widgetmap.client.view.HasViewTitle; import org.semanticweb.owlapi.model.OWLEntity; import javax.annotation.Nonnull; @@ -55,6 +56,8 @@ public abstract class AbstractWebProtegePortletPresenter implements WebProtegePo @Nullable private Place lastPlace = null; + private boolean disposed = false; + public AbstractWebProtegePortletPresenter(@Nonnull SelectionModel selectionModel, @Nonnull ProjectId projectId, @Nonnull DisplayNameRenderer displayNameRenderer, @@ -64,6 +67,7 @@ public AbstractWebProtegePortletPresenter(@Nonnull SelectionModel selectionModel this.projectId = checkNotNull(projectId); this.displayNameRenderer = displayNameRenderer; selectionModelHandlerRegistration = selectionModel.addSelectionChangedHandler(e -> { + logger.info("Handling selection changed in " + projectId + " (disposed=" + disposed + ") in " + portletUi.map(HasViewTitle::getViewTitle).orElse("(not set)")); if (trackSelection) { handleBeforeSetEntity(e.getPreviousSelection()); handleAfterSetEntity(e.getLastSelection()); @@ -209,6 +213,8 @@ public String toString() { @Override public void dispose() { + disposed = true; + logger.info("Disposing of portlet " + getClass().getSimpleName() + " in project " + projectId); selectionModelHandlerRegistration.removeHandler(); portletUi.ifPresent(HasDispose::dispose); } diff --git a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/project/ProjectPresenter.java b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/project/ProjectPresenter.java index 98d5e79414..3ec987b5f0 100644 --- a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/project/ProjectPresenter.java +++ b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/project/ProjectPresenter.java @@ -147,6 +147,7 @@ public void dispose() { linkBarPresenter.dispose(); perspectivePresenter.dispose(); eventPollingManager.stop(); + eventBus.dispose(); } @Override diff --git a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/selection/SelectionModel.java b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/selection/SelectionModel.java index 60ece4c463..273dc19b82 100644 --- a/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/selection/SelectionModel.java +++ b/webprotege-gwt-ui-client/src/main/java/edu/stanford/bmir/protege/web/client/selection/SelectionModel.java @@ -7,8 +7,10 @@ import com.google.web.bindery.event.shared.EventBus; import com.google.web.bindery.event.shared.HandlerRegistration; import edu.stanford.bmir.protege.web.client.dispatch.DispatchServiceManager; +import edu.stanford.bmir.protege.web.shared.HasDispose; import edu.stanford.bmir.protege.web.shared.inject.ProjectSingleton; import edu.stanford.bmir.protege.web.shared.place.*; +import edu.stanford.bmir.protege.web.shared.project.ProjectId; import org.semanticweb.owlapi.model.*; import javax.annotation.Nonnull; @@ -16,6 +18,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.logging.Logger; import static com.google.common.base.Preconditions.checkNotNull; @@ -25,7 +28,11 @@ * 15/05/15 */ @ProjectSingleton -public class SelectionModel { +public class SelectionModel implements HasDispose { + + private static final Logger logger = Logger.getLogger("SelectionModel"); + + private final ProjectId projectId; private final DispatchServiceManager dispatch; @@ -45,6 +52,8 @@ public class SelectionModel { private final PlaceController placeController; + private final HandlerRegistration placeChangeEventHandlerRegistration; + private ItemSelection selection = ItemSelection.empty(); private final Timer selectionTransmitDelayTimer = new Timer() { @@ -57,7 +66,7 @@ public void run() { private final List pendingSelection = new ArrayList<>(); @Inject - public SelectionModel(DispatchServiceManager dispatch, + public SelectionModel(ProjectId projectId, DispatchServiceManager dispatch, EventBus eventBus, PlaceController placeController, SelectedEntityManager selectedClassManager, @@ -66,6 +75,7 @@ public SelectionModel(DispatchServiceManager dispatch, SelectedEntityManager selectedAnnotationPropertyManager, SelectedEntityManager selectedDatatypeManager, SelectedEntityManager selectedIndividualManager) { + this.projectId = projectId; this.dispatch = dispatch; this.eventBus = eventBus; this.placeController = placeController; @@ -75,7 +85,7 @@ public SelectionModel(DispatchServiceManager dispatch, this.selectedAnnotationPropertyManager = checkNotNull(selectedAnnotationPropertyManager); this.selectedDatatypeManager = checkNotNull(selectedDatatypeManager); this.selectedIndividualManager = checkNotNull(selectedIndividualManager); - eventBus.addHandler(PlaceChangeEvent.TYPE, event -> { + this.placeChangeEventHandlerRegistration = eventBus.addHandler(PlaceChangeEvent.TYPE, event -> { Place newPlace = event.getNewPlace(); if(newPlace instanceof ProjectViewPlace) { ProjectViewPlace projectViewPlace = (ProjectViewPlace) newPlace; @@ -96,6 +106,13 @@ private void processPendingSelection() { } private void updateSelectionFromPlace(ProjectViewPlace place) { + logger.info("Responding to place changed. New place: " + place); + ProjectId placeProjectId = place.getProjectId(); + if(!projectId.equals(placeProjectId)) { + // Not my project + logger.info("The place belongs to project " + placeProjectId + " but this selection model is belongs to " + projectId + ". Ignoring new place and any change in selection."); + return; + } ItemSelection itemSelection = place.getItemSelection(); if(!itemSelection.equals(selection)) { Optional previousSelection = extractEntityFromItem(selection); @@ -203,6 +220,13 @@ private void setSelectionNow(OWLEntity entity) { if(!(place instanceof ProjectViewPlace)) { return; } + logger.info("Responding to request to set the selection now. New place: " + place); + ProjectId placeProjectId = ((ProjectViewPlace) place).getProjectId(); + if(!projectId.equals(placeProjectId)) { + // Not my project + logger.info("The place belongs to project " + placeProjectId + " but this selection model is belongs to " + projectId + ". Ignoring new place and any change in selection."); + return; + } Item item = entity .accept(new OWLEntityVisitorEx>() { @Nonnull @@ -259,7 +283,6 @@ public Item visit(@Nonnull OWLAnnotationProperty property) { placeController.goTo(nextPlace); } - private void fireEvent(Optional previousLastSelection) { // It's likely that several actions will be executed as a result of the selection // change. These can be nicely batched together so that only one HTTP call takes @@ -272,4 +295,10 @@ private void fireEvent(Optional previousLastSelection) { dispatch.executeCurrentBatch(); } } + + @Override + public void dispose() { + logger.info("Disposing of selection model for project " + projectId); + placeChangeEventHandlerRegistration.removeHandler(); + } } diff --git a/webprotege-gwt-ui-client/src/test/java/edu/stanford/bmir/protege/web/client/selection/SelectionModel_TestCase.java b/webprotege-gwt-ui-client/src/test/java/edu/stanford/bmir/protege/web/client/selection/SelectionModel_TestCase.java index 6b1f4e4584..30658af0fa 100644 --- a/webprotege-gwt-ui-client/src/test/java/edu/stanford/bmir/protege/web/client/selection/SelectionModel_TestCase.java +++ b/webprotege-gwt-ui-client/src/test/java/edu/stanford/bmir/protege/web/client/selection/SelectionModel_TestCase.java @@ -7,6 +7,7 @@ import edu.stanford.bmir.protege.web.client.dispatch.DispatchServiceManager; import edu.stanford.bmir.protege.web.shared.place.ItemSelection; import edu.stanford.bmir.protege.web.shared.place.ProjectViewPlace; +import edu.stanford.bmir.protege.web.shared.project.ProjectId; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -60,9 +61,12 @@ public class SelectionModel_TestCase { private OWLClass cls = new OWLClassImpl(IRI.create("urn:entity:cls")); + private ProjectId projectId = ProjectId.getNil(); + @Before public void setUp() { selectionModel = new SelectionModel( + projectId, dispatch, eventBus, placeController, selectedClassManager,