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:
Nate Jensen 2014-08-06 11:28:02 -05:00
parent e5af41fa86
commit 389ae22829

View file

@ -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.
* This will show the tab as updating in the header and data text controls.
* 07/23/2014 15645 zhao modified checkBasicSyntaxError()
* 08/13/2014 3497 njensen Refactored syntax checking to prevent potential infinite loop
*
* </pre>
*
@ -461,11 +462,6 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
*/
private TafRecord[] tafsInViewer;
/**
* Set to true is Python Syntax checker modified the TAF otherwise false.
*/
private boolean pythonModifiedTAF = false;
private FindReplaceDlg findDlg;
/**
@ -1099,6 +1095,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
Menu fileMenu = new Menu(menuBar);
fileMenuItem.setMenu(fileMenu);
fileMenu.addListener(SWT.Show, new Listener() {
@Override
public void handleEvent(Event event) {
setAltFlagForEditorTafTabComp();
}
@ -1210,6 +1207,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
Menu optionsMenu = new Menu(menuBar);
optionsMenuItem.setMenu(optionsMenu);
optionsMenu.addListener(SWT.Show, new Listener() {
@Override
public void handleEvent(Event event) {
setAltFlagForEditorTafTabComp();
}
@ -1245,31 +1243,16 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
autoPrintMI.setText("A&uto Print");
autoPrintMI.setSelection(configMgr
.getResourceAsBoolean(ResourceTag.AutoPrint));
autoPrintMI.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
}
});
// Update Times on Format menu item
updateTimesFormatMI = new MenuItem(optionsMenu, SWT.CHECK);
updateTimesFormatMI.setText("U&pdate Times on Format");
updateTimesFormatMI.setSelection(configMgr
.getResourceAsBoolean(ResourceTag.UpdateTimes));
updateTimesFormatMI.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
}
});
// Send Collective menu item
sendCollectMI = new MenuItem(optionsMenu, SWT.CHECK);
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);
editMenuItem.setMenu(editMenu);
editMenu.addListener(SWT.Show, new Listener() {
@Override
public void handleEvent(Event event) {
setAltFlagForEditorTafTabComp();
}
@ -1397,6 +1381,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
Menu helpMenu = new Menu(menuBar);
helpMenuItem.setMenu(helpMenu);
helpMenu.addListener(SWT.Show, new Listener() {
@Override
public void handleEvent(Event event) {
setAltFlagForEditorTafTabComp();
}
@ -2093,12 +2078,6 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
wrapChk = new Button(controlsComp, SWT.CHECK);
wrapChk.setText("Wrap");
configMgr.setDefaultFontAndColors(wrapChk);
wrapChk.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
}
});
String wrapStr = configMgr.getDataAsString(ResourceTag.Wrap);
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
*/
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();
st = editorTafTabComp.getTextEditorControl();
final Map<StyleRange, String> syntaxMap = new HashMap<StyleRange, String>();
ArrayList<String> tafList = new ArrayList<String>();
st.addMouseTrackListener(new MouseTrackAdapter() {
@Override
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>();
/*
* 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) {
int idx2 = in.indexOf("TAF", idx1 + 1);
boolean errInTaf = false;
String taf;
sMap.clear();
tList.clear();
@ -2966,52 +2982,35 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
} else {
taf = in.substring(idx1);
}
currentLineNo = st.getLineAtOffset(idx1);
errInTaf = checkSyntaxUsingPython(taf, currentLineNo, sMap, tList,
doLogMessage);
if (pythonModifiedTAF == false) {
// TAF not changed prepare to check next taf.
tafList.add(tList.get(0));
if (errInTaf) {
int currentLineNo = st.getLineAtOffset(idx1);
errorInTaf |= checkSyntaxUsingPython(taf, currentLineNo, sMap,
tList, doLogMessage);
for (StyleRange skey : sMap.keySet()) {
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.
String tafAfterCheck = tList.get(0);
checkedTafs.add(tafAfterCheck);
StringBuilder sb = new StringBuilder();
for (String tempTaf : tafList) {
sb.append(tempTaf);
for (String checkedTaf : checkedTafs) {
sb.append(checkedTaf);
sb.append("\n");
}
sb.append(tList.get(0));
sb.append("\n");
int lengthChecked = sb.length();
if (idx2 > -1) {
sb.append(in.substring(idx2));
}
in = sb.toString();
st.setText(in);
}
}
StringBuilder sb = new StringBuilder();
for (String taf : tafList) {
sb.append(taf);
sb.append("\n");
}
st.setText(sb.toString());
st.setStyleRange(null);
Set<StyleRange> srs = syntaxMap.keySet();
for (StyleRange sr : srs) {
st.setStyleRange(sr);
/*
* 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
* that occurs if tafAfterCheck comes back with two TAFS inside it.
*/
idx1 = in.indexOf("TAF", lengthChecked);
}
return errorInTaf;
@ -3036,32 +3035,19 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
*/
@SuppressWarnings("unchecked")
private boolean checkSyntaxUsingPython(String in, int currentLineNo,
Map<StyleRange, String> syntaxMap, ArrayList<String> tafList,
Map<StyleRange, String> syntaxMap, List<String> tafList,
boolean doLogMessage) {
// TODO remove
getSitesInTaf(in);
// Declare variables for processing the editor's contents.
boolean errorInTaf = false;
int[] range = new int[] { 0, 0, 0, 0 };
pythonModifiedTAF = false;
// Assume editorTafTabComp is for the active tab.
st = editorTafTabComp.getTextEditorControl();
HashMap<String, Object> resultMap = parseText(in,
editorTafTabComp.getBBB());
HashMap<String, Object> parsedText = (HashMap<String, Object>) resultMap
.get("result");
in = in.trim();
Map<String, Object> resultMap = parseText(in, editorTafTabComp.getBBB());
String newText = (String) resultMap.get("text");
Map<String, Object> parsedText = (Map<String, Object>) resultMap
.get("result");
String newTime = (String) resultMap.get("headerTime");
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);
java.util.List<String> results;
StringBuilder errorMsg = new StringBuilder();
@ -3327,7 +3313,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
* @return -- the decoded TAF
*/
@SuppressWarnings("unchecked")
private HashMap<String, Object> parseText(String text, String bbb) {
private Map<String, Object> parseText(String text, String bbb) {
IPathManager pm = PathManagerFactory.getPathManager();
@ -3339,10 +3325,8 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
File baseDir = pm.getFile(baseContext, "aviation"
+ IPathManager.SEPARATOR + "python");
HashMap<String, Object> resultMap = null;
HashMap<String, Object> map = new HashMap<String, Object>();
Map<String, Object> resultMap = null;
Map<String, Object> argMap = new HashMap<String, Object>();
try {
if (parsePythonScript == null) {
parsePythonScript = new PythonScript(baseFile.getPath(),
@ -3351,13 +3335,13 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
TafViewerEditorDlg.class.getClassLoader());
}
parsePythonScript.instantiatePythonClass("parser", "Decoder", null);
map.put("text", text);
map.put("bbb", bbb);
argMap.put("text", text);
argMap.put("bbb", bbb);
Object com = parsePythonScript.execute("parseFromJava", "parser",
map);
resultMap = (HashMap<String, Object>) com;
argMap);
resultMap = (Map<String, Object>) com;
} catch (JepException e) {
e.printStackTrace();
statusHandler.error("Error parsing TAF", e);
}
return resultMap;
}
@ -4423,6 +4407,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
*
* @see com.raytheon.viz.aviation.editor.ITafSettable#getViewerTabList()
*/
@Override
public List<ViewerTab> getViewerTabList() {
return modelsTabs;
}