Issue #3497 refactored syntax check to prevent infinite loop possibility
and apply some sanity Change-Id: I8118a99729c75fc756313db13654f34087a1e648 Former-commit-id: b080e8ef12dc3223b1676b97bc153f9422657514
This commit is contained in:
parent
e5af41fa86
commit
389ae22829
1 changed files with 92 additions and 107 deletions
|
@ -236,6 +236,7 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
|
||||||
* 09Apr2014 #3005 lvenable Added calls to mark the tabs as not current when the tabs are changed.
|
* 09Apr2014 #3005 lvenable Added calls to mark the tabs as not current when the tabs are changed.
|
||||||
* This will show the tab as updating in the header and data text controls.
|
* This will show the tab as updating in the header and data text controls.
|
||||||
* 07/23/2014 15645 zhao modified checkBasicSyntaxError()
|
* 07/23/2014 15645 zhao modified checkBasicSyntaxError()
|
||||||
|
* 08/13/2014 3497 njensen Refactored syntax checking to prevent potential infinite loop
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -461,11 +462,6 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
*/
|
*/
|
||||||
private TafRecord[] tafsInViewer;
|
private TafRecord[] tafsInViewer;
|
||||||
|
|
||||||
/**
|
|
||||||
* Set to true is Python Syntax checker modified the TAF otherwise false.
|
|
||||||
*/
|
|
||||||
private boolean pythonModifiedTAF = false;
|
|
||||||
|
|
||||||
private FindReplaceDlg findDlg;
|
private FindReplaceDlg findDlg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1099,6 +1095,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
Menu fileMenu = new Menu(menuBar);
|
Menu fileMenu = new Menu(menuBar);
|
||||||
fileMenuItem.setMenu(fileMenu);
|
fileMenuItem.setMenu(fileMenu);
|
||||||
fileMenu.addListener(SWT.Show, new Listener() {
|
fileMenu.addListener(SWT.Show, new Listener() {
|
||||||
|
@Override
|
||||||
public void handleEvent(Event event) {
|
public void handleEvent(Event event) {
|
||||||
setAltFlagForEditorTafTabComp();
|
setAltFlagForEditorTafTabComp();
|
||||||
}
|
}
|
||||||
|
@ -1210,6 +1207,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
Menu optionsMenu = new Menu(menuBar);
|
Menu optionsMenu = new Menu(menuBar);
|
||||||
optionsMenuItem.setMenu(optionsMenu);
|
optionsMenuItem.setMenu(optionsMenu);
|
||||||
optionsMenu.addListener(SWT.Show, new Listener() {
|
optionsMenu.addListener(SWT.Show, new Listener() {
|
||||||
|
@Override
|
||||||
public void handleEvent(Event event) {
|
public void handleEvent(Event event) {
|
||||||
setAltFlagForEditorTafTabComp();
|
setAltFlagForEditorTafTabComp();
|
||||||
}
|
}
|
||||||
|
@ -1245,31 +1243,16 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
autoPrintMI.setText("A&uto Print");
|
autoPrintMI.setText("A&uto Print");
|
||||||
autoPrintMI.setSelection(configMgr
|
autoPrintMI.setSelection(configMgr
|
||||||
.getResourceAsBoolean(ResourceTag.AutoPrint));
|
.getResourceAsBoolean(ResourceTag.AutoPrint));
|
||||||
autoPrintMI.addSelectionListener(new SelectionAdapter() {
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent event) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update Times on Format menu item
|
// Update Times on Format menu item
|
||||||
updateTimesFormatMI = new MenuItem(optionsMenu, SWT.CHECK);
|
updateTimesFormatMI = new MenuItem(optionsMenu, SWT.CHECK);
|
||||||
updateTimesFormatMI.setText("U&pdate Times on Format");
|
updateTimesFormatMI.setText("U&pdate Times on Format");
|
||||||
updateTimesFormatMI.setSelection(configMgr
|
updateTimesFormatMI.setSelection(configMgr
|
||||||
.getResourceAsBoolean(ResourceTag.UpdateTimes));
|
.getResourceAsBoolean(ResourceTag.UpdateTimes));
|
||||||
updateTimesFormatMI.addSelectionListener(new SelectionAdapter() {
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent event) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Send Collective menu item
|
// Send Collective menu item
|
||||||
sendCollectMI = new MenuItem(optionsMenu, SWT.CHECK);
|
sendCollectMI = new MenuItem(optionsMenu, SWT.CHECK);
|
||||||
sendCollectMI.setText("&Send in Collective");
|
sendCollectMI.setText("&Send in Collective");
|
||||||
sendCollectMI.addSelectionListener(new SelectionAdapter() {
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent event) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1289,6 +1272,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
Menu editMenu = new Menu(menuBar);
|
Menu editMenu = new Menu(menuBar);
|
||||||
editMenuItem.setMenu(editMenu);
|
editMenuItem.setMenu(editMenu);
|
||||||
editMenu.addListener(SWT.Show, new Listener() {
|
editMenu.addListener(SWT.Show, new Listener() {
|
||||||
|
@Override
|
||||||
public void handleEvent(Event event) {
|
public void handleEvent(Event event) {
|
||||||
setAltFlagForEditorTafTabComp();
|
setAltFlagForEditorTafTabComp();
|
||||||
}
|
}
|
||||||
|
@ -1397,6 +1381,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
Menu helpMenu = new Menu(menuBar);
|
Menu helpMenu = new Menu(menuBar);
|
||||||
helpMenuItem.setMenu(helpMenu);
|
helpMenuItem.setMenu(helpMenu);
|
||||||
helpMenu.addListener(SWT.Show, new Listener() {
|
helpMenu.addListener(SWT.Show, new Listener() {
|
||||||
|
@Override
|
||||||
public void handleEvent(Event event) {
|
public void handleEvent(Event event) {
|
||||||
setAltFlagForEditorTafTabComp();
|
setAltFlagForEditorTafTabComp();
|
||||||
}
|
}
|
||||||
|
@ -2093,12 +2078,6 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
wrapChk = new Button(controlsComp, SWT.CHECK);
|
wrapChk = new Button(controlsComp, SWT.CHECK);
|
||||||
wrapChk.setText("Wrap");
|
wrapChk.setText("Wrap");
|
||||||
configMgr.setDefaultFontAndColors(wrapChk);
|
configMgr.setDefaultFontAndColors(wrapChk);
|
||||||
wrapChk.addSelectionListener(new SelectionAdapter() {
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent event) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
String wrapStr = configMgr.getDataAsString(ResourceTag.Wrap);
|
String wrapStr = configMgr.getDataAsString(ResourceTag.Wrap);
|
||||||
|
|
||||||
if (wrapStr.compareTo("word") == 0) {
|
if (wrapStr.compareTo("word") == 0) {
|
||||||
|
@ -2909,20 +2888,10 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
* @return errorInTaf true when syntax error found otherwise false
|
* @return errorInTaf true when syntax error found otherwise false
|
||||||
*/
|
*/
|
||||||
private boolean checkSyntaxInEditor(boolean doLogMessage) {
|
private boolean checkSyntaxInEditor(boolean doLogMessage) {
|
||||||
// Get the content of the Taf Editor.
|
|
||||||
// Assume editorTafTabComp is for the active tab.
|
|
||||||
// DR15477: trim blank lines before Syntax Checking
|
|
||||||
String in = (editorTafTabComp.getTextEditorControl().getText().trim());
|
|
||||||
// Declare variables for processing the editor's contents.
|
|
||||||
boolean errorInTaf = false;
|
|
||||||
int idx1 = 0;
|
|
||||||
int currentLineNo = 0;
|
|
||||||
|
|
||||||
clearSyntaxErrorLevel();
|
clearSyntaxErrorLevel();
|
||||||
st = editorTafTabComp.getTextEditorControl();
|
st = editorTafTabComp.getTextEditorControl();
|
||||||
|
|
||||||
final Map<StyleRange, String> syntaxMap = new HashMap<StyleRange, String>();
|
final Map<StyleRange, String> syntaxMap = new HashMap<StyleRange, String>();
|
||||||
ArrayList<String> tafList = new ArrayList<String>();
|
|
||||||
st.addMouseTrackListener(new MouseTrackAdapter() {
|
st.addMouseTrackListener(new MouseTrackAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void mouseHover(MouseEvent e) {
|
public void mouseHover(MouseEvent e) {
|
||||||
|
@ -2952,12 +2921,59 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ArrayList<String> tList = new ArrayList<String>();
|
// Get the content of the Taf Editor.
|
||||||
|
// Assume editorTafTabComp is for the active tab.
|
||||||
|
// DR15477: trim blank lines before Syntax Checking
|
||||||
|
String in = (editorTafTabComp.getTextEditorControl().getText().trim());
|
||||||
|
checkSyntax(in, syntaxMap, doLogMessage);
|
||||||
|
// reset everything since checkSyntax may have altered the TAF
|
||||||
|
st.setStyleRange(null);
|
||||||
|
syntaxMap.clear();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO Refactor all of this to be smarter. Right now it's kind of dumb
|
||||||
|
* in that the python syntax check can potentially alter the datetime of
|
||||||
|
* the TAF and/or the whitespace/spacing of the TAF. If that occurs, the
|
||||||
|
* python does NOT return the map of syntax problems detected, so you
|
||||||
|
* have to run the syntax check again against the properly formatted
|
||||||
|
* TAF.
|
||||||
|
*
|
||||||
|
* Due to the way the code is currently structured, there's not an easy
|
||||||
|
* way to cleanly do the second syntax check only if necessary while
|
||||||
|
* keeping the style ranges correctly lined up. Therefore, for now we
|
||||||
|
* will run the syntax check once against the TAF(s) (ie the code
|
||||||
|
* above), and just presume that it altered the TAF's datetime or
|
||||||
|
* whitespace. Then we will run it a second time (ie the code below)
|
||||||
|
* since it should be guaranteed at that point to return a syntax map if
|
||||||
|
* there were any syntax issues detected.
|
||||||
|
*/
|
||||||
|
in = editorTafTabComp.getTextEditorControl().getText().trim();
|
||||||
|
boolean errorInTaf = checkSyntax(in, syntaxMap, doLogMessage);
|
||||||
|
st.setStyleRange(null);
|
||||||
|
Set<StyleRange> srs = syntaxMap.keySet();
|
||||||
|
for (StyleRange sr : srs) {
|
||||||
|
st.setStyleRange(sr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return errorInTaf;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkSyntax(String in, Map<StyleRange, String> syntaxMap,
|
||||||
|
boolean doLogMessage) {
|
||||||
|
boolean errorInTaf = false;
|
||||||
|
List<String> checkedTafs = new ArrayList<String>();
|
||||||
|
List<String> tList = new ArrayList<String>();
|
||||||
Map<StyleRange, String> sMap = new HashMap<StyleRange, String>();
|
Map<StyleRange, String> sMap = new HashMap<StyleRange, String>();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Separate each TAF individually and syntax check it, and then
|
||||||
|
* reassemble the set of TAFs each iteration to ensure the line numbers
|
||||||
|
* and style range indices will line up correctly.
|
||||||
|
*/
|
||||||
|
int idx1 = 0;
|
||||||
while (idx1 > -1) {
|
while (idx1 > -1) {
|
||||||
int idx2 = in.indexOf("TAF", idx1 + 1);
|
int idx2 = in.indexOf("TAF", idx1 + 1);
|
||||||
boolean errInTaf = false;
|
|
||||||
String taf;
|
String taf;
|
||||||
sMap.clear();
|
sMap.clear();
|
||||||
tList.clear();
|
tList.clear();
|
||||||
|
@ -2966,52 +2982,35 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
} else {
|
} else {
|
||||||
taf = in.substring(idx1);
|
taf = in.substring(idx1);
|
||||||
}
|
}
|
||||||
currentLineNo = st.getLineAtOffset(idx1);
|
|
||||||
errInTaf = checkSyntaxUsingPython(taf, currentLineNo, sMap, tList,
|
|
||||||
doLogMessage);
|
|
||||||
|
|
||||||
if (pythonModifiedTAF == false) {
|
int currentLineNo = st.getLineAtOffset(idx1);
|
||||||
// TAF not changed prepare to check next taf.
|
errorInTaf |= checkSyntaxUsingPython(taf, currentLineNo, sMap,
|
||||||
tafList.add(tList.get(0));
|
tList, doLogMessage);
|
||||||
if (errInTaf) {
|
for (StyleRange skey : sMap.keySet()) {
|
||||||
for (StyleRange skey : sMap.keySet()) {
|
syntaxMap.put(skey, sMap.get(skey));
|
||||||
syntaxMap.put(skey, sMap.get(skey));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
errorInTaf |= errInTaf;
|
|
||||||
idx1 = idx2;
|
|
||||||
} else {
|
|
||||||
// Python modified the TAF. Assume self correction.
|
|
||||||
// Ignore errors and set up to check the corrected taf.
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (String tempTaf : tafList) {
|
|
||||||
sb.append(tempTaf);
|
|
||||||
sb.append("\n");
|
|
||||||
}
|
|
||||||
sb.append(tList.get(0));
|
|
||||||
sb.append("\n");
|
|
||||||
if (idx2 > -1) {
|
|
||||||
sb.append(in.substring(idx2));
|
|
||||||
}
|
|
||||||
in = sb.toString();
|
|
||||||
st.setText(in);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
String tafAfterCheck = tList.get(0);
|
||||||
|
checkedTafs.add(tafAfterCheck);
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (String checkedTaf : checkedTafs) {
|
||||||
|
sb.append(checkedTaf);
|
||||||
|
sb.append("\n");
|
||||||
|
}
|
||||||
|
int lengthChecked = sb.length();
|
||||||
|
|
||||||
for (String taf : tafList) {
|
if (idx2 > -1) {
|
||||||
sb.append(taf);
|
sb.append(in.substring(idx2));
|
||||||
sb.append("\n");
|
}
|
||||||
}
|
in = sb.toString();
|
||||||
|
st.setText(in);
|
||||||
|
|
||||||
st.setText(sb.toString());
|
/*
|
||||||
st.setStyleRange(null);
|
* Set idx1 to the next TAF after all the text that has already been
|
||||||
|
* checked. This ensures we won't hit the very rare infinite loop
|
||||||
Set<StyleRange> srs = syntaxMap.keySet();
|
* that occurs if tafAfterCheck comes back with two TAFS inside it.
|
||||||
|
*/
|
||||||
for (StyleRange sr : srs) {
|
idx1 = in.indexOf("TAF", lengthChecked);
|
||||||
st.setStyleRange(sr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return errorInTaf;
|
return errorInTaf;
|
||||||
|
@ -3036,32 +3035,19 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private boolean checkSyntaxUsingPython(String in, int currentLineNo,
|
private boolean checkSyntaxUsingPython(String in, int currentLineNo,
|
||||||
Map<StyleRange, String> syntaxMap, ArrayList<String> tafList,
|
Map<StyleRange, String> syntaxMap, List<String> tafList,
|
||||||
boolean doLogMessage) {
|
boolean doLogMessage) {
|
||||||
// TODO remove
|
|
||||||
getSitesInTaf(in);
|
|
||||||
// Declare variables for processing the editor's contents.
|
|
||||||
boolean errorInTaf = false;
|
boolean errorInTaf = false;
|
||||||
int[] range = new int[] { 0, 0, 0, 0 };
|
int[] range = new int[] { 0, 0, 0, 0 };
|
||||||
pythonModifiedTAF = false;
|
|
||||||
|
|
||||||
// Assume editorTafTabComp is for the active tab.
|
in = in.trim();
|
||||||
st = editorTafTabComp.getTextEditorControl();
|
Map<String, Object> resultMap = parseText(in, editorTafTabComp.getBBB());
|
||||||
HashMap<String, Object> resultMap = parseText(in,
|
|
||||||
editorTafTabComp.getBBB());
|
|
||||||
HashMap<String, Object> parsedText = (HashMap<String, Object>) resultMap
|
|
||||||
.get("result");
|
|
||||||
String newText = (String) resultMap.get("text");
|
String newText = (String) resultMap.get("text");
|
||||||
|
Map<String, Object> parsedText = (Map<String, Object>) resultMap
|
||||||
|
.get("result");
|
||||||
String newTime = (String) resultMap.get("headerTime");
|
String newTime = (String) resultMap.get("headerTime");
|
||||||
tafList.add(newText);
|
tafList.add(newText);
|
||||||
|
|
||||||
// Python may change the TAF let the caller handle it prior to setting
|
|
||||||
// up any error information.
|
|
||||||
if (in.trim().equals(newText.trim()) == false) {
|
|
||||||
pythonModifiedTAF = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
editorTafTabComp.setLargeTF(newTime);
|
editorTafTabComp.setLargeTF(newTime);
|
||||||
java.util.List<String> results;
|
java.util.List<String> results;
|
||||||
StringBuilder errorMsg = new StringBuilder();
|
StringBuilder errorMsg = new StringBuilder();
|
||||||
|
@ -3327,7 +3313,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
* @return -- the decoded TAF
|
* @return -- the decoded TAF
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private HashMap<String, Object> parseText(String text, String bbb) {
|
private Map<String, Object> parseText(String text, String bbb) {
|
||||||
|
|
||||||
IPathManager pm = PathManagerFactory.getPathManager();
|
IPathManager pm = PathManagerFactory.getPathManager();
|
||||||
|
|
||||||
|
@ -3339,10 +3325,8 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
File baseDir = pm.getFile(baseContext, "aviation"
|
File baseDir = pm.getFile(baseContext, "aviation"
|
||||||
+ IPathManager.SEPARATOR + "python");
|
+ IPathManager.SEPARATOR + "python");
|
||||||
|
|
||||||
HashMap<String, Object> resultMap = null;
|
Map<String, Object> resultMap = null;
|
||||||
|
Map<String, Object> argMap = new HashMap<String, Object>();
|
||||||
HashMap<String, Object> map = new HashMap<String, Object>();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (parsePythonScript == null) {
|
if (parsePythonScript == null) {
|
||||||
parsePythonScript = new PythonScript(baseFile.getPath(),
|
parsePythonScript = new PythonScript(baseFile.getPath(),
|
||||||
|
@ -3351,13 +3335,13 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
TafViewerEditorDlg.class.getClassLoader());
|
TafViewerEditorDlg.class.getClassLoader());
|
||||||
}
|
}
|
||||||
parsePythonScript.instantiatePythonClass("parser", "Decoder", null);
|
parsePythonScript.instantiatePythonClass("parser", "Decoder", null);
|
||||||
map.put("text", text);
|
argMap.put("text", text);
|
||||||
map.put("bbb", bbb);
|
argMap.put("bbb", bbb);
|
||||||
Object com = parsePythonScript.execute("parseFromJava", "parser",
|
Object com = parsePythonScript.execute("parseFromJava", "parser",
|
||||||
map);
|
argMap);
|
||||||
resultMap = (HashMap<String, Object>) com;
|
resultMap = (Map<String, Object>) com;
|
||||||
} catch (JepException e) {
|
} catch (JepException e) {
|
||||||
e.printStackTrace();
|
statusHandler.error("Error parsing TAF", e);
|
||||||
}
|
}
|
||||||
return resultMap;
|
return resultMap;
|
||||||
}
|
}
|
||||||
|
@ -4423,6 +4407,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
*
|
*
|
||||||
* @see com.raytheon.viz.aviation.editor.ITafSettable#getViewerTabList()
|
* @see com.raytheon.viz.aviation.editor.ITafSettable#getViewerTabList()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public List<ViewerTab> getViewerTabList() {
|
public List<ViewerTab> getViewerTabList() {
|
||||||
return modelsTabs;
|
return modelsTabs;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue