Permalink
Browse files

Added support for arrays and primitives

  • Loading branch information...
1 parent 0741494 commit 487db7420ae07ca4b527b38c39064d3b139ce78d @bendlas bendlas committed with cosmin Oct 4, 2011
@@ -61,10 +61,23 @@
(assoc the-map (keyword name) (make-setter-fn method))
the-map)))
+(defn- add-array-methods [acls]
+ (let [cls (.getComponentType acls)
+ to (fn [_ sequence] (into-array cls (map (partial to-java cls)
+ sequence)))
+ from (fn [obj] (map from-java obj))]
+ (.addMethod to-java [acls Iterable] to)
+ (.addMethod from-java acls from)
+ {:to to :from from}))
;; common to-java definitions
-(defmethod to-java :default [_ value] value)
+(defmethod to-java :default [^Class cls value]
+ (if (.isArray cls)
+ ; no method for this array type yet
+ ((:to (add-array-methods cls))
+ cls value)
+ value))
(defmethod to-java [Enum String] [enum value]
(.invoke (.getDeclaredMethod enum "valueOf" (into-array [String])) nil (into-array [value])))
@@ -92,16 +105,39 @@
;; common from-java definitions
-(defmethod from-java Object [instance]
+(defmethod from-java :default [^Object instance]
"Convert a Java object to a Clojure map"
- (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)]))))
+ (let [clazz (.getClass instance)]
+ (if (.isArray clazz)
+ ((:from (add-array-methods clazz))
+ instance)
+ (let [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))
+(defmacro ^{:private true} defnumber [box prim prim-getter]
+ `(let [conv# (fn [_# number#]
+ (~(symbol (str box) "valueOf")
+ (. number# ~prim-getter)))]
+ (.addMethod to-java [~prim Number] conv#)
+ (.addMethod to-java [~box Number] conv#)))
+
+(defmacro ^{:private true} defnumbers [& boxes]
+ (cons `do
+ (for [box boxes
+ :let [box-cls (resolve box)
+ prim-cls (.get (.getField box-cls "TYPE")
+ box-cls)
+ _ (assert (class? box-cls) (str box ": no class found"))
+ _ (assert (class? prim-cls) (str box " has no TYPE field"))
+ prim-getter (symbol (str (.getName prim-cls) "Value"))]]
+ `(defnumber ~box ~(symbol (str box) "TYPE") ~prim-getter))))
+
+(defnumbers Byte Short Integer Long Float Double)
+
(defmethod from-java ::do-not-convert [value] value)
(prefer-method from-java ::do-not-convert Object)
@@ -10,7 +10,7 @@
(:use clojure.java.data)
(:use [clojure.tools.logging :only (log* info)])
(:use clojure.test)
- (:import (clojure.java.data.test Person Address State)))
+ (:import (clojure.java.data.test Person Address State Primitive)))
(deftest clojure-to-java
(let [person (to-java Person {:name "Bob"
@@ -58,3 +58,25 @@
(is (= 30 (:age person)))
(is (= "123 Main St" (:line1 (:address person))))
(is (= "TX" (:state (:address person))))))
+
+(deftest primitives
+ (let [datum {:boolMember true
+ :boolArray [true false]
+ :charMember \H
+ :charArray (map identity "Hello World")
+ :byteMember 127
+ :byteArray [1 2 3]
+ :shortMember 15000
+ :shortArray [13000 14000 15000]
+ :intMember 18000
+ :intArray [1 2 3]
+ :longMember 60000000
+ :longArray [1 2 3]
+ :floatMember 1.5
+ :floatArray [1.5 2.5 3.5]
+ :doubleMember 1.5
+ :doubleArray [1.5 2.0 2.5]
+ :nestedIntArray [[1 2] [3] [4 5 6] []]
+ :stringArray ["Argument" "Vector"]}]
+ (is (= datum
+ (from-java (to-java Primitive datum))))))
@@ -0,0 +1,133 @@
+package clojure.java.data.test;
+
+public class Primitive {
+ private boolean boolMember;
+ private boolean[] boolArray;
+ private char charMember;
+ private char[] charArray;
+
+ private byte byteMember;
+ private byte[] byteArray;
+ private short shortMember;
+ private short[] shortArray;
+ private int intMember;
+ private int[] intArray;
+ private long longMember;
+ private long[] longArray;
+ private float floatMember;
+ private float[] floatArray;
+ private double doubleMember;
+ private double[] doubleArray;
+
+ private int[][] nestedIntArray;
+ private String[] stringArray;
+
+ public boolean isBoolMember() {
+ return boolMember;
+ }
+ public void setBoolMember(boolean boolMember) {
+ this.boolMember = boolMember;
+ }
+ public boolean[] getBoolArray() {
+ return boolArray;
+ }
+ public void setBoolArray(boolean[] boolArray) {
+ this.boolArray = boolArray;
+ }
+ public char getCharMember() {
+ return charMember;
+ }
+ public void setCharMember(char charMember) {
+ this.charMember = charMember;
+ }
+ public char[] getCharArray() {
+ return charArray;
+ }
+ public void setCharArray(char[] charArray) {
+ this.charArray = charArray;
+ }
+ public byte getByteMember() {
+ return byteMember;
+ }
+ public void setByteMember(byte byteMember) {
+ this.byteMember = byteMember;
+ }
+ public byte[] getByteArray() {
+ return byteArray;
+ }
+ public void setByteArray(byte[] byteArray) {
+ this.byteArray = byteArray;
+ }
+ public short getShortMember() {
+ return shortMember;
+ }
+ public void setShortMember(short shortMember) {
+ this.shortMember = shortMember;
+ }
+ public short[] getShortArray() {
+ return shortArray;
+ }
+ public void setShortArray(short[] shortArray) {
+ this.shortArray = shortArray;
+ }
+ public int getIntMember() {
+ return intMember;
+ }
+ public void setIntMember(int intMember) {
+ this.intMember = intMember;
+ }
+ public int[] getIntArray() {
+ return intArray;
+ }
+ public void setIntArray(int[] intArray) {
+ this.intArray = intArray;
+ }
+ public long getLongMember() {
+ return longMember;
+ }
+ public void setLongMember(long longMember) {
+ this.longMember = longMember;
+ }
+ public long[] getLongArray() {
+ return longArray;
+ }
+ public void setLongArray(long[] longArray) {
+ this.longArray = longArray;
+ }
+ public float getFloatMember() {
+ return floatMember;
+ }
+ public void setFloatMember(float floatMember) {
+ this.floatMember = floatMember;
+ }
+ public float[] getFloatArray() {
+ return floatArray;
+ }
+ public void setFloatArray(float[] floatArray) {
+ this.floatArray = floatArray;
+ }
+ public double getDoubleMember() {
+ return doubleMember;
+ }
+ public void setDoubleMember(double doubleMember) {
+ this.doubleMember = doubleMember;
+ }
+ public double[] getDoubleArray() {
+ return doubleArray;
+ }
+ public void setDoubleArray(double[] doubleArray) {
+ this.doubleArray = doubleArray;
+ }
+ public int[][] getNestedIntArray() {
+ return nestedIntArray;
+ }
+ public void setNestedIntArray(int[][] nestedIntArray) {
+ this.nestedIntArray = nestedIntArray;
+ }
+ public String[] getStringArray() {
+ return stringArray;
+ }
+ public void setStringArray(String[] stringArray) {
+ this.stringArray = stringArray;
+ }
+}

0 comments on commit 487db74

Please sign in to comment.