Skip to content
Browse files

fixed ns description, removed catch all on from-java and added config…

…urable behavior for missing setter on to-java
  • Loading branch information...
1 parent 1c7d484 commit 31848c40bcd6c48f759af4458846053a58223458 @cosmin cosmin committed Apr 26, 2011
Showing with 72 additions and 9 deletions.
  1. +22 −0 pom.xml
  2. +24 −9 src/main/clojure/clojure/java/data.clj
  3. +26 −0 src/test/clojure/clojure/java/test_data.clj
View
22 pom.xml
@@ -25,4 +25,26 @@
<developerConnection>scm:git:git@github.com:clojure/java.data.git</developerConnection>
<url>git@github.com:clojure/java.data.git</url>
</scm>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.clojure</groupId>
+ <artifactId>tools.logging</artifactId>
+ <version>0.1.2</version>
+ </dependency>
+ </dependencies>
</project>
View
33 src/main/clojure/clojure/java/data.clj
@@ -8,8 +8,16 @@
(ns
^{:author "Cosmin Stejerean",
- :doc "A Clojure interface to sql databases via jdbc."}
- clojure.java.data)
+ :doc "Support for recursively converting Java beans to Clojure and vice versa."}
+ clojure.java.data
+ (:use [clojure.tools.logging :only (info)]))
+
+
+(def
+ ^{:dynamic true,
+ :doc "Specify the behavior of missing setters in to-java in the
+ default object case, using one of :ignore, :log, :error"}
+ *to-java-object-missing-setter* :ignore)
(defmulti to-java (fn [destination-type value] [destination-type (class value)]))
(defmulti from-java class)
@@ -59,7 +67,15 @@
(defmethod to-java :default [_ value] value)
(defmethod to-java [Enum String] [enum value]
- (.invoke (.getDeclaredMethod enum "valueOf" (into-array [String])) nil (into-array [value])))
+ (.invoke (.getDeclaredMethod enum "valueOf" (into-array [String])) nil (into-array [value])))
+
+
+(defn- throw-log-or-ignore-missing-setter [key clazz]
+ (let [message (str "Missing setter for " key " in " (.getCanonicalName clazz))]
+ (cond (= *to-java-object-missing-setter* :error)
+ (throw (new NoSuchFieldException message))
+ (= *to-java-object-missing-setter* :log)
+ (info message))))
(defmethod to-java [Object clojure.lang.APersistentMap] [clazz props]
"Convert a Clojure map to the specified class using reflection to set the properties"
@@ -68,7 +84,7 @@
(doseq [[key value] props]
(let [setter (get setter-map (keyword key))]
(if (nil? setter)
- (println "WARNING: Cannot set value for " key " because there is no setter.")
+ (throw-log-or-ignore-missing-setter key clazz)
(apply setter [instance value]))))
instance))
@@ -78,11 +94,10 @@
(defmethod from-java Object [instance]
"Convert a Java object to a Clojure map"
- (try
- (let [clazz (.getClass instance)
- getter-map (reduce add-getter-fn {} (get-property-descriptors clazz))]
- (into {} (for [[key getter-fn] (seq getter-map)] [key (getter-fn instance)])))
- (catch Exception e (println "Error trying to convert " instance e))))
+ (let [clazz (.getClass instance)
+ getter-map (reduce add-getter-fn {} (get-property-descriptors clazz))]
+ (into {} (for [[key getter-fn] (seq getter-map)] [key (getter-fn instance)]))))
+
(doseq [clazz [String Character Byte Short Integer Long Float Double Boolean BigInteger BigDecimal]]
(derive clazz ::do-not-convert))
View
26 src/test/clojure/clojure/java/test_data.clj
@@ -8,6 +8,7 @@
(ns clojure.java.test-data
(:use clojure.java.data)
+ (:use [clojure.tools.logging :only (log* info)])
(:use clojure.test)
(:import (clojure.java.data.test Person Address State)))
@@ -25,6 +26,31 @@
(is (= State/TX (.. person getAddress getState)))
(is (= "75432" (.. person getAddress getZip)))))
+(deftest clojure-to-java-error-on-missing-setter
+ (binding [*to-java-object-missing-setter* :error]
+ (is (thrown-with-msg? NoSuchFieldException #"Missing setter for :foobar in clojure.java.data.test.Person"
+ (to-java Person {:name "Bob" :foobar "Baz"})
+ ))))
+
+(deftest clojure-to-java-ignore-on-missing-setter
+ (binding [*to-java-object-missing-setter* :ignore]
+ (let [person (to-java Person {:name "Bob" :foobar "Baz"})]
+ (is (= "Bob" (.getName person))))))
+
+(defmacro with-temporary-root [[var-name new-value] & body]
+ `(let [current-var# ~var-name]
+ (alter-var-root (var ~var-name) (fn [ignore#] ~new-value))
+ ~@body
+ (alter-var-root (var ~var-name) (fn [ignore#] current-var#)))
+ )
+
+(deftest clojure-to-java-log-on-missing-setter
+ (binding [*to-java-object-missing-setter* :log]
+ (with-temporary-root [log* (fn [log level throwable message]
+ (throw (new Exception (str "invoked " level))))]
+ (is (thrown-with-msg? Exception #"invoked :info"
+ (to-java Person {:name "Bob" :foobar "Baz"}))))))
+
(deftest java-to-clojure
(let [address (new Address "123 Main St" "Dallas" State/TX "75432")
person (from-java (Person. "Bob" (biginteger 30) address))]

0 comments on commit 31848c4

Please sign in to comment.
Something went wrong with that request. Please try again.