Issue #1534 Check for null in initInternal to avoid exception

Change-Id: I9ccf341c3c04f08f88e5366009771f9cda510119

Former-commit-id: a574e13562 [formerly 5ed30a723e] [formerly 23e3ad2382 [formerly 77d0d92f23325407292c5a048ba1276e7e0568ad]]
Former-commit-id: 23e3ad2382
Former-commit-id: 296186190a
This commit is contained in:
Max Schenkelberg 2013-01-30 11:01:07 -06:00
parent 88d5c2f793
commit 50deaaaa79

View file

@ -22,8 +22,8 @@ package com.raytheon.viz.warnings.rsc;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; 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.dataplugin.warning.WarningRecord.WarningAction;
import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.time.DataTime; 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.IGraphicsTarget;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.drawables.IDescriptor.FramesInfo; 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.drawables.IWireframeShape;
import com.raytheon.uf.viz.core.exception.VizException; 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.LoadProperties;
import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability;
import com.raytheon.viz.core.rsc.jts.JTSCompiler; import com.raytheon.viz.core.rsc.jts.JTSCompiler;
@ -70,132 +66,38 @@ import com.vividsolutions.jts.geom.Geometry;
public class WarningsResource extends AbstractWWAResource { public class WarningsResource extends AbstractWWAResource {
protected static class RepaintHeartbeat extends TimerTask { protected static class RefreshTimerTask extends TimerTask {
private final HashSet<AbstractVizResource<?, ?>> resourceSet = new HashSet<AbstractVizResource<?, ?>>(); private final Set<WarningsResource> resourceSet = new HashSet<WarningsResource>();
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<AbstractVizResource<?, ?>> oldResourceSet = oldTask
.getResourceSet();
synchronized (oldResourceSet) {
for (AbstractVizResource<?, ?> rsc : oldResourceSet) {
this.addResource(rsc);
}
}
}
public Set<AbstractVizResource<?, ?>> getResourceSet() {
return resourceSet;
}
@Override @Override
public void run() { public void run() {
// get the unique displays from all the added resources List<WarningsResource> rscs;
ArrayList<IRenderableDisplay> displaysToRefresh = new ArrayList<IRenderableDisplay>(
1);
synchronized (resourceSet) { synchronized (resourceSet) {
for (AbstractVizResource<?, ?> rsc : resourceSet) { rscs = new ArrayList<WarningsResource>(resourceSet);
try {
IRenderableDisplay disp = rsc.getDescriptor()
.getRenderableDisplay();
if (!displaysToRefresh.contains(disp)) {
displaysToRefresh.add(disp);
} }
} catch (Exception e) { for (WarningsResource rsc : rscs) {
statusHandler rsc.issueRefresh();
.handle(Priority.PROBLEM,
"Encountered error during Warnings Heartbeat, continuing with other Warnings ",
e);
}
}
}
// 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();
} }
} }
}); public void addResource(WarningsResource rsc) {
// cancel the task if there are no more resources
boolean cancel = false;
synchronized (resourceSet) { synchronized (resourceSet) {
if (resourceSet.size() < 1) {
cancel = true;
}
}
if (cancel) {
doCancel();
}
}
public void addResource(AbstractVizResource<?, ?> rsc) {
// if task has no resources then it needs to be started when the
// first is added
boolean start = false;
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); resourceSet.add(rsc);
} }
if (start) {
WarningsResource.scheduleHeartBeat();
}
} }
public void removeResource(AbstractVizResource<?, ?> rsc) { public void removeResource(WarningsResource rsc) {
synchronized (resourceSet) { synchronized (resourceSet) {
resourceSet.remove(rsc); 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 RepaintHeartbeat heartBeatTask = null; protected static RefreshTimerTask refreshTask;
protected static Timer heartBeatTimer = null; protected static Timer refreshTimer;
/** /**
* Constructor * Constructor
@ -207,14 +109,13 @@ public class WarningsResource extends AbstractWWAResource {
@Override @Override
protected void initInternal(IGraphicsTarget target) throws VizException { protected void initInternal(IGraphicsTarget target) throws VizException {
DataTime earliest = this.descriptor.getFramesInfo().getFrameTimes()[0]; FramesInfo info = descriptor.getFramesInfo();
requestData(earliest); DataTime[] times = info.getFrameTimes();
synchronized (heartBeatChangeLock) { if (times != null && times.length > 0) {
if (heartBeatTask == null) { // Request data for "earliest" time
heartBeatTask = new RepaintHeartbeat(); requestData(times[0]);
}
heartBeatTask.addResource(this);
} }
scheduleRefreshTask(this);
} }
/* /*
@ -224,9 +125,7 @@ public class WarningsResource extends AbstractWWAResource {
*/ */
@Override @Override
protected void disposeInternal() { protected void disposeInternal() {
synchronized (heartBeatChangeLock) { cancelRefreshTask(this);
heartBeatTask.removeResource(this);
}
for (WarningEntry entry : entryMap.values()) { for (WarningEntry entry : entryMap.values()) {
if (entry.shadedShape != null) { if (entry.shadedShape != null) {
entry.shadedShape.dispose(); 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 * schedule the heart beat for the next minute
*/ */
protected static void scheduleHeartBeat() { protected static void scheduleRefreshTask(WarningsResource resource) {
// get simulated time synchronized (RefreshTimerTask.class) {
Date currentTime = SimulatedTime.getSystemTime().getTime(); if (refreshTask == null) {
refreshTimer = new Timer(true);
refreshTask = new RefreshTimerTask();
// get a calendar // get a calendar
Calendar now = Calendar.getInstance(); Calendar now = Calendar.getInstance();
// set calendar time to simulated time
now.setTime(currentTime);
// add one to the minutes field // add one to the minutes field
now.add(Calendar.MINUTE, 1); now.add(Calendar.MINUTE, 1);
// reset second and milisecond to 0 // reset second and milisecond to 0
now.set(Calendar.SECOND, 0); now.set(Calendar.SECOND, 0);
now.set(Calendar.MILLISECOND, 0); now.set(Calendar.MILLISECOND, 0);
// schedule task to fire every minute
synchronized (heartBeatChangeLock) { refreshTimer.scheduleAtFixedRate(refreshTask, now.getTime(),
try { 60 * 1000);
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);
} }
refreshTask.addResource(resource);
} }
} }