Issue #1534 Check for null in initInternal to avoid exception
Change-Id: I9ccf341c3c04f08f88e5366009771f9cda510119 Former-commit-id:5ed30a723e
[formerly5ed30a723e
[formerly 77d0d92f23325407292c5a048ba1276e7e0568ad]] Former-commit-id:23e3ad2382
Former-commit-id:296186190a
This commit is contained in:
parent
2852e10076
commit
74aa120014
1 changed files with 53 additions and 152 deletions
|
@ -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) {
|
|
||||||
statusHandler
|
|
||||||
.handle(Priority.PROBLEM,
|
|
||||||
"Encountered error during Warnings Heartbeat, continuing with other Warnings ",
|
|
||||||
e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
for (WarningsResource rsc : rscs) {
|
||||||
// create an array with final modifier
|
rsc.issueRefresh();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addResource(AbstractVizResource<?, ?> rsc) {
|
public void addResource(WarningsResource rsc) {
|
||||||
// if task has no resources then it needs to be started when the
|
|
||||||
// first is added
|
|
||||||
boolean start = false;
|
|
||||||
synchronized (resourceSet) {
|
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 RefreshTimerTask refreshTask;
|
||||||
protected static final Object heartBeatChangeLock = new Object();
|
|
||||||
|
|
||||||
protected static RepaintHeartbeat heartBeatTask = null;
|
protected static Timer refreshTimer;
|
||||||
|
|
||||||
protected static Timer heartBeatTimer = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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) {
|
||||||
// get a calendar
|
refreshTimer = new Timer(true);
|
||||||
Calendar now = Calendar.getInstance();
|
refreshTask = new RefreshTimerTask();
|
||||||
// set calendar time to simulated time
|
|
||||||
now.setTime(currentTime);
|
// get a calendar
|
||||||
// add one to the minutes field
|
Calendar now = Calendar.getInstance();
|
||||||
now.add(Calendar.MINUTE, 1);
|
// add one to the minutes field
|
||||||
// reset second and milisecond to 0
|
now.add(Calendar.MINUTE, 1);
|
||||||
now.set(Calendar.SECOND, 0);
|
// reset second and milisecond to 0
|
||||||
now.set(Calendar.MILLISECOND, 0);
|
now.set(Calendar.SECOND, 0);
|
||||||
// schedule task to fire every minute
|
now.set(Calendar.MILLISECOND, 0);
|
||||||
synchronized (heartBeatChangeLock) {
|
|
||||||
try {
|
refreshTimer.scheduleAtFixedRate(refreshTask, now.getTime(),
|
||||||
if (heartBeatTimer == null) {
|
60 * 1000);
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue