3 (:import com.interrupt.bookkeeping.cc.analysis.DepthFirstAdapter)
6 (use 'clj-stacktrace.repl)
10 (clj-stacktrace.repl/pst e)))
12 (require 'clojure.contrib.str-utils2)
13 (require 'clojure.contrib.http.agent)
14 (require 'clojure.contrib.io)
15 (require 'clojure.contrib.string)
18 (import (java.net URLEncoder))
21 ;; function stolen from http://p.hagelb.org/http-client-send-body
23 " Replacing these characters http encoded ones
33 (clojure.contrib.string/replace-str " " "%20"
34 (clojure.contrib.string/replace-str "'" "%27"
35 (clojure.contrib.string/replace-str ";" "%3B"
36 (clojure.contrib.string/replace-str "[" "%5B"
37 (clojure.contrib.string/replace-str "@" "%40"
38 (clojure.contrib.string/replace-str "=" "%3D"
39 (clojure.contrib.string/replace-str "]" "%5D" text
45 ;; set get base URL ...TODO - put in config
46 (def db-base-URL "http://localhost:8080/exist/rest/")
48 ;; set root/system dir fragment ...TODO - put in config
49 (def db-system-DIR "rootDir/system.main.system/")
51 ;; working directory lookup ...TODO - put these lookups into config
52 (defn working-dir-lookup
55 (println "DEBUG > 'working-dir-lookup' CALLED > ["(keyword token)"]" )
57 ( { :group "aauthentication.main.authentication/groups.aauth.groups/"
58 :user "aauthentication.main.authentication/users.aauth.users/"
59 :account "groups.main.groups/"
60 :journal "groups.main.groups/"
61 :entry "groups.main.groups/"
62 :debit "groups.main.groups/"
63 :credit "groups.main.groups/"
68 (defn namespace-lookup
71 (println "DEBUG > 'namespace-lookup' CALLED > ["token"]" )
73 ( { "group" "com/interrupt/bookkeeping/users"
74 "user" "com/interrupt/bookkeeping/users"
75 "account" "com/interrupt/bookkeeping/account"
76 "journal" "com/interrupt/bookkeeping/journal"
77 "entry" "com/interrupt/bookkeeping/journal"
78 "debit" "com/interrupt/bookkeeping/account"
79 "credit" "com/interrupt/bookkeeping/account"
85 (defn operate-dep-inputtype
86 [node handler_block] ;; input args ; for now we are going to load by ID
91 (if (instance? com.interrupt.bookkeeping.cc.node.AXmlCommandInput (. node getCommandInput) )
93 (println "XML input[" (.. node getCommandInput toString) "]")
95 ;; extract the context
98 ;; operate with handler
106 (if (instance? com.interrupt.bookkeeping.cc.node.AOptsCommandInput (. node getCommandInput) )
108 (println "DEBUG > OPTIONS input > token[" (.. node getCommandInput getInputOption getCommandtoken) "] > options[" (.. node getCommandInput getInputOption getCommandoption) "]")
110 ;; get token string (ie user, entry, etc) ->
111 (def token (.. node getCommandInput getInputOption getCommandtoken))
113 ;; get option args & value -> use a 'CommandOptionVisitor'
114 (def options (seq (.. node getCommandInput getInputOption getCommandoption)))
119 (if (instance? com.interrupt.bookkeeping.cc.node.AIdCommandoption input )
127 (def db-id-ID ;; TODO - chain this to look for other options if 'id' is not there
129 (clojure.contrib.str-utils2/trim
131 (clojure.contrib.str-utils2/split (.. (nth option-id 0) ;; class 'com.interrupt.bookkeeping.cc.node.AIdCommandoption'
132 getIdOpt getText) #"-[a-z]+")
139 (println "DEBUG > extracted > [" token "] > [" options "] > [" db-id-ID "]")
141 ;; from HASH -> find containing folder for token
142 (def db-working-DIR (working-dir-lookup (.. token toString trim)))
144 ;; build another <my.group> to end of db-working-DIR
145 (def db-leaf (str (.. token toString trim) "." db-id-ID ) )
146 (def db-full-PARENT (str db-base-URL db-system-DIR db-working-DIR db-leaf ))
148 (def db-document-NAME db-leaf)
151 (println "DEBUG > db-base-URL["db-base-URL"] > db-system-DIR["db-system-DIR"] > db-working-DIR["db-working-DIR"] > leaf["db-leaf"]")
152 (println "DEBUG > db-base-URL[" db-full-PARENT "]")
155 ;; this will find all <SPEECH> elements in the collection /db/shakespeare with "Juliet" as the <SPEAKER>
156 ;; http://localhost:8080/exist/rest/db/shakespeare?_query=//SPEECH[SPEAKER=%22JULIET%22]
158 ;; build XPATH expression to find 'token' based on option
159 ;; http://localhost:8080/exist/rest/db/two.xml?_query=
160 ;; declare default element namespace 'com/interrupt/bookkeeping/users'
161 ;; declare namespace aauth='com/interrupt/bookkeeping/cc/bkell/aauth';
162 ;; //system/aauth:aauthentication
164 ;; TODO - a check if we even need a query
165 (def db-query (str "_wrap=no&_query="
166 "declare default element namespace '"(namespace-lookup (.. token toString trim)) "';"
167 ;;"declare namespace users='com/interrupt/bookkeeping/users'; declare namespace bkell='com/interrupt/bookkeeping/cc/bkell'; declare namespace command='com/interrupt/bookkeeping/cc/bkell/command'; declare namespace interpret='com/interrupt/bookkeeping/interpret'; declare namespace aauth='com/interrupt/bookkeeping/cc/bkell/aauth'; "
169 ;; TODO - check if we need 'and' conditions
170 ;; "**/<token>[ @option='option_value' [ and @option='option_value' ] ]"
171 "//"(.. token toString trim)"[ @"
172 (. (nth (re-seq #"-[a-z]+" (.. (nth option-id 0) getIdOpt getText)) 0) substring 1) ;; TODO - put this part into a function (being re-used)
177 (println "DEBUG > db-query[" db-query "]")
179 (println "DEBUG > FINAL http query[" (str db-full-PARENT "/" db-leaf "?" (url-encode db-query) ) "]")
181 ;; from DB, get 'token' for 'option' args & value
182 (def result-XML (clojure.contrib.http.agent/string (clojure.contrib.http.agent/http-agent (str db-full-PARENT "/" db-leaf "?" (url-encode db-query) )
184 :header {"Content-Type" "text/xml"}
186 ;; TODO - parse results, check for i) null or ii) multiple results
190 ;; pass built XML sequence to handler
191 (handler (xml-seq result-XML))
197 (if (instance? com.interrupt.bookkeeping.cc.node.AXpathCommandInput (. node getCommandInput) )
200 (println "XPATH input[" (.. node getCommandInput toString) "]")
202 ;; extract the context
203 (let [ result_seq []]
205 ;; operate with handler
214 (doseq [ each_check checks ]
216 (println "DEBUG > each... " each_check)
217 (each_check node handler_block)
225 (defn get-depth-adapter []
227 (proxy [DepthFirstAdapter] []
230 (caseAExitCommand4 [node]
232 (println (str "DEBUG > caseAExitCommand4: " node))
234 (proxy-super inAExitCommand4 node)
235 (proxy-super outAExitCommand4 node)
242 (caseALoginCommand3 [node]
243 (println "DEBUG > caseALoginCommand3: " node)
246 (proxy-super inALoginCommand3 node)
248 (if (not= (. node getLogin ) nil)
249 (.. node getLogin (apply this) ) )
251 (if (not= (. node getLbracket ) nil)
252 (.. node getLbracket (apply this) ) )
254 (if (not= (. node getCommandInput ) nil)
258 (.. node getCommandInput (apply this) )
261 (operate-dep-inputtype node (fn [result_seq] (println "DEBUG > logging in on... " result_seq)))
265 (if (not= (. node getRbracket ) nil)
266 (.. node getRbracket (apply this) ) )
268 (proxy-super outALoginCommand3 node)
273 (caseAPrintCommand6 [node]
274 (println (str "caseAPrintCommand6: " node)) )
278 (caseALoadCommand3 [node]
279 (println "DEBUG > caseALoadCommand3 [" (class (. node getCommandInput)) "]: " node)
281 (comment "replicating java calls in the 'DepthFirstAdapter.caseALoadCommand3'")
284 (proxy-super inALoadCommand3 node)
286 (if (not= (. node getLoad ) nil)
287 (.. node getLoad (apply this) ) )
289 (if (not= (. node getLbracket ) nil)
290 (.. node getLbracket (apply this) ) )
292 (if (not= (. node getCommandInput ) nil)
294 (do ;; execute 'if' block
295 (.. node getCommandInput (apply this) )
298 (if (not (contains? com.interrupt.bookkeeping/shell :logged-in-user )) ;; check if there is a 'logged-in-user'
300 ;;throw an error if no 'logged-in-user'
301 (println "ERROR - NO logged-in-user")
304 (operate-dep-inputtype node (fn [result_seq] (println "loading... " result_seq)))
311 (if (not= (. node getRbracket ) nil)
312 (.. node getRbracket (apply this) ) )
315 (proxy-super outALoadCommand3 node)
319 ;; ADD command (for registering users too)
320 ;; 1. check that there's not an existing user
321 ;; 2. add corresponding default group to the new user
322 ;; 3. add to aauth.groups
323 ;; 4. add to aauth.users
324 ;; 5. add Associated Bookkeeping to Group