This is a quick way to wrap a Java object in a Clojure hashmap.
EDIT: Stuart kindly referred me to bean. Seems like I should do more homework :)
(defn- no-arguments? [method]
(zero? (count (.getParameterTypes method))))
(defn- getter? [method]
(let [name (.getName method)]
(and (no-arguments? method)
(not (= name "getClass"))
(.startsWith name "get"))))
(defn- obj-getters [obj]
(let [cls (if (class? obj) obj (class obj))]
(filter getter? (.getMethods cls))))
(defn- name->keyword
"\".getTimezoneoffset\" -> :timezone-offset"
[n]
(keyword (-> n (.replaceAll "([A-Z])" "-$1") (.substring 4) (.toLowerCase))))
; FIXME: This is currently doing one level conversion, it'll be nice if it'll
; recursivly convert collections, hash maps ...
(defn wrap
"Convert Java object to a hash map, using zero arguments getters
user=> (wrap (new Date))
{:timezone-offset 480, :day 2, :year 110, :time 1267559056404, :seconds 16, :month 2, :minutes 44, :hours 11, :date 2}
"
[obj]
(let [getters (obj-getters obj)
keywords (map name->keyword (map #(.getName %) getters))
values (map #(.invoke % obj nil) getters)]
(zipmap keywords values)))
No comments:
Post a Comment