Merge remote-tracking branch 'asm/asm_16.2.1' into master_16.2.1
Former-commit-id: 70338bff91bc02d5b0e2b2286164073afd85ed3c
This commit is contained in:
commit
44c2a22f93
6 changed files with 504 additions and 288 deletions
|
@ -21,61 +21,84 @@ package com.raytheon.rcm.message;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the contents of an ORPG General Status Message.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* 2009 dfriedman Initial version
|
||||||
|
* 2016-04-22 DR 18909 dfriedman Read fields of expanded GSM.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
public class GSM extends Message {
|
public class GSM extends Message {
|
||||||
public static final int OP_MODE_MAINTENANCE = 0;
|
public static final int OP_MODE_MAINTENANCE = 0;
|
||||||
public static final int OP_MODE_CLEAR_AIR = 1;
|
public static final int OP_MODE_CLEAR_AIR = 1;
|
||||||
public static final int OP_MODE_STORM = 2;
|
public static final int OP_MODE_STORM = 2;
|
||||||
|
|
||||||
public int opMode;
|
public int opMode;
|
||||||
public int rdaOpStatus;
|
public int rdaOpStatus;
|
||||||
public int vcp;
|
public int vcp;
|
||||||
public int[] cuts; // in tenths of degrees
|
public int[] cuts; // in tenths of degrees
|
||||||
public int rdaStatus;
|
public int rdaStatus;
|
||||||
public int rdaAlarms;
|
public int rdaAlarms;
|
||||||
public int dataAvailability; // "DTE"
|
public int dataAvailability; // "DTE"
|
||||||
public int rpgOpStatus;
|
public int rpgOpStatus;
|
||||||
public int rpgAlarms;
|
public int rpgAlarms;
|
||||||
public int rpgStatus;
|
public int rpgStatus;
|
||||||
public int rpgNarrowbandStatus;
|
public int rpgNarrowbandStatus;
|
||||||
public int rcc;
|
public int rcc;
|
||||||
public int productAvailability;
|
public int productAvailability;
|
||||||
public int superResCuts;
|
public int superResCuts;
|
||||||
public int rdaVersion;
|
public int rdaVersion;
|
||||||
public int rdaChannel;
|
public int rdaChannel;
|
||||||
public int rpgVersion;
|
public int rpgVersion;
|
||||||
|
public int vcpSupplemental;
|
||||||
|
|
||||||
public static GSM decode(byte[] msg) {
|
public static GSM decode(byte[] msg) {
|
||||||
return (GSM) MD.decode(msg);
|
return (GSM) MD.decode(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void decodeBlock(int index, ByteBuffer buf) {
|
protected void decodeBlock(int index, ByteBuffer buf) {
|
||||||
if (index != 1)
|
if (index != 1)
|
||||||
return;
|
return;
|
||||||
opMode = buf.getShort();
|
opMode = buf.getShort();
|
||||||
rdaOpStatus = buf.getShort();
|
rdaOpStatus = buf.getShort();
|
||||||
vcp = buf.getShort();
|
vcp = buf.getShort();
|
||||||
int nCuts = buf.getShort();
|
int nCuts = buf.getShort();
|
||||||
cuts = new int[nCuts];
|
cuts = new int[nCuts];
|
||||||
for (int i = 0; i < 20; ++i) {
|
for (int i = 0; i < 20; ++i) {
|
||||||
if (i < cuts.length)
|
short cut = buf.getShort();
|
||||||
cuts[i] = buf.getShort();
|
if (i < cuts.length) {
|
||||||
else
|
cuts[i] = cut;
|
||||||
buf.getShort();
|
}
|
||||||
}
|
}
|
||||||
rdaStatus = buf.getShort();
|
rdaStatus = buf.getShort();
|
||||||
rdaAlarms = buf.getShort();
|
rdaAlarms = buf.getShort();
|
||||||
dataAvailability = buf.getShort();
|
dataAvailability = buf.getShort();
|
||||||
rpgOpStatus = buf.getShort();
|
rpgOpStatus = buf.getShort();
|
||||||
rpgAlarms = buf.getShort();
|
rpgAlarms = buf.getShort();
|
||||||
rpgStatus = buf.getShort();
|
rpgStatus = buf.getShort();
|
||||||
rpgNarrowbandStatus = buf.getShort();
|
rpgNarrowbandStatus = buf.getShort();
|
||||||
rcc = buf.getShort();
|
rcc = buf.getShort();
|
||||||
productAvailability = buf.getShort();
|
productAvailability = buf.getShort();
|
||||||
superResCuts = buf.getShort();
|
superResCuts = buf.getShort();
|
||||||
buf.position(buf.position() + 4);
|
buf.position(buf.position() + 4);
|
||||||
rdaVersion = buf.getShort();
|
rdaVersion = buf.getShort();
|
||||||
rdaChannel = buf.getShort();
|
rdaChannel = buf.getShort();
|
||||||
buf.position(buf.position() + 4);
|
buf.position(buf.position() + 4);
|
||||||
rpgVersion = buf.getShort();
|
rpgVersion = buf.getShort();
|
||||||
}
|
if (buf.remaining() < 12) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 20; i < 25; ++i) {
|
||||||
|
short cut = buf.getShort();
|
||||||
|
if (i < cuts.length) {
|
||||||
|
cuts[i] = cut;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vcpSupplemental = buf.getShort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,12 @@ package com.raytheon.rcm.otrmgr;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.raytheon.rcm.config.RadarConfig;
|
import com.raytheon.rcm.config.RadarConfig;
|
||||||
|
import com.raytheon.rcm.config.RadarType;
|
||||||
import com.raytheon.rcm.config.RcmUtil;
|
import com.raytheon.rcm.config.RcmUtil;
|
||||||
import com.raytheon.rcm.event.OtrEvent;
|
import com.raytheon.rcm.event.OtrEvent;
|
||||||
import com.raytheon.rcm.event.RadarEvent;
|
import com.raytheon.rcm.event.RadarEvent;
|
||||||
|
@ -39,6 +41,7 @@ import com.raytheon.rcm.message.MessageFormatException;
|
||||||
import com.raytheon.rcm.message.MessageInfo;
|
import com.raytheon.rcm.message.MessageInfo;
|
||||||
import com.raytheon.rcm.message.ProductRequest;
|
import com.raytheon.rcm.message.ProductRequest;
|
||||||
import com.raytheon.rcm.message.RequestResponse;
|
import com.raytheon.rcm.message.RequestResponse;
|
||||||
|
import com.raytheon.rcm.products.ElevationInfo;
|
||||||
import com.raytheon.rcm.request.Filter;
|
import com.raytheon.rcm.request.Filter;
|
||||||
import com.raytheon.rcm.request.Request;
|
import com.raytheon.rcm.request.Request;
|
||||||
import com.raytheon.rcm.request.Sequence;
|
import com.raytheon.rcm.request.Sequence;
|
||||||
|
@ -55,9 +58,18 @@ import com.raytheon.rcm.server.RadarServer;
|
||||||
/**
|
/**
|
||||||
* Manages One Time Requests for the RPGs.
|
* Manages One Time Requests for the RPGs.
|
||||||
* <p>
|
* <p>
|
||||||
* Does not actually do much except provide a place to queue up requests while
|
* Implements a queue for pending requests to the RPGs. Performs some coalescing
|
||||||
* waiting to connect to the RPG. Does do some coalescing of duplicate
|
* of duplicate requests.
|
||||||
* requests.
|
*
|
||||||
|
* <pre>
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* 2009 dfriedman Initial version
|
||||||
|
* 2016-04-22 DR 18909 dfriedman Accurately calculate the number of expected
|
||||||
|
* responses for multiple-elevation requests.
|
||||||
|
* </pre>
|
||||||
*/
|
*/
|
||||||
public class OTRManager extends RadarEventAdapter {
|
public class OTRManager extends RadarEventAdapter {
|
||||||
|
|
||||||
|
@ -69,7 +81,7 @@ public class OTRManager extends RadarEventAdapter {
|
||||||
*/
|
*/
|
||||||
protected boolean isReady;
|
protected boolean isReady;
|
||||||
|
|
||||||
protected List<Req> requests = new ArrayList<Req>();
|
protected List<Req> requests = new ArrayList<>();
|
||||||
|
|
||||||
protected GSM lastGSM;
|
protected GSM lastGSM;
|
||||||
|
|
||||||
|
@ -226,7 +238,7 @@ public class OTRManager extends RadarEventAdapter {
|
||||||
|
|
||||||
private void trySendingRequests() {
|
private void trySendingRequests() {
|
||||||
if (isReady()) {
|
if (isReady()) {
|
||||||
ArrayList<Request> requestsToSend = new ArrayList<Request>();
|
ArrayList<Request> requestsToSend = new ArrayList<>();
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
synchronized (this.requests) {
|
synchronized (this.requests) {
|
||||||
for (Req r : requests) {
|
for (Req r : requests) {
|
||||||
|
@ -319,31 +331,55 @@ public class OTRManager extends RadarEventAdapter {
|
||||||
&& request.getElevationSelection() != Request.SPECIFIC_ELEVATION) {
|
&& request.getElevationSelection() != Request.SPECIFIC_ELEVATION) {
|
||||||
if (lastGSM != null) {
|
if (lastGSM != null) {
|
||||||
if (request.getElevationSelection() == Request.ALL_ELEVATIONS) {
|
if (request.getElevationSelection() == Request.ALL_ELEVATIONS) {
|
||||||
/*
|
RadarType radarType = RcmUtil.getRadarType(getRadarConfig());
|
||||||
* We do not get information about duplicate
|
int[] completeElevationList;
|
||||||
* elevations. Could put in TDWR-specific knowledge.
|
|
||||||
* If vcp==80 && is-low-elevation...
|
|
||||||
*
|
|
||||||
* But probably needs something like.
|
|
||||||
* nExpectedUnknown = true and (if nExpectedUnknown
|
|
||||||
* then connMgr.idleDisconnectRadar(...)
|
|
||||||
*/
|
|
||||||
// if is tdwr and vcp80...
|
|
||||||
exactCountUnknown = true;
|
|
||||||
|
|
||||||
nElevations = request.getElevationAngle() == 0 ? lastGSM.cuts.length
|
if (radarType == RadarType.WSR
|
||||||
: 1;
|
|| (radarType == RadarType.TDWR && lastGSM.rpgVersion >= 80)) {
|
||||||
|
/*
|
||||||
|
* When MESO-SAILS was added to WSR-88D, the
|
||||||
|
* expanded GSM was already available and it
|
||||||
|
* contained the complete list of elevations
|
||||||
|
* including extra SAILS elevations. Therefore,
|
||||||
|
* we can always rely on a WSR-88D's GSM for the
|
||||||
|
* list of elevation angles.
|
||||||
|
*
|
||||||
|
* Later version of the SPG contain the complete
|
||||||
|
* list of angles in an expected GSM.
|
||||||
|
*/
|
||||||
|
completeElevationList = lastGSM.cuts;
|
||||||
|
} else if (radarType == RadarType.TDWR && lastGSM.rpgVersion < 80) {
|
||||||
|
/*
|
||||||
|
* Earlier versions of the SPG do not list the
|
||||||
|
* extra low angle elevations scans. We can use
|
||||||
|
* the static elevation list instead.
|
||||||
|
*/
|
||||||
|
completeElevationList = ElevationInfo
|
||||||
|
.getInstance().getScanElevations(
|
||||||
|
radarID, lastGSM.vcp);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* No choice but to guess based on the list of
|
||||||
|
* elevations from the GSM.
|
||||||
|
*/
|
||||||
|
completeElevationList = lastGSM.cuts;
|
||||||
|
exactCountUnknown = true;
|
||||||
|
}
|
||||||
|
int elevationAngle = request.getElevationAngle();
|
||||||
|
nElevations = elevationAngle == 0 ? uniqueCount(completeElevationList)
|
||||||
|
: matchCount(elevationAngle, completeElevationList);
|
||||||
} else if (request.getElevationSelection() == Request.N_ELEVATIONS) {
|
} else if (request.getElevationSelection() == Request.N_ELEVATIONS) {
|
||||||
nElevations = Math.min(lastGSM.cuts.length,
|
nElevations = Math.min(uniqueCount(lastGSM.cuts),
|
||||||
request.getElevationAngle());
|
request.getElevationAngle());
|
||||||
} else if (request.getElevationSelection() == Request.LOWER_ELEVATIONS) {
|
} else if (request.getElevationSelection() == Request.LOWER_ELEVATIONS) {
|
||||||
|
HashSet<Integer> seenAngles = new HashSet<>();
|
||||||
nElevations = 0;
|
nElevations = 0;
|
||||||
int reqEA = request.getElevationAngle();
|
int reqEA = request.getElevationAngle();
|
||||||
for (int ea : lastGSM.cuts) {
|
for (int ea : lastGSM.cuts) {
|
||||||
if (ea <= reqEA)
|
if (ea <= reqEA && !seenAngles.contains(ea)) {
|
||||||
++nElevations;
|
++nElevations;
|
||||||
else
|
seenAngles.add(ea);
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
exactCountUnknown = true;
|
exactCountUnknown = true;
|
||||||
|
@ -356,9 +392,41 @@ public class OTRManager extends RadarEventAdapter {
|
||||||
nExpected = request.count * nElevations;
|
nExpected = request.count * nElevations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int uniqueCount(int[] angles) {
|
||||||
|
HashSet<Integer> uniqueAngles = new HashSet<>();
|
||||||
|
for (int a : angles) {
|
||||||
|
uniqueAngles.add(a);
|
||||||
|
}
|
||||||
|
return uniqueAngles.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int matchCount(int angle, int[] angles) {
|
||||||
|
int matchedAngle = findClosestAngle(angle, angles);
|
||||||
|
int count = 0;
|
||||||
|
for (int a : angles) {
|
||||||
|
if (a == matchedAngle) {
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int findClosestAngle(int angle, int[] angles) {
|
||||||
|
int result = Integer.MIN_VALUE;
|
||||||
|
int bestDiff = Integer.MAX_VALUE;
|
||||||
|
for (int a : angles) {
|
||||||
|
int diff = Math.abs(a - angle);
|
||||||
|
if (result == -1 || diff < bestDiff) {
|
||||||
|
result = a;
|
||||||
|
bestDiff = diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public void addHandler(OTRHandler handler) {
|
public void addHandler(OTRHandler handler) {
|
||||||
if (handlers == null)
|
if (handlers == null)
|
||||||
handlers = new ArrayList<OTRHandler>();
|
handlers = new ArrayList<>();
|
||||||
handlers.add(handler);
|
handlers.add(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,7 +455,7 @@ public class OTRManager extends RadarEventAdapter {
|
||||||
RadarServer radarServer;
|
RadarServer radarServer;
|
||||||
|
|
||||||
// ArrayList<Req> requests = new ArrayList<Req>();
|
// ArrayList<Req> requests = new ArrayList<Req>();
|
||||||
HashMap<String, RadarStatus> state = new HashMap<String, RadarStatus>();
|
HashMap<String, RadarStatus> state = new HashMap<>();
|
||||||
|
|
||||||
public OTRManager(RadarServer radarServer) {
|
public OTRManager(RadarServer radarServer) {
|
||||||
this.radarServer = radarServer;
|
this.radarServer = radarServer;
|
||||||
|
|
|
@ -31,184 +31,198 @@ import com.raytheon.rcm.message.GraphicProduct.PDB;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A radar server component that logs various radar events.
|
* A radar server component that logs various radar events.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* 2009 dfriedma Initial version
|
||||||
|
* 2016-04-22 DR 18909 dfriedma Log fields of expanded GSM.
|
||||||
|
* </pre>
|
||||||
*/
|
*/
|
||||||
public class EventLogger extends RadarEventAdapter {
|
public class EventLogger extends RadarEventAdapter {
|
||||||
|
|
||||||
public EventLogger() {
|
public EventLogger() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleRadarEvent(RadarEvent event) {
|
public void handleRadarEvent(RadarEvent event) {
|
||||||
switch (event.getType()) {
|
switch (event.getType()) {
|
||||||
case RadarEvent.CONNECTION_UP:
|
case RadarEvent.CONNECTION_UP:
|
||||||
Log.eventf("%s: connected", event.getRadarID());
|
Log.eventf("%s: connected", event.getRadarID());
|
||||||
break;
|
break;
|
||||||
case RadarEvent.CONNECTION_DOWN:
|
case RadarEvent.CONNECTION_DOWN:
|
||||||
Log.eventf("%s: disconnected", event.getRadarID());
|
Log.eventf("%s: disconnected", event.getRadarID());
|
||||||
break;
|
break;
|
||||||
case RadarEvent.MESSAGE_RECEIVED:
|
case RadarEvent.MESSAGE_RECEIVED:
|
||||||
{
|
{
|
||||||
StringBuilder s = new StringBuilder();
|
StringBuilder s = new StringBuilder();
|
||||||
byte[] msg = event.getMessageData();
|
byte[] msg = event.getMessageData();
|
||||||
int messageCode = Message.messageCodeOf(msg);
|
int messageCode = Message.messageCodeOf(msg);
|
||||||
s.append("code=" + messageCode);
|
s.append("code=" + messageCode);
|
||||||
s.append(" size=" + msg.length);
|
s.append(" size=" + msg.length);
|
||||||
if (messageCode == Message.GSM) {
|
if (messageCode == Message.GSM) {
|
||||||
s.append(' ');
|
s.append(' ');
|
||||||
GSM gsm = null;
|
GSM gsm = null;
|
||||||
try {
|
try {
|
||||||
gsm = GSM.decode(msg);
|
gsm = GSM.decode(msg);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
s.append("(Message decoding failed)");
|
s.append("(Message decoding failed)");
|
||||||
}
|
}
|
||||||
if (gsm != null)
|
if (gsm != null)
|
||||||
s.append(formatGSM(gsm));
|
s.append(formatGSM(gsm));
|
||||||
} else if (messageCode == Message.REQUEST_RESPONSE) {
|
} else if (messageCode == Message.REQUEST_RESPONSE) {
|
||||||
s.append(' ');
|
s.append(' ');
|
||||||
RequestResponse rr = null;
|
RequestResponse rr = null;
|
||||||
try {
|
try {
|
||||||
rr = RequestResponse.decode(msg);
|
rr = RequestResponse.decode(msg);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
s.append("(Message decoding failed)");
|
s.append("(Message decoding failed)");
|
||||||
}
|
}
|
||||||
if (rr != null)
|
if (rr != null)
|
||||||
s.append(formatPRR(rr));
|
s.append(formatPRR(rr));
|
||||||
} else if (messageCode >= 16) {
|
} else if (messageCode >= 16) {
|
||||||
PDB pdb = null;
|
PDB pdb = null;
|
||||||
|
|
||||||
s.append(' ');
|
s.append(' ');
|
||||||
try {
|
try {
|
||||||
pdb = GraphicProduct.pdbOfMessage(msg);
|
pdb = GraphicProduct.pdbOfMessage(msg);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
s.append("(Message decoding failed)");
|
s.append("(Message decoding failed)");
|
||||||
}
|
}
|
||||||
if (pdb != null)
|
if (pdb != null)
|
||||||
s.append(String.format("elev=%.1f sequence=%d"+
|
s.append(String.format("elev=%.1f sequence=%d"+
|
||||||
" vs=%3$tY-%3$tm-%3$td %3$tH:%3$tM:%3$tS #%4$d",
|
" vs=%3$tY-%3$tm-%3$td %3$tH:%3$tM:%3$tS #%4$d",
|
||||||
pdb.getElevationAngle() / 10.0, pdb.sequence,
|
pdb.getElevationAngle() / 10.0, pdb.sequence,
|
||||||
pdb.volumeScanTime, pdb.volumeScan));
|
pdb.volumeScanTime, pdb.volumeScan));
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.eventf("%s: message %s", event.getRadarID(), s.toString());
|
Log.eventf("%s: message %s", event.getRadarID(), s.toString());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final String[] rdaOpStatusStr = {
|
protected final String[] rdaOpStatusStr = {
|
||||||
"auto-calib-disab", "online", "maint-req", "maint-mand", "cmd-shutdown",
|
"auto-calib-disab", "online", "maint-req", "maint-mand", "cmd-shutdown",
|
||||||
"inoperable", null, "wideband-disconn"
|
"inoperable", null, "wideband-disconn"
|
||||||
};
|
};
|
||||||
protected final String[] rdaStatusStr = {
|
protected final String[] rdaStatusStr = {
|
||||||
null, "startup", "standby", "restart", "operate", null, "offline-op"
|
null, "startup", "standby", "restart", "operate", null, "offline-op"
|
||||||
};
|
};
|
||||||
protected final String[] rdaAlarmStr = {
|
protected final String[] rdaAlarmStr = {
|
||||||
"indeterminate", "tower", "pedestal", "transmitter", "receiver", "control", "comms"
|
"indeterminate", "tower", "pedestal", "transmitter", "receiver", "control", "comms"
|
||||||
};
|
};
|
||||||
protected final String[] dteStr = {
|
protected final String[] dteStr = {
|
||||||
null, "none", "refl", "vel", "sw", "dual-pol"
|
null, "none", "refl", "vel", "sw", "dual-pol"
|
||||||
};
|
};
|
||||||
protected final String[] rpgOpStr = {
|
protected final String[] rpgOpStr = {
|
||||||
"load-shed", "online", "maint-req", "maint-mand", "cmd-shutdown"
|
"load-shed", "online", "maint-req", "maint-mand", "cmd-shutdown"
|
||||||
};
|
};
|
||||||
protected final String[] rpgAlarmStr = {
|
protected final String[] rpgAlarmStr = {
|
||||||
"none", "node-conn", null, "ctl-task-fail", "db-fail", null, "input-load-shed",
|
"none", "node-conn", null, "ctl-task-fail", "db-fail", null, "input-load-shed",
|
||||||
null, "store-load-shed", null, null, null, "link-fail", "redundant-channel-error",
|
null, "store-load-shed", null, null, null, "link-fail", "redundant-channel-error",
|
||||||
"task-fail", "media-fail"
|
"task-fail", "media-fail"
|
||||||
};
|
};
|
||||||
protected final String[] rpgStatusStr = {
|
protected final String[] rpgStatusStr = {
|
||||||
"restart", "operate", "standby", null, "test-mode"
|
"restart", "operate", "standby", null, "test-mode"
|
||||||
};
|
};
|
||||||
protected final String[] productAvailStr = {
|
protected final String[] productAvailStr = {
|
||||||
"avail", "degraded", "not-avail"
|
"avail", "degraded", "not-avail"
|
||||||
};
|
};
|
||||||
protected final String[] prrStr = {
|
protected final String[] prrStr = {
|
||||||
"no-such-msg", "no-such-prod", "not-gen", "proc-fault",
|
"no-such-msg", "no-such-prod", "not-gen", "proc-fault",
|
||||||
"narrowband-loadshed", "illegal-req", "mem-loadshed", "cpu-loadshed",
|
"narrowband-loadshed", "illegal-req", "mem-loadshed", "cpu-loadshed",
|
||||||
"slot-unavail", "task-failed", "task-unavail", "avail-next-scan",
|
"slot-unavail", "task-failed", "task-unavail", "avail-next-scan",
|
||||||
"moment-disabled", "invalid-password", null, "aborted-scan",
|
"moment-disabled", "invalid-password", null, "aborted-scan",
|
||||||
"inval-prod-param", "data-seq-error", "task-term"
|
"inval-prod-param", "data-seq-error", "task-term"
|
||||||
};
|
};
|
||||||
|
protected final String[] vcpSupplementalStr = {
|
||||||
|
"AVSET", "SAILS", "site-specific-vcp", "RxRN", "CBT"
|
||||||
|
};
|
||||||
|
|
||||||
protected String formatBits(short bits, String[] strings) {
|
protected String formatBits(short bits, String[] strings) {
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder();
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
if ((bits & (1 << i)) != 0) {
|
if ((bits & (1 << i)) != 0) {
|
||||||
if (result.length() > 0)
|
if (result.length() > 0)
|
||||||
result.append(',');
|
result.append(',');
|
||||||
String s = null;
|
String s = null;
|
||||||
if (i < strings.length)
|
if (i < strings.length)
|
||||||
s = strings[i];
|
s = strings[i];
|
||||||
if (s == null)
|
if (s == null)
|
||||||
s = "unk" + Integer.toString(15 - i);
|
s = "unk" + Integer.toString(15 - i);
|
||||||
result.append(s);
|
result.append(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String formatPrrBits(int bits, String[] strings) {
|
protected String formatPrrBits(int bits, String[] strings) {
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder();
|
||||||
for (int i = 0; i < 32; i++) {
|
for (int i = 0; i < 32; i++) {
|
||||||
// PRR bits are defined from the MSB on down, so
|
// PRR bits are defined from the MSB on down, so
|
||||||
// note the (31-i)
|
// note the (31-i)
|
||||||
if ((bits & (1 << (31-i))) != 0) {
|
if ((bits & (1 << (31-i))) != 0) {
|
||||||
if (result.length() > 0)
|
if (result.length() > 0)
|
||||||
result.append(',');
|
result.append(',');
|
||||||
String s = null;
|
String s = null;
|
||||||
if (i < strings.length)
|
if (i < strings.length)
|
||||||
s = strings[i];
|
s = strings[i];
|
||||||
if (s == null)
|
if (s == null)
|
||||||
s = "unk" + Integer.toString(31 - i);
|
s = "unk" + Integer.toString(31 - i);
|
||||||
result.append(s);
|
result.append(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String formatGSM(GSM gsm) {
|
protected String formatGSM(GSM gsm) {
|
||||||
StringBuilder o = new StringBuilder();
|
StringBuilder o = new StringBuilder();
|
||||||
String s;
|
String s;
|
||||||
|
|
||||||
switch (gsm.opMode) {
|
switch (gsm.opMode) {
|
||||||
case GSM.OP_MODE_CLEAR_AIR: s = "clear-air"; break;
|
case GSM.OP_MODE_CLEAR_AIR: s = "clear-air"; break;
|
||||||
case GSM.OP_MODE_STORM: s = "storm"; break;
|
case GSM.OP_MODE_STORM: s = "storm"; break;
|
||||||
case GSM.OP_MODE_MAINTENANCE: s = "maintenance"; break;
|
case GSM.OP_MODE_MAINTENANCE: s = "maintenance"; break;
|
||||||
default: s = "(" +Integer.toString(gsm.opMode) + ")";
|
default: s = "(" +Integer.toString(gsm.opMode) + ")";
|
||||||
}
|
}
|
||||||
o.append("opMode=" + s);
|
o.append("opMode=" + s);
|
||||||
|
|
||||||
o.append(" vcp=" + gsm.vcp);
|
o.append(" vcp=" + gsm.vcp);
|
||||||
o.append(" cuts=" + Arrays.toString(gsm.cuts));
|
o.append(" cuts=" + Arrays.toString(gsm.cuts));
|
||||||
|
|
||||||
o.append(String.format(" rdaOp=%s rdaStat=%s rdaAlarm=%s dte=%s rpgOp=%s rpgStat=%s rpgAlarm=%s",
|
o.append(String.format(" rdaOp=%s rdaStat=%s rdaAlarm=%s dte=%s rpgOp=%s rpgStat=%s rpgAlarm=%s",
|
||||||
formatBits((short) gsm.rdaOpStatus, rdaOpStatusStr),
|
formatBits((short) gsm.rdaOpStatus, rdaOpStatusStr),
|
||||||
formatBits((short) gsm.rdaStatus, rdaStatusStr),
|
formatBits((short) gsm.rdaStatus, rdaStatusStr),
|
||||||
formatBits((short) gsm.rdaAlarms, rdaAlarmStr),
|
formatBits((short) gsm.rdaAlarms, rdaAlarmStr),
|
||||||
formatBits((short) gsm.dataAvailability, dteStr),
|
formatBits((short) gsm.dataAvailability, dteStr),
|
||||||
formatBits((short) gsm.rpgOpStatus, rpgOpStr),
|
formatBits((short) gsm.rpgOpStatus, rpgOpStr),
|
||||||
formatBits((short) gsm.rpgStatus, rpgStatusStr),
|
formatBits((short) gsm.rpgStatus, rpgStatusStr),
|
||||||
formatBits((short) gsm.rpgAlarms, rpgAlarmStr)));
|
formatBits((short) gsm.rpgAlarms, rpgAlarmStr)));
|
||||||
|
|
||||||
o.append(String.format(" avail=%s",
|
o.append(String.format(" avail=%s",
|
||||||
formatBits((short) gsm.productAvailability, productAvailStr)));
|
formatBits((short) gsm.productAvailability, productAvailStr)));
|
||||||
|
|
||||||
o.append(String.format(" rdaVer=%.1f rpgVer=%.1f", gsm.rdaVersion/10.0, gsm.rpgVersion/10.));
|
o.append(String.format(" suppl=%s",
|
||||||
|
formatBits((short) gsm.vcpSupplemental, vcpSupplementalStr)));
|
||||||
|
|
||||||
return o.toString();
|
o.append(String.format(" rdaVer=%.1f rpgVer=%.1f", gsm.rdaVersion/10.0, gsm.rpgVersion/10.));
|
||||||
}
|
|
||||||
|
|
||||||
protected String formatPRR(RequestResponse rr) {
|
return o.toString();
|
||||||
StringBuilder o = new StringBuilder();
|
}
|
||||||
|
|
||||||
o.append(String.format("productCode=%d sequence=%d elev=%d flags=%s",
|
protected String formatPRR(RequestResponse rr) {
|
||||||
rr.productCode,
|
StringBuilder o = new StringBuilder();
|
||||||
rr.sequence,
|
|
||||||
rr.elevationAngle,
|
|
||||||
formatPrrBits(rr.errorCode, prrStr)));
|
|
||||||
|
|
||||||
return o.toString();
|
o.append(String.format("productCode=%d sequence=%d elev=%d flags=%s",
|
||||||
}
|
rr.productCode,
|
||||||
|
rr.sequence,
|
||||||
|
rr.elevationAngle,
|
||||||
|
formatPrrBits(rr.errorCode, prrStr)));
|
||||||
|
|
||||||
|
return o.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -369,6 +369,7 @@ import com.raytheon.viz.ui.simulatedtime.SimulatedTimeOperations;
|
||||||
* 06Jan2016 5225 randerso Fix problem with mixed case not getting converted to upper case
|
* 06Jan2016 5225 randerso Fix problem with mixed case not getting converted to upper case
|
||||||
* when multiple text editors are open on the same product.
|
* when multiple text editors are open on the same product.
|
||||||
* Mar 17, 2016 RM 18727 D. Friedman Fix use of verification listener when entering and exiting editor.
|
* Mar 17, 2016 RM 18727 D. Friedman Fix use of verification listener when entering and exiting editor.
|
||||||
|
* Apr 15, 2016 RM 18870 D. Friedman Replace commas with ellipses only at start of edit and then word-wrap.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -4254,20 +4255,19 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
||||||
// section
|
// section
|
||||||
setCurrentHeaderAndBody();
|
setCurrentHeaderAndBody();
|
||||||
|
|
||||||
// if product is a WarnGen product and is not enabled for mixed case
|
|
||||||
// transmission, replace all commas with ellipses
|
|
||||||
if ((product != null) && warngenPils.contains(product.getNnnid())
|
|
||||||
&& !MixedCaseProductSupport.isMixedCase(product.getNnnid())) {
|
|
||||||
textEditor.setText(textEditor.getText()
|
|
||||||
.replaceAll(", {0,1}", "..."));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark the uneditable warning text
|
// Mark the uneditable warning text
|
||||||
if (markUneditableText(textEditor)) {
|
if (markUneditableText(textEditor)) {
|
||||||
// Enable listener to monitor attempt to edit locked text
|
// Enable listener to monitor attempt to edit locked text
|
||||||
verifyUndeditableText = true;
|
verifyUndeditableText = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if product is a WarnGen product and is not enabled for mixed case
|
||||||
|
// transmission, replace all commas with ellipses
|
||||||
|
if ((product != null) && warngenPils.contains(product.getNnnid())
|
||||||
|
&& !MixedCaseProductSupport.isMixedCase(product.getNnnid())) {
|
||||||
|
replaceCommasWithEllipses(product);
|
||||||
|
}
|
||||||
|
|
||||||
// Set the menu buttons to reflect the edit mode.
|
// Set the menu buttons to reflect the edit mode.
|
||||||
editorButtonMenuStates(inEditMode);
|
editorButtonMenuStates(inEditMode);
|
||||||
|
|
||||||
|
@ -4295,6 +4295,60 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
||||||
editHeader("warning", true);
|
editHeader("warning", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void replaceCommasWithEllipses(StdTextProduct product) {
|
||||||
|
boolean wasVerifying = verifyUndeditableText;
|
||||||
|
try {
|
||||||
|
verifyUndeditableText = false;
|
||||||
|
/*
|
||||||
|
* Performing wrapping as few times as possible to reduce the
|
||||||
|
* chances of breaking the product format. Also, the location list
|
||||||
|
* does not wrap properly unless all commas in the paragraph have
|
||||||
|
* been changed to ellipses.
|
||||||
|
*/
|
||||||
|
Pattern p = Pattern.compile(", {0,1}");
|
||||||
|
int pendingParagraphLineStart = -1;
|
||||||
|
while (true) {
|
||||||
|
String text = textEditor.getText();
|
||||||
|
Matcher m = p.matcher(text);
|
||||||
|
if (! m.find())
|
||||||
|
break;
|
||||||
|
int line = textEditor.getLineAtOffset(m.start());
|
||||||
|
int paragraphLineStart = findParagraphStart(line);
|
||||||
|
String lineText = textEditor.getLine(line);
|
||||||
|
boolean lineNeedsWrap = lineText.length()
|
||||||
|
- (m.end() - m.start()) + 3 > charWrapCol;
|
||||||
|
if (pendingParagraphLineStart >= 0
|
||||||
|
&& paragraphLineStart != pendingParagraphLineStart
|
||||||
|
&& lineNeedsWrap) {
|
||||||
|
wrapWholeParagraphAtLine(pendingParagraphLineStart);
|
||||||
|
pendingParagraphLineStart = -1;
|
||||||
|
// Line numbers may have changed so restart.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
textEditor.replaceTextRange(m.start(), m.end() - m.start(), "...");
|
||||||
|
if (lineNeedsWrap) {
|
||||||
|
pendingParagraphLineStart = paragraphLineStart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pendingParagraphLineStart >= 0) {
|
||||||
|
wrapWholeParagraphAtLine(pendingParagraphLineStart);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
verifyUndeditableText = wasVerifying;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wrapWholeParagraphAtLine(int paragraphLineStart) {
|
||||||
|
String line = textEditor.getLine(paragraphLineStart);
|
||||||
|
// Avoid rewrapInternal early bailout check.
|
||||||
|
if (line.length() < charWrapCol
|
||||||
|
&& line.indexOf("...") == line.lastIndexOf("...")) {
|
||||||
|
paragraphLineStart++;
|
||||||
|
}
|
||||||
|
int offset = textEditor.getOffsetAtLine(paragraphLineStart);
|
||||||
|
rewrap(offset, offset);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel the editor mode.
|
* Cancel the editor mode.
|
||||||
*
|
*
|
||||||
|
@ -4402,16 +4456,6 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
||||||
textEditor.setText(originalText);
|
textEditor.setText(originalText);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if product is a WarnGen product and is not enabled for mixed case
|
|
||||||
// transmission, replace all commas with ellipses
|
|
||||||
StdTextProduct product = TextDisplayModel.getInstance()
|
|
||||||
.getStdTextProduct(token);
|
|
||||||
if ((product != null) && warngenPils.contains(product.getNnnid())
|
|
||||||
&& !MixedCaseProductSupport.isMixedCase(product.getNnnid())) {
|
|
||||||
textEditor.setText(textEditor.getText()
|
|
||||||
.replaceAll(", {0,1}", "..."));
|
|
||||||
}
|
|
||||||
|
|
||||||
markUneditableText(textEditor);
|
markUneditableText(textEditor);
|
||||||
|
|
||||||
// Disable the lockable text listener since the application is no
|
// Disable the lockable text listener since the application is no
|
||||||
|
@ -7109,14 +7153,6 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
||||||
|
|
||||||
textEditor.append(textProduct);
|
textEditor.append(textProduct);
|
||||||
|
|
||||||
// if product is a WarnGen product and is not enabled for mixed case
|
|
||||||
// transmission, replace all commas with ellipses
|
|
||||||
if (warngenPils.contains(product.getNnnid())
|
|
||||||
&& !MixedCaseProductSupport.isMixedCase(product.getNnnid())) {
|
|
||||||
textEditor.setText(textEditor.getText()
|
|
||||||
.replaceAll(", {0,1}", "..."));
|
|
||||||
}
|
|
||||||
|
|
||||||
markUneditableText(textEditor);
|
markUneditableText(textEditor);
|
||||||
|
|
||||||
// Update text display model with the product that was
|
// Update text display model with the product that was
|
||||||
|
@ -8038,7 +8074,10 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
||||||
|
|
||||||
paragraphStart = paragraphStart.toUpperCase();
|
paragraphStart = paragraphStart.toUpperCase();
|
||||||
// is this the locations paragraph?
|
// is this the locations paragraph?
|
||||||
if (paragraphStart.startsWith("* LOCATIONS")) {
|
if (paragraphStart.startsWith("* LOCATIONS")
|
||||||
|
|| paragraphStart.startsWith(("* SOME LOCATIONS"))
|
||||||
|
|| paragraphStart.startsWith(("LOCATIONS IMPACTED"))
|
||||||
|
|| paragraphStart.startsWith(("SOME LOCATIONS THAT"))) {
|
||||||
inLocations = true;
|
inLocations = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8079,7 +8118,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.length() <= charWrapCol) {
|
if (line.length() <= charWrapCol) {
|
||||||
extendShortLine(lineNumber, padding);
|
extendShortLine(lineNumber, padding, inLocations);
|
||||||
if (textEditor.getLine(lineNumber).length() <= charWrapCol) {
|
if (textEditor.getLine(lineNumber).length() <= charWrapCol) {
|
||||||
// extended line is still short enough do not wrap
|
// extended line is still short enough do not wrap
|
||||||
if (lineNumber < endWrapLine) {
|
if (lineNumber < endWrapLine) {
|
||||||
|
@ -8110,8 +8149,9 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
||||||
*
|
*
|
||||||
* @param lineNumber
|
* @param lineNumber
|
||||||
* @param padding
|
* @param padding
|
||||||
|
* @param inLocations
|
||||||
*/
|
*/
|
||||||
private void extendShortLine(int lineNumber, final String padding) {
|
private void extendShortLine(int lineNumber, final String padding, boolean inLocations) {
|
||||||
// if the line is too short move the next line up
|
// if the line is too short move the next line up
|
||||||
// if there is a next line
|
// if there is a next line
|
||||||
String line = textEditor.getLine(lineNumber);
|
String line = textEditor.getLine(lineNumber);
|
||||||
|
@ -8190,10 +8230,12 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
||||||
String wordSpace = "";
|
String wordSpace = "";
|
||||||
if (noSeparatorPattern.matcher(endLine).matches()
|
if (noSeparatorPattern.matcher(endLine).matches()
|
||||||
&& noSeparatorPattern.matcher(startNextLine)
|
&& noSeparatorPattern.matcher(startNextLine)
|
||||||
.matches()) {
|
.matches()
|
||||||
|
&& (!inLocations || !line.endsWith("..."))) {
|
||||||
// Put a space between words when merging the lines.
|
// Put a space between words when merging the lines.
|
||||||
wordSpace = " ";
|
wordSpace = " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
textEditor.replaceTextRange(newlinePosition, deleteLen,
|
textEditor.replaceTextRange(newlinePosition, deleteLen,
|
||||||
wordSpace);
|
wordSpace);
|
||||||
String afterReplace = textEditor.getText();
|
String afterReplace = textEditor.getText();
|
||||||
|
@ -8207,7 +8249,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
||||||
|
|
||||||
// is this line still too short?
|
// is this line still too short?
|
||||||
if (textEditor.getLine(lineNumber).length() <= charWrapCol) {
|
if (textEditor.getLine(lineNumber).length() <= charWrapCol) {
|
||||||
extendShortLine(lineNumber, padding);
|
extendShortLine(lineNumber, padding, inLocations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8460,7 +8502,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
||||||
private void recompileRegex() {
|
private void recompileRegex() {
|
||||||
this.standardWrapRegex = Pattern.compile("( |..).{1,"
|
this.standardWrapRegex = Pattern.compile("( |..).{1,"
|
||||||
+ (charWrapCol - 3) + "}(\\s|-)");
|
+ (charWrapCol - 3) + "}(\\s|-)");
|
||||||
this.locationsFirstRegex = Pattern.compile("^\\* LOCATIONS [^\\.]{1,"
|
this.locationsFirstRegex = Pattern.compile("^(?:\\* (?:SOME )?LOCATIONS|LOCATIONS IMPACTED|SOME LOCATIONS THAT) [^\\.]{1,"
|
||||||
+ (charWrapCol - 13) + "}\\s");
|
+ (charWrapCol - 13) + "}\\s");
|
||||||
this.locationsBodyRegex = Pattern.compile("(( |..).{1,"
|
this.locationsBodyRegex = Pattern.compile("(( |..).{1,"
|
||||||
+ (charWrapCol - 5) + "}\\.\\.\\.)|(( |..).{1,"
|
+ (charWrapCol - 5) + "}\\.\\.\\.)|(( |..).{1,"
|
||||||
|
|
|
@ -1,19 +1,39 @@
|
||||||
package com.raytheon.viz.warnings.rsc;
|
package com.raytheon.viz.warnings.rsc;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
||||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord;
|
import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord;
|
||||||
|
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||||
|
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||||
|
import com.raytheon.uf.common.dataquery.responses.DbQueryResponse;
|
||||||
|
import com.raytheon.uf.viz.core.RecordFactory;
|
||||||
|
import com.raytheon.uf.viz.core.alerts.AbstractAlertMessageParser;
|
||||||
|
import com.raytheon.uf.viz.core.alerts.AlertMessage;
|
||||||
import com.raytheon.uf.viz.core.exception.VizException;
|
import com.raytheon.uf.viz.core.exception.VizException;
|
||||||
|
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||||
|
import com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData;
|
||||||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||||
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------- -------- ----------- --------------------------
|
||||||
|
* Apr 21, 2016 DR 18905 Qinglu Lin Added code to handle no SPS auto-update issue.
|
||||||
|
*
|
||||||
|
*/
|
||||||
@XmlAccessorType(XmlAccessType.NONE)
|
@XmlAccessorType(XmlAccessType.NONE)
|
||||||
public class CWASPSResourceData extends WWAResourceData {
|
public class CWASPSResourceData extends WWAResourceData {
|
||||||
|
|
||||||
|
private static AlertMessageToPDOParserSPS alertParser = new AlertMessageToPDOParserSPS();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
|
@ -34,4 +54,42 @@ public class CWASPSResourceData extends WWAResourceData {
|
||||||
|
|
||||||
return new CWASPSResource(this, loadProperties);
|
return new CWASPSResource(this, loadProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AbstractAlertMessageParser getAlertParser() {
|
||||||
|
return alertParser;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class AlertMessageToPDOParserSPS extends AbstractAlertMessageParser {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object parseAlertMessage(AlertMessage message,
|
||||||
|
AbstractRequestableResourceData reqResourceData) throws VizException {
|
||||||
|
Object objectToSend = null;
|
||||||
|
Map<String, Object> attribs = new HashMap<>(message.decodedAlert);
|
||||||
|
|
||||||
|
if (reqResourceData.isUpdatingOnMetadataOnly()) {
|
||||||
|
PluginDataObject record = RecordFactory.getInstance()
|
||||||
|
.loadRecordFromMap(attribs);
|
||||||
|
objectToSend = record;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* TODO avoid requesting data that will not be used, for example
|
||||||
|
* when time matching won't allow the frame to be displayed.
|
||||||
|
*/
|
||||||
|
attribs.remove(PluginDataObject.DATAURI_ID);
|
||||||
|
DbQueryRequest request = new DbQueryRequest(
|
||||||
|
RequestConstraint.toConstraintMappingExcludeNull(attribs));
|
||||||
|
request.setLimit(1);
|
||||||
|
DbQueryResponse response = (DbQueryResponse) ThriftClient
|
||||||
|
.sendRequest(request);
|
||||||
|
PluginDataObject[] pdos = response
|
||||||
|
.getEntityObjects(PluginDataObject.class);
|
||||||
|
if (pdos.length > 0) {
|
||||||
|
objectToSend = pdos[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return objectToSend;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@ import com.raytheon.uf.common.wmo.WMOTimeParser;
|
||||||
* Jun 19, 2014 3226 bclement added validator callback
|
* Jun 19, 2014 3226 bclement added validator callback
|
||||||
* Jul 07, 2015 4581 skorolev Corrected decodeStrikes to avoid BufferUnderflowException.
|
* Jul 07, 2015 4581 skorolev Corrected decodeStrikes to avoid BufferUnderflowException.
|
||||||
* Apr 07, 2016 DR18763 mgamazaychikov Switched to using LightningWMOHeader.
|
* Apr 07, 2016 DR18763 mgamazaychikov Switched to using LightningWMOHeader.
|
||||||
|
* Apr 21, 2016 DR18849 mgamazaychikov Decrypt all data in decrypt method.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -200,9 +201,19 @@ public class TotalLightningDecoder {
|
||||||
*/
|
*/
|
||||||
private PluginDataObject[] decodeInternal(LightningWMOHeader wmoHdr,
|
private PluginDataObject[] decodeInternal(LightningWMOHeader wmoHdr,
|
||||||
String fileName, byte[] pdata) throws DecoderException {
|
String fileName, byte[] pdata) throws DecoderException {
|
||||||
if (!validFlashPacket(pdata, COMBINATION_PACKET_HEADER_SIZE)) {
|
byte[] pdataPreDecrypt = pdata;
|
||||||
/* assume data is encrypted if we can't understand it */
|
// determine if the data is encrypted or not based on comparing
|
||||||
pdata = decrypt(wmoHdr, fileName, pdata);
|
// checksums for flash packet
|
||||||
|
pdata = decrypt(wmoHdr, fileName, pdata);
|
||||||
|
boolean isDecryptedValid = validFlashPacket(pdata,
|
||||||
|
COMBINATION_PACKET_HEADER_SIZE);
|
||||||
|
boolean isPreDecryptedValid = validFlashPacket(pdataPreDecrypt,
|
||||||
|
COMBINATION_PACKET_HEADER_SIZE);
|
||||||
|
// assume that all data is encrypted, so decrypt it
|
||||||
|
if (!isDecryptedValid && isPreDecryptedValid) {
|
||||||
|
// this means that data is not encrypted, proceed without
|
||||||
|
// decryption
|
||||||
|
pdata = pdataPreDecrypt;
|
||||||
}
|
}
|
||||||
List<LightningStrikePoint> strikes = decodeStrikes(fileName, pdata);
|
List<LightningStrikePoint> strikes = decodeStrikes(fileName, pdata);
|
||||||
if (!strikes.isEmpty()) {
|
if (!strikes.isEmpty()) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue