Issue #1442 Changes to update display when Simulated Time is changed. Corrections to pqact.conf.template.
Changes based on code review and added listener to GridManager and unit test. Change-Id: Ida593a7e3cc7d4fd9bd6f44a4455145114484650 Former-commit-id:1cd076671c
[formerly 7f70c2f65453db6bf3097ae8157511c38a36b136] Former-commit-id:1e492b81ff
This commit is contained in:
parent
e8d8dcc795
commit
f10521f861
13 changed files with 442 additions and 117 deletions
|
@ -45,6 +45,7 @@ import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Jul 3, 2007 chammack Initial Creation.
|
* Jul 3, 2007 chammack Initial Creation.
|
||||||
|
* Jan 14, 2013 1442 rferrel Added method searchTreeUsingContraints.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -279,7 +280,41 @@ public class DecisionTree<T> {
|
||||||
insertCriteria(searchCriteria, item, true);
|
insertCriteria(searchCriteria, item, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search the tree by calling RequestConstraint.evaluate with the map values
|
||||||
|
* for each level of the tree.
|
||||||
|
*
|
||||||
|
* @param searchCriteria
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public List<T> searchTree(Map<String, Object> searchCriteria) {
|
public List<T> searchTree(Map<String, Object> searchCriteria) {
|
||||||
|
return searchTree(searchCriteria, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search the tree to find entries that were put into the tree using the
|
||||||
|
* exact same criteria as searchCriteria.
|
||||||
|
*
|
||||||
|
* @param searchCriteria
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<T> searchTreeUsingContraints(
|
||||||
|
Map<String, RequestConstraint> searchCriteria) {
|
||||||
|
return searchTree(searchCriteria, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal search method
|
||||||
|
*
|
||||||
|
* @param searchCriteria
|
||||||
|
* @param evaluateConstraints
|
||||||
|
* true if the map values should be passed to
|
||||||
|
* RequestConstraint.evaluate, false if they chould be passed to
|
||||||
|
* RequestConstraint.equals
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private List<T> searchTree(Map<String, ?> searchCriteria,
|
||||||
|
boolean evaluateConstraints) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
List<T> lst = new ArrayList<T>();
|
List<T> lst = new ArrayList<T>();
|
||||||
if (head == null) {
|
if (head == null) {
|
||||||
|
@ -288,13 +323,13 @@ public class DecisionTree<T> {
|
||||||
|
|
||||||
Node curNode = head;
|
Node curNode = head;
|
||||||
|
|
||||||
searchTree(curNode, searchCriteria, lst, 0);
|
searchTree(curNode, searchCriteria, lst, 0, evaluateConstraints);
|
||||||
return lst;
|
return lst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void searchTree(Node curNode, Map<String, Object> searchCriteria,
|
private void searchTree(Node curNode, Map<String, ?> searchCriteria,
|
||||||
List<T> resultList, int lvl) {
|
List<T> resultList, int lvl, boolean evaluatedConstraint) {
|
||||||
|
|
||||||
if (curNode == null) {
|
if (curNode == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -312,12 +347,14 @@ public class DecisionTree<T> {
|
||||||
Object parsedValue = searchCriteria.get(curNode.decisionAttribute);
|
Object parsedValue = searchCriteria.get(curNode.decisionAttribute);
|
||||||
|
|
||||||
boolean foundSomething = false;
|
boolean foundSomething = false;
|
||||||
|
if (evaluatedConstraint) {
|
||||||
// Evaluate through the values: First search for an exact match
|
// Evaluate through the values: First search for an exact match
|
||||||
// of non-null values
|
// of non-null values
|
||||||
for (Node n : curNode.nodeChildren) {
|
for (Node n : curNode.nodeChildren) {
|
||||||
RequestConstraint c = n.decision;
|
RequestConstraint c = n.decision;
|
||||||
if (c == null
|
if (c == null
|
||||||
|| (c == RequestConstraint.WILDCARD || parsedValue == null || c
|
|| (c == RequestConstraint.WILDCARD
|
||||||
|
|| parsedValue == null || c
|
||||||
.evaluate(parsedValue))) {
|
.evaluate(parsedValue))) {
|
||||||
// for (int k = 0; k < lvl; k++) {
|
// for (int k = 0; k < lvl; k++) {
|
||||||
// System.out.print(" ");
|
// System.out.print(" ");
|
||||||
|
@ -325,7 +362,24 @@ public class DecisionTree<T> {
|
||||||
foundSomething = true;
|
foundSomething = true;
|
||||||
// System.out.println("visit: " + curNode.decisionAttribute
|
// System.out.println("visit: " + curNode.decisionAttribute
|
||||||
// + ":: " + c);
|
// + ":: " + c);
|
||||||
searchTree(n, searchCriteria, resultList, lvl + 1);
|
searchTree(n, searchCriteria, resultList, lvl + 1,
|
||||||
|
evaluatedConstraint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Evaluate using existing constraints.
|
||||||
|
for (Node n : curNode.nodeChildren) {
|
||||||
|
RequestConstraint c = n.decision;
|
||||||
|
if (parsedValue.equals(c)) {
|
||||||
|
// for (int k = 0; k < lvl; k++) {
|
||||||
|
// System.out.print(" ");
|
||||||
|
// }
|
||||||
|
foundSomething = true;
|
||||||
|
// System.out.println("visit: " + curNode.decisionAttribute
|
||||||
|
// + ":: " + c);
|
||||||
|
searchTree(n, searchCriteria, resultList, lvl + 1,
|
||||||
|
evaluatedConstraint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ import com.raytheon.uf.viz.core.rsc.URICatalog.IURIRefreshCallback;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Apr 12, 2007 chammack Initial Creation.
|
* Apr 12, 2007 chammack Initial Creation.
|
||||||
|
* Jan 14, 2013 1442 rferrel Added query method.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -70,6 +71,8 @@ public class URICatalog extends DecisionTree<List<IURIRefreshCallback>> {
|
||||||
|
|
||||||
protected Map<Map<String, RequestConstraint>, List<IURIRefreshCallback>> queuedRCMap = new HashMap<Map<String, RequestConstraint>, List<IURIRefreshCallback>>();
|
protected Map<Map<String, RequestConstraint>, List<IURIRefreshCallback>> queuedRCMap = new HashMap<Map<String, RequestConstraint>, List<IURIRefreshCallback>>();
|
||||||
|
|
||||||
|
private Map<Map<String, RequestConstraint>, List<IURIRefreshCallback>> queryRCMap = new HashMap<Map<String, RequestConstraint>, List<IURIRefreshCallback>>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Singleton accessor
|
* Singleton accessor
|
||||||
*
|
*
|
||||||
|
@ -193,14 +196,29 @@ public class URICatalog extends DecisionTree<List<IURIRefreshCallback>> {
|
||||||
do {
|
do {
|
||||||
workingTime = time;
|
workingTime = time;
|
||||||
Map<Map<String, RequestConstraint>, List<IURIRefreshCallback>> runRCList = null;
|
Map<Map<String, RequestConstraint>, List<IURIRefreshCallback>> runRCList = null;
|
||||||
|
Map<Map<String, RequestConstraint>, List<IURIRefreshCallback>> runQueryList = null;
|
||||||
synchronized (URICatalog.this) {
|
synchronized (URICatalog.this) {
|
||||||
|
if (queuedRCMap.size() > 0) {
|
||||||
runRCList = queuedRCMap;
|
runRCList = queuedRCMap;
|
||||||
queuedRCMap = new HashMap<Map<String, RequestConstraint>, List<IURIRefreshCallback>>();
|
queuedRCMap = new HashMap<Map<String, RequestConstraint>, List<IURIRefreshCallback>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (queryRCMap.size() > 0) {
|
||||||
|
runQueryList = queryRCMap;
|
||||||
|
queryRCMap = new HashMap<Map<String, RequestConstraint>, List<IURIRefreshCallback>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runRCList != null) {
|
||||||
catalogAndQueryDataURIsInternal(runRCList, monitor);
|
catalogAndQueryDataURIsInternal(runRCList, monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runQueryList != null) {
|
||||||
|
doQuery(runQueryList, monitor);
|
||||||
|
}
|
||||||
} while (!monitor.isCanceled() && workingTime != time
|
} while (!monitor.isCanceled() && workingTime != time
|
||||||
&& queuedRCMap.size() > 0);
|
&& (queuedRCMap.size() > 0 || queryRCMap.size() > 0));
|
||||||
return Status.OK_STATUS;
|
return Status.OK_STATUS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,40 +263,24 @@ public class URICatalog extends DecisionTree<List<IURIRefreshCallback>> {
|
||||||
try {
|
try {
|
||||||
for (Map.Entry<Map<String, RequestConstraint>, List<IURIRefreshCallback>> entry : rcMap
|
for (Map.Entry<Map<String, RequestConstraint>, List<IURIRefreshCallback>> entry : rcMap
|
||||||
.entrySet()) {
|
.entrySet()) {
|
||||||
|
Map<String, RequestConstraint> map = entry.getKey();
|
||||||
|
List<IURIRefreshCallback> runnable = entry.getValue();
|
||||||
if (monitor.isCanceled()) {
|
if (monitor.isCanceled()) {
|
||||||
// If we are cancelled add our runnables back into the queue
|
// If we are cancelled add our runnables back into the queue
|
||||||
// instead of requesting times
|
// instead of requesting times
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
List<IURIRefreshCallback> runnables = queuedRCMap
|
List<IURIRefreshCallback> runnables = queuedRCMap
|
||||||
.get(entry.getKey());
|
.get(map);
|
||||||
if (runnables == null) {
|
if (runnables == null) {
|
||||||
queuedRCMap.put(entry.getKey(), entry.getValue());
|
queuedRCMap.put(map, runnable);
|
||||||
} else {
|
} else {
|
||||||
runnables.addAll(entry.getValue());
|
runnables.addAll(runnable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Map<String, RequestConstraint> map = entry.getKey();
|
doCallbacks(map, runnable);
|
||||||
DataTime[] dt = DataCubeContainer.performTimeQuery(map, true);
|
|
||||||
DataTime newDataTime = null;
|
|
||||||
if (dt != null && dt.length > 0) {
|
|
||||||
newDataTime = dt[dt.length - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
List<IURIRefreshCallback> runnable = entry.getValue();
|
|
||||||
|
|
||||||
final DataTime dataTime = newDataTime;
|
|
||||||
if (runnable != null) {
|
|
||||||
|
|
||||||
Iterator<IURIRefreshCallback> iterator = runnable
|
|
||||||
.iterator();
|
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
final IURIRefreshCallback r = iterator.next();
|
|
||||||
r.updateTime(dataTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Map<String, RequestConstraint> updateMap : DataCubeContainer
|
for (Map<String, RequestConstraint> updateMap : DataCubeContainer
|
||||||
.getBaseUpdateConstraints(map)) {
|
.getBaseUpdateConstraints(map)) {
|
||||||
insert(updateMap, rcMap.get(map));
|
insert(updateMap, rcMap.get(map));
|
||||||
|
@ -297,6 +299,76 @@ public class URICatalog extends DecisionTree<List<IURIRefreshCallback>> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void doCallbacks(Map<String, RequestConstraint> map,
|
||||||
|
List<IURIRefreshCallback> runnable) throws VizException {
|
||||||
|
DataTime[] dt = DataCubeContainer.performTimeQuery(map, true);
|
||||||
|
DataTime newDataTime = null;
|
||||||
|
if (dt != null && dt.length > 0) {
|
||||||
|
newDataTime = dt[dt.length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
final DataTime dataTime = newDataTime;
|
||||||
|
if (runnable != null) {
|
||||||
|
|
||||||
|
Iterator<IURIRefreshCallback> iterator = runnable.iterator();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
final IURIRefreshCallback r = iterator.next();
|
||||||
|
r.updateTime(dataTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform query using the existing constraints in map.
|
||||||
|
*
|
||||||
|
* @param map
|
||||||
|
*/
|
||||||
|
public void query(Map<String, RequestConstraint> map) {
|
||||||
|
synchronized (this) {
|
||||||
|
List<List<IURIRefreshCallback>> runableList = searchTreeUsingContraints(map);
|
||||||
|
List<IURIRefreshCallback> runnables = queryRCMap.get(map);
|
||||||
|
if (runnables == null) {
|
||||||
|
runnables = new ArrayList<URICatalog.IURIRefreshCallback>();
|
||||||
|
queryRCMap.put(map, runnables);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (List<IURIRefreshCallback> runnable : runableList) {
|
||||||
|
runnables.addAll(runnable);
|
||||||
|
}
|
||||||
|
rebuildSchedulerJob.schedule();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doQuery(
|
||||||
|
Map<Map<String, RequestConstraint>, List<IURIRefreshCallback>> queryMap,
|
||||||
|
IProgressMonitor monitor) {
|
||||||
|
try {
|
||||||
|
for (Map.Entry<Map<String, RequestConstraint>, List<IURIRefreshCallback>> entry : queryMap
|
||||||
|
.entrySet()) {
|
||||||
|
Map<String, RequestConstraint> map = entry.getKey();
|
||||||
|
List<IURIRefreshCallback> runnable = entry.getValue();
|
||||||
|
if (monitor.isCanceled()) {
|
||||||
|
// If we are cancelled add our runnables back into the queue
|
||||||
|
// instead of requesting times
|
||||||
|
synchronized (this) {
|
||||||
|
List<IURIRefreshCallback> runnables = queryRCMap
|
||||||
|
.get(map);
|
||||||
|
if (runnables == null) {
|
||||||
|
queryRCMap.put(map, runnable);
|
||||||
|
} else {
|
||||||
|
runnables.addAll(runnable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
doCallbacks(map, runnable);
|
||||||
|
}
|
||||||
|
} catch (VizException e) {
|
||||||
|
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void insert(Map<String, RequestConstraint> map,
|
private void insert(Map<String, RequestConstraint> map,
|
||||||
List<IURIRefreshCallback> runnables) throws VizException {
|
List<IURIRefreshCallback> runnables) throws VizException {
|
||||||
insertCriteria(map, runnables, false);
|
insertCriteria(map, runnables, false);
|
||||||
|
@ -306,7 +378,5 @@ public class URICatalog extends DecisionTree<List<IURIRefreshCallback>> {
|
||||||
|
|
||||||
/** check and update most recent time */
|
/** check and update most recent time */
|
||||||
public abstract void updateTime(DataTime time);
|
public abstract void updateTime(DataTime time);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,8 @@ import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
import com.raytheon.uf.common.time.BinOffset;
|
import com.raytheon.uf.common.time.BinOffset;
|
||||||
import com.raytheon.uf.common.time.DataTime;
|
import com.raytheon.uf.common.time.DataTime;
|
||||||
|
import com.raytheon.uf.common.time.ISimulatedTimeChangeListener;
|
||||||
|
import com.raytheon.uf.common.time.SimulatedTime;
|
||||||
import com.raytheon.uf.viz.core.VariableSubstitutionUtil;
|
import com.raytheon.uf.viz.core.VariableSubstitutionUtil;
|
||||||
import com.raytheon.uf.viz.core.VizApp;
|
import com.raytheon.uf.viz.core.VizApp;
|
||||||
import com.raytheon.uf.viz.core.exception.VizException;
|
import com.raytheon.uf.viz.core.exception.VizException;
|
||||||
|
@ -84,6 +86,7 @@ import com.raytheon.viz.ui.editor.AbstractEditor;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Mar 12, 2009 chammack Initial creation
|
* Mar 12, 2009 chammack Initial creation
|
||||||
|
* Jan 14, 2013 1442 rferrel Add Simulated Time Change Listener.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -127,6 +130,12 @@ public class BundleContributionItem extends ContributionItem {
|
||||||
|
|
||||||
protected boolean performQuery = true;
|
protected boolean performQuery = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag to indicate simulated time has changed and item's values needs to
|
||||||
|
* be refreshed the next time it is displayed.
|
||||||
|
*/
|
||||||
|
private boolean timeChangeUpdate = false;
|
||||||
|
|
||||||
public BundleContributionItem(CommonBundleMenuContribution contribution,
|
public BundleContributionItem(CommonBundleMenuContribution contribution,
|
||||||
VariableSubstitution[] includeSubstitutions) throws VizException {
|
VariableSubstitution[] includeSubstitutions) throws VizException {
|
||||||
super(VariableSubstitutionUtil.processVariables(contribution.id,
|
super(VariableSubstitutionUtil.processVariables(contribution.id,
|
||||||
|
@ -165,6 +174,25 @@ public class BundleContributionItem extends ContributionItem {
|
||||||
this.substitutions);
|
this.substitutions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The bundle persists for the life of CAVE; no need to remove the
|
||||||
|
// listener.
|
||||||
|
ISimulatedTimeChangeListener stcl = new ISimulatedTimeChangeListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void timechanged() {
|
||||||
|
// Updating the value here will generate a flood of requests for
|
||||||
|
// all bundles.
|
||||||
|
//
|
||||||
|
// This will force the update of the item's value the next time
|
||||||
|
// it is displayed.
|
||||||
|
//
|
||||||
|
// Any open widget using the bundle will need to handle the
|
||||||
|
// update.
|
||||||
|
timeChangeUpdate = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
SimulatedTime.getSystemTime().addSimulatedTimeChangeListener(stcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -212,6 +240,22 @@ public class BundleContributionItem extends ContributionItem {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This allows a widget such as an open dialog to force the bundle to query
|
||||||
|
* for new values based on Simulated Time. Allows a widget to refresh its
|
||||||
|
* display after a user has modified Simulated Time.
|
||||||
|
*/
|
||||||
|
public void refreshText() {
|
||||||
|
lastUsedTime = null;
|
||||||
|
if (pdoMapList != null && pdoMapList.size() > 0) {
|
||||||
|
URICatalog cat = URICatalog.getInstance();
|
||||||
|
for (BundleDataItem d : pdoMapList) {
|
||||||
|
cat.query(d.metadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timeChangeUpdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
protected synchronized void updateMenuText() {
|
protected synchronized void updateMenuText() {
|
||||||
if (widget == null)
|
if (widget == null)
|
||||||
return;
|
return;
|
||||||
|
@ -325,6 +369,11 @@ public class BundleContributionItem extends ContributionItem {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected void onShow() {
|
protected void onShow() {
|
||||||
|
if (timeChangeUpdate) {
|
||||||
|
refreshText();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (performQuery) {
|
if (performQuery) {
|
||||||
if (!shownBefore) {
|
if (!shownBefore) {
|
||||||
shownBefore = true;
|
shownBefore = true;
|
||||||
|
@ -438,7 +487,6 @@ public class BundleContributionItem extends ContributionItem {
|
||||||
URICatalog.getInstance().catalogAndQueryDataURI(d.metadata,
|
URICatalog.getInstance().catalogAndQueryDataURI(d.metadata,
|
||||||
new BundleRefreshCallback(d.offset));
|
new BundleRefreshCallback(d.offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,10 @@ import org.eclipse.swt.widgets.Shell;
|
||||||
import org.eclipse.ui.PlatformUI;
|
import org.eclipse.ui.PlatformUI;
|
||||||
import org.eclipse.ui.services.IServiceLocator;
|
import org.eclipse.ui.services.IServiceLocator;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.time.ISimulatedTimeChangeListener;
|
||||||
|
import com.raytheon.uf.common.time.SimulatedTime;
|
||||||
import com.raytheon.uf.viz.core.ContextManager;
|
import com.raytheon.uf.viz.core.ContextManager;
|
||||||
|
import com.raytheon.uf.viz.ui.menus.widgets.BundleContributionItem;
|
||||||
import com.raytheon.viz.ui.VizWorkbenchManager;
|
import com.raytheon.viz.ui.VizWorkbenchManager;
|
||||||
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
||||||
|
|
||||||
|
@ -49,6 +52,7 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Sep 14, 2011 mnash Initial creation
|
* Sep 14, 2011 mnash Initial creation
|
||||||
|
* Jan 09, 2013 1442 rferrel Add Simulated Time Change Listener.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -64,6 +68,12 @@ public class TearOffMenuDialog extends CaveSWTDialog {
|
||||||
|
|
||||||
private Composite fullComp;
|
private Composite fullComp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener to force the dialog's items' display to be updated when user
|
||||||
|
* changes Simulated time.
|
||||||
|
*/
|
||||||
|
ISimulatedTimeChangeListener stcl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param parentShell
|
* @param parentShell
|
||||||
*/
|
*/
|
||||||
|
@ -170,14 +180,36 @@ public class TearOffMenuDialog extends CaveSWTDialog {
|
||||||
addListener(SWT.Close, deactivate);
|
addListener(SWT.Close, deactivate);
|
||||||
|
|
||||||
activate.handleEvent(new Event());
|
activate.handleEvent(new Event());
|
||||||
|
|
||||||
|
stcl = new ISimulatedTimeChangeListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void timechanged() {
|
||||||
|
updateItems();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
SimulatedTime.getSystemTime().addSimulatedTimeChangeListener(stcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void disposed() {
|
protected void disposed() {
|
||||||
|
SimulatedTime.getSystemTime().removeSimulatedTimeChangeListener(stcl);
|
||||||
for (Control control : fullComp.getChildren()) {
|
for (Control control : fullComp.getChildren()) {
|
||||||
control.dispose();
|
control.dispose();
|
||||||
}
|
}
|
||||||
super.disposed();
|
super.disposed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force update of item's display.
|
||||||
|
*/
|
||||||
|
private void updateItems() {
|
||||||
|
// items[0] is the tear off object and is not in the dialog's display.
|
||||||
|
for (int index = 1; index < items.length; ++index) {
|
||||||
|
MenuItem item = items[index];
|
||||||
|
if (item.getData() instanceof BundleContributionItem) {
|
||||||
|
((BundleContributionItem) item.getData()).refreshText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,8 @@ import com.raytheon.edex.msg.PracticeDataURINotificationMessage;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
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.SimulatedTime;
|
||||||
import com.raytheon.uf.viz.core.RecordFactory;
|
import com.raytheon.uf.viz.core.RecordFactory;
|
||||||
import com.raytheon.uf.viz.core.alerts.AlertMessage;
|
import com.raytheon.uf.viz.core.alerts.AlertMessage;
|
||||||
import com.raytheon.uf.viz.core.exception.NoPluginException;
|
import com.raytheon.uf.viz.core.exception.NoPluginException;
|
||||||
|
@ -65,6 +67,7 @@ import com.raytheon.viz.core.mode.CAVEMode;
|
||||||
* 02/28/08 966 chammack Refactored to support generalized listeners
|
* 02/28/08 966 chammack Refactored to support generalized listeners
|
||||||
* 05/08/08 1127 randerso Changed to implement INotificationObserver
|
* 05/08/08 1127 randerso Changed to implement INotificationObserver
|
||||||
* 10/06/08 1433 chammack Updated to use VizStatus
|
* 10/06/08 1433 chammack Updated to use VizStatus
|
||||||
|
* 01/14/2013 1442 rferrel Filter out simulated time "future" alerts.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
|
@ -233,6 +236,27 @@ public class ProductAlertObserver implements INotificationObserver {
|
||||||
// collection for future messages
|
// collection for future messages
|
||||||
Collection<AlertMessage> messagesToProc = messages;
|
Collection<AlertMessage> messagesToProc = messages;
|
||||||
messages = new ConcurrentLinkedQueue<AlertMessage>();
|
messages = new ConcurrentLinkedQueue<AlertMessage>();
|
||||||
|
SimulatedTime time = SimulatedTime.getSystemTime();
|
||||||
|
if (!time.isRealTime()) {
|
||||||
|
// Filter out any "future" alerts.
|
||||||
|
long simTime = time.getTime().getTime();
|
||||||
|
Iterator<AlertMessage> iter = messagesToProc.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
AlertMessage message = iter.next();
|
||||||
|
Map<String, Object> attribs = new HashMap<String, Object>(
|
||||||
|
message.decodedAlert);
|
||||||
|
DataTime messageTime = (DataTime) attribs
|
||||||
|
.get("dataTime");
|
||||||
|
if (messageTime != null
|
||||||
|
&& (simTime < messageTime.getRefTime()
|
||||||
|
.getTime())) {
|
||||||
|
iter.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (messagesToProc.isEmpty()) {
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
observer.alertArrived(messagesToProc);
|
observer.alertArrived(messagesToProc);
|
||||||
|
|
|
@ -46,6 +46,7 @@ import org.eclipse.ui.PlatformUI;
|
||||||
import org.eclipse.ui.commands.ICommandService;
|
import org.eclipse.ui.commands.ICommandService;
|
||||||
import org.eclipse.ui.progress.UIJob;
|
import org.eclipse.ui.progress.UIJob;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.time.ISimulatedTimeChangeListener;
|
||||||
import com.raytheon.uf.common.time.SimulatedTime;
|
import com.raytheon.uf.common.time.SimulatedTime;
|
||||||
import com.raytheon.uf.common.time.TimeRange;
|
import com.raytheon.uf.common.time.TimeRange;
|
||||||
import com.raytheon.uf.viz.core.VizApp;
|
import com.raytheon.uf.viz.core.VizApp;
|
||||||
|
@ -68,6 +69,7 @@ import com.raytheon.viz.gfe.temporaleditor.TemporalEditor;
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Apr 7, 2009 randerso Redesigned
|
* Apr 7, 2009 randerso Redesigned
|
||||||
* May 18, 2009 2159 rjpeter Added temporal editor.
|
* May 18, 2009 2159 rjpeter Added temporal editor.
|
||||||
|
* Jan 14, 2013 1442 rferrel Add SimulatedTimeChangeListener.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author randerso
|
* @author randerso
|
||||||
|
@ -151,11 +153,13 @@ public class GridManager implements IGridManager,
|
||||||
/**
|
/**
|
||||||
* Job to update the time display
|
* Job to update the time display
|
||||||
*/
|
*/
|
||||||
private static class UpdateJob extends UIJob {
|
private static class UpdateJob extends UIJob implements
|
||||||
|
ISimulatedTimeChangeListener {
|
||||||
|
|
||||||
public UpdateJob() {
|
public UpdateJob() {
|
||||||
super("GridManagerUpdate");
|
super("GridManagerUpdate");
|
||||||
this.setSystem(true);
|
this.setSystem(true);
|
||||||
|
SimulatedTime.getSystemTime().addSimulatedTimeChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -178,6 +182,18 @@ public class GridManager implements IGridManager,
|
||||||
|
|
||||||
return Status.OK_STATUS;
|
return Status.OK_STATUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* com.raytheon.uf.common.time.ISimulatedTimeChangeListener#timechanged
|
||||||
|
* ()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void timechanged() {
|
||||||
|
wakeUp();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -86,6 +86,7 @@ import com.raytheon.viz.core.units.UnitRegistrar;
|
||||||
* Oct 02, 2012 #1236 dgilling Allow SimulatedTime to be set from
|
* Oct 02, 2012 #1236 dgilling Allow SimulatedTime to be set from
|
||||||
* the command line even if practice
|
* the command line even if practice
|
||||||
* mode is off.
|
* mode is off.
|
||||||
|
* Jan 09, 2013 #1442 rferrel Changes to notify SimultedTime listeners.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -319,11 +320,13 @@ public abstract class AbstractCAVEComponent implements IStandaloneComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatedTime systemTime = SimulatedTime.getSystemTime();
|
SimulatedTime systemTime = SimulatedTime.getSystemTime();
|
||||||
|
systemTime.notifyListeners(false);
|
||||||
systemTime.setRealTime();
|
systemTime.setRealTime();
|
||||||
systemTime.setFrozen(isFrozen);
|
systemTime.setFrozen(isFrozen);
|
||||||
if (timeValue != 0) {
|
if (timeValue != 0) {
|
||||||
systemTime.setTime(new Date(timeValue));
|
systemTime.setTime(new Date(timeValue));
|
||||||
}
|
}
|
||||||
|
systemTime.notifyListeners(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -54,6 +54,7 @@ import com.raytheon.viz.ui.VizWorkbenchManager;
|
||||||
* May 21, 2008 1122 ebabin Updated to use new StatusBarDisplay.
|
* May 21, 2008 1122 ebabin Updated to use new StatusBarDisplay.
|
||||||
* 09JUL2008 1234 ebabin Updates for color, and display issues.
|
* 09JUL2008 1234 ebabin Updates for color, and display issues.
|
||||||
* Oct 17, 2012 1229 rferrel Made dialog non-blocking.
|
* Oct 17, 2012 1229 rferrel Made dialog non-blocking.
|
||||||
|
* Jan 09, 2013 1442 rferrel Changes to notify Simulated Time listeners
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -338,8 +339,9 @@ public class SetTimeDialog extends CaveSWTDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setVizTime() {
|
private void setVizTime() {
|
||||||
|
SimulatedTime systemTime = SimulatedTime.getSystemTime();
|
||||||
if (useCurrentTimeRdo.getSelection()) {
|
if (useCurrentTimeRdo.getSelection()) {
|
||||||
SimulatedTime.getSystemTime().setRealTime();
|
systemTime.setRealTime();
|
||||||
} else if (setTimeRdo.getSelection()) {
|
} else if (setTimeRdo.getSelection()) {
|
||||||
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
||||||
cal.clear();
|
cal.clear();
|
||||||
|
@ -348,9 +350,10 @@ public class SetTimeDialog extends CaveSWTDialog {
|
||||||
this.daySpnr.getSelection(), this.hourSpnr.getSelection(),
|
this.daySpnr.getSelection(), this.hourSpnr.getSelection(),
|
||||||
this.minuteSpnr.getSelection(),
|
this.minuteSpnr.getSelection(),
|
||||||
this.secondSpnr.getSelection());
|
this.secondSpnr.getSelection());
|
||||||
SimulatedTime.getSystemTime().setFrozen(
|
systemTime.notifyListeners(false);
|
||||||
freezeTimeChk.getSelection());
|
systemTime.setFrozen(freezeTimeChk.getSelection());
|
||||||
SimulatedTime.getSystemTime().setTime(cal.getTime());
|
systemTime.setTime(cal.getTime());
|
||||||
|
systemTime.notifyListeners(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ import org.eclipse.ui.progress.UIJob;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
|
import com.raytheon.uf.common.time.ISimulatedTimeChangeListener;
|
||||||
import com.raytheon.uf.common.time.SimulatedTime;
|
import com.raytheon.uf.common.time.SimulatedTime;
|
||||||
import com.raytheon.viz.core.mode.CAVEMode;
|
import com.raytheon.viz.core.mode.CAVEMode;
|
||||||
import com.raytheon.viz.ui.actions.ShowTimeDialog;
|
import com.raytheon.viz.ui.actions.ShowTimeDialog;
|
||||||
|
@ -62,6 +63,7 @@ import com.raytheon.viz.ui.actions.ShowTimeDialog;
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Nov 30,2007 461 bphillip Initial Creation
|
* Nov 30,2007 461 bphillip Initial Creation
|
||||||
* 09JUL2008 1234 ebabin Updates for color, and display issues.
|
* 09JUL2008 1234 ebabin Updates for color, and display issues.
|
||||||
|
* Jan 09, 2013 1442 rferrel Added Simulated Time Change listener.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -140,6 +142,8 @@ public class TimeDisplay extends ContributionItem {
|
||||||
// workaround for the random tooltip following the cursor
|
// workaround for the random tooltip following the cursor
|
||||||
private boolean displayTooltip = true;
|
private boolean displayTooltip = true;
|
||||||
|
|
||||||
|
private ISimulatedTimeChangeListener timeChangeListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
|
@ -150,6 +154,15 @@ public class TimeDisplay extends ContributionItem {
|
||||||
gmtFormatter.setTimeZone(GMT);
|
gmtFormatter.setTimeZone(GMT);
|
||||||
|
|
||||||
localFormatter = new SimpleDateFormat(localPattern);
|
localFormatter = new SimpleDateFormat(localPattern);
|
||||||
|
timeChangeListener = new ISimulatedTimeChangeListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void timechanged() {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
SimulatedTime.getSystemTime().addSimulatedTimeChangeListener(
|
||||||
|
timeChangeListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -160,6 +173,8 @@ public class TimeDisplay extends ContributionItem {
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
activeList.remove(this);
|
activeList.remove(this);
|
||||||
|
SimulatedTime.getSystemTime().removeSimulatedTimeChangeListener(
|
||||||
|
timeChangeListener);
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for hooks to send notification when simulated time is modified.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Jan 09, 2013 1442 rferrel Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author rferrel
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface ISimulatedTimeChangeListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method called with simulated time is modified.
|
||||||
|
*/
|
||||||
|
public void timechanged();
|
||||||
|
}
|
|
@ -19,10 +19,9 @@
|
||||||
**/
|
**/
|
||||||
package com.raytheon.uf.common.time;
|
package com.raytheon.uf.common.time;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.TimeZone;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simulated time clock with offset and scale capabilities.
|
* Simulated time clock with offset and scale capabilities.
|
||||||
|
@ -38,6 +37,8 @@ import java.util.TimeZone;
|
||||||
* Jul 16, 2008 randerso Initial creation
|
* Jul 16, 2008 randerso Initial creation
|
||||||
* Aug 24, 2012 0743 djohnson Add option to use milliseconds for operations, change to singleton.
|
* Aug 24, 2012 0743 djohnson Add option to use milliseconds for operations, change to singleton.
|
||||||
* Nov 02, 2012 1302 djohnson Change mistakenly public constructor to private.
|
* Nov 02, 2012 1302 djohnson Change mistakenly public constructor to private.
|
||||||
|
* Jan 07, 2013 1442 rferrel Changes to add/remove/notify Simulated Time Change Listeners.
|
||||||
|
* Use SimulatedTimeTest for unit testing.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -51,6 +52,10 @@ public final class SimulatedTime {
|
||||||
*/
|
*/
|
||||||
private static final SimulatedTime systemTime = new SimulatedTime();
|
private static final SimulatedTime systemTime = new SimulatedTime();
|
||||||
|
|
||||||
|
private List<ISimulatedTimeChangeListener> listeners;
|
||||||
|
|
||||||
|
private boolean doNotify;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the system global simulate time instance
|
* Retrieve the system global simulate time instance
|
||||||
*
|
*
|
||||||
|
@ -99,41 +104,19 @@ public final class SimulatedTime {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private SimulatedTime() {
|
private SimulatedTime() {
|
||||||
|
this.listeners = new ArrayList<ISimulatedTimeChangeListener>();
|
||||||
|
this.doNotify = true;
|
||||||
setRealTime();
|
setRealTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public synchronized void addSimulatedTimeChangeListener(
|
||||||
* Creates a simulated time starting at the specified time with
|
ISimulatedTimeChangeListener listener) {
|
||||||
* acceleration/deceleration, optionally frozen.
|
listeners.add(listener);
|
||||||
*
|
|
||||||
* @param date
|
|
||||||
* starting time
|
|
||||||
* @param scale
|
|
||||||
* 1.0 for normal time rate, >1.0 for accelerated time < 1.0 for
|
|
||||||
* decelerated time. If negative time will run backward.
|
|
||||||
* @param isFrozen
|
|
||||||
* true to freeze time
|
|
||||||
*/
|
|
||||||
private SimulatedTime(Date date, double scale, boolean isFrozen) {
|
|
||||||
this(date.getTime(), scale, isFrozen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public synchronized void removeSimulatedTimeChangeListener(
|
||||||
* Creates a simulated time starting at the specified time with
|
ISimulatedTimeChangeListener listener) {
|
||||||
* acceleration/deceleration, optionally frozen.
|
listeners.remove(listener);
|
||||||
*
|
|
||||||
* @param millis
|
|
||||||
* starting time in milliseconds
|
|
||||||
* @param scale
|
|
||||||
* 1.0 for normal time rate, >1.0 for accelerated time < 1.0 for
|
|
||||||
* decelerated time. If negative time will run backward.
|
|
||||||
* @param isFrozen
|
|
||||||
* true to freeze time
|
|
||||||
*/
|
|
||||||
private SimulatedTime(long millis, double scale, boolean isFrozen) {
|
|
||||||
setTime(millis);
|
|
||||||
this.scale = scale;
|
|
||||||
this.isFrozen = isFrozen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -153,6 +136,7 @@ public final class SimulatedTime {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
scale = 1.0;
|
scale = 1.0;
|
||||||
isFrozen = false;
|
isFrozen = false;
|
||||||
|
fireTimeChangeListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -193,6 +177,7 @@ public final class SimulatedTime {
|
||||||
baseTime = now();
|
baseTime = now();
|
||||||
offset = millis - baseTime;
|
offset = millis - baseTime;
|
||||||
}
|
}
|
||||||
|
fireTimeChangeListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -213,7 +198,10 @@ public final class SimulatedTime {
|
||||||
* decelerated time. If negative time will run backward.
|
* decelerated time. If negative time will run backward.
|
||||||
*/
|
*/
|
||||||
public void setScale(double scale) {
|
public void setScale(double scale) {
|
||||||
|
if (this.scale != scale) {
|
||||||
this.scale = scale;
|
this.scale = scale;
|
||||||
|
fireTimeChangeListeners();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -243,42 +231,34 @@ public final class SimulatedTime {
|
||||||
offset = frozenTime - baseTime;
|
offset = frozenTime - baseTime;
|
||||||
}
|
}
|
||||||
this.isFrozen = isFrozen;
|
this.isFrozen = isFrozen;
|
||||||
|
fireTimeChangeListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test routine
|
* Allows turning off notification of listeners when making several updates
|
||||||
|
* at the same time. Changing to false turns off notification. Changing to
|
||||||
|
* true allows notification and triggers a notification.
|
||||||
*
|
*
|
||||||
* @param args
|
* @param doNotify
|
||||||
* N/A
|
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public void notifyListeners(boolean doNotify) {
|
||||||
String timeFormat = "HH:mm:ss z dd-MMM-yyyy";
|
if (this.doNotify != doNotify) {
|
||||||
TimeZone GMT = TimeZone.getTimeZone("GMT");
|
this.doNotify = doNotify;
|
||||||
|
fireTimeChangeListeners();
|
||||||
SimpleDateFormat gmtFormatter = new SimpleDateFormat(timeFormat);
|
|
||||||
gmtFormatter.setTimeZone(GMT);
|
|
||||||
|
|
||||||
SimpleDateFormat local = new SimpleDateFormat(timeFormat);
|
|
||||||
|
|
||||||
Calendar cal = Calendar.getInstance(GMT);
|
|
||||||
cal.clear();
|
|
||||||
cal.set(1960, 5, 5, 0, 0, 0);
|
|
||||||
|
|
||||||
SimulatedTime simTime = new SimulatedTime(cal.getTime(), 2.0, false);
|
|
||||||
for (int i = 0; i < 15; i++) {
|
|
||||||
Date date = simTime.getTime();
|
|
||||||
System.out.println(gmtFormatter.format(date) + ", "
|
|
||||||
+ local.format(date)
|
|
||||||
+ (simTime.isFrozen() ? " frozen" : ""));
|
|
||||||
simTime.setFrozen(i >= 5 && i < 10);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(1000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify listeners of time change.
|
||||||
|
*/
|
||||||
|
private void fireTimeChangeListeners() {
|
||||||
|
if (doNotify) {
|
||||||
|
// Copy to make thread safe.
|
||||||
|
List<ISimulatedTimeChangeListener> list = new ArrayList<ISimulatedTimeChangeListener>(
|
||||||
|
listeners);
|
||||||
|
for (ISimulatedTimeChangeListener listener : list) {
|
||||||
|
listener.timechanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,8 +153,8 @@ HDS ^(O.[JMNQ].{1,3}) KWBJ (..)(..)(..)[^!]*!(grib|grib2)/[^/]*/([^/]*)/#([^/]*)
|
||||||
# OTLA88 KWBI 010000 /mSST !grib/ncep/SST/#235/201102010000/F000/TMP/sfc/
|
# OTLA88 KWBI 010000 /mSST !grib/ncep/SST/#235/201102010000/F000/TMP/sfc/
|
||||||
#HDS ^(O.L.{1,3}) KWBI (..)(..)(..)[^!]*!(grib|grib2)/[^/]*/([^/]*)/#([^/]*)/([0-9]{8})([0-9]{4})/(F[0-9]{3})/([^/]*)
|
#HDS ^(O.L.{1,3}) KWBI (..)(..)(..)[^!]*!(grib|grib2)/[^/]*/([^/]*)/#([^/]*)/([0-9]{8})([0-9]{4})/(F[0-9]{3})/([^/]*)
|
||||||
# FILE -overwrite -log -close -edex /data_store/\5/(\2:yyyy)(\2:mm)\2/\3/\6/GRID\7/\9Z_\(10)_\(11)-\1_KWBI_\2\3\4_(seq).\5.%Y%m%d%H
|
# FILE -overwrite -log -close -edex /data_store/\5/(\2:yyyy)(\2:mm)\2/\3/\6/GRID\7/\9Z_\(10)_\(11)-\1_KWBI_\2\3\4_(seq).\5.%Y%m%d%H
|
||||||
#!MAINT! Combined the above two patterns into one. The only difference was KWBM vs KWBI
|
#!MAINT! Combined the above two patterns into one. The only difference was KWBM vs KWBI and the O.L or O.N in \1
|
||||||
HDS ^(O.N.{1,3}) (KWBM|KWBI) (..)(..)(..)[^!]*!(grib|grib2)/[^/]*/([^/]*)/#([^/]*)/([0-9]{8})([0-9]{4})/(F[0-9]{3})/([^/]*)
|
HDS ^(O.[LN].{1,3}) (KWBM|KWBI) (..)(..)(..)[^!]*!(grib|grib2)/[^/]*/([^/]*)/#([^/]*)/([0-9]{8})([0-9]{4})/(F[0-9]{3})/([^/]*)
|
||||||
FILE -overwrite -log -close -edex /data_store/\6/(\3:yyyy)(\3:mm)\3/\4/\7/GRID\8/\(10)Z_\(11)_\(12)-\1_\2_\3\4\5_(seq).\6.%Y%m%d%H
|
FILE -overwrite -log -close -edex /data_store/\6/(\3:yyyy)(\3:mm)\3/\4/\7/GRID\8/\(10)Z_\(11)_\(12)-\1_\2_\3\4\5_(seq).\6.%Y%m%d%H
|
||||||
|
|
||||||
# AWIPS1: GRID ^OEBA88.*KNWC /Grid/SBN/Raw
|
# AWIPS1: GRID ^OEBA88.*KNWC /Grid/SBN/Raw
|
||||||
|
@ -335,6 +335,14 @@ HDS ^(ZETA98) (KTUA|PACR|KSTR|KRSA|KORN|KRHA|KKRF|KMSR|KTAR|KPTR|KTIR|KALR|KFWR)
|
||||||
ANY ^(ZDIA98) (....) (..)(..)(..)[^!]*!(grib|grib2)/[^/]*/([^/]*)/#([^/]*)/([0-9]{8})([0-9]{4})/(F[0-9]{3})
|
ANY ^(ZDIA98) (....) (..)(..)(..)[^!]*!(grib|grib2)/[^/]*/([^/]*)/#([^/]*)/([0-9]{8})([0-9]{4})/(F[0-9]{3})
|
||||||
FILE -overwrite -log -close -edex /data_store/\6/(\3:yyyy)(\3:mm)\3/\4/\7/GRID\8/\(10)Z_\(11)-\1_\2_\3\4\5_(seq).\6.%Y%m%d%H
|
FILE -overwrite -log -close -edex /data_store/\6/(\3:yyyy)(\3:mm)\3/\4/\7/GRID\8/\(10)Z_\(11)-\1_\2_\3\4\5_(seq).\6.%Y%m%d%H
|
||||||
|
|
||||||
|
# Restore from build 12.12 with new grib storage convention.
|
||||||
|
HRS ^(YA)([WX])(A..) (KKCI) (..)(..)(..).*!(grib|grib2)/[^/]*/([^/]*)/#([^/]*)/([0-9]{8})([0-9]{4})/(F[0-9]{3})
|
||||||
|
FILE -overwrite -log -close -edex /data_store/\8/(\5:yyyy)(\5:mm)\5/\6/\9/GRID\(10)/\(12)Z_\(13)-\1\2\3_\4_5\6\7_(seq).\8.%Y%m%d%H
|
||||||
|
|
||||||
|
HRS ^(ZV)(W)([ADGJM]..) (KKCI) (..)(..)(..).*!(grib|grib2)/[^/]*/([^/]*)/#([^/]*)/([0-9]{8})([0-9]{4})/(F[0-9]{3})
|
||||||
|
FILE -overwrite -log -close -edex /data_store/\8/(\5:yyyy)(\5:mm)\5/\6/\9/GRID\(10)/\(12)Z_\(13)-\1\2\3_\4_5\6\7_(seq).\8.%Y%m%d%H
|
||||||
|
|
||||||
|
|
||||||
# AWIPS1: POINT .*IUPT(0[1-4]).*|.*IUPT40.* /ispan/bufr/profiler
|
# AWIPS1: POINT .*IUPT(0[1-4]).*|.*IUPT40.* /ispan/bufr/profiler
|
||||||
# IUPT01 KBOU 020300
|
# IUPT01 KBOU 020300
|
||||||
# AWIPS1: POINT ^IUAK01.* /ispan/bufr/profiler
|
# AWIPS1: POINT ^IUAK01.* /ispan/bufr/profiler
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.util.Date;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
import com.raytheon.uf.common.util.TestUtil;
|
import com.raytheon.uf.common.util.TestUtil;
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ import com.raytheon.uf.common.util.TestUtil;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Aug 24, 2012 djohnson Initial creation
|
* Aug 24, 2012 djohnson Initial creation
|
||||||
|
* Jan 15, 2013 1442 rferrel Added tests for notify Time changes.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -73,4 +75,29 @@ public class SimulatedTimeTest {
|
||||||
|
|
||||||
TestUtil.assertNotEquals(start, end);
|
TestUtil.assertNotEquals(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testListenerNotifiedOnTimeChanges() throws Exception {
|
||||||
|
SimulatedTime simulatedTime = SimulatedTime.getSystemTime();
|
||||||
|
ISimulatedTimeChangeListener listener = Mockito
|
||||||
|
.mock(ISimulatedTimeChangeListener.class);
|
||||||
|
simulatedTime.addSimulatedTimeChangeListener(listener);
|
||||||
|
try {
|
||||||
|
simulatedTime.setFrozen(true);
|
||||||
|
Mockito.verify(listener).timechanged();
|
||||||
|
} finally {
|
||||||
|
simulatedTime.removeSimulatedTimeChangeListener(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemovedListenerNotNotifiedOnTimeChanges() throws Exception {
|
||||||
|
SimulatedTime simulatedTime = SimulatedTime.getSystemTime();
|
||||||
|
ISimulatedTimeChangeListener listener = Mockito
|
||||||
|
.mock(ISimulatedTimeChangeListener.class);
|
||||||
|
simulatedTime.addSimulatedTimeChangeListener(listener);
|
||||||
|
simulatedTime.removeSimulatedTimeChangeListener(listener);
|
||||||
|
simulatedTime.setFrozen(true);
|
||||||
|
Mockito.verify(listener, Mockito.never()).timechanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue