-- in xpath_handler, calculating i. leaf-node and ii. context-dir
[bkell-clj.git] / src / xpath_handler.clj
blob5d4f4f6871ad620b2c46b629b8d3a001c0e1659e
2 (ns xpath_handler 
3   
4   (:import com.interrupt.cc.xpath.lexer.Lexer) 
5         (:import com.interrupt.cc.xpath.lexer.LexerException) 
6         (:import com.interrupt.cc.xpath.node.Node) 
7         (:import com.interrupt.cc.xpath.node.Start) 
8         (:import com.interrupt.cc.xpath.parser.Parser) 
9         (:import com.interrupt.cc.xpath.parser.ParserException) 
10   (:import com.interrupt.cc.xpath.analysis.DepthFirstAdapter) 
11   (:import com.interrupt.bob.processor.cc.DepthFirstVisitor)
12   
13   (:import java.io.InputStreamReader)
14   (:import java.io.PushbackReader) 
15   (:import java.io.ByteArrayInputStream) 
16   (:import java.util.ArrayList)
17   
18   (:use helpers) 
19   
23         ;; remove the SableCC added <spaces> and ` 
24         (defn filter-xpath-input [input-string]
25                         (clojure.contrib.string/replace-str " " "" 
26                         (clojure.contrib.string/replace-str "`" "" input-string))
27         )
28         
29         ;; build the XPath parser  
30         (defn get-pushback-parser [xpath-string] 
31                 (Parser. (Lexer. (PushbackReader. (InputStreamReader. 
32                                                                                                                                                                 (ByteArrayInputStream. (. xpath-string getBytes))) 
33                                                                                                                                                                 1024)))
34         )
35         
36         ;; the XPath string that the proxy / adapter will use to figure out context directory & XPath expression 
37         ;; (def XPATH-string (ref ""))
38         (def xpath-data (ref {})) 
39         
40         ;; we're gonna build our eXist URL with this 
41         (def URL-build (ref "")) 
42         
43         ;; pilfered stack ideas and some implementation from: http://programming-puzzler.blogspot.com/2009/04/adts-in-clojure.html 
44         (def stack (ref [])) 
45         (defn stack-peek [] 
46                 (peek (deref stack)))
47         (defn stack-push [e] 
48                 (dosync (alter stack conj e)) 
49                 (println "PUSH stack [" (deref stack) "]" ))
50         (defn stack-pop [] 
51                 (dosync (alter stack pop)))
52         (defn stack-empty? [] 
53                 (dosync (alter stack empty?)))
54         
55         
56         ;; get DepthFirstAdapter proxy 
57         (defn get-adapter-proxy [] 
58                 
59                 (proxy [DepthFirstAdapter] [] 
60                         
61                         ;; keep a stack with 
62                         ;;      i.      AbbrevRoot 
63                         ;;      ii.     Word 
64                         ;;                              - keep the last/previous token 
65                         ;;      iii.    RelativePath 
66                         ;;      iv.     Predicate 
67                         (caseTAbbrevRootDesc [node] 
68                                 
69                                 (println "caseTAbbrevRootDesc CALLED \t\t\t\t class[" (. node getClass) "] \t\t\t\t" (. node toString))
70                                 (stack-push node)
71                                 
72                         )
73                         (caseTLetter [node] 
74                                 
75                                 (println "caseTLetter CALLED \t\t\t\t\t class[" (. node getClass) "] \t\t\t\t\t" (. node toString))
76                                 (stack-push node)
77                                 
78                         )
79                         (caseAPredicatelist [node] 
80                                 
81                                 (proxy-super inAPredicatelist node)     ;; duplicating adapter 'in' call 
82                     
83                                 (println "caseAPredicatelist CALLED \t\t\t\t class[" (. node getClass) "] \t\t\t\t" (. node toString) "\t\t filtered " (filter-xpath-input (. node toString)))
84                                 (doseq [ each_predicate (java.util.ArrayList. (. node getPredicate)) ] 
85                                         (do
86                                                 
87                                                 (println "DEBUG > each predicate... " each_predicate " predicate expresion[" (. each_predicate getExpr) 
88                                                                         "] getExprsingle[" (.. each_predicate getExpr getExprsingle) "] ugghhhh!! ["    ;; this is where = breaks off: getComparisonexpr -here- getComparisonexprPart
89                                                                                         ;;(.. each_predicate getExpr getExprsingle getOrexpr getAndexpr getComparisonexpr getComparisonexprPart getRangeexpr) "]" )
90                                                                                         (.. each_predicate getExpr getExprsingle getOrexpr getAndexpr getComparisonexpr getRangeexpr) "]" )
91                                                 
92                                                 ;; LATER - DON'T traverse children & evaluate... for now 
93                                                 ;;(. each_predicate apply this)
94                                                 
95                                                 
96                                                 ;; ** here we are assuming there's only one predicate in the list 
97                                                 (def predicate-name 
98                                                                 (clojure.contrib.string/replace-str "@" "" 
99                                                                         (clojure.contrib.string/replace-str " " "" 
100                                                                                 (.. each_predicate getExpr getExprsingle getOrexpr getAndexpr getComparisonexpr getRangeexpr toString)))) 
101                                                 (def predicate-value 
102                                                                 (clojure.contrib.string/replace-str "'" "" 
103                                                                         (clojure.contrib.string/replace-str " " "" 
104                                                                                 (.. each_predicate getExpr getExprsingle getOrexpr getAndexpr getComparisonexpr getComparisonexprPart getRangeexpr toString))))
105                                                 (println "DEBUG > predicate-name[" predicate-name "] > predicate-value[" predicate-value "]")
106                                                 
107                                                 
108                                                 ;; (peek, then..) pop 'TLetter' & 'RelativePathexpr' 
109                                                 (def top (stack-peek))
110                                                 
111                                                 ;; put in a check to see if we are at the leaf document
112                                                 (println "leaf check [" (. (clojure.contrib.string/trim (. top toString)) equals (:leaf-node (deref xpath-data))) "] > top[" (clojure.contrib.string/trim (. top toString)) "] > leaf-node[" (:leaf-node (deref xpath-data)) "]") 
113                                                 (if (. (clojure.contrib.string/trim (. top toString)) equals (:leaf-node (deref xpath-data)))
114                                                         
115                                                         (println "---> We are at the leaf document " ) 
116                                                         ;; TODO - write out context directory 
117                                                         ;; TODO - write out leaf document 
118                                                         ;; TODO - begin writing out XPath expression 
119                                                         
120                                                 )
121                                                 
122                                                 (stack-pop)     ;; pop the token 
123                                                 (stack-pop)     ;; LATER - pop the relativepathpart - we'll have to assume that there's a relative_path_part... for now  
124                                                 
125                                                 (println "top of stack["top"] > class["(. top getClass)"]")
126                                                 (cond 
127                                                         (instance? com.interrupt.cc.xpath.node.TAbbrevRootDesc top ) 
128                                                                 '() 
129                                                         
130                                                         (instance? com.interrupt.cc.xpath.node.TLetter top ) 
131                                                                 (dosync 
132                                                                         (alter URL-build str (clojure.contrib.string/replace-str " " "" (. top toString) ) "." predicate-value)
133                                                                         (alter URL-build str "/"))
134                                                         
135                                                         ;;(instance? com.interrupt.cc.xpath.node.ARootRelativepathexprPartPart  top ) 
136                                                         ;;      (dosync (alter URL-build str "/"))
137                                                         
138                                                         (instance? com.interrupt.cc.xpath.node.APredicatelist top ) 
139                                                                 '() 
140                                                 )
141                                         )
142                                 )
143                                 (println "URL-build[" (deref URL-build) "]")
144                                 (println)
145                                 (println)
146                                 
147                                 
148                                 ;;* at the end of processing the XPath 
149                                 ;;      - capture leaf document 
150                                 ;;      - build XPath expr to feed to RESTful exist 
151                                 
152                                 
153                                 (proxy-super outAPredicatelist node)    ;; duplicating adapter 'out' call 
154                                 
155                         )
156                         (caseARootRelativepathexprPartPart [node] 
157                                 
158                                 (println "caseARootRelativepathexprPartPart CALLED \t\t class[" (. node getClass) "] \t\t\t\t" (. node toString)) 
159                                 (stack-push node) 
160                                 
161                         )
162                 )
163         ) 
164         
165         
166 (defn xpath_handler [node handler] 
167    (if (instance? com.interrupt.bookkeeping.cc.node.AXpathCommandInput (. node getCommandInput) ) 
168                 
169                 (do 
170                    
171                    (println "xpath_handler > node[" (.. node getClass) "] > getLoad[" (.. node getLoad getText) "]")
172                    (println "XPATH input[" (.. node getCommandInput toString) "]")
173                    
174                    ;; 1. filter out <spaces> and ` 
175                    (def input-string (filter-xpath-input (.. node getCommandInput toString)))
176                    (println "input-string \t[" input-string "]")
177                    (println "stripped XPath \t[" (clojure.contrib.string/replace-re #"\\[[^\\]]*\\]" "" input-string) "]" )
178                    
179                          ;; 1.1 
180                          (dosync 
181                                         
182                                         ;; put in whole xpath string 
183                                         (alter xpath-data conj { :xpath-string input-string } )
184                                         
185                                         ;; for token substring between last / and [ 
186                                         (alter xpath-data conj { 
187                                                         :leaf-node 
188                                                         (.      (:xpath-string (deref xpath-data)) substring 
189                                                                         (+ (. (:xpath-string (deref xpath-data)) lastIndexOf "/") 1)
190                                                                         (. (:xpath-string (deref xpath-data)) lastIndexOf "[")) 
191                                                 })
192                                         
193                                         ;; with token, lookup context directory 
194                                         (alter xpath-data conj { :context-dir (working-dir-lookup (:leaf-node (deref xpath-data))) } )
195                                         
196                                         (println "LEAF token > " (:leaf-node (deref xpath-data)))
197                                         (println "LEAF context directory > " (:context-dir (deref xpath-data)))
198                          )
199                          
200                          ;; 1.2 build an xpath parser    
201                          (def tree (.parse (get-pushback-parser input-string))) 
202                          (. tree apply (get-adapter-proxy ) )
203                          
204                          ;; 2. token - find i) leaf document to search ii) root & xpath expression to feed to RESTful  exist 
205                    ;; 3. build RESTful call 
206                    ;; 4. make RESTful call
207                    ;; 5. pass result sequece to handler 
208                    
209                    ;; extract the context 
210                    (let [ result_seq []]
211                       
212                       ;; operate with handler
213                       (handler result_seq)
214                    )
215                 )
216    )