diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/role/DataProviderEventController.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/role/DataProviderEventController.java index 0a7482a015..f6d09b762b 100644 --- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/role/DataProviderEventController.java +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/role/DataProviderEventController.java @@ -25,7 +25,6 @@ import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Event; -import org.hibernate.InstantiationException; import com.google.common.eventbus.Subscribe; import com.raytheon.uf.common.status.IUFStatusHandler; @@ -37,7 +36,9 @@ import com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueParticipantEv import com.raytheon.uf.viz.collaboration.comm.identity.event.ParticipantEventType; import com.raytheon.uf.viz.collaboration.comm.identity.user.SharedDisplayRole; import com.raytheon.uf.viz.collaboration.comm.provider.TransferRoleCommand; +import com.raytheon.uf.viz.collaboration.display.editor.ReprojectEditor; import com.raytheon.uf.viz.collaboration.display.editor.SharedEditorData; +import com.raytheon.uf.viz.collaboration.ui.Activator; import com.raytheon.uf.viz.collaboration.ui.ColorChangeEvent; import com.raytheon.uf.viz.collaboration.ui.SessionColorManager; import com.raytheon.uf.viz.collaboration.ui.data.SessionContainer; @@ -50,6 +51,7 @@ import com.raytheon.uf.viz.collaboration.ui.rsc.CollaborationWrapperResource; import com.raytheon.uf.viz.collaboration.ui.rsc.CollaborationWrapperResourceData; import com.raytheon.uf.viz.collaboration.ui.rsc.DataProviderRscData; import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.IRenderableDisplayChangedListener; import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; import com.raytheon.uf.viz.core.drawables.ResourcePair; @@ -66,6 +68,8 @@ import com.raytheon.viz.ui.EditorUtil; import com.raytheon.viz.ui.editor.AbstractEditor; /** + * TODO: This class is in severe need of a refactor! + * * Handles the events of a session that are specific to the Data Provider role. * * @@ -83,13 +87,31 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * @version 1.0 */ -public class DataProviderEventController extends AbstractRoleEventController { +public class DataProviderEventController extends AbstractRoleEventController + implements IRenderableDisplayChangedListener { private static final transient IUFStatusHandler statusHandler = UFStatus .getHandler(DataProviderEventController.class); private ResourceWrapperListener wrappingListener; + private DispatcherFactory factory = new DispatcherFactory() { + @Override + public Dispatcher createNewDispatcher(IRenderableDisplay display) + throws InstantiationException { + try { + CollaborationDispatcher dispatcher = new CollaborationDispatcher( + session, display); + dispatchers.add(dispatcher); + return dispatcher; + } catch (CollaborationException e) { + throw new InstantiationException( + "Error constructing collaboration dispatcher: " + + e.getLocalizedMessage()); + } + } + }; + private List dispatchers = new LinkedList(); public DataProviderEventController(ISharedDisplaySession session) { @@ -249,6 +271,35 @@ public class DataProviderEventController extends AbstractRoleEventController { // Replace pane resources that will be shared with // CollaborationWrapperResource objects for (IDisplayPane pane : editor.getDisplayPanes()) { + handleNewDisplay(pane); + setActiveDisplay(pane.getRenderableDisplay()); + } + + editor.addRenderableDisplayChangedListener(this); + } + } + + private void setActiveDisplay(IRenderableDisplay display) { + for (CollaborationDispatcher dispatcher : dispatchers) { + dispatcher.setActiveDisplay(display); + } + ReprojectEditor event = new ReprojectEditor(); + event.setTargetGeometry(display.getDescriptor().getGridGeometry()); + try { + session.sendObjectToVenue(event); + } catch (CollaborationException e) { + Activator.statusHandler.handle( + Priority.PROBLEM, + "Error sending reprojection event: " + + e.getLocalizedMessage(), e); + } + } + + private void handleNewDisplay(IDisplayPane pane) { + try { + if (DispatchingGraphicsFactory.injectRemoteFunctionality(pane, + factory)) { + // If we injected successfully, do resource management ResourceList list = pane.getDescriptor().getResourceList(); for (ResourcePair rp : pane.getDescriptor().getResourceList()) { wrapResourcePair(rp); @@ -256,26 +307,8 @@ public class DataProviderEventController extends AbstractRoleEventController { list.addPreAddListener(wrappingListener); list.addPostRemoveListener(wrappingListener); } - - // Inject remote graphics functionality in container - DispatchingGraphicsFactory.injectRemoteFunctionality(editor, - new DispatcherFactory() { - @Override - public Dispatcher createNewDispatcher( - IRenderableDisplay display) - throws InstantiationException { - try { - CollaborationDispatcher dispatcher = new CollaborationDispatcher( - session, display); - dispatchers.add(dispatcher); - return dispatcher; - } catch (CollaborationException e) { - throw new InstantiationException( - "Error creation collaboration dispatcher", - CollaborationDispatcher.class, e); - } - } - }); + } catch (InstantiationException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); } } @@ -383,10 +416,10 @@ public class DataProviderEventController extends AbstractRoleEventController { list.removePreAddListener(wrappingListener); list.removePostRemoveListener(wrappingListener); } - DispatchingGraphicsFactory.extractRemoteFunctionality(editor); } } + // Dispatchers created are responsible for display extraction for (CollaborationDispatcher dispatcher : dispatchers) { dispatcher.dispose(); } @@ -410,4 +443,22 @@ public class DataProviderEventController extends AbstractRoleEventController { } } } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.IRenderableDisplayChangedListener# + * renderableDisplayChanged(com.raytheon.uf.viz.core.IDisplayPane, + * com.raytheon.uf.viz.core.drawables.IRenderableDisplay, + * com.raytheon.uf.viz + * .core.IRenderableDisplayChangedListener.DisplayChangeType) + */ + @Override + public void renderableDisplayChanged(IDisplayPane pane, + IRenderableDisplay newRenderableDisplay, DisplayChangeType type) { + if (type == DisplayChangeType.ADD) { + handleNewDisplay(pane); + setActiveDisplay(newRenderableDisplay); + } + } } diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/role/ParticipantEventController.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/role/ParticipantEventController.java index 57ed3a8330..8bad4c73ed 100644 --- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/role/ParticipantEventController.java +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/role/ParticipantEventController.java @@ -33,7 +33,6 @@ import com.raytheon.uf.viz.collaboration.ui.data.SessionContainer; import com.raytheon.uf.viz.collaboration.ui.data.SharedDisplaySessionMgr; import com.raytheon.uf.viz.collaboration.ui.editor.EditorSetup; import com.raytheon.uf.viz.collaboration.ui.editor.SharedResource; -import com.raytheon.uf.viz.collaboration.ui.rsc.CollaborationResource; import com.raytheon.uf.viz.collaboration.ui.rsc.CollaborationResourceData; import com.raytheon.uf.viz.core.IDisplayPane; import com.raytheon.uf.viz.core.VizApp; @@ -65,8 +64,6 @@ public class ParticipantEventController extends AbstractRoleEventController { private static final transient IUFStatusHandler statusHandler = UFStatus .getHandler(ParticipantEventController.class); - private CollaborationResource collabRsc; - public ParticipantEventController(ISharedDisplaySession session) { super(session); } @@ -111,21 +108,25 @@ public class ParticipantEventController extends AbstractRoleEventController { CollaborationEditor editor = SharedDisplaySessionMgr .getSessionContainer(session.getSessionId()) .getCollaborationEditor(); - for (IDisplayPane pane : editor.getDisplayPanes()) { - IDescriptor desc = pane.getDescriptor(); - if (desc instanceof AbstractDescriptor) { - try { - ((AbstractDescriptor) desc).setGridGeometry(event - .getTargetGeometry()); - } catch (VizException e) { - statusHandler.handle(Priority.PROBLEM, - "Error reprojecting collaboration display: " - + e.getLocalizedMessage(), e); + if (editor != null) { + // Only reproject if editor has been created + for (IDisplayPane pane : editor.getDisplayPanes()) { + IDescriptor desc = pane.getDescriptor(); + if (desc instanceof AbstractDescriptor) { + try { + ((AbstractDescriptor) desc) + .setGridGeometry(event + .getTargetGeometry()); + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, + "Error reprojecting collaboration display: " + + e.getLocalizedMessage(), e); + } } + pane.setZoomLevel(1.0); + pane.scaleToClientArea(); + pane.refresh(); } - pane.setZoomLevel(1.0); - pane.scaleToClientArea(); - pane.refresh(); } } }); @@ -169,8 +170,6 @@ public class ParticipantEventController extends AbstractRoleEventController { ResourcePair rp = ResourcePair.constructSystemResourcePair(crd); desc.getResourceList().add(rp); desc.getResourceList().instantiateResources(desc, true); - collabRsc = (CollaborationResource) rp.getResource(); - this.session.registerEventHandler(collabRsc); } /* @@ -188,9 +187,6 @@ public class ParticipantEventController extends AbstractRoleEventController { if (container != null) { super.deactivateResources(container.getCollaborationEditor()); } - if (this.collabRsc != null) { - this.session.unRegisterEventHandler(collabRsc); - } } @Subscribe diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/role/dataprovider/CollaborationDispatcher.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/role/dataprovider/CollaborationDispatcher.java index 3b41b1f8ee..e7449e0911 100644 --- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/role/dataprovider/CollaborationDispatcher.java +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/role/dataprovider/CollaborationDispatcher.java @@ -44,6 +44,7 @@ import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; import com.raytheon.uf.viz.core.jobs.JobPool; import com.raytheon.uf.viz.core.rsc.IInputHandler; import com.raytheon.uf.viz.remote.graphics.Dispatcher; +import com.raytheon.uf.viz.remote.graphics.DispatchingGraphicsFactory; import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; import com.raytheon.uf.viz.remote.graphics.events.AbstractRemoteGraphicsEvent; import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent; @@ -126,6 +127,8 @@ public class CollaborationDispatcher extends Dispatcher { private IRenderableDisplay display; + private IRenderableDisplay activeDisplay; + public CollaborationDispatcher(ISharedDisplaySession session, IRenderableDisplay display) throws CollaborationException { this.session = session; @@ -139,6 +142,28 @@ public class CollaborationDispatcher extends Dispatcher { // display.getContainer().registerMouseHandler(mouseCapturer); } + /** + * Update the active display to render for + * + * @param display + */ + public void setActiveDisplay(IRenderableDisplay active) { + if (display != active) { + disposeFrames(); + } + this.activeDisplay = active; + display.refresh(); + } + + /** + * Returns the IRenderableDisplay this dispatcher is dispatching for + * + * @return + */ + public IRenderableDisplay getDisplay() { + return display; + } + @Subscribe public void handleNeedsRenderFrameEvent(RenderFrameNeededEvent event) { synchronized (previousFrames) { @@ -173,7 +198,10 @@ public class CollaborationDispatcher extends Dispatcher { @Override public void dispatch(AbstractRemoteGraphicsEvent eventObject) { if (eventObject instanceof IRenderFrameEvent) { - send(eventObject); + if (activeDisplay == display) { + // Only dispatch render frame events IF we are active + send(eventObject); + } return; } // Set PERSISTENCE to true if testing persisting capabilities @@ -291,10 +319,21 @@ public class CollaborationDispatcher extends Dispatcher { Activator.statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); } + disposeFrames(); + session.unRegisterEventHandler(this); + + // Extract the remote functionality + for (IDisplayPane pane : display.getContainer().getDisplayPanes()) { + if (pane.getRenderableDisplay() == display) { + DispatchingGraphicsFactory.extractRemoteFunctionality(pane); + } + } + } + + private void disposeFrames() { for (RenderFrame frame : previousFrames) { frame.dispose(); } previousFrames.clear(); - session.unRegisterEventHandler(this); } } diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/role/dataprovider/CollaborationObjectEventStorage.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/role/dataprovider/CollaborationObjectEventStorage.java index 5c51fef454..f941039ce3 100644 --- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/role/dataprovider/CollaborationObjectEventStorage.java +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/role/dataprovider/CollaborationObjectEventStorage.java @@ -308,7 +308,7 @@ public class CollaborationObjectEventStorage implements }; mkcol.setURI(folderPath); HttpClientResponse rsp = executeRequest(mkcol); - if (isSuccess(rsp.code) == false) { + if (isSuccess(rsp.code) == false && isDirExists(rsp.code) == false) { throw new CollaborationException("Folder creation failed for " + folderPath + ": " + new String(rsp.data)); } @@ -340,6 +340,10 @@ public class CollaborationObjectEventStorage implements return code == 404 || code == 410; } + private boolean isDirExists(int code) { + return code == 405 || code == 301; + } + @DynamicSerialize public static class CollaborationHttpPersistedObject { diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/rsc/CollaborationResource.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/rsc/CollaborationResource.java index f8ee2de965..757a029ef6 100644 --- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/rsc/CollaborationResource.java +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/rsc/CollaborationResource.java @@ -144,6 +144,7 @@ public class CollaborationResource extends @Override protected void disposeInternal() { + resourceData.getSession().unRegisterEventHandler(this); dataManager.dispose(); renderingRouter = null; } @@ -221,6 +222,7 @@ public class CollaborationResource extends ParticipantInitializedEvent event = new ParticipantInitializedEvent(); event.setUserId(session.getUserID().getFQName()); try { + session.registerEventHandler(this); session.sendObjectToPeer(session.getCurrentDataProvider(), event); } catch (CollaborationException e) { Activator.statusHandler.handle(Priority.PROBLEM, diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/telestrator/CollaborationDrawingResource.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/telestrator/CollaborationDrawingResource.java index b52cf53572..773737b79e 100644 --- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/telestrator/CollaborationDrawingResource.java +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/telestrator/CollaborationDrawingResource.java @@ -238,9 +238,11 @@ public class CollaborationDrawingResource extends */ @Override public void project(CoordinateReferenceSystem crs) throws VizException { - synchronized (layerMap) { - for (DrawingToolLayer layer : layerMap.values()) { - layer.reproject(descriptor.getGridGeometry()); + if (layerMap != null) { + synchronized (layerMap) { + for (DrawingToolLayer layer : layerMap.values()) { + layer.reproject(descriptor.getGridGeometry()); + } } } } diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/DispatchingGraphicsFactory.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/DispatchingGraphicsFactory.java index d69606ef8e..a53abadedc 100644 --- a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/DispatchingGraphicsFactory.java +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/DispatchingGraphicsFactory.java @@ -27,7 +27,6 @@ import org.opengis.coverage.grid.GridEnvelope; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.viz.core.AbstractGraphicsFactoryAdapter; import com.raytheon.uf.viz.core.IDisplayPane; -import com.raytheon.uf.viz.core.IDisplayPaneContainer; import com.raytheon.uf.viz.core.IExtent; import com.raytheon.uf.viz.core.IGraphicsTarget; import com.raytheon.uf.viz.core.IView; @@ -154,42 +153,53 @@ public class DispatchingGraphicsFactory extends AbstractGraphicsFactoryAdapter { return delegate.constrcutCanvas(canvasComp); } - public static void injectRemoteFunctionality( - IDisplayPaneContainer container, DispatcherFactory factory) { - try { - for (IDisplayPane pane : container.getDisplayPanes()) { - IRenderableDisplay display = pane.getRenderableDisplay(); - Dispatcher dispatcher = factory.createNewDispatcher(display); - // Wrap the graphics adapter in dispatching one - display.setGraphicsAdapter(new DispatchingGraphicsFactory( - display.getGraphicsAdapter(), dispatcher)); - refreshPane(pane); - } - } catch (InstantiationException e) { - extractRemoteFunctionality(container); - throw new RuntimeException(e); + /** + * Injects the DispatchingGraphicsFactory into the given display + * + * @param display + * @param factory + * @throws InstantiationException + */ + public static boolean injectRemoteFunctionality(IDisplayPane pane, + DispatcherFactory factory) throws InstantiationException { + boolean injected = false; + IRenderableDisplay display = pane.getRenderableDisplay(); + AbstractGraphicsFactoryAdapter currAdapter = display + .getGraphicsAdapter(); + if (currAdapter instanceof DispatchingGraphicsFactory == false) { + // Wrap the graphics adapter in dispatching one + display.setGraphicsAdapter(new DispatchingGraphicsFactory( + currAdapter, factory.createNewDispatcher(display))); + refreshPane(pane); + injected = true; } + return injected; } /** - * Removes remote graphics functionality from a display pane container + * Extracts the DispatchingGraphicsFactory from the given renderable display * - * @param container + * @param display */ - public static void extractRemoteFunctionality( - IDisplayPaneContainer container) { - for (IDisplayPane pane : container.getDisplayPanes()) { - IRenderableDisplay display = pane.getRenderableDisplay(); - AbstractGraphicsFactoryAdapter adapter = display - .getGraphicsAdapter(); - if (adapter instanceof DispatchingGraphicsFactory) { - AbstractGraphicsFactoryAdapter wrapped = ((DispatchingGraphicsFactory) adapter).delegate; - display.setGraphicsAdapter(wrapped); - refreshPane(pane); - } + public static boolean extractRemoteFunctionality(IDisplayPane pane) { + boolean extracted = false; + IRenderableDisplay display = pane.getRenderableDisplay(); + AbstractGraphicsFactoryAdapter adapter = display.getGraphicsAdapter(); + if (adapter instanceof DispatchingGraphicsFactory) { + AbstractGraphicsFactoryAdapter wrapped = ((DispatchingGraphicsFactory) adapter).delegate; + display.setGraphicsAdapter(wrapped); + refreshPane(pane); + extracted = true; } + return extracted; } + /** + * Refresh the IDisplayPane and recycle the resources on the pane. Should be + * executed after graphics injection + * + * @param pane + */ private static void refreshPane(IDisplayPane pane) { IRenderableDisplay display = pane.getRenderableDisplay(); IDescriptor descriptor = display.getDescriptor();