Skip to content

Commit 2f7e1c1

Browse files
committed
fixes JDATA-24 and JDATA-25
Signed-off-by: Sean Corfield <[email protected]>
1 parent a8fe660 commit 2f7e1c1

File tree

2 files changed

+43
-20
lines changed

2 files changed

+43
-20
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
## Change Log
22

3+
* Release 1.2.next in progress
4+
* In builders, for overloaded setters (for which we have matching properties), try to pick the "obviously better" match (using `instance?` against the property value), and only throw if we can't pick one [JDATA-25](https://clojure.atlassian.net/browse/JDATA-25).
5+
* In builders, ignore setters for which we do not have matching properties [JDATA-24](https://clojure.atlassian.net/browse/JDATA-24).
6+
37
* Release 1.2.107 on 2024-02-19
48
* Update parent pom and tools.logging versions
59

src/main/clojure/clojure/java/data/builder.clj

+39-20
Original file line numberDiff line numberDiff line change
@@ -43,31 +43,50 @@
4343
(.getName clazz))))
4444
(first builds))))))
4545

46-
(defn- find-setters [^Class builder methods opts]
46+
(defn- find-setters [^Class builder methods props opts]
4747
(let [candidates
4848
(filter (fn [^java.lang.reflect.Method m]
4949
(and (= 1 (alength ^"[Ljava.lang.Class;" (.getParameterTypes m)))
5050
(= builder (.getReturnType m))
5151
(or (not (re-find #"^set[A-Z]" (.getName m)))
5252
(not (:ignore-setters? opts)))))
5353
methods)]
54-
(reduce (fn [setter-map ^java.lang.reflect.Method m]
55-
(let [prop (keyword
56-
(cond (re-find #"^set[A-Z]" (.getName m))
57-
(let [^String n (subs (.getName m) 3)]
58-
(str (Character/toLowerCase (.charAt n 0)) (subs n 1)))
59-
(re-find #"^with[A-Z]" (.getName m))
60-
(let [^String n (subs (.getName m) 4)]
61-
(str (Character/toLowerCase (.charAt n 0)) (subs n 1)))
62-
:else
63-
(.getName m)))]
54+
(->> candidates
55+
(reduce
56+
(fn [setter-map ^java.lang.reflect.Method m]
57+
(let [prop (keyword
58+
(cond (re-find #"^set[A-Z]" (.getName m))
59+
(let [^String n (subs (.getName m) 3)]
60+
(str (Character/toLowerCase (.charAt n 0)) (subs n 1)))
61+
(re-find #"^with[A-Z]" (.getName m))
62+
(let [^String n (subs (.getName m) 4)]
63+
(str (Character/toLowerCase (.charAt n 0)) (subs n 1)))
64+
:else
65+
(.getName m)))]
66+
(if (contains? props prop)
6467
(if (contains? setter-map prop)
65-
(throw (IllegalArgumentException.
66-
(str "Duplicate setter found for " prop
67-
" in " (.getName builder) " class")))
68-
(assoc setter-map prop (#'j/make-setter-fn m)))))
69-
{}
70-
candidates)))
68+
(let [clazz1 (#'j/get-setter-type (second (get setter-map prop)))
69+
clazz2 (#'j/get-setter-type m)
70+
p-val (get props prop)]
71+
(cond (and (instance? clazz1 p-val)
72+
(not (instance? clazz2 p-val)))
73+
setter-map ; existing setter is a better match:
74+
(and (not (instance? clazz1 p-val))
75+
(instance? clazz2 p-val))
76+
;; this setter is a better match:
77+
(assoc setter-map prop [(#'j/make-setter-fn m) m])
78+
:else ; neither is an obviously better match:
79+
(throw (IllegalArgumentException.
80+
(str "Duplicate setter found for " prop
81+
" in " (.getName builder) " class")))))
82+
(assoc setter-map prop [(#'j/make-setter-fn m) m]))
83+
;; if we are not trying to set this property, ignore the setter:
84+
setter-map)))
85+
{})
86+
(reduce-kv
87+
(fn [m k v]
88+
(assoc m k (first v)))
89+
{}))))
7190

7291
(defn- build-on [instance setters ^Class clazz props]
7392
(reduce-kv (fn [builder k v]
@@ -94,7 +113,7 @@
94113
;; * B setPropertyName( T )
95114
;; treat both as setters; thrown exception if they clash
96115
;; (maybe an option to ignore setXyz( T ) methods?)
97-
(find-setters java.util.Locale$Builder (.getMethods java.util.Locale$Builder) {})
116+
(find-setters java.util.Locale$Builder (.getMethods java.util.Locale$Builder) {} {})
98117

99118
;; general pattern will be to:
100119
;; * get the builder class somehow
@@ -113,7 +132,7 @@
113132
^Class builder (get-builder-class clazz)]
114133
(.invoke (get-builder clazz (.getMethods builder) opts)
115134
(build-on (j/to-java builder ^clojure.lang.APersistentMap {})
116-
(find-setters builder (.getMethods builder) opts)
135+
(find-setters builder (.getMethods builder) props opts)
117136
builder
118137
props)
119138
nil)))
@@ -161,7 +180,7 @@
161180
([^Class clazz ^Class builder instance props opts]
162181
(.invoke (get-builder clazz (.getMethods builder) opts)
163182
(build-on instance
164-
(find-setters builder (.getMethods builder) opts)
183+
(find-setters builder (.getMethods builder) props opts)
165184
builder
166185
props)
167186
nil)))

0 commit comments

Comments
 (0)