|
|
@@ -36,7 +36,8 @@ public class RBeanModel implements BeanModel, Serializable {
|
|
|
|
|
|
private final IClass<?> type;
|
|
|
private final Map<String, BeanMethod> methods;
|
|
|
- private final Map<String, BeanMethod> fluent;
|
|
|
+ private final Map<String, BeanMethod> fluentGet;
|
|
|
+ private final Map<String, BeanMethod> fluentSet;
|
|
|
private final Map<String, BeanProperty> properties;
|
|
|
private final Set<String> keys;
|
|
|
|
|
|
@@ -46,7 +47,8 @@ public class RBeanModel implements BeanModel, Serializable {
|
|
|
Map<String, RBeanPropertyBuilder> pinfo = new LazyMap<>(new OpenMap<>(), RBeanPropertyBuilder::new);
|
|
|
MultiMap<String, IMethod> minfo = new OpenMultiMap<>();
|
|
|
|
|
|
- fluent = new OpenMap<>();
|
|
|
+ fluentGet = new OpenMap<>();
|
|
|
+ fluentSet = new OpenMap<>();
|
|
|
|
|
|
for(IMethod m : type.methods()) {
|
|
|
if(m.parent().equals(IClass.OBJECT) && !OBJECT_METHODS.contains(m.name())) {
|
|
|
@@ -68,7 +70,11 @@ public class RBeanModel implements BeanModel, Serializable {
|
|
|
else {
|
|
|
minfo.put(m.name(), m);
|
|
|
if(m.arguments().count() == 0 && !m.parent().equals(IClass.OBJECT)) {
|
|
|
- fluent.put(m.name(), new RBeanMethod(m));
|
|
|
+ fluentGet.put(m.name(), new RBeanMethod(m));
|
|
|
+ }
|
|
|
+
|
|
|
+ if(m.arguments().count() == 1 && !m.parent().equals(IClass.OBJECT) && (m.returns().isVoid() || m.returns().isSuper(m.parent())) ) {
|
|
|
+ fluentSet.put(m.name(), new RBeanMethod(m));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -79,9 +85,9 @@ public class RBeanModel implements BeanModel, Serializable {
|
|
|
properties = new OpenMap<>();
|
|
|
for(Entry<String, RBeanPropertyBuilder> item : pinfo.entrySet()) {
|
|
|
properties.put(item.getKey(), FBeanModel.resolve(item.getValue()));
|
|
|
- fluent.remove(item.getKey());
|
|
|
+ fluentGet.remove(item.getKey());
|
|
|
}
|
|
|
- this.keys = new FlatSet<String>().join(properties.keySet()).join(fluent.keySet());
|
|
|
+ this.keys = new FlatSet<String>().join(properties.keySet()).join(fluentGet.keySet()).join(fluentSet.keySet());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -284,13 +290,13 @@ public class RBeanModel implements BeanModel, Serializable {
|
|
|
|
|
|
@Override
|
|
|
public boolean containsKey(Object key) {
|
|
|
- return properties.containsKey(key) || fluent.containsKey(key);
|
|
|
+ return properties.containsKey(key) || fluentGet.containsKey(key) || fluentSet.containsKey(key);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public boolean containsValue(Object value) {
|
|
|
- return properties.values().stream().map(p -> p.get(that)).anyMatch(v -> Objects.equals(v, value)) &&
|
|
|
- fluent.values().stream().map(p -> p.invoke(that)).anyMatch(v -> Objects.equals(v, value));
|
|
|
+ return properties.values().stream().map(p -> p.get(that)).anyMatch(v -> Objects.equals(v, value)) ||
|
|
|
+ fluentGet.values().stream().map(p -> p.invoke(that)).anyMatch(v -> Objects.equals(v, value));
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -299,7 +305,12 @@ public class RBeanModel implements BeanModel, Serializable {
|
|
|
if(p != null) {
|
|
|
return p.replace(that, value);
|
|
|
}
|
|
|
- BeanMethod m = fluent.get(key);
|
|
|
+ BeanMethod s = fluentSet.get(key);
|
|
|
+ if(s != null) {
|
|
|
+ s.invoke(that, value);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ BeanMethod m = fluentGet.get(key);
|
|
|
if(m != null) {
|
|
|
throw FBeanModel.newUnsupportedOperationException("Computed fluent property " + key + " is read-only");
|
|
|
}
|
|
|
@@ -315,10 +326,14 @@ public class RBeanModel implements BeanModel, Serializable {
|
|
|
if(p != null) {
|
|
|
return p.get(that);
|
|
|
}
|
|
|
- BeanMethod m = fluent.get(key);
|
|
|
+ BeanMethod m = fluentGet.get(key);
|
|
|
if(m != null) {
|
|
|
return m.invoke(that);
|
|
|
}
|
|
|
+ BeanMethod s = fluentSet.get(key);
|
|
|
+ if(s != null) {
|
|
|
+ throw FBeanModel.newUnsupportedOperationException("Computed fluent property " + key + " is write-only");
|
|
|
+ }
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
@@ -333,13 +348,14 @@ public class RBeanModel implements BeanModel, Serializable {
|
|
|
public Iterator<Entry<String, Object>> iterator() {
|
|
|
return IteratorUtils.concat(
|
|
|
IteratorUtils.map(properties.values().iterator(), p -> new PEntry(p, that)),
|
|
|
- IteratorUtils.map(fluent.values().iterator(), p1 -> new MEntry(p1, that))
|
|
|
+ IteratorUtils.map(fluentGet.values().iterator(), p -> new MEntry(p, that)),
|
|
|
+ IteratorUtils.map(fluentSet.values().iterator(), p -> new MEntry(p, that))
|
|
|
);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public int size() {
|
|
|
- return properties.size() + fluent.size();
|
|
|
+ return properties.size() + fluentGet.size();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -358,7 +374,7 @@ public class RBeanModel implements BeanModel, Serializable {
|
|
|
if(p != null) {
|
|
|
return Objects.equals(entry.getValue(), p.get(that));
|
|
|
}
|
|
|
- BeanMethod m = fluent.get(key);
|
|
|
+ BeanMethod m = fluentGet.get(key);
|
|
|
if(m != null) {
|
|
|
return Objects.equals(entry.getValue(), m.invoke(that));
|
|
|
}
|