1627aca2632d66e9bae19a8642cc670eb4caf993
[oweals/gnunet.git] / src / monkey / seaspider / org / gnunet / seaspider / ExpressionDatabaseHandler.java
1 package org.gnunet.seaspider;
2
3 import java.io.File;
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;
11
12 /**
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. 
17  * For example: 
18  * int x = 0; 
19  * int y = 1; 
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
23  */
24 public class ExpressionDatabaseHandler {
25
26         private static final boolean DEBUG = false;
27
28         private static final boolean PRINT_STACK = false;
29
30         private static SqlJetDb db;
31
32         private static ISqlJetTable table;
33
34         private static String currentFileName = null;
35
36         private static int currentScopeEnd = 0;
37
38         private static Stack<HashMap<String, Integer>> expressionStack = new Stack<HashMap<String, Integer>>();
39
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)";
44
45                 File dbFile = new File(databasePath);
46                 dbFile.delete();/* Delete it if already existent */
47
48                 /* Create Expressions database */
49                 try {
50                         db = SqlJetDb.open(dbFile, true);
51                         db.getOptions().setAutovacuum(true);
52                         db.beginTransaction(SqlJetTransactionMode.WRITE);
53                         try {
54                                 db.getOptions().setUserVersion(1);/* Sets the user's cookie */
55                         } finally {
56                                 db.commit();
57                         }
58                         /* Create table Expression */
59                         db.createTable(createTableQuery);
60                         db.beginTransaction(SqlJetTransactionMode.WRITE);
61                         table = db.getTable("Expression");
62                 } catch (SqlJetException e) {
63                         e.printStackTrace();
64                 }
65         }
66
67         public static void closeDatabase() {
68                 try {
69                         db.commit();
70                         db.close();
71                 } catch (SqlJetException e) {
72                         e.printStackTrace();
73                 }
74         }
75
76         private static void doInsertExpression(String fileName,
77                         String expressionSyntax, int startLineNo, int endLineNo) {
78                 try {
79                         if (DEBUG)
80                                 System.out.println(fileName + ":[" + startLineNo + "-"
81                                                 + endLineNo + "]: " + expressionSyntax);
82                         table.insert(null, currentFileName, expressionSyntax, startLineNo,
83                                         endLineNo);
84                 } catch (SqlJetException e) {
85                         e.printStackTrace();
86                 }
87         }
88
89         private static boolean isRedundant(String expressionSyntax) {
90                 Iterator<HashMap<String, Integer>> itr = expressionStack.iterator();
91                 HashMap<String, Integer> scope;
92
93                 while (itr.hasNext()) {
94                         scope = itr.next();
95                         if (null != scope.get(expressionSyntax))
96                                 return true;
97                 }
98
99                 return false;
100         }
101
102         private static int getScopeEnd(HashMap<String, Integer> scope) {
103                 Iterator<Integer> itr = scope.values().iterator();
104                 return itr.next();
105         }
106
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);
111
112                 return scope;
113         }
114
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());
127                         }
128                 }
129                 System.out.println("");
130         }
131
132         private static void insertExpression(String fileName,
133                         String expressionSyntax, int startLineNo, int endLineNo) {
134
135                 HashMap<String, Integer> currentScopeExpressions = null;
136
137                 if (PRINT_STACK)
138                         printExpressionStack(expressionSyntax, startLineNo, endLineNo);
139
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);
146                 } else {
147                         if (endLineNo > currentScopeEnd) {
148                                 /*
149                                  * We are either in a new function or back to an outer scope
150                                  */
151                                 expressionStack.pop();
152                                 if (expressionStack.empty()) {
153                                         /* We are in a new function */
154                                         currentScopeExpressions = pushNewScope(endLineNo);
155                                 } else {
156                                         /* We just left an inner scope to an outer one */
157                                         currentScopeExpressions = expressionStack.lastElement();
158                                         currentScopeEnd = getScopeEnd(currentScopeExpressions);
159                                         if (isRedundant(expressionSyntax))
160                                                 return;
161                                 }
162                         } else {
163                                 /* Either we delved into a sub-scope or we are in the same scope */
164                                 if (isRedundant(expressionSyntax))
165                                         return;
166                                 if (endLineNo == currentScopeEnd) // same scope
167                                         currentScopeExpressions = expressionStack.lastElement();
168                                 else
169                                         // new sub-scope
170                                         currentScopeExpressions = pushNewScope(endLineNo);
171                         }
172                 }
173
174                 /* Add the new expression */
175                 currentScopeExpressions.put(expressionSyntax, endLineNo);
176                 doInsertExpression(fileName, expressionSyntax, startLineNo, endLineNo);
177         }
178
179         /**
180          * Inserts expression into the Expression Database
181          * 
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
186          */
187         public static void insertIntoExpressionTable(String fileName,
188                         String expressionSyntax, int startLineNo, int endLineNo) {
189                 if (expressionSyntax.matches("[0-9]*"))
190                         return;
191                 if (expressionSyntax.startsWith("\""))
192                         return;
193                 if (db == null) {
194                         System.out
195                                         .println("Error:Database handle is not initialized. Program will exit now!");
196                         System.exit(1);
197                 }
198                 
199                 String[] fileNameArr = fileName.split("src/");
200                 if (fileNameArr.length > 1)
201                         fileName = fileNameArr[1];
202                 insertExpression(fileName, expressionSyntax, startLineNo, endLineNo);
203         }
204 }