Skip to content

Commit

Permalink
Issue446: Bean accessors don't account for IndexedPropertyDescriptors
Browse files Browse the repository at this point in the history
  • Loading branch information
ec027900 committed Feb 1, 2020
1 parent b7c002b commit 4bd9490
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 5 deletions.
3 changes: 3 additions & 0 deletions project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
(some->> x :ns ns-name str (re-matches (re-pattern (apply str patterns)))))))
:generative (fn [x] (some->> x :ns ns-name str (re-matches #"^clara\.generative.*")))
:performance (fn [x] (some->> x :ns ns-name str (re-matches #"^clara\.performance.*")))}

;; Remove any "Test Facts" from being included in the jar.
:jar-exclusions [#".*TestFact\.(java|class)"]

:scm {:name "git"
:url "https://github.com/cerner/clara-rules"}
Expand Down
14 changes: 9 additions & 5 deletions src/main/clojure/clara/rules/compiler.clj
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
Accumulator
ISystemFact]
[java.beans
PropertyDescriptor]
PropertyDescriptor
IndexedPropertyDescriptor]
[clojure.lang
IFn]))

Expand Down Expand Up @@ -179,10 +180,13 @@
;; Iterate through the bean properties, returning tuples and the corresponding methods.
(for [^PropertyDescriptor property (seq (.. java.beans.Introspector
(getBeanInfo cls)
(getPropertyDescriptors)))]

[(symbol (string/replace (.. property (getName)) #"_" "-")) ; Replace underscore with idiomatic dash.
(symbol (str "." (.. property (getReadMethod) (getName))))])))
(getPropertyDescriptors)))
:let [read-method (.getReadMethod property)]
;; In the event that there the class has an indexed property without a basic accessor we will simply skip
;; the accessor as we will not know how to retrieve the value. see https://github.com/cerner/clara-rules/issues/446
:when read-method]
[(symbol (string/replace (.getName property) #"_" "-")) ; Replace underscore with idiomatic dash.
(symbol (str "." (.getName read-method)))])))

(defn effective-type [type]
(if (compiling-cljs?)
Expand Down
38 changes: 38 additions & 0 deletions src/main/java/clara/test/facts/BeanTestFact.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package clara.test.facts;

/**
* A Java Pojo for the express purpose of testing the behavior of compilation and execution of rules.
*
* This class should not be included in the released artifact, if it did make it into a released artifact it should be
* ignored and not consumed as it may be moved/removed without warning to consumers.
*/
public class BeanTestFact {
private String[] locations;
private String[] roadConditions;

public BeanTestFact(String[] locations) {
this.locations = locations;
}

// Standard and Indexed property accessors
public void setLocations(String[] locations) {
this.locations = locations;
}
public String[] getLocations() {
return locations;
}
public void setLocations(int pos, String location) {
locations[pos] = location;
}
public String getLocations(int pos){
return locations[pos];
}

// Partial Indexed property accessor, ie. no standard accessor
public void setRoadConditions(int pos, String condition) {
roadConditions[pos] = condition;
}
public String getRoadConditions(int pos){
return roadConditions[pos];
}
}
29 changes: 29 additions & 0 deletions src/test/clojure/clara/test_java_facts.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
(ns clara.test-java-facts
(:require [clara.tools.testing-utils :as tu]
[clara.rules :as rules]
[clojure.test :refer [is deftest run-tests testing use-fixtures]])
(:import [clara.test.facts
BeanTestFact]))

;; A test to demonstrate that a Pojo with indexed property accessors can be used as an alpha root in a session,
;; see https://github.com/cerner/clara-rules/issues/446
(tu/def-rules-test test-basic-rule
{:rules [kansas-rule [[[BeanTestFact
(= ?locs locations)
(some #(= "Kansas" %) ?locs)]]
(rules/insert! "Kansas Exists")]]
:queries [string-query [[] [[?s <- String]]]]

:sessions [empty-session [kansas-rule string-query] {}]}

(let [locs (make-array String 2)]
(aset locs 0 "Florida")
(aset locs 1 "Kansas")
(let [session-strings (into #{}
(map :?s)
(-> empty-session
(rules/insert (BeanTestFact. locs))
(rules/fire-rules)
(rules/query string-query)))]
(is (= 1 (count session-strings)))
(is (contains? session-strings "Kansas Exists")))))

0 comments on commit 4bd9490

Please sign in to comment.