TSK-318 Hide special chars escaping from user in List search

- moved escaping logic to be entirely done later at query time
- added column in gui for regex boolean, and column header
- added attribute to XML to store whether regex or not
This commit is contained in:
adam-m 2012-01-19 15:53:27 -05:00
parent e45946e506
commit 91bdf52fe1
3 changed files with 107 additions and 79 deletions

View File

@ -288,6 +288,9 @@
<Property name="autoResizeMode" type="int" value="0"/>
<Property name="showHorizontalLines" type="boolean" value="false"/>
<Property name="showVerticalLines" type="boolean" value="false"/>
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
<TableHeader reorderingAllowed="false" resizingAllowed="true"/>
</Property>
</Properties>
</Component>
</SubComponents>

View File

@ -94,8 +94,8 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
deleteWordButton.setToolTipText("Remove selected keyword(s) from the list");
deleteAllWordsButton.setToolTipText("Remove all keywords from the list (clear it)");
keywordTable.setAutoscrolls(true);
keywordTable.setTableHeader(null);
//keywordTable.setAutoscrolls(true);
//keywordTable.setTableHeader(null);
keywordTable.setShowHorizontalLines(false);
keywordTable.setShowVerticalLines(false);
@ -105,14 +105,15 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
keywordTable.setSize(260, 200);
final int width = keywordTable.getSize().width;
TableColumn column = null;
for (int i = 0; i < 2; i++) {
for (int i = 0; i < 3; i++) {
column = keywordTable.getColumnModel().getColumn(i);
if (i == 1) {
column.setPreferredWidth(((int) (width * 0.2)));
if (i > 0) {
column.setPreferredWidth(((int) (width * 0.15)));
//column.setCellRenderer(new CellTooltipRenderer());
} else {
}
else {
column.setCellRenderer(new CellTooltipRenderer());
column.setPreferredWidth(((int) (width * 0.75)));
column.setPreferredWidth(((int) (width * 0.68)));
}
}
keywordTable.setCellSelectionEnabled(false);
@ -166,18 +167,19 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
//some hardcoded keywords for testing
//phone number
tableModel.addKeyword("\\d\\d\\d[\\.-]\\d\\d\\d[\\.-]\\d\\d\\d\\d");
tableModel.addKeyword("\\d{8,10}");
tableModel.addKeyword("phone|fax");
tableModel.addKeyword("\\d\\d\\d[\\.-]\\d\\d\\d[\\.-]\\d\\d\\d\\d", false);
tableModel.addKeyword("\\d{8,10}", false);
tableModel.addKeyword("phone|fax", false);
//IP address
tableModel.addKeyword("(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])");
tableModel.addKeyword("(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])", false);
//email
tableModel.addKeyword("[e\\-]{0,2}mail");
tableModel.addKeyword("[A-Z0-9._%-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}");
tableModel.addKeyword("[e\\-]{0,2}mail", false);
tableModel.addKeyword("[A-Z0-9._%-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}", false);
//URL
tableModel.addKeyword("ftp|sftp|ssh|http|https|www");
tableModel.addKeyword("ftp|sftp|ssh|http|https|www", false);
//escaped literal word \d\d\d
tableModel.addKeyword("\\Q\\d\\d\\d\\E");
tableModel.addKeyword("\\Q\\d\\d\\d\\E", false);
tableModel.addKeyword("\\d\\d\\d\\d", true);
}
/** This method is called from within the constructor to
@ -212,7 +214,7 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
org.openide.awt.Mnemonics.setLocalizedText(filesIndexedValLabel, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.filesIndexedValLabel.text")); // NOI18N
titleLabel.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
titleLabel.setFont(new java.awt.Font("Tahoma", 0, 12));
org.openide.awt.Mnemonics.setLocalizedText(titleLabel, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.titleLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(loadListButton, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.loadListButton.text")); // NOI18N
@ -276,6 +278,7 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
keywordTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
keywordTable.setShowHorizontalLines(false);
keywordTable.setShowVerticalLines(false);
keywordTable.getTableHeader().setReorderingAllowed(false);
jScrollPane1.setViewportView(keywordTable);
org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(KeywordSearchListTopComponent.class, "KeywordSearchListTopComponent.searchButton.text")); // NOI18N
@ -358,7 +361,7 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
.addGap(11, 11, 11)
.addComponent(curListNameLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(curListValLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 222, Short.MAX_VALUE)))
.addComponent(curListValLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 296, Short.MAX_VALUE)))
.addGap(22, 22, 22))
.addGroup(layout.createSequentialGroup()
.addComponent(filesIndexedNameLabel)
@ -395,26 +398,20 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
private void addWordButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addWordButtonActionPerformed
String newWord = addWordField.getText().trim();
String newWordEscaped = Pattern.quote(newWord);
boolean isLiteral = !chRegex.isSelected();
if (newWord.equals("")) {
return;
} else if (keywordExists(newWord) || keywordExists(newWordEscaped)) {
} else if (keywordExists(newWord, isLiteral)) {
KeywordSearchUtil.displayDialog("New Keyword Entry", "Keyword already exists in the list.", KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
return;
}
String toAdd = null;
if (!chRegex.isSelected()) {
toAdd = newWordEscaped;
} else {
toAdd = newWord;
}
//check if valid
boolean valid = true;
try {
Pattern.compile(toAdd);
Pattern.compile(newWord);
} catch (PatternSyntaxException ex1) {
valid = false;
} catch (IllegalArgumentException ex2) {
@ -426,8 +423,8 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
}
//add & reset checkbox
tableModel.addKeyword(newWord, isLiteral);
chRegex.setSelected(false);
tableModel.addKeyword(toAdd);
addWordField.setText("");
if (deleteWordButton.isEnabled() == false) {
@ -448,7 +445,7 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
final String FEATURE_NAME = "Save Keyword List";
KeywordSearchListsXML writer = KeywordSearchListsXML.getCurrent();
List<String> keywords = tableModel.getAllKeywords();
Map<String,Boolean> keywords = tableModel.getAllKeywords();
if (keywords.isEmpty()) {
KeywordSearchUtil.displayDialog(FEATURE_NAME, "Keyword List is empty and cannot be saved", KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
return;
@ -718,19 +715,7 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
@Override
public Map<String, Boolean> getQueryList() {
List<String> selected = getAllKeywords();
//filter out blank just in case
Map<String, Boolean> ret = new LinkedHashMap<String, Boolean>();
for (String s : selected) {
if (!s.trim().equals("")) {
//use false for isLiteral because we are currently escaping
//the keyword earlier as it is stored
//might need to change and pass isLiteral
//if the query object needs to treat it specially
ret.put(s, false);
}
}
return ret;
return getAllKeywords();
}
@Override
@ -753,17 +738,16 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
}
}
public List<String> getAllKeywords() {
public Map<String,Boolean> getAllKeywords() {
return tableModel.getAllKeywords();
}
public List<String> getSelectedKeywords() {
public Map<String,Boolean> getSelectedKeywords() {
return tableModel.getSelectedKeywords();
}
private boolean keywordExists(String keyword) {
return tableModel.keywordExists(keyword);
private boolean keywordExists(String keyword, boolean isLiteral) {
return tableModel.keywordExists(keyword, isLiteral);
}
private class KeywordTableModel extends AbstractTableModel {
@ -773,7 +757,7 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
@Override
public int getColumnCount() {
return 2;
return 3;
}
@Override
@ -781,6 +765,29 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
return keywordData.size();
}
@Override
public String getColumnName(int column) {
String colName = null;
switch (column) {
case 0:
colName = "Keyword";
break;
case 1:
colName = "RegEx.";
break;
case 2:
colName = "Sel.";
break;
default:
;
}
return colName;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Object ret = null;
@ -795,6 +802,9 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
ret = (Object) entry.keyword;
break;
case 1:
ret = (Object) !entry.isLiteral;
break;
case 2:
ret = (Object) entry.isActive;
break;
default:
@ -806,12 +816,12 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex == 1 ? true : false;
return columnIndex == 2 ? true : false;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (columnIndex == 1) {
if (columnIndex == 2) {
TableEntry entry = null;
//iterate until row
Iterator<TableEntry> it = keywordData.iterator();
@ -832,40 +842,41 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
return getValueAt(0, c).getClass();
}
List<String> getAllKeywords() {
List<String> ret = new ArrayList<String>();
Map<String,Boolean> getAllKeywords() {
Map<String,Boolean> ret = new LinkedHashMap<String,Boolean>();
for (TableEntry e : keywordData) {
ret.add(e.keyword);
ret.put(e.keyword, e.isLiteral);
}
return ret;
}
List<String> getSelectedKeywords() {
List<String> ret = new ArrayList<String>();
Map<String,Boolean> getSelectedKeywords() {
Map<String,Boolean> ret = new LinkedHashMap<String,Boolean>();
for (TableEntry e : keywordData) {
if (e.isActive && !e.keyword.equals("")) {
ret.add(e.keyword);
ret.put(e.keyword, e.isLiteral);
}
}
return ret;
}
boolean keywordExists(String keyword) {
List<String> all = getAllKeywords();
return all.contains(keyword);
boolean keywordExists(String keyword, boolean isLiteral) {
Map<String,Boolean> all = getAllKeywords();
return all.containsKey(keyword) && all.get(keyword) == isLiteral;
}
void addKeyword(String keyword) {
if (!keywordExists(keyword)) {
keywordData.add(new TableEntry(keyword));
void addKeyword(String keyword, boolean isLiteral) {
if (!keywordExists(keyword, isLiteral)) {
keywordData.add(new TableEntry(keyword, isLiteral));
}
fireTableDataChanged();
}
void addKeywords(List<String> keywords) {
for (String keyword : keywords) {
if (!keywordExists(keyword)) {
keywordData.add(new TableEntry(keyword));
void addKeywords(Map<String,Boolean> keywords) {
for (String keyword : keywords.keySet()) {
boolean isLiteral = keywords.get(keyword);
if (!keywordExists(keyword, isLiteral)) {
keywordData.add(new TableEntry(keyword, isLiteral));
}
}
fireTableDataChanged();
@ -874,7 +885,7 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
void resync(String listName) {
KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent();
KeywordSearchList list = loader.getList(listName);
List<String> keywords = list.getKeywords();
Map<String,Boolean> keywords = list.getKeywords();
deleteAll();
addKeywords(keywords);
@ -903,22 +914,31 @@ public final class KeywordSearchListTopComponent extends TopComponent implements
class TableEntry implements Comparable {
String keyword;
Boolean isLiteral;
Boolean isActive;
TableEntry(String keyword, Boolean isActive) {
TableEntry(String keyword, Boolean isLiteral, Boolean isActive) {
this.keyword = keyword;
this.isLiteral = isLiteral;
this.isActive = isActive;
}
TableEntry(String keyword) {
TableEntry(String keyword, Boolean isLiteral) {
this.keyword = keyword;
this.isLiteral = isLiteral;
this.isActive = false;
}
@Override
@Override
public int compareTo(Object o) {
return this.keyword.compareTo(((TableEntry) o).keyword);
int keywords = this.keyword.compareTo(((TableEntry) o).keyword);
if (keywords != 0)
return keywords;
else return this.isLiteral.compareTo(((TableEntry) o).isLiteral);
}
}
}

View File

@ -66,6 +66,7 @@ public class KeywordSearchListsXML {
private static final String LIST_CREATE_ATTR = "created";
private static final String LIST_MOD_ATTR = "modified";
private static final String KEYWORD_EL = "keyword";
private static final String KEYWORD_LITERAL_ATTR = "literal";
private static final String CUR_LISTS_FILE_NAME = "keywords.xml";
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static final String ENCODING = "UTF-8";
@ -182,7 +183,7 @@ public class KeywordSearchListsXML {
* @param newList list of keywords
* @return true if old list was replaced
*/
boolean addList(String name, List<String> newList) {
boolean addList(String name, Map<String,Boolean> newList) {
boolean replaced = false;
KeywordSearchList curList = getList(name);
final Date now = new Date();
@ -264,15 +265,17 @@ public class KeywordSearchListsXML {
KeywordSearchList list = theLists.get(listName);
String created = dateFormatter.format(list.getDateCreated());
String modified = dateFormatter.format(list.getDateModified());
List<String> keywords = list.getKeywords();
Map<String,Boolean> keywords = list.getKeywords();
Element listEl = doc.createElement(LIST_EL);
listEl.setAttribute(LIST_NAME_ATTR, listName);
listEl.setAttribute(LIST_CREATE_ATTR, created);
listEl.setAttribute(LIST_MOD_ATTR, modified);
for (String keyword : keywords) {
for (String keyword : keywords.keySet()) {
Element keywordEl = doc.createElement(KEYWORD_EL);
String regex = keywords.get(keyword)==true?"true":"false";
keywordEl.setAttribute(KEYWORD_LITERAL_ATTR, regex);
keywordEl.setTextContent(keyword);
listEl.appendChild(keywordEl);
}
@ -310,7 +313,7 @@ public class KeywordSearchListsXML {
final String modified = listEl.getAttribute(LIST_MOD_ATTR);
Date createdDate = dateFormatter.parse(created);
Date modDate = dateFormatter.parse(modified);
List<String> words = new ArrayList<String>();
Map<String,Boolean> words = new LinkedHashMap<String,Boolean>();
KeywordSearchList list = new KeywordSearchList(name, createdDate, modDate, words);
//parse all words
@ -318,7 +321,9 @@ public class KeywordSearchListsXML {
final int numKeywords = wordsNList.getLength();
for (int j = 0; j < numKeywords; ++j) {
Element wordEl = (Element) wordsNList.item(j);
words.add(wordEl.getTextContent());
String regex = wordEl.getAttribute(KEYWORD_LITERAL_ATTR);
boolean isRegex = regex.equals("true");
words.put(wordEl.getTextContent(), isRegex);
}
theLists.put(name, list);
@ -405,9 +410,9 @@ class KeywordSearchList {
private String name;
private Date created;
private Date modified;
private List<String> keywords;
private Map<String,Boolean> keywords;
KeywordSearchList(String name, Date created, Date modified, List<String> keywords) {
KeywordSearchList(String name, Date created, Date modified, Map<String,Boolean> keywords) {
this.name = name;
this.created = created;
this.modified = modified;
@ -447,7 +452,7 @@ class KeywordSearchList {
return modified;
}
List<String> getKeywords() {
Map<String,Boolean> getKeywords() {
return keywords;
}
}