From 808617296815f0cf15983750e50452860c7f863f Mon Sep 17 00:00:00 2001 From: Nate Jensen Date: Thu, 6 Mar 2014 17:06:30 -0600 Subject: [PATCH] Issue #2826 fix collaboration mosaic image disposed issue Change-Id: I0f54a95b710c6c4e092052be08771500fbb4f614 Former-commit-id: 95bc80c8d0cde46dc7315966d486e01df6164b84 [formerly d9af17287d77b85478fe6e002dbc9e628f649e98] [formerly 7fa8bf636fbee66f1cff20b3fdfc9359f7a7d880] [formerly 95bc80c8d0cde46dc7315966d486e01df6164b84 [formerly d9af17287d77b85478fe6e002dbc9e628f649e98] [formerly 7fa8bf636fbee66f1cff20b3fdfc9359f7a7d880] [formerly 7bfad8ce17c81d4164e6a76630c3665c2b872ab9 [formerly 7fa8bf636fbee66f1cff20b3fdfc9359f7a7d880 [formerly 50b3e6bb7fcee54f1199b78354d404f325b32773]]]] Former-commit-id: 7bfad8ce17c81d4164e6a76630c3665c2b872ab9 Former-commit-id: 488451e9aa431ac40c46eba8c04e9d9b91dfb5e1 [formerly cb816444126d3bc2f0b6ec7f707d1f26bd279eff] [formerly 41f274281fde4fea1d15e1e1d46e9ffa39d95f5d [formerly 04d7ef0e7a72c745ad2c4020e2a192197d83c55e]] Former-commit-id: 8fdf2bb6022e36b9b68b7b679abfa23d5a4fd59e [formerly 69bdf2bd6053b426f828e673d340f1e2e4b99c8a] Former-commit-id: 45ff104294405d029a4ba7382d8672309de4f919 --- .../display/rsc/CollaborationResource.java | 7 +-- .../rendering/ImagingRenderingHandler.java | 50 +++++++++++++++++-- .../rsc/rendering/ShapeRenderingHandler.java | 22 ++++++-- .../CollaborationObjectEventStorage.java | 15 +++--- .../events/AbstractRemoteGraphicsEvent.java | 8 ++- 5 files changed, 83 insertions(+), 19 deletions(-) diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/CollaborationResource.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/CollaborationResource.java index df925b1934..c0fa346c02 100644 --- a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/CollaborationResource.java +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/CollaborationResource.java @@ -70,7 +70,7 @@ import com.raytheon.viz.ui.cmenu.IContextMenuProvider; /** * A resource for displaying rendered data that is received from the Data - * Provider. + * Provider. Only participants (non-leaders) will have this resource. * *
  * 
@@ -78,7 +78,8 @@ import com.raytheon.viz.ui.cmenu.IContextMenuProvider;
  * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Apr 3, 2012            njensen     Initial creation
+ * Apr 03, 2012            njensen     Initial creation
+ * Mar 06, 2014 2826       njensen     Fix spelling mistake
  * 
  * 
* @@ -339,7 +340,7 @@ public class CollaborationResource extends } @Subscribe - public void persitableArrived(final IPersistedEvent event) { + public void persistableArrived(final IPersistedEvent event) { if (event.getDisplayId() != resourceData.getDisplayId()) { return; } diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/ImagingRenderingHandler.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/ImagingRenderingHandler.java index 33dcaf107f..b1a13722ea 100644 --- a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/ImagingRenderingHandler.java +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/ImagingRenderingHandler.java @@ -21,8 +21,13 @@ package com.raytheon.uf.viz.collaboration.display.rsc.rendering; import java.awt.image.RenderedImage; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; import java.util.List; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; import com.google.common.eventbus.Subscribe; import com.raytheon.uf.common.colormap.IColorMap; import com.raytheon.uf.common.colormap.image.ColorMapData; @@ -80,6 +85,7 @@ import com.raytheon.uf.viz.remote.graphics.extensions.DispatchingMosaicOrderedEx * ------------- -------- ----------- -------------------------- * Apr 16, 2012 mschenke Initial creation * Feb 21, 2014 2817 bsteffen Fix mesh cloning. + * Mar 06, 2014 2826 njensen Added mosaicMemberMap and relevant safety * * * @@ -91,6 +97,15 @@ public class ImagingRenderingHandler extends CollaborationRenderingHandler { private Object colorMapLock = new Object(); + /** + * Map contains the images that combine to make a mosaic. This is + * specifically tracked because there's a small window of opportunity where + * a member image is disposed but the mosaic is told to paint and is not yet + * aware of that member's disposal. + */ + private Multimap mosaicMemberMap = ArrayListMultimap + .create(); + @Subscribe public void renderImages(PaintImagesEvent event) { PaintProperties paintProps = getPaintProperties(); @@ -153,6 +168,31 @@ public class ImagingRenderingHandler extends CollaborationRenderingHandler { @Subscribe public void disposeImage(IImage image) { + synchronized (mosaicMemberMap) { + if (image instanceof IMosaicImage) { + // guava will kindly remove the key from the map when there are + // no members left + mosaicMemberMap.removeAll(image); + } else { + for (IMosaicImage mosaic : mosaicMemberMap.keySet()) { + boolean didRemove = false; + Collection collect = mosaicMemberMap + .get(mosaic); + Iterator itr = collect.iterator(); + while (itr.hasNext()) { + DrawableImage itrImage = itr.next(); + if (image.equals(itrImage.getImage())) { + itr.remove(); + didRemove = true; + } + } + if (didRemove) { + mosaic.setImagesToMosaic(collect + .toArray(new DrawableImage[0])); + } + } + } + } image.dispose(); } @@ -416,7 +456,6 @@ public class ImagingRenderingHandler extends CollaborationRenderingHandler { extensionClass = IMosaicOrderedImageExtension.class; } try { - dataManager.putRenderableObject( imageId, target.getExtension(extensionClass).initializeRaster( @@ -432,8 +471,13 @@ public class ImagingRenderingHandler extends CollaborationRenderingHandler { IMosaicImage image = dataManager.getRenderableObject( event.getObjectId(), IMosaicImage.class); if (image != null) { - image.setImagesToMosaic(ImagingRenderingHandler.toDrawableImages( - event.getImagesToMosaic(), dataManager)); + DrawableImage[] drawables = ImagingRenderingHandler + .toDrawableImages(event.getImagesToMosaic(), dataManager); + image.setImagesToMosaic(drawables); + + synchronized (mosaicMemberMap) { + mosaicMemberMap.replaceValues(image, Arrays.asList(drawables)); + } } } diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/ShapeRenderingHandler.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/ShapeRenderingHandler.java index 87ee128095..c79c96c269 100644 --- a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/ShapeRenderingHandler.java +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/ShapeRenderingHandler.java @@ -19,7 +19,9 @@ **/ package com.raytheon.uf.viz.collaboration.display.rsc.rendering; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import org.eclipse.swt.graphics.RGB; @@ -63,7 +65,8 @@ import com.vividsolutions.jts.geom.LineString; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Apr 16, 2012 mschenke Initial creation + * Apr 16, 2012 mschenke Initial creation + * Mar 05, 2014 2826 njensen Fixed null pointer in renderShadedShapes * * * @@ -238,13 +241,22 @@ public class ShapeRenderingHandler extends CollaborationRenderingHandler { DrawShadedShapeEvent[] shapeEvents = event.getObjects(); float alpha = event.getAlpha(); float brightness = event.getBrightness(); - IShadedShape[] shapes = new IShadedShape[shapeEvents.length]; - for (int i = 0; i < shapes.length; ++i) { - shapes[i] = dataManager.getRenderableObject( + List shapes = new ArrayList( + shapeEvents.length); + for (int i = 0; i < shapeEvents.length; ++i) { + IShadedShape shp = dataManager.getRenderableObject( shapeEvents[i].getObjectId(), IShadedShape.class); + /* + * small potential for the shape to be null if it was disposed and + * removed from the server before we got it + */ + if (shp != null) { + shapes.add(shp); + } } try { - getGraphicsTarget().drawShadedShapes(alpha, brightness, shapes); + getGraphicsTarget().drawShadedShapes(alpha, brightness, + shapes.toArray(new IShadedShape[0])); } catch (VizException e) { Activator.statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/storage/CollaborationObjectEventStorage.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/storage/CollaborationObjectEventStorage.java index e3535f1350..16ab2cb619 100644 --- a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/storage/CollaborationObjectEventStorage.java +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/storage/CollaborationObjectEventStorage.java @@ -78,6 +78,7 @@ import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent; * Feb 24, 2014 2751 bclement added separate paths for each provider under session id * Feb 25, 2014 2751 bclement fixed provider id path for webDAV * Feb 28, 2014 2756 bclement added auth, moved response code checks to response object + * Mar 06, 2014 2826 njensen Fix spelling mistake * * * @@ -125,7 +126,8 @@ public class CollaborationObjectEventStorage implements + e.getLocalizedMessage()); // unlikely that utf8 isn't supported, but just go again with the // default encoding - persistance.sessionDataURL += URLEncoder.encode(persistance.providerid); + persistance.sessionDataURL += URLEncoder + .encode(persistance.providerid); } } @@ -232,7 +234,8 @@ public class CollaborationObjectEventStorage implements * @return * @throws CollaborationException */ - private HttpPut createPut(String url, byte[] body) throws CollaborationException{ + private HttpPut createPut(String url, byte[] body) + throws CollaborationException { URI uri = URI.create(url); HttpPut put = new HttpPut(uri); authManager.signRequest(put, providerid, uri, body); @@ -277,7 +280,7 @@ public class CollaborationObjectEventStorage implements public AbstractDispatchingObjectEvent retrieveEvent(IPersistedEvent event) throws CollaborationException { if (event instanceof CollaborationHttpPersistedEvent) { - CollaborationHttpPersistedObject object = retreiveStoredObject((CollaborationHttpPersistedEvent) event); + CollaborationHttpPersistedObject object = retrieveStoredObject((CollaborationHttpPersistedEvent) event); if (object == null) { // No object available return null; @@ -304,7 +307,7 @@ public class CollaborationObjectEventStorage implements * @return null if object was deleted * @throws CollaborationException */ - private CollaborationHttpPersistedObject retreiveStoredObject( + private CollaborationHttpPersistedObject retrieveStoredObject( CollaborationHttpPersistedEvent event) throws CollaborationException { String objectPath = event.getResourcePath(); @@ -421,7 +424,7 @@ public class CollaborationObjectEventStorage implements text = reader.getText().trim(); if (inFileTag && text.endsWith(".obj")) { event.setResourcePath(objectPath + text); - CollaborationHttpPersistedObject eventObject = retreiveStoredObject(event); + CollaborationHttpPersistedObject eventObject = retrieveStoredObject(event); if (eventObject != null) { objectEvents.add(eventObject); } else { @@ -466,7 +469,7 @@ public class CollaborationObjectEventStorage implements String object = htmlStr.substring(foundAt, endsAt); if (object.endsWith(objectEnding)) { event.setResourcePath(objectPath + object); - CollaborationHttpPersistedObject eventObject = retreiveStoredObject(event); + CollaborationHttpPersistedObject eventObject = retrieveStoredObject(event); if (eventObject != null) { objectEvents.add(eventObject); } else { diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/AbstractRemoteGraphicsEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/AbstractRemoteGraphicsEvent.java index 8be02e9065..22b5b3ec0d 100644 --- a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/AbstractRemoteGraphicsEvent.java +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/AbstractRemoteGraphicsEvent.java @@ -23,7 +23,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; /** - * TODO Add Description + * An event for a remote graphic that is tied to a particular display. * *
  * 
@@ -31,7 +31,8 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
  * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Mar 8, 2012            mschenke     Initial creation
+ * Mar 08, 2012            mschenke    Initial creation
+ * Mar 06, 2014 2826       njensen     Improved javadoc
  * 
  * 
* @@ -41,6 +42,9 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @DynamicSerialize public abstract class AbstractRemoteGraphicsEvent { + /** + * the renderable display the object was created on + */ @DynamicSerializeElement private int displayId;