Example of the code used : package dbsucxent.pathProcessor;
import java.sql.Connection;
import dbsucxent.constant.Constant;
import java.util.regex.*;
import java.sql.ResultSet;
import java.sql.Statement;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
public class Translator {
String _xPath;
String _fromSQL;
String XPathErrMsg = "";
boolean _updated;
CurrentPath _currentPath;
WhereSQL _whereSQL;
boolean _isPositionPredicate;
Connection _dbConnection;
boolean _singleDoc;
boolean _showPath; // to include path of every leaf
boolean _useTemp;
int _depth;
String _lastElement; // added by LTM
boolean _ishardcode = false;
public int stepIndex = 1;
public String[] pathString;
public int _minDLevel = 0;
boolean _isNewQuery = true;
boolean _isFirstPredicate = true;
boolean _isWriteSQLToFile = false;
public String[] element; // containing parts of XQuery splitted by descendant axis with position predicates omitted
public String[] pos_ele; // containing parts of XQUery splitted by descendant axis
public int[] p; // storing starting level of each parts of XQuery splitted by descendant axis
public int[] Pos ; //storing starting level of each part of XQuery splitted by descendant axis
public int[] start_from; // start position for seacrh substring
public int[] Info; // storing the position vector's information
//public int num; // number of rows/tuples in the table Info
public int n; //number of elements splitted by descendant axis
public int height;
public int _pathId;
public String _pathExp;
public int subtreeId;
public Translator(String xPath, Connection conn, boolean single, boolean showPath, boolean useTemp) {
_xPath = xPath;
_fromSQL = "";
_updated = false;
_dbConnection = conn;
_currentPath = new CurrentPath(_dbConnection);
_singleDoc = single;
_useTemp = useTemp;
_showPath = showPath;
_ishardcode = single;
_whereSQL = new WhereSQL(_singleDoc, _showPath);
//added by Hanh
subtreeId = 0;
Pos = new int[4];
Info = new int[12];
}
//added by john start - for validating node comparison query
//returns the total size of the number of operators in the XPath
public String[] getOperands(String operator)
{
ArrayList tempresult = new ArrayList();
int bracketCounter = 0, prevPos = 0;
boolean quote = false;
boolean doublequote = false;
boolean stringliteral = false;
for (int i = 0; i < _xPath.length(); i++) {
//if XPath does not contain string literal and if XPath consists of '\'
//or '"', set quote (') and doublequote (") to true and stringliteral to true
if (!stringliteral) {
if (_xPath.charAt(i) == '\'') {
quote = true;
stringliteral = true;
} else if (_xPath.charAt(i) == '"') {
doublequote = true;
stringliteral = true;
}
} else {
//if XPath contains string literal, but does not contain quote (') and
//doublequote (") ie set to false, therefore stringliteral is set to false
if (quote && _xPath.charAt(i) == '\'') {
quote = false;
stringliteral = false;
} else if (doublequote && _xPath.charAt(i) == '"') {
doublequote = false;
stringliteral = false;
}
}
//if XPath contains position predicates
if ((_xPath.charAt(i) == '[') && (!stringliteral)) {
//start of position predicate, increase bracketCounter
bracketCounter++;
} else if ((_xPath.charAt(i) == ']') && (!stringliteral)) {
//end of position predicate, decrease bracketCounter
bracketCounter--;
}
//if operator at previous XPath position are equal, and does not consists of any brackets
//add the extracted operator into the tempresult array, then i+4 for prevPos to go on to compare next operator
if ((_xPath.charAt(i) == operator.charAt(0) && _xPath.charAt(i+1) == operator.charAt(1)
&& _xPath.charAt(i+2) == operator.charAt(2) && _xPath.charAt(i+3) == operator.charAt(3))
&& (bracketCounter == 0)) {
tempresult.add(_xPath.substring(prevPos, i));
prevPos = i + 4;
}
}
//adds the full string from prevPos onwards into the tempresult array
tempresult.add(_xPath.substring(prevPos));
//cast the ArrayList to a String array to store the size of the the tempresult array and returns the size
String[] result = (String[]) tempresult.toArray(new String [tempresult.size ()]);
return result;
}
//added by john end
@SuppressWarnings(value = "unchecked")
//SQL Query Translation --> XQuery --> SQL
public String translate() throws NoSuchPathException {
/* ------------------------------------------------
Added by Erwin 25-Jul-2007
To check if the given XPath is a well-formed XPath
------------------------------------------------- */
if (!isXPathWellFormed(_xPath) && !_xPath.contains("closest::")) {
throw new NoSuchPathException("\"" + _xPath + "\" is not a well-formed XPath!\n\r\n\rError message from XPath parser:\n\r" + XPathErrMsg);
}
//node comparison translation added by john begin
String[] operands = null;
int comparison = 0;
//check if XPath contains occurances of following operands: is, <<, >> (1 operand only)
//if contains, set comparison and operands
if(_xPath.indexOf(" is ")>0)
{
comparison = Constant.IS_OPERATOR;
operands = getOperands(" is ");
}
else if(_xPath.indexOf(" << ")>0)
{
comparison = Constant.PRECEDE_OPERATOR;
operands = getOperands(" << ");
}
else if(_xPath.indexOf(" >> ")>0)
{
comparison = Constant.FOLLOW_OPERATOR;
operands = getOperands(" >> ");
}
//if 2 operands
if(operands != null && operands.length == 2)
{
return processComparison(operands, comparison);
}
//node comparison translation added by john end
/* ------------------------------------------------
Added by Erwin 2007-Sep-04
To rewrite some XPath
- /a/b[position()>=1] is equal to /a/b
- /a/b[position()<=last()] is equal to /a/b
------------------------------------------------- */
if (_xPath.contains("[position()>=1]")) {
_xPath = _xPath.replace("[position()>=1]", "");
} else if (_xPath.contains("[position()<=last()]")) {
_xPath = _xPath.replace("[position()<=last()]", "");
}
/* ------------------------------------------------
Added by Erwin 25-Jul-2007
To translate simple XPath
E.g: /a/b/c/d, /a/(star)/c/d, /a/b/c/@d, //a/b/c, /a//b/(star)/c, /a//b/(star)/@c, //a/@*, /a/(star)/c/@*
------------------------------------------------- */
//added by HANH
//made it into comment by HANH --> later delete comment sign
boolean recursive = true;
if (!_xPath.contains("attribute::")
&& !_xPath.contains("following::")
&& !_xPath.contains("following-sibling::")
&& !_xPath.contains("preceding::")
&& !_xPath.contains("preceding-sibling::")
&& !_xPath.contains("namespace::")
&& (_xPath.contains("descendant::")||(_xPath.contains("//"))))
{
/*if (!_xPath.contains("::") && !_xPath.contains("//"))
{
if (!_xPath.contains("["))
{
String sql_exp = "";
sql_exp = _xPath.substring(1);
sql_exp = sql_exp.replaceAll("/","#.");
sql_exp = "." + sql_exp + "#";
return "select V.LeafValue, V.PathId, V.BranchOrder, " +
"V.DeweyOrderSum, V.DocId, V.LeafOrder " +
"from PathValue V, Path P " +
"where V.PathId = P.PathId and P.PathExp like '" +
sql_exp + "%' order by V.DeweyOrderSum";
}
else
{
String sql_pos_exp = "";
sql_pos_exp = _xPath.substring(1);
sql_pos_exp = sql_pos_exp.replaceAll("/", "#.");
sql_pos_exp = "." + sql_pos_exp + "#";
String sql_exp = sql_pos_exp;
while (sql_exp.indexOf('[') != -1)
{
int start_pos = sql_exp.indexOf('[');
int end_pos = sql_exp.indexOf(']');
sql_exp = sql_exp.substring(0,start_pos) + sql_exp.substring(end_pos+1);
}
String sqlquery = "";
try
{
Statement stmt = _dbConnection.createStatement();
sqlquery = "delete from Temp";
stmt.executeUpdate(sqlquery);
ResultSet rs = stmt.executeQuery("Select count(Level) as Height from DocumentRValue");
while(rs.next())
{
height = rs.getInt("Height") + 1;
}
System.out.println("Height = "+height); // debug purpose --> delete later
sqlquery = "select PathId, PathExp from Path where PathExp like '"+sql_exp+"%' and PathExp not like '@'";
rs = stmt.executeQuery(sqlquery);
while (rs.next())
{
subtreeId++;
for (int i = 0; i<=height+1; i++)
{
Info[i] = 0;
}
_pathId = rs.getInt("PathId");
_pathExp = rs.getString("PathExp");
//just paste
int pos_open = 0;
int pos_close = 0;
pos_open = sql_pos_exp.indexOf('[',pos_close);
pos_close = sql_pos_exp.indexOf(']',pos_open);
Info[0] = _pathId;
Info[1] = subtreeId;
while (pos_open != -1)
{
System.out.println("pos_open = " + pos_open); //debug purpose --> delete later
String str = sql_pos_exp.substring(pos_open+1,pos_close);
int pos = Integer.parseInt(str);
int count = 0;
for(int j=0; j<pos_open; j++)
if (sql_pos_exp.charAt(j)=='.') count++;
int lv = count;
if (lv == 1 && pos == 1) Info[lv+1] = 0;
else Info[lv+1] = pos;
pos_open = sql_pos_exp.indexOf('[',pos_close);
pos_close = sql_pos_exp.indexOf(']',pos_open);
}
sqlquery = "Insert into Temp values(";
for (int k=0; k<11; k++) //change 11 to height+1 later
{
sqlquery += Info[k] + ",";
}
sqlquery += Info[11] + ")";
try
{
Statement stmt1 = _dbConnection.createStatement();
stmt1.executeUpdate(sqlquery);
stmt1.close();
}
catch (Exception ex)
{
System.out.println(ex.getMessage());
JOptionPane.showMessageDialog(null,ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
rs.close();
stmt.close();
sqlquery = "select V.LeafValue, V.PathId, " +
"V.BranchOrder, V.DeweyOrderSum, V.DocId, V.LeafOrder " +
"from dbo.PathValue V, dbo.Temp T " +
"where V.PathId = T.PathId ";
for (int i=1; i<=height; i++)
{
sqlquery += "and dbo.Child(V.SiblingSum,"+i+",T.["+i+"])=1 ";
}
sqlquery += "order by V.DeweyOrderSum option (force order)";
return sqlquery;
}
catch (Exception ex)
{
System.out.println(ex.getMessage());
JOptionPane.showMessageDialog(null,ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
return "ERROR";
}
}
} // end of if for _xPath contains only child axis
else */
{ //temprorarily only response to descendant axis not ancestor
if (!_xPath.contains("["))
{
System.out.println("descendant axis without position predicate");
boolean firstStepIsDescendantAxis = false;
String sql_exp = _xPath;
System.out.println("sql_exp = "+sql_exp);
if ( (sql_exp.substring(0,2)).compareTo("//") == 0 )
{
System.out.println("case 1");
sql_exp = sql_exp.substring(2);
sql_exp = "%." + sql_exp;
firstStepIsDescendantAxis = true;
System.out.println("sql_exp = "+sql_exp);
}
else if ( (sql_exp.length() > 13) && (sql_exp.substring(0,13)).compareTo("/descendant::") == 0 )
{
System.out.println("case 2");
sql_exp = sql_exp.substring(13);
sql_exp = "%." + sql_exp;
firstStepIsDescendantAxis = true;
System.out.println("sql_exp = "+sql_exp);
}
else
{
System.out.println("case 3");
sql_exp = sql_exp.substring(1);
sql_exp = "." + sql_exp;
System.out.println("sql_exp = "+sql_exp);
}
sql_exp = sql_exp.replaceAll("//", "#%.");
sql_exp = sql_exp.replaceAll("/descendant::", "#%.");
sql_exp = sql_exp.replaceAll("/", "#.");
sql_exp = sql_exp + "#";
System.out.println("sql_exp = "+sql_exp); //debug purpose --> delete later
element = sql_exp.split("%");
n = element.length;
if (firstStepIsDescendantAxis)
{
for (int i=0; i<n-1; i++)
element[i] = element[i+1];
n--;
}
int refLevel = 0;
for (int i=0; i<element[n-1].length();i++)
{
if (element[n-1].charAt(i) == '.') refLevel++;
}
refLevel--;
//debug purpose --> delete later
for (int i =0; i<n; i++)
System.out.println("element["+i+"] = "+element[i]);
p = new int[n];
start_from = new int[n];
String sqlquery = "";
try
{
Statement stmt = _dbConnection.createStatement();
String PVPathId = "0";
sqlquery = "select PathId from Path where PathExp like '"+sql_exp+"%' and PathExp like '%@%'";
ResultSet ars = stmt.executeQuery(sqlquery);
String AttributePathId = "0";
while(ars.next()) {
int _attrPathId = ars.getInt("PathId");
AttributePathId = AttributePathId + ", " + _attrPathId;
}
ars.close();
System.out.println("xpath like sql_exp which is "+sql_exp);
sqlquery = "select PathId, PathExp from Path where PathExp like '"+sql_exp+"%' and PathExp not like '%@%'";
int clr = stmt.executeUpdate("delete from Pos");
stmt.executeUpdate("delete from Temp");
System.out.println("clr = "+clr);
ResultSet rs = stmt.executeQuery(sqlquery);
while(rs.next())
{
_pathId = rs.getInt("PathId");
PVPathId = PVPathId + ", " + _pathId;
_pathExp = rs.getString("PathExp");
System.out.println("_pathId = "+_pathId); //debug purpose --> delte later
System.out.println("_pathExp = "+_pathExp); // debug purpose --> delete later
System.out.println("firstStepIsDescendantAxis = "+firstStepIsDescendantAxis); //debug purpose --> delete later
for (int i=0; i<n; i++)
{
p[i] = 0;
start_from[i] = 0;
}
for (int i = 0; i<=height+1; i++)
{
Info[i] = 0;
}
if (recursive == false) {
}
else {
if (firstStepIsDescendantAxis) InfoFill_NoPredicate(0);
else
{
System.out.println("p[0] = "+p[0]);
InfoFill_NoPredicate(1);
}
}
}
if (recursive == false) {
sqlquery = "With V (LeafValue, PathId, BranchOrder, " +
"DeweyOrderSum, DocId, LeafOrder" +
")" + "As(\n" +
"Select V1.LeafValue, V1.PathId, " +
"V1.BranchOrder, V1.DeweyOrderSum, " +
"V1.DocId, V1.LeafOrder\n" +
"From dbo.PathValue V1\n" +
"Where V1.PathId in (" + PVPathId +")\n" +
")\n" +
"Select V.*, 1 As Attr\n" +
"From V\n" +
"Union All\n" +
"Select A.LeafValue, A.PathId, " +
"V.BranchOrder, V.DeweyOrderSum, " +
"A.DocId, A.LeafOrder, 0 As Attr\n" +
"From Attribute A, V\n" +
"Where A.docId = V.DocId\n" +
"And A.LeafOrder = V.LeafOrder\n" +
"And A.PathId in (" + AttributePathId + ")\n" +
"Order By DeweyOrderSum, Attr\n" +
"Option (force order)";
}
else {
sqlquery = "With V (LeafValue, PathId, BranchOrder, " +
"DeweyOrderSum, DocId, LeafOrder, " +
"refLevel)" + "As(\n" +
"Select V1.LeafValue, V1.PathId, " +
"V1.BranchOrder, V1.DeweyOrderSum, " +
"V1.DocId, V1.LeafOrder, " +
"(P.Position + " + refLevel + ") as refLevel\n" +
"From dbo.Pos P, dbo.PathValue V1\n" +
"Where V1.PathId in (" + PVPathId +")\n" +
"And V1.PathId = P.PathId\n" +
"And P.PartId = " + n + "\n" +
//"Order By rerLevel, V1.DeweyOrderSum\n" +
//"Option (force order)\n" +
")\n" +
"Select V.*, 1 As Attr\n" +
"From V\n" +
"Union All\n" +
"Select A.LeafValue, A.PathId, " +
"V.BranchOrder, V.DeweyOrderSum, " +
"A.DocId, A.LeafOrder, V.refLevel, 0 As Attr\n" +
"From Attribute A, V\n" +
"Where A.docId = V.DocId\n" +
"And A.LeafOrder = V.LeafOrder\n" +
"And A.PathId in (" + AttributePathId + ")\n" +
"Order By refLevel, DeweyOrderSum, Attr\n" +
"Option (force order)";
}
rs.close();
stmt.close();
return sqlquery;
}
catch (Exception ex)
{
System.out.println(ex.getMessage());
//JOptionPane.showMessageDialog(null,ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
return "ERROR";
}
} // end of if for _xPath contains only child and descendant/ancestor axes with no position predicate
else
{
boolean firstStepIsDescendantAxis = false;
String sql_pos_exp = _xPath;
if ( (sql_pos_exp.substring(0,2)).compareTo("//") == 0 )
{
sql_pos_exp = sql_pos_exp.substring(2);
sql_pos_exp = "%." + sql_pos_exp;
firstStepIsDescendantAxis = true;
}
else if ( (sql_pos_exp.length() > 13) && (sql_pos_exp.substring(0,13)).compareTo("/descendant::") == 0 )
{
sql_pos_exp = sql_pos_exp.substring(13);
sql_pos_exp = "%." + sql_pos_exp;
firstStepIsDescendantAxis = true;
}
else
{
sql_pos_exp = sql_pos_exp.substring(1);
sql_pos_exp = "." + sql_pos_exp;
}
sql_pos_exp = sql_pos_exp.replaceAll("//", "#%.");
sql_pos_exp = sql_pos_exp.replaceAll("/descendant::", "#%.");
sql_pos_exp = sql_pos_exp.replaceAll("/", "#.");
sql_pos_exp = sql_pos_exp + "#";
System.out.println("sql_pos_exp = "+sql_pos_exp); // debug purpose --> delete later
String sql_exp = sql_pos_exp;
while (sql_exp.indexOf('[') != -1)
{
int start_pos = sql_exp.indexOf('[');
int end_pos = sql_exp.indexOf(']');
sql_exp = sql_exp.substring(0,start_pos) + sql_exp.substring(end_pos+1);
}
System.out.println("sql_exp = "+sql_exp); //debug purpose --> delete later
element = sql_exp.split("%");
pos_ele = sql_pos_exp.split("%");
n = element.length;
if (firstStepIsDescendantAxis)
{
for (int i=0; i<n-1; i++)
{
element[i] = element[i+1];
pos_ele[i] = pos_ele[i+1];
}
n--;
}
int refLevel = 0;
for (int i=0; i<element[n-1].length();i++)
{
if (element[n-1].charAt(i)=='.') refLevel++;
}
refLevel--;
//debug purpose --> delete later
for (int i =0; i<n; i++)
System.out.println("element["+i+"] = "+element[i]);
for (int i=0; i<n; i++)
{
System.out.println("element["+i+"] = "+element[i]);
System.out.println("pos_ele["+i+"] = "+pos_ele[i]);
}// debug purpose --. delete later
p = new int[n];
start_from = new int[n];
for (int i=0; i<n; i++)
{
p[i] = 0;
start_from[i] = 0;
}
//num = 0;
String sqlquery = "";
try
{
Statement stmt = _dbConnection.createStatement();
stmt.executeUpdate("delete from Pos");
stmt.executeUpdate("delete from Temp");
ResultSet rs = stmt.executeQuery("Select count(Level) as Height from DocumentRValue");
while(rs.next())
{
height = rs.getInt("Height") + 1;
}
System.out.println("Height = "+height); // debug purpose --> delete later
String PVPathId = "0";
sqlquery = "select PathId from Path where PathExp like '"+sql_exp+"%' and PathExp like '%@%'";
ResultSet ars = stmt.executeQuery(sqlquery);
String AttributePathId = "0";
while(ars.next()) {
int _attrPathId = ars.getInt("PathId");
AttributePathId = AttributePathId + ", " + _attrPathId;
}
ars.close();
sqlquery = "Select PathId, PathExp from Path where PathExp like '"+sql_exp+"%' and PathExp not like '%@%'";
ResultSet results = stmt.executeQuery(sqlquery);
while(results.next())
{
_pathId = results.getInt("PathId");
PVPathId = PVPathId + ", " + _pathId;
_pathExp = results.getString("PathExp");
System.out.println("_pathId = "+_pathId); //debug purpose --> delte later
System.out.println("_pathExp = "+_pathExp); // debug purpose --> delete later
System.out.println("firstStepIsDescendantAxis = "+firstStepIsDescendantAxis); //debug purpose --> delete later
for (int i=0; i<n; i++)
{
p[i] = 0;
start_from[i] = 0;
}
if (recursive == false) {
fillTemp();
}
else {
if (firstStepIsDescendantAxis) InfoFill(0);
else
{
InfoFill(1);
}
}
//num++; not increase value of num here
}
if (recursive == false) {
sqlquery = "With V (LeafValue, PathId, BranchOrder, " +
"DeweyOrderSum, DocId, LeafOrder" +
")" + "As(\n" +
"Select V1.LeafValue, V1.PathId, " +
"V1.BranchOrder, V1.DeweyOrderSum, " +
"V1.DocId, V1.LeafOrder\n " +
"From dbo.Temp T, dbo.PathValue V1\n" +
"Where V1.PathId in (" + PVPathId + ")\n" +
"And V1.PathId = T.PathId\n ";
for (int i=1; i<=height; i++)
{
sqlquery += "and dbo.Child(V1.SiblingSum,"+i+",T.["+i+"])=1\n";
}
sqlquery += ")\n" +
"Select V.*, 1 As Attr\n" +
"From V\n" +
"Union All\n" +
"Select A.LeafValue, A.PathId, " +
"V.BranchOrder, V.DeweyOrderSum, " +
"A.DocId, A.LeafOrder, 0 As Attr\n" +
"From Attribute A, V\n" +
"Where A.docId = V.DocId\n" +
"And A.LeafOrder = V.LeafOrder\n" +
"And A.PathId in (" + AttributePathId + ")\n" +
"Order By DeweyOrderSum, Attr\n" +
"Option (force order)";
}
else {
sqlquery = "With V (LeafValue, PathId, BranchOrder, " +
"DeweyOrderSum, DocId, LeafOrder, " +
"refLevel)" + "As(\n" +
"Select V1.LeafValue, V1.PathId, " +
"V1.BranchOrder, V1.DeweyOrderSum, " +
"V1.DocId, V1.LeafOrder, " +
"(P.Position + " + refLevel + ") as refLevel\n" +
"From dbo.Temp T, dbo.Pos P, dbo.PathValue V1\n" +
"Where V1.PathId in (" + PVPathId + ")\n" +
"And V1.PathId = T.PathId " +
"And P.PathId = T.PathId\n" +
"And T.SubtreeId = P.SubtreeId\n" +
"And P.PartId = "+n+"\n";
for (int i=1; i<=height; i++)
{
sqlquery += "and dbo.Child(V1.SiblingSum,"+i+",T.["+i+"])=1\n";
}
sqlquery += ")\n" +
"Select V.*, 1 As Attr\n" +
"From V\n" +
"Union All\n" +
"Select A.LeafValue, A.PathId, " +
"V.BranchOrder, V.DeweyOrderSum, " +
"A.DocId, A.LeafOrder, V.refLevel, 0 As Attr\n" +
"From Attribute A, V\n" +
"Where A.docId = V.DocId\n" +
"And A.LeafOrder = V.LeafOrder\n" +
"And A.PathId in (" + AttributePathId + ")\n" +
"Order By refLevel, DeweyOrderSum, Attr\n" +
"Option (force order)";
}
results.close();
stmt.close();
return sqlquery;
}
catch (Exception ex)
{
System.out.println(ex.getMessage());
//JOptionPane.showMessageDialog(null,ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
return "ERROR";
}
} // end of else for _xPath contains child/descendant/ancestor axes with position predicate
}
} // end of modification by HANH
else {
if (!_xPath.contains("::") && !_xPath.contains("[") && !_xPath.contains("]")) {
SimpleXPathTranslator xpathtranslator = new SimpleXPathTranslator(_dbConnection, _xPath);
String _SQL = xpathtranslator.getTranslatedSQL(_showPath);
if (_SQL.equals("ERROR")) {
throw new NoSuchPathException("\"" + _xPath + "\" does not exist");
} else {
if (_useTemp) {
_SQL = rewriteSQLUsingTempTable(_SQL, false);
}
return _SQL;
}
}
/* ------------------------------------------------
Added by Clement Ng Zhifeng 12-Feb-2008
To translate simple closest axis XPath
E.g: /a/b/c/closest::d
------------------------------------------------- */
if ((_xPath.contains("closest::")) && (!_xPath.contains("[") && !_xPath.contains("]"))) {
SimpleClosestTranslator simpleclosest = new SimpleClosestTranslator(_dbConnection, _xPath);
String _SQL = simpleclosest.getTranslatedSQL(_showPath);
if (_SQL.endsWith("ERROR")) {
throw new NoSuchPathException("\"" + _xPath + "\" does not exist");
} else {
return _SQL;
}
}
if (((_xPath.contains("closest::"))) && (_xPath.contains("[")) && (_xPath.contains("]"))) {
String tempPath = "";
String tempPath1 = "";
int tempCount = 0, a = 0;
String positionPred = "";
tempCount = _xPath.lastIndexOf("/");
//in this case only can handle position predicate at the root's direct child
if (_xPath.charAt(0) == '/') {
tempPath1 = _xPath.substring(1, tempCount);
a = tempPath1.indexOf("/");
tempPath1 = _xPath.substring(a+1, tempCount);
System.out.println("tempPath1 is now " + tempPath1);
positionPred = tempPath1.substring(tempPath1.indexOf("[") + 1, tempPath1.indexOf("]") );
if (_xPath.contains("position()")) {
System.out.println("Hello");
int g = tempPath1.indexOf("=") + 1;
System.out.println("g is " + g);
String temp1 = tempPath1.substring(tempPath1.indexOf("=") + 1, tempPath1.indexOf("]") );
temp1.trim();
System.out.println("temp1 now = " + temp1);
String lowerBound = temp1.substring(0, temp1.indexOf("t") );
String upperBound = temp1.substring(temp1.indexOf("o") + 1, temp1.length());
lowerBound.trim();
upperBound.trim();
//int tmp = Integer.parseInt(lowerBound) - 1;
//lowerBound = Integer.toString(tmp);
System.out.println("lowerbound is " + lowerBound);
System.out.println("upperbound is " + upperBound);
SimpleClosestPositionPredicateTranslator scppt2 = new SimpleClosestPositionPredicateTranslator(_dbConnection, _xPath, lowerBound.trim(), upperBound.trim());
String _SQL = scppt2.getTranslatedSQL(_showPath);
if (_SQL.endsWith("ERROR")) {
throw new NoSuchPathException("\"" + _xPath + "\" does not exist");
} else {
return _SQL;
}
} else {
System.out.println("Position Predicate is " + positionPred);
SimpleClosestPositionPredicateTranslator scppt = new SimpleClosestPositionPredicateTranslator(_dbConnection, _xPath, positionPred, "@");
String _SQL = scppt.getTranslatedSQL(_showPath);
if (_SQL.endsWith("ERROR")) {
throw new NoSuchPathException("\"" + _xPath + "\" does not exist");
} else {
return _SQL;
}
}
} else {
System.out.println("Position Predicate is not at the correct place");
}
tempPath = _xPath.substring(0, tempCount);
tempCount = tempPath.lastIndexOf("/");
tempPath = tempPath.substring(0, tempCount);
//if (tempPath.lastIndexOf("]") == tempPath.length()-1){
// positionPred = tempPath.substring(tempPath.indexOf("[") + 1, tempPath.indexOf("]") );
// System.out.println("Position Predicate is " + positionPred);
// System.out.println("tempPath is " + tempPath);
//continue here with the Translation of the XPath with simple position predicate
// SimpleClosestPositionPredicateTranslator scppt = new SimpleClosestPositionPredicateTranslator(_dbConnection, _xPath, positionPred);
// String _SQL = scppt.getTranslatedSQL(_showPath);
// if (_SQL.endsWith("ERROR")) {
// throw new NoSuchPathException("\"" + _xPath + "\" does not exist");
// } else {
// return _SQL;
// }
//} else {
// System.out.println("Position Predicate is not at the correct place");
//}
}
/* ------------------------------------------------
* end of add by Clement Ng Zhifeng
/* ------------------------------------------------
/* ------------------------------------------------
Added by Erwin 22-Oct-2007
To split the XPath based on steps
For example:
- /a/b[title='TCP/IP']/c will be split into
- ("", "a","b[title='TCP/IP']","c")
Remark: This replaces Klarinda's code
------------------------------------------------- */
int bracketCounter = 0;
int prevPos = 0;
ArrayList tempresult = new ArrayList();
boolean quote = false;
boolean doublequote = false;
boolean stringliteral = false;
for (int i = 0; i < _xPath.length(); i++) {
if (!stringliteral) {
if (_xPath.charAt(i) == '\'') {
quote = true;
stringliteral = true;
} else if (_xPath.charAt(i) == '"') {
doublequote = true;
stringliteral = true;
}
} else {
if (quote && _xPath.charAt(i) == '\'') {
quote = false;
stringliteral = false;
} else if (doublequote && _xPath.charAt(i) == '"') {
doublequote = false;
stringliteral = false;
}
}
if ((_xPath.charAt(i) == '"') && (!stringliteral)) {
quote = true;
}
if ((_xPath.charAt(i) == '[') && (!stringliteral)) {
bracketCounter++;
} else if ((_xPath.charAt(i) == ']') && (!stringliteral)) {
bracketCounter--;
}
if ((_xPath.charAt(i) == '/') && (bracketCounter == 0)) {
tempresult.add(_xPath.substring(prevPos, i));
prevPos = i + 1;
}
}
tempresult.add(_xPath.substring(prevPos));
String[] result = (String[]) tempresult.toArray(new String[tempresult.size()]);
if (_xPath.contains("ancestor::") || _xPath.contains("descendant::") || _xPath.contains("ancestor-or-self::") || _xPath.contains("descendant-or-self::")) {
System.out.println("Translator.translate() HARDCODE");
_ishardcode = false;
_whereSQL.sethardcode(_ishardcode, _dbConnection);
} else if (_singleDoc) {
// added by erwin 2007-07-06
System.out.println("Translator.translate() HARDCODE");
_ishardcode = true;
_whereSQL.sethardcode(_ishardcode, _dbConnection);
}
_isNewQuery = true;
_isFirstPredicate = true;
for (int x = 1; x < result.length; x++) {
result[x] = result[x].trim(); // trim leading and trailing space
//System.out.println("\n\nTranslator.translate(), result[" + x + "] = " + result[x]); // klarinda 20060629
pathString = result; // added by wang geng
stepIndex = x; // added by wang geng
if (x == result.length - 1) {
// if the last step
processStep(result[x], false, true);
_depth = _currentPath.getLevel();
_lastElement = result[x];
} else {
// if not the last step
processStep(result[x], false, false);
}
}
// join with Path table to obtain paths
if (_showPath) {
_whereSQL.addPaths();
}
String _SQL = _whereSQL.get();
if (_useTemp) {
_SQL = rewriteSQLUsingTempTable(_SQL, _whereSQL.getTables() == 1 ? true : false);
}
if (_isWriteSQLToFile) {
try {
BufferedWriter out = new BufferedWriter(new FileWriter("c:/SQL-Query.sql", true));
out.write("XPath = " + _xPath + "\n\r");
out.write("SQL Query\n\r");
out.write(_SQL + "\n\r");
out.write("-------------------------------------------\n\r\n\r");
out.close();
} catch (IOException e) {
}
}
return _SQL;
}
}
//added by Hanh
public void InfoFill_NoPredicate(int i)
{
System.out.println("call InfoFill_NoPredicate(_pathExp,i)");
System.out.println("_pathExp = "+_pathExp);
System.out.println("i = "+i); // debug purpose --> delete later
System.out.println("n = "+n);
//if(i >= n) return; //stop recursive
if (i>0 && i<n) start_from[i] = p[i-1] + element[i-1].length();
System.out.println("start_from["+i+"] = "+start_from[i]); // debug purpose --> delete later
while ((start_from[i]<_pathExp.length())&&( _pathExp.indexOf(element[i],start_from[i]) > -1) && (i<=n-1))
{
System.out.println("inside while loop");
p[i] = _pathExp.indexOf(element[i],start_from[i]);
System.out.println("p["+i+"] = "+p[i]);
if (i==(n-1))
{
Fill_NoPredicate();
start_from[i] = p[i] + element[i].length();
}
else
{
start_from[i] = p[i] + element[i].length();
InfoFill_NoPredicate(i+1);
}
}
}
//added by Hanh
public void Fill_NoPredicate()
{
System.out.println("Fill_NoPredicate is called");
subtreeId++;
System.out.println("subtreeId = "+subtreeId);
for (int i=0; i< n; i++)
{
Pos[0] = _pathId;
System.out.println("Pos[0] = "+Pos[0]);
Pos[1] = subtreeId;
System.out.println("Pos[1] = "+Pos[1]);
Pos[2] = i+1;
System.out.println("i + 1 = "+(i+1));
System.out.println("Pos[2] = "+Pos[2]);
if (p[i] == 0) Pos[3] = 1;
else
{
int level = 0;
for (int j=0; j<p[i]; j++)
{
if(_pathExp.charAt(j)=='.') level++;
}
level++;
Pos[3] = level;
}
System.out.println("Pos[3] = "+Pos[3]);
//num++;
String sqlquery = "";
try
{
Statement stmt = _dbConnection.createStatement();
sqlquery = "Insert into Pos values(";
for (int k=0; k<3; k++)
{
sqlquery = sqlquery + Pos[k] + ",";
}
sqlquery += Pos[3]+ ")";
stmt.executeUpdate(sqlquery);
stmt.close();
}
catch (Exception ex)
{
System.out.println(ex.getMessage());
//JOptionPane.showMessageDialog(null,ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
}
//added by Hanh
public void InfoFill(int i)
{
System.out.println("call InfoFill(_pathExp,i)");
System.out.println("_pathExp = "+_pathExp);
System.out.println("i = "+i); // debug purpose --> delete later
System.out.println("n = "+n);
if (i>0 && i<n) start_from[i] = p[i-1] + element[i-1].length();
System.out.println("start_from["+i+"] = "+start_from[i]); // debug purpose --> delete later
while ((start_from[i]<_pathExp.length()) && (_pathExp.indexOf(element[i],start_from[i]) > -1) && (i<= n-1))
{
p[i] = _pathExp.indexOf(element[i],start_from[i]);
if (i==n-1)
{
Fill();
start_from[i] = p[i] + element[i].length();
}
else
{
start_from[i] = p[i] + element[i].length();
InfoFill(i+1);
}
}
}
//addded by Hanh
public void Fill()
{
subtreeId++;
System.out.println("Call Fill(_pathExp)"); //debug purpose -->delete later
for (int i=1; i<=height+1; i++)
{
Info[i] = 0;
}
Info[0] = _pathId;
Info[1] = subtreeId;
for (int i=0; i<n; i++)
{
Pos[0] = _pathId;
Pos[1] = subtreeId;
Pos[2] = i+1;
int pos_open = 0;
int pos_close = 0;
System.out.println("pos_ele["+i+"] = " + pos_ele[i]); // debug purpose --> delete later
pos_open = pos_ele[i].indexOf('[',pos_close);
pos_close = pos_ele[i].indexOf(']',pos_open);
int level = 0;
if (p[i] == 0) level = 1;
else
{
for (int j=0; j< p[i]; j++)
if (_pathExp.charAt(j)=='.') level++;
level++;
}
Pos[3] = level;
String sqlquery = "";
try
{
System.out.println("Try to insert into Pos");
Statement stmt = _dbConnection.createStatement();
sqlquery = "Insert into Pos values(";
for (int k=0; k<3; k++)
{
sqlquery = sqlquery + Pos[k] + ",";
}
sqlquery += Pos[3]+ ")";
stmt.executeUpdate(sqlquery);
stmt.close();
}
catch (Exception ex)
{
System.out.println(ex.getMessage());
//JOptionPane.showMessageDialog(null,ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
while (pos_open != -1)
{
System.out.println("now part "+i+" is tested");
System.out.println("pos_open = " + pos_open); //debug purpose --> delete later
String str = pos_ele[i].substring(pos_open+1,pos_close);
int pos = Integer.parseInt(str);
int count = 0;
for(int j=0; j<pos_open; j++)
if (pos_ele[i].charAt(j)=='.') count++;
int lv = level + count - 1;
if (lv == 1 && pos == 1) Info[lv+1] = 0;
else Info[lv+1] = pos;
pos_open = pos_ele[i].indexOf('[',pos_close);
pos_close = pos_ele[i].indexOf(']',pos_open);
}
//debug purpose ---> delete later
for (int k = 0; k< height+2; k++)
{
System.out.print("Temp["+k+"] = "+Info[k]+" ");
}
System.out.println();
}
String sqlquery = "";
try
{
System.out.println("Try to insert into Temp");
Statement stmt = _dbConnection.createStatement();
sqlquery = "Insert into Temp values(";
for (int k=0; k<11; k++) //change 11 to height+1 later
{
sqlquery += Info[k] + ",";
}
sqlquery += Info[11] + ")";
stmt.executeUpdate(sqlquery);
stmt.close();
}
catch (Exception ex)
{
System.out.println(ex.getMessage());
//JOptionPane.showMessageDialog(null,ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
for (int i=0; i<=height; i++)
{
System.out.print(Info[i]+"");
System.out.println();
} //debug purpose --> delete later
//num++;
}
// added by Hanh
public void fillTemp() {
subtreeId++;
System.out.println("Call Fill(_pathExp)"); //debug purpose -->delete later
for (int i=1; i<=height+1; i++)
{
Info[i] = 0;
}
Info[0] = _pathId;
Info[1] = subtreeId;
int pos_open =0;
int pos_close = 0;
int level = 0;
for (int i=0; i<n; i++) {
pos_open = pos_ele[i].indexOf('[',pos_close);
if (pos_open != -1) {
level = 0;
System.out.println("[][]][][][][]][][][][]pos of element "+i+" is "+_pathExp.indexOf(element[i],0));
for (int j=0; j<_pathExp.indexOf(element[i],0); j++)
if (_pathExp.charAt(j) == '.') level++;
}
System.out.println("[][][[][][][][][][][][]level is "+level);
while (pos_open != -1) {
pos_close = pos_ele[i].indexOf(']', pos_close);
String str = pos_ele[i].substring(pos_open+1, pos_close);
int pos = Integer.parseInt(str);
int count = 0;
for(int j=0; j<pos_open; j++)
if (pos_ele[i].charAt(j)=='.') count++;
int lv = level + count;
if (lv == 1 && pos == 1) Info[lv+1] = 0;
else Info[lv+1] = pos;
pos_open = pos_ele[i].indexOf('[',pos_close);
}
}
String sqlquery = "";
try
{
System.out.println("Try to insert into Temp");
Statement stmt = _dbConnection.createStatement();
sqlquery = "Insert into Temp values(";
for (int k=0; k<11; k++) //change 11 to height+1 later
{
sqlquery += Info[k] + ",";
}
sqlquery += Info[11] + ")";
stmt.executeUpdate(sqlquery);
stmt.close();
}
catch (Exception ex)
{
System.out.println(ex.getMessage());
//JOptionPane.showMessageDialog(null,ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
for (int i=0; i<=height; i++)
{
System.out.print(Info[i]+"");
System.out.println();
} //debug purpose --> delete later
}
// added by erwin
//added by john start
@SuppressWarnings(value = "unchecked")
public String translateOperand(boolean byIdentity, int comparison) throws NoSuchPathException {
/* ------------------------------------------------
Added by Erwin 2007-Sep-04
To rewrite some XPath
- /a/b[position()>=1] is equal to /a/b
- /a/b[position()<=last()] is equal to /a/b
------------------------------------------------- */
if (_xPath.contains("[position()>=1]")) {
_xPath = _xPath.replace("[position()>=1]", "");
} else if (_xPath.contains("[position()<=last()]")) {
_xPath = _xPath.replace("[position()<=last()]", "");
}
/* ------------------------------------------------
Added by Erwin 25-Jul-2007
To translate simple XPath
E.g: /a/b/c/d, /a/(star)/c/d, /a/b/c/@d, //a/b/c, /a//b/(star)/c, /a//b/(star)/@c, //a/@*, /a/(star)/c/@*
------------------------------------------------- */
//if it is just a simple XPath
if (!_xPath.contains("::") && !_xPath.contains("[") && !_xPath.contains("]")) {
SimpleXPathTranslator xpathtranslator = new SimpleXPathTranslator(_dbConnection, _xPath);
String _SQL = xpathtranslator.getOperandSQL(byIdentity, comparison);
if(xpathtranslator.isAttribute())
_whereSQL.setonlyReturnAttribute(true);
if (_SQL.equals("ERROR")) {
throw new NoSuchPathException("\"" + _xPath + "\" does not exist");
} else {
//if XPath does not contain attribute, get attribute path
_whereSQL.setAttributePath(xpathtranslator.getAttrPath());
_whereSQL.setLevel(xpathtranslator.getLevel());
return _SQL;
}
}
/* ------------------------------------------------
Added by Erwin 22-Oct-2007
To split the XPath based on steps
For example:
- /a/b[title='TCP/IP']/c will be split into
- ("", "a","b[title='TCP/IP']","c")
Remark: This replaces Klarinda's code
------------------------------------------------- */
int bracketCounter = 0;
int prevPos = 0;
ArrayList tempresult = new ArrayList();
boolean quote = false;
boolean doublequote = false;
boolean stringliteral = false;
for (int i = 0; i < _xPath.length(); i++) {
if (!stringliteral) {
if (_xPath.charAt(i) == '\'') {
quote = true;
stringliteral = true;
} else if (_xPath.charAt(i) == '"') {
doublequote = true;
stringliteral = true;
}
} else {
if (quote && _xPath.charAt(i) == '\'') {
quote = false;
stringliteral = false;
} else if (doublequote && _xPath.charAt(i) == '"') {
doublequote = false;
stringliteral = false;
}
}
if ((_xPath.charAt(i) == '"') && (!stringliteral)) {
quote = true;
}
if ((_xPath.charAt(i) == '[') && (!stringliteral)) {
bracketCounter++;
} else if ((_xPath.charAt(i) == ']') && (!stringliteral)) {
bracketCounter--;
}
if ((_xPath.charAt(i) == '/') && (bracketCounter == 0)) {
tempresult.add(_xPath.substring(prevPos, i));
System.out.println(_xPath.substring(prevPos, i));
prevPos = i + 1;
}
}
tempresult.add(_xPath.substring(prevPos));
String[] result = (String[]) tempresult.toArray(new String [tempresult.size ()]);
// klarinda 20070426 for hardcode rvalue
// if (result[0].trim().equals("HARDCODE")) { --> what is it?
// added by erwin 2007-09-04
// if there is ancestor/descendant axes, set _isharcode = false;
if (_xPath.contains("ancestor::") || _xPath.contains("descendant::") || _xPath.contains("ancestor-or-self::") || _xPath.contains("descendant-or-self::")) {
System.out.println("Translator.translate() HARDCODE");
_ishardcode = false;
_whereSQL.sethardcode(_ishardcode, _dbConnection);
} else if (_singleDoc) {
// added by erwin 2007-07-06
System.out.println("Translator.translate() HARDCODE");
_ishardcode = true;
_whereSQL.sethardcode(_ishardcode, _dbConnection);
}
_isNewQuery = true;
_isFirstPredicate = true;
for (int x = 1; x < result.length; x++) {
result[x] = result[x].trim(); // trim leading and trailing space
//System.out.println("\n\nTranslator.translate(), result[" + x + "] = " + result[x]); // klarinda 20060629
pathString = result; // added by wang geng
stepIndex = x; // added by wang geng
if (x == result.length - 1) {
// if the last step
processStep(result[x], false, true);
_depth = _currentPath.getLevel();
_lastElement = result[x];
} else {
// if not the last step
processStep(result[x], false, false);
}
}
// join with Path table to obtain paths
if (_showPath) {
_whereSQL.addPaths();
}
_whereSQL.setLevel(_currentPath.getLevel());
if(byIdentity)
return _whereSQL.getRightOperand(_currentPath.isLeafNode(), comparison);
else
return _whereSQL.getLeftOperand();
}
//process comparison between 2 operators
public String processComparison(String[] operands, int comparison) throws NoSuchPathException
{
_xPath = operands[0].trim();
String leftOperand = translateOperand(false, comparison);
Translator rightTranslator = new Translator(operands[1].trim(), _dbConnection, _singleDoc, _showPath, _useTemp);
String rightOperand, compareSQL;
//check whether rightOperand contains the following operators: is, precede
if(comparison == Constant.IS_OPERATOR)
{
rightOperand = rightTranslator.translateOperand(true, comparison);
compareSQL = _whereSQL.is(leftOperand, rightOperand, rightTranslator._whereSQL);
}
else if(comparison == Constant.PRECEDE_OPERATOR)
{
rightOperand = rightTranslator.translateOperand(true, comparison);
_whereSQL.setDBConnection(_dbConnection);
compareSQL = _whereSQL.precede(leftOperand, rightOperand, rightTranslator._whereSQL);
}
else
{
//if it is not is and precede operator implies it is follow operator
//rightOperand = rightTranslator.translateOperand(true, _whereSQL.getOnlyReturnAttribute(), comparison);
rightOperand = rightTranslator.translateOperand(true, comparison);
_whereSQL.setDBConnection(_dbConnection);
compareSQL = _whereSQL.follow(leftOperand, rightOperand, rightTranslator._whereSQL);
}
if (_useTemp)
compareSQL = rewriteSQLUsingTempTable(compareSQL, false);
return compareSQL;
}
//added by john end
private String rewriteSQLUsingTempTable(String input, boolean isSingleTable) {
String _NewSQL = "";
_NewSQL = input;
if (input.contains("FROM Attribute A, V") && input.contains("UNION ALL")) {
_NewSQL = _NewSQL.replace("WITH V", "INSERT INTO PVTemp");
_NewSQL = _NewSQL.replace("AS (", "");
if (isSingleTable) {
_NewSQL = _NewSQL.replace(") SELECT", "; \n SELECT");
_NewSQL = _NewSQL.replace(") SELECT", "; \n SELECT");
} else {
_NewSQL = _NewSQL.replace(") SELECT", "OPTION (FORCE ORDER); \n SELECT");
_NewSQL = _NewSQL.replace(") SELECT", "OPTION (FORCE ORDER); \n SELECT");
}
_NewSQL = _NewSQL.replace("FROM V", "FROM PVTemp V");
_NewSQL = _NewSQL.replace("FROM Attribute A, V", "FROM Attribute A, PVTemp V");
} else if (input.contains("FROM V, Attribute A") && input.contains("UNION ALL")) {
_NewSQL = _NewSQL.replace("WITH V", "INSERT INTO PVTemp");
_NewSQL = _NewSQL.replace("AS (", "");
_NewSQL = _NewSQL.replace(") SELECT", "; \n SELECT");
_NewSQL = _NewSQL.replace(") SELECT", "; \n SELECT");
_NewSQL = _NewSQL.replace("FROM V", "FROM PVTemp V");
_NewSQL = _NewSQL.replace("FROM Attribute A, V", "FROM Attribute A, PVTemp V");
}
return _NewSQL;
}
// added by LTM
public int getDepth() {
return _depth;
}
// added by LTM
public String getLastElement() {
return _lastElement;
}
// klarinda 20061206
// given an XPath step, return the Step class (Step class contains the
// summary for each step)
// this class contains some string manipulation
// ideally W3C XPath Parser should be used
private Step getStep(String splice) throws NoSuchPathException {
String axis;
String nameTest = null;
String predicates = null;
String[] predicate = {" "};
String[] equalityOperator = null;
String[] equality = null;
boolean hasPredicate = false;
boolean[] hasEquality = {false};
// split axis and predicate
String[] parts = splice.split("::");
// axis default?
if (parts.length == 1) {
// klarinda 20061103 add if @ -> attribute
if (parts[0].length() == 0) {
axis = "descendant";
} else if (parts[0].charAt(0) == '@') {
axis = "attribute";
} else {
axis = "child";
}
predicates = parts[0];
} else if (parts.length == 2) {
axis = parts[0];
predicates = parts[1];
} else {
throw new NoSuchPathException("Too many axis, axis undetermined");
}
// split predicate into nameTest and position based predicate(if any)
int x = predicates.indexOf("[");
int y = predicates.lastIndexOf("]");
String[] parts2 = null;
if (x >= 0) {
parts2 = new String[2];
parts2[0] = predicates.substring(0, x);
parts2[1] = predicates.substring(x + 1, y);
} else {
parts2 = new String[1];
parts2[0] = predicates;
}
//String[] parts2 = predicates.split("[\\[\\]]");
for (int k = 0; k < parts2.length; k++) {
// klarinda 20060629
parts2[k] = parts2[k].trim();
}
// klarinda 20061122 string manipulation to separate based on "and",
// "or", "(", or ")"
// for example, the predicate: [title="abc" and ( ( publisher='xyz' and
// price>400) or position()= 2 to 4 )]
// i and or ( "expr" )
// 0 false false 0 "title="abc"" 0
// 1 true false 2 "publisher='xyz'" 0
// 2 true false 0 "price>400" 1
// 3 false true 0 "position()= 2 to 4" 1
String[] expr = new String[20]; // assume 20 is max
int[] noOfOpenParenthesis = new int[20];
int[] noOfCloseParenthesis = new int[20];
boolean[] andExpr = new boolean[20];
boolean[] orExpr = new boolean[20];
int state = 1;
int pos = 0;
int begin = pos;
int exprIndex = 0;
boolean quote = false;
boolean doublequote = false;
boolean stringliteral = false;
boolean functioncall = false;
String pred = "";
if (parts2.length == 2) {
// changed by erwin
pred = parts2[1];
} else if (parts2.length > 2) {
for (int i = parts2.length - 2; i > 1; i--) {
}
}
while (pos < pred.length()) {
if (state == 1) {
if (pred.charAt(pos) == ' ') {
} else if (pred.charAt(pos) == '(') {
noOfOpenParenthesis[exprIndex]++;
} else {
state++; // go to the next state
quote = false;
doublequote = false; // initialization for the next state
stringliteral = false;
functioncall = false;
begin = pos;
pos--; // need to minus because the pos will be incremented
}
} else if (state == 2) {
if (!stringliteral) {
if (pred.charAt(pos) == '\'') {
quote = true;
stringliteral = true;
} else if (pred.charAt(pos) == '"') {
doublequote = true;
stringliteral = true;
} else if (pred.charAt(pos) == '(') {
functioncall = true;
} else if (pred.charAt(pos) == ')' && functioncall) {
functioncall = false;
} else if (pred.charAt(pos) == ')' && !functioncall) {
expr[exprIndex] = pred.substring(begin, pos).trim();
exprIndex++;
state++;
pos--;
} else if (pos == pred.length() - 1) {
expr[exprIndex] = pred.substring(begin, pos + 1).trim();
exprIndex++;
} else if (pos + 5 < pred.length() && pred.substring(pos, pos + 5).compareTo(" and ") == 0) {
expr[exprIndex] = pred.substring(begin, pos).trim();
exprIndex++;
andExpr[exprIndex] = true;
pos = pos + 4;
state = 1;
} else if (pos + 4 < pred.length() && pred.substring(pos, pos + 4).compareTo(" or ") == 0) {
expr[exprIndex] = pred.substring(begin, pos).trim();
exprIndex++;
orExpr[exprIndex] = true;
pos = pos + 3;
state = 1;
}
} else {
if (quote && pred.charAt(pos) == '\'') {
quote = false;
stringliteral = false;
if (pos == pred.length() - 1) {
expr[exprIndex] = pred.substring(begin, pos + 1).trim();
exprIndex++;
}
} else if (doublequote && pred.charAt(pos) == '"') {
doublequote = false;
stringliteral = false;
if (pos == pred.length() - 1) {
expr[exprIndex] = pred.substring(begin, pos + 1).trim();
exprIndex++;
}
}
}
} else if (state == 3) {
if (pred.charAt(pos) == ' ') {
} else if (pred.charAt(pos) == ')') {
noOfCloseParenthesis[exprIndex - 1]++;
} else {
state++; // go to the next state
pos--;
}
} else if (state == 4) {
if (pred.substring(pos, pos + 3).compareTo("and") == 0) {
andExpr[exprIndex] = true;
pos++;
pos++;
} else if (pred.substring(pos, pos + 2).compareTo("or") == 0) {
orExpr[exprIndex] = true;
pos++;
}
state = 1;
} else {
throw new NoSuchPathException("Invalid state!");
}
pos++;
}
if (parts2.length == 1) {
nameTest = parts2[0];
String[] temp = {" "};
predicate = temp;
hasPredicate = false;
} else if (parts2.length == 2) {
// changed by erwin
nameTest = parts2[0];
// predicate = parts2[1];
hasPredicate = true;
if (exprIndex == 0 && parts2[1].endsWith("last()")) {
exprIndex++;
expr[0] = parts2[1];
}
// actually the name predicate supposed to be changed to expression.
// but there are too many parts need to be changed because of this.
// so i just keep the original
predicate = new String[exprIndex];
for (int i = 0; i < exprIndex; i++) {
predicate[i] = expr[i];
}
equality = new String[predicate.length];
hasEquality = new boolean[predicate.length];
equalityOperator = new String[predicate.length];
_isPositionPredicate = false;
for (int i = 0; i < predicate.length; i++) {
hasEquality[i] = false;
equalityOperator[i] = "";
equality[i] = "";
String[] equalityParts = predicate[i].split("!=");
if (equalityParts.length > 1) {
equalityOperator[i] = "!=";
predicate[i] = equalityParts[0];
equality[i] = equalityParts[1];
hasEquality[i] = true;
} else {
equalityParts = predicate[i].split("<=");
}
if (equalityParts.length > 1 && !hasEquality[i]) {
if (equalityParts[0].trim().equals("position()")) {
predicate[i] = equalityParts[1].trim();
equalityOperator[i] = "<=";
_isPositionPredicate = true;
equalityParts = predicate[i].split(">=");
} else {
equalityOperator[i] = "<=";
predicate[i] = equalityParts[0];
equality[i] = equalityParts[1];
hasEquality[i] = true;
}
} else {
equalityParts = predicate[i].split(">=");
}
if (equalityParts.length > 1 && !hasEquality[i]) {
if (equalityParts[0].trim().equals("position()")) {
predicate[i] = equalityParts[1].trim();
equalityOperator[i] = ">=";
_isPositionPredicate = true;
equalityParts = predicate[i].split("=");
} else {
equalityOperator[i] = ">=";
predicate[i] = equalityParts[0];
equality[i] = equalityParts[1];
hasEquality[i] = true;
}
} else {
equalityParts = predicate[i].split("=");
}
if (equalityParts.length > 1 && !hasEquality[i]) {
if (equalityParts[0].trim().equals("position()")) {
predicate[i] = equalityParts[1].trim();
// added by erwin
equalityParts = predicate[i].split("<");
_isPositionPredicate = true;
} else {
equalityOperator[i] = "=";
if (equalityParts.length > 2) {
equality[i] = equalityParts[equalityParts.length - 1];
predicate[i] = "";
for (int xx = equalityParts.length - 2; xx >= 0; xx--) {
if (xx != equalityParts.length - 2) {
predicate[i] = equalityOperator[i] + predicate[i];
}
predicate[i] = equalityParts[xx] + predicate[i];
}
} else {
predicate[i] = equalityParts[0];
equality[i] = equalityParts[1];
}
// SQL can't accept ", can only accept '
// SQL need to escape ', ex: Smith's --> Smith''s
String temp = equalityParts[equalityParts.length - 1].trim();
if (temp.charAt(0) == '\'' || temp.charAt(0) == '"') {
equality[i] = "'" + temp.substring(1, temp.length() - 1).replaceAll("'", "''") + "'";
} else {
equality[i] = temp;
}
hasEquality[i] = true;
}
} else {
equalityParts = predicate[i].split("<");
}
if (equalityParts.length > 1 && !hasEquality[i]) {
if (equalityParts[0].trim().equals("position()")) {
predicate[i] = equalityParts[1].trim();
_isPositionPredicate = true;
//hasEquality[i] = predicate[i].contains("last()") == true ? false : true;
equalityOperator[i] = "<";
equalityParts = predicate[i].split(">");
} else {
equalityOperator[i] = "<";
predicate[i] = equalityParts[0];
equality[i] = equalityParts[1];
hasEquality[i] = true;
}
} else {
equalityParts = predicate[i].split(">");
}
if (equalityParts.length > 1 && !hasEquality[i]) {
if (equalityParts[0].trim().equals("position()")) {
predicate[i] = equalityParts[1].trim();
_isPositionPredicate = true;
equalityOperator[i] = ">";
} else {
equalityOperator[i] = ">";
predicate[i] = equalityParts[0];
equality[i] = equalityParts[1];
hasEquality[i] = true;
}
} else if (equalityParts.length == 1 && equalityParts[0].equals(predicate[i]) && equalityOperator[i].length() == 0) {
Pattern pat = Pattern.compile("([0-9])+ (TO) ([0-9])+");
Matcher mat = pat.matcher(predicate[i].toUpperCase());
if (mat.matches()) {
} else if (predicate[i].contains("last()")) {
predicate[i] = equalityParts[0];
hasEquality[i] = false;
} else if (!isNumber(predicate[i])) {
equalityOperator[i] = "!!!";
predicate[i] = equalityParts[0];
hasEquality[i] = true;
}
}
predicate[i] = predicate[i].trim();
}
}
/* System.out.println("Translator.getStep(), createStep");
System.out.println(" axis : " + axis);
System.out.println(" nameTest : " + nameTest);
System.out.print(" predicate : ");
if (predicate != null) {
for (int k = 0; k < predicate.length; k++) {
System.out.print(predicate[k] + ", ");
}
}
System.out.print("\n");
System.out.print(" equality : ");
if (equality != null) {
for (int k = 0; k < equality.length; k++) {
System.out.print(equality[k] + ", ");
}
}
System.out.print("\n");
System.out.println(" hasPredicate : " + hasPredicate);
System.out.print(" hasEquality : ");
if (hasEquality != null) {
for (int k = 0; k < hasEquality.length; k++) {
System.out.print(hasEquality[k] + ", ");
}
}
System.out.print("\n");
System.out.print(" equalityOp : ");
if (equalityOperator != null) {
for (int k = 0; k < equalityOperator.length; k++) {
System.out.print(equalityOperator[k] + ", ");
}
}
System.out.print("\n");
System.out.print(" no of ( : ");
if (predicate != null) {
for (int k = 0; k < predicate.length; k++) {
System.out.print(noOfOpenParenthesis[k] + ", ");
}
}
System.out.print("\n");
System.out.print(" no of ) : ");
if (predicate != null) {
for (int k = 0; k < predicate.length; k++) {
System.out.print(noOfCloseParenthesis[k] + ", ");
}
}
System.out.print("\n");
System.out.print(" andExpr : ");
if (predicate != null) {
for (int k = 0; k < predicate.length; k++) {
System.out.print(andExpr[k] + ", ");
}
}
System.out.print("\n");
System.out.print(" or Expr : ");
if (predicate != null) {
for (int k = 0; k < predicate.length; k++) {
System.out.print(orExpr[k] + ", ");
}
}
System.out.print("\n");
*/
Step step = new Step(axis, nameTest, predicate, equality, hasPredicate, hasEquality, equalityOperator, noOfOpenParenthesis, noOfCloseParenthesis, andExpr, orExpr);
return step;
}
/*
* process each step first step: processStep(result[x],true,false); -->
* always ignore 1st step others : processStep(result[x],false,false); last
* step : processStep(result[x],false,true);
*/
void processStep(String splice, boolean first, boolean last) throws NoSuchPathException {
// added by erwin to handle /a/b[x=1][y=2]
if (splice.contains("][")) {
String[] temp = splice.split("[\\[\\]]");
String newPred = "[";
for (int i = 1; i < temp.length; i += 2) {
//checks predicate pattern
Pattern p = Pattern.compile("(\\[(position\\(\\)(>|<|(<=)|(>=)|=))?(([0-9])+( (to) ([0-9])+)?|(last\\(\\))((-)([0-9])+)?)\\])");
Matcher m = p.matcher("[" + temp[i] + "]");
//if pattern matches, gets the split predicate,
//else return normal predicate [x=1][y=2] ie no splitting done
if (m.matches()) {
if (newPred.length() == 1) {
newPred += temp[i] + "]";
} else {
newPred += "][" + temp[i];
}
} else {
if (newPred.length() == 1) {
newPred += temp[i];
} else {
newPred += " and " + temp[i];
}
}
}
newPred += "]";
splice = temp[0] + newPred;
}
Step step = getStep(splice); // 20061206 separate the string manipulation part to another function
if ((step.getAxis().compareTo("child") == 0) && (step.hasPredicate() == false)) {
_currentPath.add(step.getNameTest(), "child");
_updated = true;
_depth++;
} else if (step.getAxis().compareTo("self") == 0) {
if (_whereSQL.getTables() == 0) {
_whereSQL.newTable();
}
String lastStep = _currentPath.getLastStep();
String inpath = "";
String inpathAttr = "";
// wild card needs to return the principal node kind of the step
// axis
// For example, child::* will select all element children of the
// context node (doesn't include attribute or text node)
// node() matches any node
// child::node() selects all the children of the context node; no
// attribute nodes are returned, b'cos attributes are not children
if (lastStep.compareTo("*") == 0) {
inpath = _currentPath.getPathExcludeAttrText(false);
inpathAttr = _currentPath.getPathExcludeAttrText(true);
} else if (lastStep.compareTo("node()") == 0) {
inpath = _currentPath.getPathExcludeAttr(false);
inpathAttr = _currentPath.getPathExcludeAttr(true);
} else {
inpath = _currentPath.getPath(false);
inpathAttr = _currentPath.getPath(true);
}
if (inpath.equals("()")) {
throw new NoSuchPathException("The path does not exist");
}
_whereSQL.add("VK.PathID IN " + inpath, false);
_whereSQL.setAttributePath(inpathAttr); // klarinda 20060908
// (separate Attribute table)
if (step.hasPredicate() == false) {
_currentPath.removeLast();
_currentPath.add(step.getNameTest());
_updated = true;
} else {
_currentPath.removeLast(); // klarinda 20061208
_currentPath.add(step.getNameTest()); // klarinda 20061208
_whereSQL.newRv(_currentPath.getLevel()); // klarinda 20061208
// (because the newRV from processPredicate is removed)
processPredicate(step);
}
} else if (step.getAxis().compareTo("attribute") == 0) {
if (!last) {
throw new NoSuchPathException("Attribute axis should be the last step");
}
_currentPath.add(step.getNameTest());
String inpathAttr = _currentPath.getPath(true);
_whereSQL.setAttributePath(inpathAttr);
_updated = false;
} else {
// To check if there is position predicate
// added by E.L 22-Oct-2007
boolean _curStepHasEquality = true;
boolean[] temp = step.hasEquality();
for (int x = 0; x < temp.length; x++) {
if (!temp[x]) {
_curStepHasEquality = false;
break;
}
}
// update to SQL
if (_updated == true && _currentPath.getLevel() > 1 && !_curStepHasEquality) {
if (_whereSQL.getTables() == 0) {
_whereSQL.newTable();
}
String inpath = "";
String inpathAttr = "";
inpath = _currentPath.getPath(false);
inpathAttr = _currentPath.getPath(true);
if (inpath.equals("()")) {
throw new NoSuchPathException("The path does not exist");
}
_whereSQL.add("VK.PathID IN " + inpath, false);
_whereSQL.setAttributePath(inpathAttr); // klarinda 20060908
_updated = false;
}
if (_currentPath.getLevel() > 1 && !_curStepHasEquality) {
if (_whereSQL.getTables() == 0) {
_whereSQL.newTable(); // } fix added by LTM
}
int j = _currentPath.getLevel();
if (_currentPath.getPathString().indexOf("%") < 0) {
// for descendant step, BranchOrder can not be determined
// ---Wang Geng
_whereSQL.add("VK.BranchOrder < " + j, false); // to get the
// context nodes (represented by 1st desc leaf node)
}
}
// process axis
processAxis(step);
// process predicate
if (step.hasPredicate()) {
processPredicate(step);
_isFirstPredicate = false;
}
}
if (step.getAxis().compareTo("attribute") == 0) {
if (!last) {
throw new NoSuchPathException("Attribute axis should be the last step");
}
_whereSQL.setonlyReturnAttribute(true);
_whereSQL.setAttributePath(_currentPath.getPath(true));
_updated = false;
}
// last step finalization (update path to SQL if not updated)
if (last && _updated == true) {
if (_whereSQL.getTables() == 0) {
_whereSQL.newTable();
}
String inpath = "";
String inpathAttr = "";
// wild card needs to return the principal node kind of the step axis
// For example, child::* will select all element children of the
// context node (doesn't include attribute or text node)
// node() matches any node
// child::node() selects all the children of the context node; no
// attribute nodes are returned, b'cos attributes are not children
if (step.getNameTest().compareTo("*") == 0) {
inpath = _currentPath.getPathExcludeAttrText(false);
inpathAttr = _currentPath.getPathExcludeAttrText(true);
} else if (step.getNameTest().compareTo("node()") == 0) {
inpath = _currentPath.getPathExcludeAttr(false);
inpathAttr = _currentPath.getPathExcludeAttr(true);
} else {
inpath = _currentPath.getPath(false);
inpathAttr = _currentPath.getPath(true);
}
if (inpath.equals("()")) {
throw new NoSuchPathException("The path does not exist");
}
_whereSQL.add("VK.PathID IN " + inpath, false);
_whereSQL.setAttributePath(inpathAttr);
}
}
void processChildAxis(Step step) {
//get current level of child element
int j = _currentPath.getLevel() - 1;
//if current level not root
if (_currentPath.getLevel() > 1) {
int noTables = _whereSQL.getTables();
_whereSQL.newRv(_currentPath.getLevel());
_whereSQL.newRv(_currentPath.getLevel() + 1);
if (_isFirstPredicate) {
_whereSQL.newTable();
// j will always be greater than zero
if (noTables > 0) {
if (j > 0) {
// theorem 1
_whereSQL.add("VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RL.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RL.RValue as BIGINT) - 1 ", false);
} else {
_whereSQL.add("VK.DeweyOrderSum >= 0", false);
}
}
}
} else {
_whereSQL.newRv(_currentPath.getLevel() + 1);
_whereSQL.newTable();
// never reachable
if (_currentPath.getLevel() > 1) {
_whereSQL.add("VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", false);
}
}
_currentPath.add(step.getNameTest()); // klarinda 20061205 (move inside if-else)
}
void processFollowingAxis(Step step) {
_whereSQL.setDistinct(true);
int j = _currentPath.getLevel();
_whereSQL.newRv(j);
_whereSQL.newTable();
_whereSQL.setAttributePath("");
_currentPath.clearPath();
_currentPath.add("*");
if (step.getNameTest().compareTo("*") == 0 && step.getNameTest().compareTo("node()") == 0) {
_whereSQL.add("VK.DeweyOrderSum >= VL.DeweyOrderSum + 1 * CAST(RK.RValue as BIGINT) - 1 ", false);
} else {
int k = _currentPath.getQNameLevel_setCurrentPath(step.getNameTest()); // level from root to QName
if (k >= j) {
_whereSQL.add("VK.DeweyOrderSum >= VL.DeweyOrderSum + 1 * CAST(RK.RValue as BIGINT) - 1 ", false);
} else {
_whereSQL.newRv(k);
_whereSQL.add("VK.DeweyOrderSum >= VL.DeweyOrderSum + 1 * CAST(RL.RValue as BIGINT) - 1 " + "+ CAST(RK.RValue as BIGINT) - 1 ", false);
}
}
}
void processPrecedingAxis(Step step) {
_whereSQL.setDistinct(true);
int j = _currentPath.getLevel();
_whereSQL.newTable();
_whereSQL.setAttributePath("");
_currentPath.clearPath(); // klarinda 20060912 to facilitate nametest after fol / prec
_currentPath.add("*"); // klarinda 20060912 to facilitate nametest after fol / prec
if (step.getNameTest().compareTo("*") == 0 && step.getNameTest().compareTo("node()") == 0) {
_whereSQL.add("VK.DeweyOrderSum < VL.DeweyOrderSum ", false);
} else {
int k = _currentPath.getQNameLevel_setCurrentPath(step.getNameTest()); // level from root to QName
if (k >= j) {
_whereSQL.add("VK.DeweyOrderSum < VL.DeweyOrderSum ", false);
} else {
// since QName level (k) < context node level (j),
// so need to exclude the nodes which has common ancestor at
// QName level using theorem 1
_whereSQL.newRv(k);
_whereSQL.add("VK.DeweyOrderSum < VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1 ", false);
}
}
}
void processFollowingSiblingAxis(Step step) {
_whereSQL.setDistinct(true);
_whereSQL.newRv(_currentPath.getLevel() - 1);
_whereSQL.newRv(_currentPath.getLevel());
_whereSQL.newTable();
int j = _currentPath.getLevel() - 1;
if (j > 1 && _whereSQL.getTables() > 0) {
_whereSQL.add("VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum + 2 * CAST(RK.RValue as BIGINT) - 1" + "\n\t\t AND VL.DeweyOrderSum + CAST(RL.RValue as BIGINT) - 1 ", false);
} else if (j < 1) {
_whereSQL.add("VK.DeweyOrderSum < 0", false);
} else {
_whereSQL.add("VK.DeweyOrderSum >= VL.DeweyOrderSum + 2 * CAST(RK.RValue as BIGINT) - 1", false);
}
_currentPath.removeLast();
_currentPath.add(step.getNameTest());
}
void processPrecedingSiblingAxis(Step step) {
_whereSQL.setDistinct(true);
_whereSQL.newRv(_currentPath.getLevel() - 1);
_whereSQL.newRv(_currentPath.getLevel());
_whereSQL.newTable();
int j = _currentPath.getLevel() - 1;
if (j > 1) {
_whereSQL.add("VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RL.RValue as BIGINT) + 1" + "\n\t\t AND VL.DeweyOrderSum - 1 ", false);
} else {
// klarinda 20060629 - add else
_whereSQL.add("VK.DeweyOrderSum < VL.DeweyOrderSum ", false);
}
_currentPath.removeLast();
_currentPath.add(step.getNameTest());
}
void processAxis(Step step) throws NoSuchPathException {
int type = step.getType();
if (type == Constant.CHILD) {
processChildAxis(step);
} else if (type == Constant.FOLLOWING) {
processFollowingAxis(step);
} else if (type == Constant.PRECEDING) {
processPrecedingAxis(step);
} else if (type == Constant.FOLLOWING_SIBLING) {
processFollowingSiblingAxis(step);
} else if (type == Constant.PRECEDING_SIBLING) {
processPrecedingSiblingAxis(step);
} else if (type == Constant.ATTRIBUTE) {
} else if (type == Constant.PARENT) {
// parent --> note implemented yet
_currentPath.removeLast();
_currentPath.removeLast();
if (step.getNameTest().compareTo("*") == 0 || step.getNameTest().compareTo("node()") == 0) {
_currentPath.add(step.getNameTest());
}
_whereSQL.setDistinct(true);
_whereSQL.newRv(_currentPath.getLevel());
_whereSQL.newRv(_currentPath.getLevel() + 1);
_whereSQL.newTable();
if (_currentPath.getLevel() > 0) {
_whereSQL.add("VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RL.RValue as BIGINT) + 1" + "\n\t\t AND VL.DeweyOrderSum + CAST(RL.RValue as BIGINT) - 1", false);
} else {
throw new NoSuchPathException("Parent axis incorrect");
}
} else if (type == Constant.SELF) {
} else if (type == Constant.ANCESTOR || type == Constant.ANCESTOR_OR_SELF) {
// ancestor
_whereSQL._ancestorIndex++;
_whereSQL.newTable();
_whereSQL.newATable(_whereSQL._ancestorIndex);
_whereSQL.add("A" + _whereSQL._ancestorIndex + ".AncestorId=" + _whereSQL._ancestorIndex, false);
if (_whereSQL._ADMonitor == -1) {
// last AD step is ancestor
if (type == Constant.ANCESTOR_OR_SELF) {
_whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level<=A" + (_whereSQL._ancestorIndex - 1) + ".Level-2+" + _currentPath.getLevel(), false);
} else {
_whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level<A" + (_whereSQL._ancestorIndex - 1) + ".Level-2+" + _currentPath.getLevel(), false);
}
_whereSQL.add("VL.BranchOrder<A" + (_whereSQL._ancestorIndex - 1) + ".Level-2+" + _currentPath.getLevel(), false);
} else if (_whereSQL._ADMonitor == 1) {
// last AD step is
// descendant
if (type == Constant.ANCESTOR_OR_SELF) {
_whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level<=D" + (_whereSQL._descendantIndex) + ".Level+" + _currentPath.getLevel(), false);
} else {
_whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level<D" + (_whereSQL._descendantIndex) + ".Level+" + _currentPath.getLevel(), false);
}
_whereSQL.add("VL.BranchOrder<D" + (_whereSQL._descendantIndex) + ".Level+" + _currentPath.getLevel(), false);
} else {
// no ancestor or descendant before
if (type == Constant.ANCESTOR_OR_SELF) {
_whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level<=" + _currentPath.getLevel(), false);
} else {
_whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level<" + _currentPath.getLevel(), false);
}
}
_whereSQL.add("VK.PathID=A" + _whereSQL._ancestorIndex + ".PathID", false);
_whereSQL.newRv("A" + _whereSQL._ancestorIndex + ".level-1");
_whereSQL.add("VL.DeweyOrdersum<=(SELECT Min(VTmp.deweyordersum) from PathValue as VTmp where VTmp.PathId=VL.PathId AND VTmp.DocId=VL.DocId AND ABS(VTmp.DeweyOrderSum-dbo.getMinDeweyOrder(VL.DeweyOrderSum,RK.RValue,VL.DocId)) < CAST(RK.RValue as BIGINT))", false);
_whereSQL.add("ABS(VK.DeweyOrderSum-dbo.getMinDeweyOrder(VL.DeweyOrderSum,RK.RValue,V2.DocId)) < CAST(RK.RValue as BIGINT)", false);
if (_whereSQL._ADMonitor == -1) {
int tempIndex = _whereSQL._ancestorIndex - 1;
_whereSQL.newRv("A" + tempIndex + ".level-3+" + _currentPath.getLevel());
}
if (_whereSQL._ADMonitor == 1) {
_whereSQL.newRv("D" + _whereSQL._descendantIndex + ".level-1+" + _currentPath.getLevel());
}
if (_whereSQL._ADMonitor == 0) {
_whereSQL.newRv(_currentPath.getLevel() + "-1");
}
_whereSQL.add("(ABS(VK.DeweyOrderSum-dbo.getMinDeweyOrder(VL.DeweyOrderSum,RK.RValue,V2.DocId)) > CAST(RK.RValue as BIGINT) OR ABS(VK.DeweyOrderSum-dbo.getMinDeweyOrder(VL.DeweyOrderSum,RK.RValue,V2.DocId)) < 3)", false);
try {
Statement statement = _dbConnection.createStatement();
Statement statement2 = _dbConnection.createStatement();
String sqlquery;
if (_isNewQuery) {
sqlquery = "TRUNCATE TABLE AncestorTemp ";
statement.execute(sqlquery);
_isNewQuery = false;
}
if (_whereSQL._ancestorIndex == 1) {
sqlquery = "DELETE FROM AncestorTemp WHERE NOT Level<0";
statement.execute(sqlquery);
}
String tempCurrentStepNameTest = "." + step.getNameTest() + "#";
stepIndex++;
while (stepIndex < pathString.length) {
Step tempStep = getStep(pathString[stepIndex]);
if (tempStep.hasPredicate() || tempStep.getType() != Constant.CHILD) {
break;
}
tempCurrentStepNameTest = tempCurrentStepNameTest + "." + tempStep.getNameTest() + "#";
stepIndex++;
}
sqlquery = "SELECT PathExp,PathId FROM Path WHERE PATHEXP LIKE '%" + tempCurrentStepNameTest + "%'";
ResultSet results = statement.executeQuery(sqlquery);
int count;
while (results.next()) {
count = 0;
String pathExpTemp = results.getString("PathExp");
while (pathExpTemp.indexOf(tempCurrentStepNameTest) >= 0) {
String tempString = pathExpTemp;
pathExpTemp = pathExpTemp.substring(0, pathExpTemp.indexOf(tempCurrentStepNameTest)) + "." + step.getNameTest() + "#";
for (int i = 0; i < pathExpTemp.length(); i++) {
if (pathExpTemp.charAt(i) == '.') {
count++;
}
}
sqlquery = "INSERT INTO AncestorTemp (PathId,AncestorId,Level,AnceBranchOrd) VALUES (" + results.getString("PathId") + "," + _whereSQL._ancestorIndex + "," + count + ",0)";
statement2.execute(sqlquery);
pathExpTemp = tempString.substring(pathExpTemp.length(), tempString.length());
}
}
sqlquery = "SELECT ALL P.PathId AS PathId,P.PathExp AS PathExp,A.Level AS Level FROM Path AS P,AncestorTemp AS A WHERE P.PathId=A.PathId AND A.AncestorId=" + (_whereSQL._ancestorIndex) + "ORDER BY P.PathId";
ResultSet resultPathExp = statement.executeQuery(sqlquery);
resultPathExp.next();
String prePathExp = resultPathExp.getString("PathExp");
String currentPathExp;
while (resultPathExp.next()) {
currentPathExp = resultPathExp.getString("PathExp");
String[] tempPathExp1 = prePathExp.split("\\.");
String[] tempPathExp2 = currentPathExp.split("\\.");
int i = 1;
while (i < tempPathExp1.length && tempPathExp1[i].trim().indexOf(tempPathExp2[i].trim()) == 0) {
i++;
}
i--;
sqlquery = "UPDATE AncestorTemp SET AnceBranchOrd=" + i + " WHERE AncestorId=" + (_whereSQL._ancestorIndex) + " AND PathId=" + resultPathExp.getString("PathId") + " AND Level=" + resultPathExp.getString("Level");
statement2.execute(sqlquery);
prePathExp = currentPathExp;
}
if (_whereSQL._ADMonitor == 1) {
_whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level>D" + (_whereSQL._descendantIndex) + ".DescBranchOrd", false);
}
if (_whereSQL._ADMonitor == -1) {
_whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level>A" + (_whereSQL._ancestorIndex - 1) + ".AnceBranchOrd", false);
}
} catch (Exception ex) {
}
_currentPath.clearPath();
_currentPath.add("*");
_currentPath.add(step.getNameTest());
_whereSQL._ADMonitor = -1;
} else if (type == Constant.ANCESTOR_OR_SELF) { // ancestor-or-self
} else if (type == Constant.DESCENDANT || type == Constant.DESCENDANT_OR_SELF) {
// descendant
if (type == Constant.DESCENDANT_OR_SELF) {
String[] partsTemp = _currentPath.getPathString().split("\\.");
String TempNameTest = partsTemp[partsTemp.length - 1].substring(0, partsTemp[partsTemp.length - 1].length() - 1);
if (TempNameTest.indexOf("%") == 0) {
TempNameTest = TempNameTest.substring(1, TempNameTest.length());
}
if (TempNameTest.compareTo(step.getNameTest()) == 0) {
_currentPath.removeLast();
}
} else {
}
if (_currentPath.getLevel() > 1) {
_whereSQL.newRv(_currentPath.getLevel());
} else {
_whereSQL.newRv(_currentPath.getLevel() + 1);
}
if (_whereSQL._ADMonitor == 1) {
_whereSQL.add("D" + _whereSQL._descendantIndex + ".Level<=D" + (_whereSQL._descendantIndex + 1) + ".Level", false);
_whereSQL.add("VK.BranchOrder<RK.Level+1", false);
}
if (_whereSQL._ADMonitor == -1) {
_whereSQL.add("A" + _whereSQL._ancestorIndex + ".Level<D" + (_whereSQL._descendantIndex + 1) + ".Level+1+" + _currentPath.getLevel(), false);
_whereSQL.add("VK.BranchOrder<RK.Level+1", false);
}
_whereSQL._descendantIndex++;
_whereSQL.newTable();
if (_currentPath.getLevel() > 1) {
_whereSQL.add("VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum " + " \n\t\t AND VL.DeweyOrderSum + 2*CAST(RK.RValue as BIGINT) - 2 ", false);
}
_currentPath.addForDescendantAxis(step.getNameTest()); // change by erwin
String tempCurrentPath;
tempCurrentPath = _currentPath.getPathString();
String tempCurrentStepNameTest = "." + step.getNameTest() + "#";
stepIndex++;
while (stepIndex < pathString.length) {
Step tempStep = getStep(pathString[stepIndex]);
if (tempStep.hasPredicate() || tempStep.getType() != Constant.CHILD) {
break;
}
_currentPath.add(tempStep.getNameTest());
tempCurrentStepNameTest = tempCurrentStepNameTest + "." + tempStep.getNameTest() + "#";
stepIndex++;
}
String inpath;
inpath = _currentPath.getPath(false);
inpath = inpath.substring(1, inpath.length() - 1);
_currentPath.setCurrentPathString(tempCurrentPath);
String[] inpathId = inpath.split(",");
try {
Statement statement = _dbConnection.createStatement();
Statement statement2 = _dbConnection.createStatement();
int tempIndex = 0;
String[] tempPathExpStepArr;
String tempStepPathExp;
String sqlquery;
int tempLevel;
if (_isNewQuery) {
sqlquery = "TRUNCATE TABLE DescendantTemp ";
statement.execute(sqlquery);
_isNewQuery = false;
}
if (_whereSQL._descendantIndex == 1) {
sqlquery = "DELETE FROM DescendantTemp WHERE NOT Level<0";
statement.execute(sqlquery);
}
String[] tempStepCurrentPath;
if (_whereSQL._ADMonitor == -1) {
tempStepCurrentPath = _currentPath.getPathString().substring(3, _currentPath.getPathString().length()).split("\\.");
} else {
tempStepCurrentPath = _currentPath.getPathString().split("\\.");
}
for (int i = 1; i < tempStepCurrentPath.length - 1; i++) {
if (tempStepCurrentPath[i].indexOf("%") == 0) {
tempStepCurrentPath[i] = tempStepCurrentPath[i].substring(1, tempStepCurrentPath[i].indexOf("#"));
} else {
tempStepCurrentPath[i] = tempStepCurrentPath[i].substring(0, tempStepCurrentPath[i].indexOf("#"));
}
}
for (int i = 0; i < inpathId.length; i++) {
String tempPathExp;
sqlquery = "SELECT PathExp FROM Path WHERE PathId=" + inpathId[i];
ResultSet results = statement.executeQuery(sqlquery);
results.next();
tempPathExp = results.getString("PathExp");
for (int i2 = 1; i2 < tempStepCurrentPath.length - 1; i2++) {
tempIndex = tempPathExp.indexOf("." + tempStepCurrentPath[i2] + "#", tempIndex);
tempIndex++;
}
tempIndex += tempStepCurrentPath[tempStepCurrentPath.length - 2].length();
int minLevel = -1;
while (tempPathExp.indexOf(tempCurrentStepNameTest, tempIndex) > tempIndex) {
tempIndex = tempPathExp.indexOf(tempCurrentStepNameTest, tempIndex);
tempStepPathExp = tempPathExp.substring(0, tempIndex) + "." + step.getNameTest() + "#";
tempPathExpStepArr = tempStepPathExp.split("\\.");
tempLevel = tempPathExpStepArr.length - 1 - _currentPath.getLevel();
if (tempLevel < minLevel || minLevel == -1) {
minLevel = tempLevel;
}
sqlquery = "INSERT INTO DescendantTemp (PathId,DescendantId,Level,DescBranchOrd) VALUES (" + inpathId[i] + "," + _whereSQL._descendantIndex + "," + tempLevel + ",0)";
statement.execute(sqlquery);
tempIndex++;
}
tempIndex = 0;
_minDLevel = minLevel;
}
sqlquery = "SELECT ALL P.PathId AS PathId,P.PathExp AS PathExp,D.Level AS Level FROM Path AS P,DescendantTemp AS D WHERE P.PathId=D.PathId AND D.DescendantId=" + _whereSQL._descendantIndex + "ORDER BY P.PathId";
ResultSet resultPathExp = statement.executeQuery(sqlquery);
resultPathExp.next();
String prePathExp = resultPathExp.getString("PathExp");
String currentPathExp;
while (resultPathExp.next()) {
currentPathExp = resultPathExp.getString("PathExp");
String[] tempPathExp1 = prePathExp.split("\\.");
String[] tempPathExp2 = currentPathExp.split("\\.");
int i = 1;
while (i < tempPathExp1.length && tempPathExp1[i].trim().indexOf(tempPathExp2[i].trim()) == 0) {
i++;
}
i--;
sqlquery = "UPDATE DescendantTemp SET DescBranchOrd=" + i + " WHERE DescendantId=" + _whereSQL._descendantIndex + " AND PathId=" + resultPathExp.getString("PathId") + " AND Level=" + resultPathExp.getString("Level");
statement2.execute(sqlquery);
prePathExp = currentPathExp;
}
} catch (Exception ex) {
}
_whereSQL.newDTable(_whereSQL._descendantIndex);
_whereSQL.add("D" + _whereSQL._descendantIndex + ".PathId=VK.PathId", false);
_whereSQL.add("D" + _whereSQL._descendantIndex + ".DescendantId=" + _whereSQL._descendantIndex, false);
_whereSQL._ADMonitor = 1;
} else if (type == Constant.DESCENDANT_OR_SELF) { // descendant-or-self
} else {
throw new NoSuchPathException("Path axis incorrect");
}
_updated = true;
}
void processPredicate(Step step) throws NoSuchPathException {
int n_from = 0;
int n_to = 0;
int nf;
int nt;
int noOfEquality = 0; // k
boolean additionalPred = false;
String additionalPredStr = "";
for (int i = 0; i < step.getPredicate().length; i++) {
if (step.hasEquality(i)) {
noOfEquality++; // count how many tables need to be added
}
}
// new table only needed if the predicate is not position based predicate
_whereSQL.setNoOfNewTables(noOfEquality); // klarinda 20061123
_whereSQL.setDistinct(true);
for (int i = 0; i < step.getPredicate().length; i++) {
if (step.hasEquality(i)) {
CurrentPath tempPath = new CurrentPath(_dbConnection);
tempPath.addString(_currentPath.getPathString());
// for predicate > 1 steps (klarinda 20061120)
String[] predicateStep = step.getPredicate(i).split("/");
for (int x = 0; x < predicateStep.length; x++) {
if (!predicateStep[x].trim().equals("text()")) {
if ((predicateStep[x].trim().contains("[")) && (predicateStep[x].trim().contains("]"))) {
//pattern consists of attribute @(from a through z, A through Z, 0 through 9 (inclusive) and position (>, <, <=, >=, =), 0 through 9 (inclusive, can be double digit, eg 88) to
//0 through 9 (inclusive, can be double digit, eg 88) OR last - 0 through 9 (inclusive)
//@abc\\[position()(equality sign) (0-9) to (0-9) OR @abc\\[last()-(0-9)]
Pattern p = Pattern.compile("([@a-zA-Z_0-9])+(\\[(position\\(\\)(>|<|(<=)|(>=)|=))?(([0-9])+( (to) ([0-9])+)?|(last\\(\\))((-)([0-9])+)?)\\])?");
Matcher m = p.matcher(predicateStep[x].trim());
if (m.matches()) {
//if pattern matches --> >1 predicate, get additional predicate numbers (0-9) to (0-9)
additionalPred = true;
additionalPredStr = predicateStep[x].trim().substring(predicateStep[x].trim().indexOf("[") + 1, predicateStep[x].trim().lastIndexOf("]"));
predicateStep[x] = predicateStep[x].trim().substring(0, predicateStep[x].trim().indexOf("["));
//add predicate path ie, before "[" to the string array, tempPath
tempPath.add(predicateStep[x].trim());
} else {
throw new NoSuchPathException("Currently, XCalibur does not support your XPath!");
}
} else {
tempPath.add(predicateStep[x].trim());
}
}
}
_whereSQL.newTable();
if (step.getEquality(i).trim().length() > 0) {
if ((step.getEquality(i).trim().charAt(0) == '"') && (step.getEquality(i).trim().charAt(step.getEquality(i).trim().length() - 1) == '"')) {
step.setEquality(i, step.getEquality(i).trim().replaceAll("\"", "'"));
}
}
boolean isJoin = false;
// if ((step.getEqualityOperator(i).equals("=") || step.getEqualityOperator(i).equals("!=")) && step.getEquality(i).charAt(0) != '\'') {
if (!step.getEqualityOperator(i).equals("!!!") && !_isPositionPredicate) {
if (step.getEquality(i).charAt(0) != '\'') {
try {
Float.valueOf(step.getEquality(i));
} catch (NumberFormatException e) {
isJoin = true;
boolean isSlash = (step.getEquality(i).charAt(0) == '/') ? true : false;
boolean isJoinAttribute = false;
CurrentPath joinPath = new CurrentPath(_dbConnection);
if (!isSlash) {
joinPath.addString(_currentPath.getPathString());
}
String[] joinStep = step.getEquality(i).split("/");
for (int x = 0; x < joinStep.length; x++) {
joinPath.add(joinStep[x].trim());
}
isJoinAttribute = (joinStep[joinStep.length - 1].trim().charAt(0) == '@') ? true : false;
String joinPathId = joinPath.getOnePath();
if (joinPathId.equals("()")) {
throw new NoSuchPathException("The join path does not exist");
}
String joinValue;
if (isJoinAttribute) {
// attribute table is separated from elements
_whereSQL.newJoinAttributeTable();
_whereSQL.add("ALj.PathID IN " + joinPathId, true); // j is for join
joinValue = " ALj.LeafValue ";
if (!isSlash) {
_whereSQL.newJoinTable();
_whereSQL.add(" ALj.docId = VL.docId \n AND VLj.leafOrder = ALj.LeafOrder ", true);
}
} else {
_whereSQL.newJoinTable(); // the order of table in
// fromSQL is not so correct (ignore this prob for time being)
_whereSQL.add("VLj.PathID IN " + joinPathId, true); // j is for join
joinValue = " VLj.LeafValue ";
}
String joinNotSlash = "";
if (!isSlash) {
joinNotSlash = "\n\t AND VK.DeweyOrderSum BETWEEN VLj.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VLj.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ";
}
if (step.getPredicate(i).charAt(0) == '@') {
// attribute, need to join with attribute table
_whereSQL.newAttributeTable();
_whereSQL.add("AL.LeafOrder = VL.LeafOrder ", true);
if (step.getEqualityOperator(i).equals("=")) {
// added by erwin
Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
Matcher mat = pat.matcher(joinValue);
if (mat.matches()) {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "AL.LeafValue LIKE " + joinValue + " \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
} else {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "AL.LeafValue LIKE " + joinValue + " COLLATE SQL_Latin1_General_CP1_CS_AS \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
}
} else {
// added by erwin
Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
Matcher mat = pat.matcher(joinValue);
if (mat.matches()) {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "AL.LeafValue NOT LIKE " + joinValue + " \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
} else {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "AL.LeafValue NOT LIKE " + joinValue + " COLLATE SQL_Latin1_General_CP1_CS_AS \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
}
}
} else {
if (step.getEqualityOperator(i).equals("=")) {
// added by erwin
Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
Matcher mat = pat.matcher(joinValue);
if (mat.matches()) {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VL.LeafValue LIKE " + joinValue + " \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
} else {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VL.LeafValue LIKE " + joinValue + " COLLATE SQL_Latin1_General_CP1_CS_AS \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
}
} else if (step.getEqualityOperator(i).equals("=")) {
// added by erwin
Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
Matcher mat = pat.matcher(joinValue);
if (mat.matches()) {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VL.LeafValue NOT LIKE " + joinValue + " \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
} else {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VL.LeafValue NOT LIKE " + joinValue + " COLLATE SQL_Latin1_General_CP1_CS_AS \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
}
} else if (step.getEqualityOperator(i).equals(">")) {
// added by erwin
Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
Matcher mat = pat.matcher(joinValue);
if (mat.matches()) {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.LeafValue as FLOAT) > CAST(" + joinValue + " as FLOAT) \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
} else {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.LeafValue as FLOAT) > CAST(" + joinValue + " as FLOAT) \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
}
} else if (step.getEqualityOperator(i).equals(">=")) {
// added by erwin
Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
Matcher mat = pat.matcher(joinValue);
if (mat.matches()) {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.LeafValue as FLOAT) >= CAST(" + joinValue + " as FLOAT) \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
} else {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.LeafValue as FLOAT) >= CAST(" + joinValue + " as FLOAT) \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
}
} else if (step.getEqualityOperator(i).equals("<")) {
// added by erwin
Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
Matcher mat = pat.matcher(joinValue);
if (mat.matches()) {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.LeafValue as FLOAT) < CAST(" + joinValue + " as FLOAT) \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
} else {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.LeafValue as FLOAT) < CAST(" + joinValue + " as FLOAT) \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
}
} else if (step.getEqualityOperator(i).equals("<=")) {
// added by erwin
Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
Matcher mat = pat.matcher(joinValue);
if (mat.matches()) {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.LeafValue as FLOAT) <= CAST(" + joinValue + " as FLOAT) \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
} else {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.LeafValue as FLOAT) <= CAST(" + joinValue + " as FLOAT) \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 " + joinNotSlash, step.getNoOfCloseParenthesis(i));
}
}
}
}
}
}
if (!isJoin) {
if (step.getPredicate(i).indexOf("@") >= 0) {
// added bby erwin 2007-08-02
// -> for /a/b[c/@id] need to join with attribute table
_whereSQL.newAttributeTable(true);
String dummy = tempPath.removeLast2();
String inpath = tempPath.getPath(false);
_whereSQL.add("VL.PathID IN " + inpath, false);
tempPath.add(dummy);
_whereSQL.add("AL.LeafOrder = VL.LeafOrder ", true);
if (step.getEqualityOperator(i).equals("=")) {
// added by erwin
Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
Matcher mat = pat.matcher(step.getEquality(i));
if (mat.matches()) {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "AL.LeafValue LIKE " + step.getEquality(i) + " \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
} else {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "AL.LeafValue LIKE " + step.getEquality(i) + " COLLATE SQL_Latin1_General_CP1_CS_AS \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
}
} else if (step.getEqualityOperator(i).equals("!=")) {
Pattern pat = Pattern.compile("([0-9])+.([0-9])+");
Matcher mat = pat.matcher(step.getEquality(i));
if (mat.matches()) {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "AL.LeafValue NOT LIKE " + step.getEquality(i) + " \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
} else {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "AL.LeafValue NOT LIKE " + step.getEquality(i) + " COLLATE SQL_Latin1_General_CP1_CS_AS \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
}
} else if (step.getEqualityOperator(i).equals("!!!")) {
// added by erwin
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "\n\t VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
} else {
try {
Float temp = Float.valueOf(step.getEquality(i));
if (temp == null) {
throw new NoSuchPathException("Predicate value incorrect");
}
} catch (NumberFormatException e) {
throw new NoSuchPathException("Precicate value incorrect");
}
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(AL.LeafValue as FLOAT) " + step.getEqualityOperator(i) + " " + step.getEquality(i) + "\n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
}
} else {
// For MINT query only
if (step.getEqualityOperator(i).equals("!!!")) {
_whereSQL.addAndOrExprMINT(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
} else if (step.getEqualityOperator(i).equals("=")) {
Pattern pat = Pattern.compile("([0-9])+(.([0-9])+)?");
Matcher mat = pat.matcher(step.getEquality(i));
if (mat.matches()) {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VL.LeafValue LIKE " + step.getEquality(i) + " \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
} else {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VL.LeafValue LIKE " + step.getEquality(i) + " COLLATE SQL_Latin1_General_CP1_CS_AS \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
}
} else if (step.getEqualityOperator(i).equals("!=")) {
Pattern pat = Pattern.compile("([0-9])+(.([0-9])+)?");
Matcher mat = pat.matcher(step.getEquality(i));
if (mat.matches()) {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VL.LeafValue NOT LIKE " + step.getEquality(i) + " \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
} else {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VL.LeafValue NOT LIKE " + step.getEquality(i) + " COLLATE SQL_Latin1_General_CP1_CS_AS \n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
}
} else {
try {
Float temp = Float.valueOf(step.getEquality(i));
if (temp == null) {
throw new NoSuchPathException("Predicate value incorrect");
}
} catch (NumberFormatException e) {
throw new NoSuchPathException("Precicate value incorrect");
}
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "CAST(VL.LeafValue as FLOAT) " + step.getEqualityOperator(i) + " " + step.getEquality(i) + "\n\t AND VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum - CAST(RK.RValue as BIGINT) + 1" + " \n\t\t AND VL.DeweyOrderSum + CAST(RK.RValue as BIGINT) - 1 ", step.getNoOfCloseParenthesis(i));
}
}
}
String inpath = tempPath.getOnePath();
// klarinda 20070108 for MINT query only
if (step.getEqualityOperator(i).equals("!!!")) {
if (step.getPredicate(i).indexOf("@") < 0) {
inpath = tempPath.getPath(false);
}
}
// end of klarinda 20070108
if (inpath.equals("()")) {
throw new NoSuchPathException("The path does not exist");
}
if (step.getPredicate(i).indexOf("@") >= 0) {
// added bby erwin
// 2007-08-02 -> for /a/b[c/@id]
_whereSQL.add("AL.PathID IN " + inpath, true);
} else {
_whereSQL.add("VL.PathID IN " + inpath, true);
}
// klarinda 20070108 for MINT query only
if (step.getEqualityOperator(i).equals("!!!")) {
// to get the context nodes (represented by 1st desc leaf node)
_whereSQL.add("VL.BranchOrder < " + tempPath.getLevel(), false);
}
} else {
switch (step.getType()) {
case Constant.CHILD:
n_from = step.getPredicateFrom(i);
n_to = step.getPredicateTo(i);
break;
case Constant.FOLLOWING:
n_from = step.getPredicateFrom(i) + 1;
n_to = step.getPredicateTo(i) + 1;
break;
case Constant.PRECEDING:
n_from = -step.getPredicateFrom(i) + 1;
n_to = -step.getPredicateTo(i) + 1;
break;
case Constant.FOLLOWING_SIBLING:
n_from = step.getPredicateFrom(i) + 1;
n_to = step.getPredicateTo(i) + 1;
break;
case Constant.PRECEDING_SIBLING:
n_from = -step.getPredicateFrom(i) + 1;
n_to = -step.getPredicateTo(i) + 1;
break;
case Constant.SELF:
n_from = step.getPredicateFrom(i);
n_to = step.getPredicateTo(i);
break;
default:
System.out.println("ERROR:Axis type cannot have predicate\n"); // ???
}
switch (step.getPredicateType()) {
case 0:
// position based predicate without name test
nf = n_from - 1;
nt = n_to;
if (!_isFirstPredicate) {
_whereSQL.newTable();
}
if (step.getPredicate(i).startsWith("last()")) {
String inpathAttr = _currentPath.getPath(false);
int c = _whereSQL.getLastTempTableCounter();
String additionExp2 = step.getPredicate(i).replace("last()", "");
String additionExp1 = "(L" + (c + 1) + ".MAXI " + additionExp2 + " - 1 )";
String myQuery = "";
try {
Statement stmt = _dbConnection.createStatement();
if (c == 0) {
stmt.executeUpdate("TRUNCATE TABLE [LASTTEMP] ");
if (_currentPath.getLevel() == 2) {
myQuery = "INSERT INTO [LASTTEMP]" + "SELECT ROW_NUMBER() OVER(PARTITION BY DOCID ORDER BY LEAFORDER), " + "DOCID, SiblingSum, " + (c + 1) + " AS FLAG, " + "0 AS DEWEYORDERSUM, 0 AS PDOS " + "FROM PATHVALUE " + "WHERE PathID IN " + inpathAttr + " " + " AND (BRANCHORDER = " + _currentPath.getLevel() + " - 1 OR BRANCHORDER = 0) ";
stmt.executeUpdate(myQuery);
} else {
String parentPath = _currentPath.getPrevPath(false);
myQuery = "INSERT INTO [LASTTEMP]" + "SELECT ROW_NUMBER() OVER(PARTITION BY DOCID ORDER BY LEAFORDER), " + "DOCID, SiblingSum, " + "0 AS FLAG, " + "DEWEYORDERSUM, 0 AS PDOS " + "FROM PATHVALUE " + "WHERE PathID IN " + parentPath + " " + " AND (BRANCHORDER = " + _currentPath.getLevel() + " - 2 OR BRANCHORDER = 0) ";
stmt.executeUpdate(myQuery);
myQuery = "INSERT INTO [LASTTEMP]" + "SELECT " + " ROW_NUMBER() OVER(PARTITION BY P.DOCID,L.DEWEYORDERSUM ORDER BY P.DOCID, P.DEWEYORDERSUM) AS RID, " + " P.DOCID, P.SIBLINGSUM, 1 AS FLAG, P.DEWEYORDERSUM, L.DEWEYORDERSUM AS PDOS " + "FROM LASTTEMP AS L, PATHVALUE AS P, DocumentRValue R " + "WHERE L.DOCID = P.DOCID " + " AND L.DOCID = R.DOCID " + " AND L.FLAG = 0 " + " AND R.LEVEL = " + (_currentPath.getLevel() - 2) + " " + " AND P.PathID IN " + inpathAttr + " " + " AND P.BRANCHORDER < " + _currentPath.getLevel() + " " + " AND P.DeweyOrderSum BETWEEN L.DeweyOrderSum - CAST(R.RValue as BIGINT) + 1 " + " AND L.DeweyOrderSum + CAST(R.RValue as BIGINT) - 1" + " AND P.SiblingSum >= L.SiblingSum ";
stmt.executeUpdate(myQuery);
}
} else {
// multi last predicate
}
stmt.close();
} catch (Exception e) {
}
_whereSQL.addLastTempTable(_currentPath.getLevel());
if (step.getEqualityOperator(i).equals("<")) {
additionExp1 = "0";
additionExp2 = "-1";
}
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), " VK.DeweyOrderSum BETWEEN VM.DeweyOrderSum + " + additionExp1 + " * (2 * CAST(RK.RValue as BIGINT) - 1)" + " \n\t\t AND VM.DeweyOrderSum + " + " (L" + (c + 1) + ".MAXI " + additionExp2 + " )" + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", step.getNoOfCloseParenthesis(i));
} else {
if (_isFirstPredicate) {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VK.DeweyOrderSum BETWEEN VM.DeweyOrderSum + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1) " + " \n\t\t AND VM.DeweyOrderSum + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", step.getNoOfCloseParenthesis(i));
} else {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), "VK.DeweyOrderSum BETWEEN VL.DeweyOrderSum + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1) " + " \n\t\t AND VL.DeweyOrderSum + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", step.getNoOfCloseParenthesis(i));
}
}
break;
case 1:
nf = n_from - 1;
nt = n_to;
// k20061123 change VL to VM
if (step.getPredicate(i).startsWith("last()")) {
String inpathAttr = _currentPath.getPath(false);
int c = _whereSQL.getLastTempTableCounter();
String additionExp2 = step.getPredicate(i).replace("last()", "");
String additionExp1 = "(L" + (c + 1) + ".MAXI " + additionExp2 + " - 1 )";
String myQuery = "";
try {
Statement stmt = _dbConnection.createStatement();
if (c == 0) {
stmt.executeUpdate("TRUNCATE TABLE [LASTTEMP] ");
if (_currentPath.getLevel() == 2) {
myQuery = "INSERT INTO [LASTTEMP]" + "SELECT ROW_NUMBER() OVER(PARTITION BY DOCID ORDER BY LEAFORDER), " + "DOCID, SiblingSum, " + (c + 1) + " AS FLAG, " + "0 AS DEWEYORDERSUM, 0 AS PDOS " + "FROM PATHVALUE " + "WHERE PathID IN " + inpathAttr + " " + " AND (BRANCHORDER = " + _currentPath.getLevel() + " - 1 OR BRANCHORDER = 0) ";
stmt.executeUpdate(myQuery);
} else {
String parentPath = _currentPath.getPrevPath(false);
myQuery = "INSERT INTO [LASTTEMP]" + "SELECT ROW_NUMBER() OVER(PARTITION BY DOCID ORDER BY LEAFORDER), " + "DOCID, SiblingSum, " + "0 AS FLAG, " + "DEWEYORDERSUM, 0 AS PDOS " + "FROM PATHVALUE " + "WHERE PathID IN " + parentPath + " " + " AND (BRANCHORDER = " + _currentPath.getLevel() + " - 2 OR BRANCHORDER = 0) ";
stmt.executeUpdate(myQuery);
myQuery = "INSERT INTO [LASTTEMP]" + "SELECT " + " ROW_NUMBER() OVER(PARTITION BY P.DOCID,L.DEWEYORDERSUM ORDER BY P.DOCID, P.DEWEYORDERSUM) AS RID, " + " P.DOCID, P.SIBLINGSUM, 1 AS FLAG, P.DEWEYORDERSUM, L.DEWEYORDERSUM AS PDOS " + "FROM LASTTEMP AS L, PATHVALUE AS P, DocumentRValue R " + "WHERE L.DOCID = P.DOCID " + " AND L.DOCID = R.DOCID " + " AND L.FLAG = 0 " + " AND R.LEVEL = " + (_currentPath.getLevel() - 2) + " " + " AND P.PathID IN " + inpathAttr + " " + " AND P.BRANCHORDER < " + _currentPath.getLevel() + " " + " AND P.DeweyOrderSum BETWEEN L.DeweyOrderSum - CAST(R.RValue as BIGINT) + 1 " + " AND L.DeweyOrderSum + CAST(R.RValue as BIGINT) - 1" + " AND P.SiblingSum >= L.SiblingSum ";
stmt.executeUpdate(myQuery);
}
} else {
// multi last predicate
}
stmt.close();
} catch (Exception e) {
}
if (step.getEqualityOperator(i).equals("<")) {
additionExp1 = "0";
additionExp2 = "-1";
}
_whereSQL.addLastTempTable(_currentPath.getLevel());
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), " VK.SiblingSum BETWEEN VM.SiblingSum + " + additionExp1 + " * (2 * CAST(RK.RValue as BIGINT) - 1)" + " \n\t\t AND VM.SiblingSum + " + " (L" + (c + 1) + ".MAXI " + additionExp2 + " )" + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", step.getNoOfCloseParenthesis(i));
} else {
if (nt == -1) {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), " VK.SiblingSum > VM.SiblingSum + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1) + 1", step.getNoOfCloseParenthesis(i));
} else if (nf == -1) {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), " VK.SiblingSum < VM.SiblingSum + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1", step.getNoOfCloseParenthesis(i));
} else {
_whereSQL.addAndOrExpr(step.getAndExpr(i), step.getOrExpr(i), step.getNoOfOpenParenthesis(i), " VK.SiblingSum BETWEEN VM.SiblingSum + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1)" + " \n\t\t AND VM.SiblingSum + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", step.getNoOfCloseParenthesis(i));
}
}
break;
default:
}
}
}
if (additionalPred) {
Pattern pat = Pattern.compile("([0-9])+(.([0-9])+)?");
Matcher mat = pat.matcher(additionalPredStr);
if (mat.matches()) {
nf = Integer.parseInt(additionalPredStr) - 1;
nt = Integer.parseInt(additionalPredStr);
_whereSQL.newRv(_currentPath.getLevel() + 1);
_whereSQL.addAndOrExpr(true, false, 0, " VL.SiblingSum BETWEEN 0 + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1)" + " \n\t\t AND 0 + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", 0);
} else if (additionalPredStr.startsWith("position()")) {
pat = Pattern.compile("([0-9])+ (TO) ([0-9])+");
mat = pat.matcher(additionalPredStr.toUpperCase());
if (mat.matches()) {
String[] toParts = additionalPredStr.toUpperCase().split("TO");
Integer castedInt = new Integer(toParts[0].trim());
nf = castedInt.intValue() - 1;
castedInt = new Integer(toParts[1].trim());
nt = castedInt.intValue();
_whereSQL.newRv(_currentPath.getLevel() + 1);
_whereSQL.addAndOrExpr(true, false, 0, " VL.SiblingSum BETWEEN 0 + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1)" + " \n\t\t AND 0 + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", 0);
} else if (additionalPredStr.contains(">=")) {
String[] toParts = additionalPredStr.toUpperCase().split(">=");
Integer castedInt = new Integer(toParts[1].trim());
nt = -1;
nf = castedInt.intValue() - 1;
_whereSQL.newRv(_currentPath.getLevel() + 1);
_whereSQL.addAndOrExpr(true, false, 0, " VL.SiblingSum > 0 + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1) + 1 ", 0);
} else if (additionalPredStr.contains("<=")) {
String[] toParts = additionalPredStr.toUpperCase().split("<=");
Integer castedInt = new Integer(toParts[1].trim());
nf = 0;
nt = castedInt.intValue();
_whereSQL.newRv(_currentPath.getLevel() + 1);
_whereSQL.addAndOrExpr(true, false, 0, " VL.SiblingSum BETWEEN 0 + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1)" + " \n\t\t AND 0 + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", 0);
} else if (additionalPredStr.contains(">")) {
String[] toParts = additionalPredStr.toUpperCase().split(">");
Integer castedInt = new Integer(toParts[1].trim());
nf = castedInt.intValue();
_whereSQL.newRv(_currentPath.getLevel() + 1);
_whereSQL.addAndOrExpr(true, false, 0, " VL.SiblingSum > 0 + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1) + 1 ", 0);
} else if (additionalPredStr.contains("<")) {
String[] toParts = additionalPredStr.toUpperCase().split("<");
Integer castedInt = new Integer(toParts[1].trim());
nt = castedInt.intValue() - 1;
nf = 0;
_whereSQL.newRv(_currentPath.getLevel() + 1);
_whereSQL.addAndOrExpr(true, false, 0, " VL.SiblingSum BETWEEN 0 + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1)" + " \n\t\t AND 0 + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", 0);
} else if (additionalPredStr.contains("=")) {
String[] toParts = additionalPredStr.toUpperCase().split("=");
Integer castedInt = new Integer(toParts[1].trim());
nf = castedInt.intValue() - 1;
castedInt = new Integer(toParts[1].trim());
nt = castedInt.intValue();
_whereSQL.newRv(_currentPath.getLevel() + 1);
_whereSQL.addAndOrExpr(true, false, 0, " VL.SiblingSum BETWEEN 0 + " + nf + " * (2 * CAST(RK.RValue as BIGINT) - 1)" + " \n\t\t AND VK.SiblingSum + " + nt + " * (2 * CAST(RK.RValue as BIGINT) - 1) - 1 ", 0);
}
}
}
_whereSQL.endOfPredicate();
System.out.println(_whereSQL.get());
}
// add by erwin 2007-07-04
private boolean isNumber(String s) {
try {
int I = Integer.parseInt(s);
} catch (NumberFormatException e) {
return false;
}
return true;
}
// added by erwin 25-Jul-2007
private boolean isXPathWellFormed(String XPath) {
long t1 = System.currentTimeMillis();
try {
dbsucxent.pathProcessor.w3cxpathparser.XPath parser = new dbsucxent.pathProcessor.w3cxpathparser.XPath(new java.io.StringBufferInputStream(XPath));
dbsucxent.pathProcessor.w3cxpathparser.SimpleNode tree;
tree = parser.XPath2();
if (((dbsucxent.pathProcessor.w3cxpathparser.SimpleNode) tree.jjtGetChild(0)).toString().equals("XPath")) {
long t2 = System.currentTimeMillis();
return true;
}
} catch (dbsucxent.pathProcessor.w3cxpathparser.ParseException pe) {
XPathErrMsg = pe.getMessage();
} catch (dbsucxent.pathProcessor.w3cxpathparser.TokenMgrError tme) {
XPathErrMsg = tme.getMessage();
}
long t2 = System.currentTimeMillis();
return false;
}
void ProcessChildAncestor(String[] OriginalPath, int arrIndex) {
if (arrIndex < 3) {
for (int i = 0; i < OriginalPath.length; i++) {
OriginalPath[i] = "";
}
} else {
OriginalPath[arrIndex] = OriginalPath[arrIndex].substring(0,
+ "-or-self" + OriginalPath[arrIndex].substring(8);
OriginalPath[arrIndex - 1] = "[child::" + OriginalPath[arrIndex - 1].substring(0, OriginalPath[arrIndex - 1].length()) + "]";
OriginalPath[arrIndex - 2] = OriginalPath[arrIndex - 2] + OriginalPath[arrIndex - 1];
OriginalPath[arrIndex - 1] = "";
}
}
void ProcessSelfAncestor(String[] originalPath, int arrIndex) {
if (arrIndex < 4) {
for (int i = 0; i < originalPath.length; i++) {
originalPath[i] = "";
}
} else {
originalPath[arrIndex - 1] = "[" + originalPath[arrIndex - 1] + "]";
originalPath[arrIndex - 2] = originalPath[arrIndex - 2] + originalPath[arrIndex - 1];
originalPath[arrIndex - 1] = "";
}
}
void ProcessFollowingSiblingAncestor(String[] originalPath, int arrIndex) {
if (arrIndex < 4) {
for (int i = 0; i < originalPath.length; i++) {
originalPath[i] = "";
}
} else {
originalPath[arrIndex - 1] = "[" + originalPath[arrIndex - 1] + "]";
originalPath[arrIndex - 2] = originalPath[arrIndex - 2] + originalPath[arrIndex - 1];
originalPath[arrIndex - 1] = "";
}
}
void ProcessDescendantAncestor(String[] originalPath, int arrIndex) {
if (arrIndex < 3) {
for (int i = 0; i < originalPath.length; i++) {
originalPath[i] = "";
}
} else {
String tempOriginalPath = "[" + originalPath[arrIndex - 1] + "]";
originalPath[arrIndex - 1] = "[" + originalPath[arrIndex - 1] + "]/";
for (int i = arrIndex; i < originalPath.length; i++) {
originalPath[arrIndex - 1] = originalPath[arrIndex - 1] + originalPath[i] + "/";
}
originalPath[arrIndex - 1] = originalPath[arrIndex - 1].substring(0, originalPath[arrIndex - 1].length() - 1);
originalPath[arrIndex - 1] = originalPath[arrIndex - 1] + "|";
originalPath[arrIndex] = "/descendant-or-self" + originalPath[arrIndex].substring(originalPath[arrIndex].indexOf("::")) + tempOriginalPath;
for (int i = arrIndex - 2; i > 0; i--) {
originalPath[arrIndex] = "/" + originalPath[i] + originalPath[arrIndex];
}
originalPath[arrIndex - 2] = originalPath[arrIndex - 2] + originalPath[arrIndex - 1];
originalPath[arrIndex - 1] = "";
if (originalPath[arrIndex].indexOf("/") == 0) {
originalPath[arrIndex] = originalPath[arrIndex].substring(1, originalPath[arrIndex].length());
}
}
}
void ProcessFollowingAncestor(String[] originalPath, int arrIndex) {
if (arrIndex < 4) {
for (int i = 0; i < originalPath.length; i++) {
originalPath[i] = "";
}
} else {
String tempOriginalPath = originalPath[arrIndex - 1];
originalPath[arrIndex - 1] = "following" + originalPath[arrIndex].substring(originalPath[arrIndex].indexOf("::")) + "[descendant" + originalPath[arrIndex - 1].substring(originalPath[arrIndex - 1].indexOf("::")) + "]/";
for (int i = arrIndex + 1; i < originalPath.length; i++) {
originalPath[arrIndex - 1] = originalPath[arrIndex - 1] + originalPath[i] + "/";
}
originalPath[arrIndex - 1] = originalPath[arrIndex - 1].substring(0, originalPath[arrIndex - 1].length() - 1);
originalPath[arrIndex - 1] = originalPath[arrIndex - 1] + "|";
originalPath[arrIndex] = "/ancestor-or-self::*[following-sibling::*/descendant-or-self" + tempOriginalPath.substring(tempOriginalPath.indexOf("::")) + "]/" + originalPath[arrIndex];
for (int i = arrIndex - 2; i > 0; i--) {
originalPath[arrIndex] = "/" + originalPath[i] + originalPath[arrIndex];
}
if (originalPath[arrIndex].indexOf("/") == 0) {
originalPath[arrIndex] = originalPath[arrIndex].substring(1, originalPath[arrIndex].length());
}
}
}
String mergeString(String[] modifiedPath) {
String finalPath = "/";
for (int i = 1; i < modifiedPath.length; i++) {
finalPath = finalPath + modifiedPath[i];
if (modifiedPath[i].length() > 0 && i < modifiedPath.length - 1) {
finalPath = finalPath + "/";
}
}
if (finalPath.length() == 1) {
finalPath = "";
}
return finalPath;
}
String splitAncestorOrSelf(String originalPath) {
String finalPath = "";
if (originalPath.indexOf("/ancestor-or-self::") > 0) {
finalPath = originalPath.substring(0, originalPath.indexOf("/ancestor-or-self::")) + "/ancestor::" + originalPath.substring(originalPath.indexOf("/ancestor-or-self::") + 19);
finalPath = finalPath + "|" + originalPath.substring(0, originalPath.indexOf("/ancestor-or-self::")) + "/self::" + originalPath.substring(originalPath.indexOf("/ancestor-or-self::") + 19);
} else {
finalPath = originalPath;
}
return finalPath;
}
String symmetryPath(String originalPath) {
String finalPath = "";
String[] unionPathArr = originalPath.split("\\|");
for (int i = 0; i < unionPathArr.length; i++) {
if (unionPathArr[i].indexOf("/ancestor::") > 0) {
String[] stepsArr = unionPathArr[i].split("/");
int k = 1;
while (k < stepsArr.length && stepsArr[k].indexOf("ancestor::") != 0) {
k++;
}
if (stepsArr[k - 1].indexOf("self::") == 0) {
ProcessSelfAncestor(stepsArr, k);
unionPathArr[i] = splitAncestorOrSelf(mergeString(stepsArr));
} else if (stepsArr[k - 1].indexOf("following-sibling::") == 0) {
ProcessFollowingSiblingAncestor(stepsArr, k);
unionPathArr[i] = splitAncestorOrSelf(mergeString(stepsArr));
} else if (stepsArr[k - 1].indexOf("descendant::") == 0) {
ProcessDescendantAncestor(stepsArr, k);
unionPathArr[i] = splitAncestorOrSelf(mergeString(stepsArr));
} else if (stepsArr[k - 1].indexOf("following::") == 0) {
ProcessFollowingAncestor(stepsArr, k);
unionPathArr[i] = splitAncestorOrSelf(mergeString(stepsArr));
} else {
ProcessChildAncestor(stepsArr, k);
unionPathArr[i] = splitAncestorOrSelf(mergeString(stepsArr));
}
if (unionPathArr[i].indexOf("/ancestor::") > 0) {
unionPathArr[i] = symmetryPath(unionPathArr[i]);
}
}
}
for (int i = 0; i < unionPathArr.length; i++) {
finalPath = finalPath + "|" + unionPathArr[i];
}
finalPath = finalPath.substring(finalPath.indexOf("/"));
return finalPath;
}
// added by Wang Geng, Following code is used to generate CPathId for
// Sandeep's algo
void generateCPath() {
try {
Statement statement = _dbConnection.createStatement();
Statement statement2 = _dbConnection.createStatement();
Statement statement3 = _dbConnection.createStatement();
String sqlquery;
sqlquery = "SELECT PathExp,PathId FROM Path WHERE CPathId=0 ORDER BY PathId";
ResultSet results = statement.executeQuery(sqlquery);
int count = 0;
String[] partsTemp;
String TempNameTest;
int maxLeafNum = 0;
String maxLeafNode = ".#";
while (true) {
while (results.next()) {
partsTemp = results.getString("PathExp").split("\\.");
TempNameTest = "." + partsTemp[partsTemp.length - 1].trim();
if (TempNameTest.compareTo(maxLeafNode) != 0) {
sqlquery = "SELECT Count(*) as CPathNum FROM Path WHERE PathExp LIKE '%" + TempNameTest.trim() + " %'";
ResultSet Results2 = statement2.executeQuery(sqlquery);
Results2.next();
if (maxLeafNum < Results2.getInt("CPathNum")) {
maxLeafNum = Results2.getInt("CPathNum");
maxLeafNode = TempNameTest;
}
}
}
if (maxLeafNum != 0) {
sqlquery = "SELECT PathId FROM Path WHERE PathExp LIKE '%" + maxLeafNode + " %' ORDER BY PathId";
ResultSet Results3 = statement2.executeQuery(sqlquery);
int i = 1 + count;
while (Results3.next()) {
sqlquery = "UPDATE Path SET CPathId=" + i + " WHERE PathId=" + Results3.getString("PathId");
statement3.execute(sqlquery);
i++;
}
count = count + maxLeafNum;
maxLeafNum = 0;
} else {
break;
}
sqlquery = "SELECT PathExp,PathId FROM Path WHERE CPathId=0 ORDER BY PathId";
results = statement.executeQuery(sqlquery);
}
} catch (Exception ex) {
}
}
}