1 package org.gnunet.seaspider;
4 import java.util.HashMap;
5 import java.util.Iterator;
6 import java.util.Stack;
7 import org.tmatesoft.sqljet.core.SqlJetException;
8 import org.tmatesoft.sqljet.core.SqlJetTransactionMode;
9 import org.tmatesoft.sqljet.core.table.ISqlJetTable;
10 import org.tmatesoft.sqljet.core.table.SqlJetDb;
13 * ExpressionDatabaseHandler is fed by expressions from the C code parser, and
14 * inserts them into SQLite Expression database using SQLJet API. Before
15 * inserting an expression into the database, ExpressionDatabaseHandler makes
16 * sure it's not redundant.
20 * int z = x + y // line 3
21 * The parser input for line 3 is: z, x, y, x + y, and z = x + y The
22 * expressions to be committed to the database will be only: z, and z = x + y
24 public class ExpressionDatabaseHandler {
26 private static final boolean DEBUG = false;
28 private static final boolean PRINT_STACK = false;
30 private static SqlJetDb db;
32 private static ISqlJetTable table;
34 private static String currentFileName = null;
36 private static int currentScopeEnd = 0;
38 private static Stack<HashMap<String, Integer>> expressionStack = new Stack<HashMap<String, Integer>>();
40 public static void createExpressionDatabase(String databasePath) {
41 String createTableQuery = "CREATE TABLE Expression ( expr_ID INTEGER PRIMARY KEY AUTOINCREMENT, "
42 + "file_name TEXT NOT NULL , expr_syntax TEXT NOT NULL ,"
43 + " start_lineno INT, end_lineno INT)";
45 File dbFile = new File(databasePath);
46 dbFile.delete();/* Delete it if already existent */
48 /* Create Expressions database */
50 db = SqlJetDb.open(dbFile, true);
51 db.getOptions().setAutovacuum(true);
52 db.beginTransaction(SqlJetTransactionMode.WRITE);
54 db.getOptions().setUserVersion(1);/* Sets the user's cookie */
58 /* Create table Expression */
59 db.createTable(createTableQuery);
60 db.beginTransaction(SqlJetTransactionMode.WRITE);
61 table = db.getTable("Expression");
62 } catch (SqlJetException e) {
67 public static void closeDatabase() {
71 } catch (SqlJetException e) {
76 private static void doInsertExpression(String fileName,
77 String expressionSyntax, int startLineNo, int endLineNo) {
80 System.out.println(fileName + ":[" + startLineNo + "-"
81 + endLineNo + "]: " + expressionSyntax);
82 table.insert(null, currentFileName, expressionSyntax, startLineNo,
84 } catch (SqlJetException e) {
89 private static boolean isRedundant(String expressionSyntax) {
90 Iterator<HashMap<String, Integer>> itr = expressionStack.iterator();
91 HashMap<String, Integer> scope;
93 while (itr.hasNext()) {
95 if (null != scope.get(expressionSyntax))
102 private static int getScopeEnd(HashMap<String, Integer> scope) {
103 Iterator<Integer> itr = scope.values().iterator();
107 private static HashMap<String, Integer> pushNewScope(int endLineNo) {
108 HashMap<String, Integer> scope = new HashMap<String, Integer>();
109 currentScopeEnd = endLineNo;
110 expressionStack.push(scope);
115 private static void printExpressionStack(String expressionSyntax,
116 int startLineNo, int endLineNo) {
117 HashMap<String, Integer> hashMap;
118 Iterator<String> itr;
119 System.out.println("Commit call for expression: " + expressionSyntax
120 + " start:" + startLineNo + " end:" + endLineNo);
121 for (int i = 0; i < expressionStack.size(); i++) {
122 hashMap = expressionStack.get(i);
123 itr = hashMap.keySet().iterator();
124 System.out.println("Printing expressions of scope " + i + ":");
125 while (itr.hasNext()) {
126 System.out.println(itr.next());
129 System.out.println("");
132 private static void insertExpression(String fileName,
133 String expressionSyntax, int startLineNo, int endLineNo) {
135 HashMap<String, Integer> currentScopeExpressions = null;
138 printExpressionStack(expressionSyntax, startLineNo, endLineNo);
140 if (null == currentFileName || !currentFileName.equals(fileName)) {
141 /* First time, or new file */
142 currentFileName = fileName;
143 if (!expressionStack.empty())
144 expressionStack.clear();
145 currentScopeExpressions = pushNewScope(endLineNo);
147 if (endLineNo > currentScopeEnd) {
149 * We are either in a new function or back to an outer scope
151 expressionStack.pop();
152 if (expressionStack.empty()) {
153 /* We are in a new function */
154 currentScopeExpressions = pushNewScope(endLineNo);
156 /* We just left an inner scope to an outer one */
157 currentScopeExpressions = expressionStack.lastElement();
158 currentScopeEnd = getScopeEnd(currentScopeExpressions);
159 if (isRedundant(expressionSyntax))
163 /* Either we delved into a sub-scope or we are in the same scope */
164 if (isRedundant(expressionSyntax))
166 if (endLineNo == currentScopeEnd) // same scope
167 currentScopeExpressions = expressionStack.lastElement();
170 currentScopeExpressions = pushNewScope(endLineNo);
174 /* Add the new expression */
175 currentScopeExpressions.put(expressionSyntax, endLineNo);
176 doInsertExpression(fileName, expressionSyntax, startLineNo, endLineNo);
180 * Inserts expression into the Expression Database
182 * @param fileName source file the expression comes from
183 * @param expressionSyntax string of the expression
184 * @param startLineNo line number of the expression
185 * @param endLineNo end line of the expression scope
187 public static void insertIntoExpressionTable(String fileName,
188 String expressionSyntax, int startLineNo, int endLineNo) {
189 if (expressionSyntax.matches("[0-9]*"))
191 if (expressionSyntax.startsWith("\""))
195 .println("Error:Database handle is not initialized. Program will exit now!");
199 String[] fileNameArr = fileName.split("src/");
200 if (fileNameArr.length > 1)
201 fileName = fileNameArr[1];
202 insertExpression(fileName, expressionSyntax, startLineNo, endLineNo);