package model;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import misc.ResultTreeNode;
import antlr.CommonAST;
import application.Application;
public class RegEx {
// inline arguments
private List<String> regExList = null;
private int currentIndex = 0;
private int indexStart = 0;
private int indexEnd = 0;
private boolean valid = true;
private boolean subValid = false;
private String filePath = null;
private boolean modified = false;
private ResultTreeNode resultTree = null;
private ResultTreeNode selectedMatch = null;
private CommonAST regExTree = null;
public int maxItems = 10;
// Vector used to decompose results of a match
Vector usedGroups = null;
public RegEx(int undoLevel) {
this.maxItems = undoLevel;
regExList = new ArrayList<String>();
regExList.add("");
}
/**
* This method creates the displayable tree from matched groups
**/
public ResultTreeNode applyRegEx(boolean partial, String text) {
String pattern = "";
if (partial)
pattern = getRegularExpression().substring(this.indexStart, this.indexEnd);
else
pattern = getRegularExpression();
return getResultTree(pattern, text);
}
/**
* This method creates the displayable tree from matched groups
**/
private ResultTreeNode getResultTree(String pattern, String text) {
resultTree = new ResultTreeNode(Application.messages.getString("TITLE_RESULT"), "", 0, 0);
resultTree.setToolTipText("<html>"+Application.messages.getString("TOOLTIP_RESULTS_ROOT")+"</html>");
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(text);
// Creation of the tree from the matched results
while (m.find()) {
usedGroups = new Vector();
resultTree.add(getResultTree(m,0));
}
return resultTree;
}
/**
* This method recursively adds leaves to the group's leaf
**/ @SuppressWarnings("unchecked")
private ResultTreeNode getResultTree(Matcher m, int groupIndex) {
// Create the leaf for the current group and add it to the used groups vector
usedGroups.add(groupIndex);
ResultTreeNode treeNode = new ResultTreeNode(m.group(groupIndex), "", m.start(groupIndex), m.end(groupIndex));
// Seek for children
for (int i = groupIndex+1; i < m.groupCount(); i++) {
// if the group #i is contained by the current group and has never been added in the tree, add it !
if (m.start(i) >= m.start(groupIndex) && m.end(i) <= m.end(groupIndex) && !usedGroups.contains(i)) {
ResultTreeNode child = getResultTree(m, i);
treeNode.add(child);
}
}
return treeNode;
}
/**
* This method creates the regEx tree from the grammar
**/
public CommonAST updateRegExTree() {
StringReader sr = new StringReader("("+this.getRegularExpression()+")");
ExpressionLexer lexer = new ExpressionLexer(sr);
ExpressionParser parser = new ExpressionParser(lexer);
CommonAST newTree = null;
try {
parser.regular_expression();
newTree = (CommonAST)parser.getAST();
} catch (Exception e) {
System.out.println("Error building tree from RegEx: "+e);
}
if (newTree != null)
this.regExTree = newTree;
return regExTree;
}
public void addRegExToList(String regularExpression) {
// do not add it if similar to the previous one
if (!getRegularExpression().equals(regularExpression)) {
// remove all items after the current one
if (currentIndex < regExList.size()-1) {
for (int i = regExList.size()-1; i > currentIndex; i--)
regExList.remove(i);
}
// remove the first element if the list is full
if (currentIndex == this.maxItems) {
regExList.remove(0);
currentIndex--;
}
// append the element to the list
regExList.add(regularExpression);
currentIndex++;
}
}
/**
* unDo the last typing operation
* @return string after operation
*/
public String unDo() {
if (currentIndex > 0) {
currentIndex--;
return getRegularExpression();
}
else
return getRegularExpression();
}
/**
* reDo the last undone typing operation
* @return string after operation
*/
public String reDo() {
if (currentIndex < regExList.size()-1) {
currentIndex++;
return getRegularExpression();
}
else
return getRegularExpression();
}
/**
* checkValidity checks whehther or not the regular expression is valid
* It updates and returns the "valid" boolean
* @return boolean valid
*/
public PatternSyntaxException checkValidity() {
try {
Pattern.compile(getRegularExpression());
} catch (PatternSyntaxException e) {
return e;
}
return null;
}
/**
* checkValidity checks whehther or not the selected regular expression is valid
* @return boolean test
*/
public boolean checkSubValidity(int indexS, int indexE) {
if (indexS != indexE) {
subValid = true;
try {
Pattern.compile(getRegularExpression().substring(indexS, indexE));
} catch (PatternSyntaxException e) {
System.out.println(e);
subValid = false;
} catch (StringIndexOutOfBoundsException e) {
subValid = false;
}
}
else
subValid = false;
this.indexStart = indexS;
this.indexEnd = indexE;
return subValid;
}
//-------------------------------------------------------------------------
// Accessors
public String getRegularExpression() {
return regExList.get(currentIndex);
}
public String setRegularExpression(String regularExpression) {
if(regularExpression.compareTo(this.regExList.get(currentIndex)) != 0) {
// set the regex as modified
modified = true;
// add regEx to the list (for further undo/redo operations)
addRegExToList(regularExpression);
}
// return the new regularExpression
return getRegularExpression();
}
public CommonAST getParseTree() {
return this.regExTree;
}
public boolean isValid() {
return valid;
}
public boolean isSubValid() {
return subValid;
}
public ResultTreeNode getResultTree() {
return resultTree;
}
public void setResultTree(ResultTreeNode resultTree) {
this.resultTree = resultTree;
}
public ResultTreeNode getSelectedMatch() {
return selectedMatch;
}
public ResultTreeNode setSelectedMatch(ResultTreeNode selectedMatch) {
return this.selectedMatch = selectedMatch;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.modified = false;
this.filePath = filePath;
}
public boolean isModified() {
return modified;
}
public int getIndexEnd() {
return indexEnd;
}
public int getIndexStart() {
return indexStart;
}
}