(defn xmlrpc-servlet
"Returns a servlet which calls the supplied function for every XML-RPC
request.
handler-fn => (fn [method-name & args] ...)"
[handler-fn]
(proxy [XmlRpcServlet] []
(newXmlRpcHandlerMapping []
(proxy [XmlRpcHandlerMapping] []
(getHandler [handler-name]
(proxy [XmlRpcHandler] []
(execute [#^XmlRpcRequest request]
(let [nargs (.getParameterCount request)
args (map #(.getParameter request %) (range 0 nargs))
method (.getMethodName request)]
(jmap (apply handler-fn method args))))))))))
(defn to-map
"Return a java.util.Map, backed by the supplied Clojure map.
(Clojure maps can't be java.util.Maps themselves because that
conflicts with java.util.Collection"
[#^clojure.lang.IPersistentMap map]
(proxy [Object java.util.Map] []
(containsKey [key]
(contains? map key))
(containsValue [value]
(some (fn [k,v] (= v value)) (seq map)))
(entrySet []
(set (seq map)))
(get [key]
(get map key))
(isEmpty []
(= {} map))
(keySet []
(set (keys map)))
(size []
(count map))
(values []
(vals map))))
(defn jmap
"Takes any Clojure persistent collection, and returns a
collection conforming to Java idioms (specifically, with
all IPersistentMaps turned into java.util.HashMaps), and
all java.util.Collections replaced with ArrayLists of
their (transformed) contents."
[#^clojure.lang.IPersistentCollection coll]
(cond
(instance? clojure.lang.IPersistentMap coll)
(loop [ret (new java.util.HashMap) s (seq coll)]
(if s
(let [[k,v] (first s)]
(.put ret (jmap k) (jmap v))
(recur ret (rest s)))
ret))
(instance? java.util.Collection coll)
(loop [ret (new java.util.ArrayList) s (seq coll)]
(if s
(do
(.add ret (jmap (first s)))
(recur ret (rest s)))
ret))
:else
coll))