From 74aa120014cf91db4b5d1425b185e5d4c2c2b936 Mon Sep 17 00:00:00 2001 From: Max Schenkelberg Date: Wed, 30 Jan 2013 11:01:07 -0600 Subject: [PATCH] Issue #1534 Check for null in initInternal to avoid exception Change-Id: I9ccf341c3c04f08f88e5366009771f9cda510119 Former-commit-id: 5ed30a723e490f086a41b847b9b49d00c2c69764 [formerly 5ed30a723e490f086a41b847b9b49d00c2c69764 [formerly 77d0d92f23325407292c5a048ba1276e7e0568ad]] Former-commit-id: 23e3ad23826dbe66e8be59a6d4999428901723eb Former-commit-id: 296186190af36698c45667d644da476fa4edbec9 --- .../viz/warnings/rsc/WarningsResource.java | 205 +++++------------- 1 file changed, 53 insertions(+), 152 deletions(-) diff --git a/cave/com.raytheon.viz.warnings/src/com/raytheon/viz/warnings/rsc/WarningsResource.java b/cave/com.raytheon.viz.warnings/src/com/raytheon/viz/warnings/rsc/WarningsResource.java index bc02f41e81..d4257aede8 100644 --- a/cave/com.raytheon.viz.warnings/src/com/raytheon/viz/warnings/rsc/WarningsResource.java +++ b/cave/com.raytheon.viz.warnings/src/com/raytheon/viz/warnings/rsc/WarningsResource.java @@ -22,8 +22,8 @@ package com.raytheon.viz.warnings.rsc; import java.util.ArrayList; import java.util.Calendar; -import java.util.Date; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.Timer; import java.util.TimerTask; @@ -33,14 +33,10 @@ import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord; import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.time.DataTime; -import com.raytheon.uf.common.time.SimulatedTime; import com.raytheon.uf.viz.core.IGraphicsTarget; -import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.drawables.IDescriptor.FramesInfo; -import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; import com.raytheon.uf.viz.core.drawables.IWireframeShape; import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.rsc.AbstractVizResource; import com.raytheon.uf.viz.core.rsc.LoadProperties; import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; import com.raytheon.viz.core.rsc.jts.JTSCompiler; @@ -70,132 +66,38 @@ import com.vividsolutions.jts.geom.Geometry; public class WarningsResource extends AbstractWWAResource { - protected static class RepaintHeartbeat extends TimerTask { + protected static class RefreshTimerTask extends TimerTask { - private final HashSet> resourceSet = new HashSet>(); - - private boolean cancelled = false; - - public RepaintHeartbeat() { - - } - - /** - * copy resources from old task, just in case some were added after it - * should have been replaced (threads are fun) - **/ - public void copyResourceSet(RepaintHeartbeat oldTask) { - // copy resources, in case one was added after a cancel - Set> oldResourceSet = oldTask - .getResourceSet(); - synchronized (oldResourceSet) { - for (AbstractVizResource rsc : oldResourceSet) { - this.addResource(rsc); - } - } - } - - public Set> getResourceSet() { - return resourceSet; - } + private final Set resourceSet = new HashSet(); @Override public void run() { - // get the unique displays from all the added resources - ArrayList displaysToRefresh = new ArrayList( - 1); + List rscs; synchronized (resourceSet) { - for (AbstractVizResource rsc : resourceSet) { - try { - IRenderableDisplay disp = rsc.getDescriptor() - .getRenderableDisplay(); - if (!displaysToRefresh.contains(disp)) { - displaysToRefresh.add(disp); - } - } catch (Exception e) { - statusHandler - .handle(Priority.PROBLEM, - "Encountered error during Warnings Heartbeat, continuing with other Warnings ", - e); - } - } + rscs = new ArrayList(resourceSet); } - - // create an array with final modifier - final IRenderableDisplay[] refreshList = displaysToRefresh - .toArray(new IRenderableDisplay[displaysToRefresh.size()]); - - // execute refersh in UI thread - VizApp.runAsync(new Runnable() { - - @Override - public void run() { - for (IRenderableDisplay disp : refreshList) { - disp.refresh(); - } - } - - }); - - // cancel the task if there are no more resources - boolean cancel = false; - synchronized (resourceSet) { - if (resourceSet.size() < 1) { - cancel = true; - } - } - - if (cancel) { - doCancel(); + for (WarningsResource rsc : rscs) { + rsc.issueRefresh(); } } - public void addResource(AbstractVizResource rsc) { - // if task has no resources then it needs to be started when the - // first is added - boolean start = false; + public void addResource(WarningsResource rsc) { synchronized (resourceSet) { - // if this is the first resource added to an empty set start the - // timer - if (resourceSet.size() < 1) { - start = true; - } resourceSet.add(rsc); } - if (start) { - WarningsResource.scheduleHeartBeat(); - } } - public void removeResource(AbstractVizResource rsc) { + public void removeResource(WarningsResource rsc) { synchronized (resourceSet) { resourceSet.remove(rsc); - // cancel the task if there are no more resources - if (resourceSet.size() < 1) { - doCancel(); - } } } - private void doCancel() { - synchronized (heartBeatChangeLock) { - if (cancelled == false) { - cancelled = true; - heartBeatTimer.cancel(); - heartBeatTask = new RepaintHeartbeat(); - heartBeatTimer = new Timer(); - heartBeatTask.copyResourceSet(this); - } - } - } } - /** lock when changing heartBeatTask **/ - protected static final Object heartBeatChangeLock = new Object(); + protected static RefreshTimerTask refreshTask; - protected static RepaintHeartbeat heartBeatTask = null; - - protected static Timer heartBeatTimer = null; + protected static Timer refreshTimer; /** * Constructor @@ -207,14 +109,13 @@ public class WarningsResource extends AbstractWWAResource { @Override protected void initInternal(IGraphicsTarget target) throws VizException { - DataTime earliest = this.descriptor.getFramesInfo().getFrameTimes()[0]; - requestData(earliest); - synchronized (heartBeatChangeLock) { - if (heartBeatTask == null) { - heartBeatTask = new RepaintHeartbeat(); - } - heartBeatTask.addResource(this); + FramesInfo info = descriptor.getFramesInfo(); + DataTime[] times = info.getFrameTimes(); + if (times != null && times.length > 0) { + // Request data for "earliest" time + requestData(times[0]); } + scheduleRefreshTask(this); } /* @@ -224,9 +125,7 @@ public class WarningsResource extends AbstractWWAResource { */ @Override protected void disposeInternal() { - synchronized (heartBeatChangeLock) { - heartBeatTask.removeResource(this); - } + cancelRefreshTask(this); for (WarningEntry entry : entryMap.values()) { if (entry.shadedShape != null) { entry.shadedShape.dispose(); @@ -404,43 +303,45 @@ public class WarningsResource extends AbstractWWAResource { } + /** + * Cancel the heart beat timer task + * + * @param resource + */ + protected static void cancelRefreshTask(WarningsResource resource) { + synchronized (RefreshTimerTask.class) { + if (refreshTask != null) { + refreshTask.removeResource(resource); + if (refreshTask.resourceSet.isEmpty()) { + refreshTimer.cancel(); + refreshTimer = null; + refreshTask = null; + } + } + } + } + /** * schedule the heart beat for the next minute */ - protected static void scheduleHeartBeat() { - // get simulated time - Date currentTime = SimulatedTime.getSystemTime().getTime(); - // get a calendar - Calendar now = Calendar.getInstance(); - // set calendar time to simulated time - now.setTime(currentTime); - // add one to the minutes field - now.add(Calendar.MINUTE, 1); - // reset second and milisecond to 0 - now.set(Calendar.SECOND, 0); - now.set(Calendar.MILLISECOND, 0); - // schedule task to fire every minute - synchronized (heartBeatChangeLock) { - try { - if (heartBeatTimer == null) { - heartBeatTimer = new Timer(); - } - // schedule on the minute every minute - heartBeatTimer.schedule(heartBeatTask, now.getTime(), - 1 * 60 * 1000); - } catch (Exception e) { - try { - heartBeatTimer.cancel(); - } catch (Exception e2) { - // ignore, we just want to make sure the timer is cancelled - } finally { - // create a new task if there was an error when scheduling - heartBeatTask = new RepaintHeartbeat(); - heartBeatTimer = new Timer(); - } - statusHandler.handle(Priority.SIGNIFICANT, - "Error scheduling warnings heart beat ", e); + protected static void scheduleRefreshTask(WarningsResource resource) { + synchronized (RefreshTimerTask.class) { + if (refreshTask == null) { + refreshTimer = new Timer(true); + refreshTask = new RefreshTimerTask(); + + // get a calendar + Calendar now = Calendar.getInstance(); + // add one to the minutes field + now.add(Calendar.MINUTE, 1); + // reset second and milisecond to 0 + now.set(Calendar.SECOND, 0); + now.set(Calendar.MILLISECOND, 0); + + refreshTimer.scheduleAtFixedRate(refreshTask, now.getTime(), + 60 * 1000); } + refreshTask.addResource(resource); } }