Skip to content

Commit

Permalink
Relax mutator rules.
Browse files Browse the repository at this point in the history
  • Loading branch information
gk-brown committed Dec 31, 2024
1 parent 44ba5de commit fd0ef7a
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 87 deletions.
62 changes: 32 additions & 30 deletions kilo-client/src/main/java/org/httprpc/kilo/beans/BeanAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import static org.httprpc.kilo.util.Optionals.*;

Expand All @@ -65,10 +65,12 @@ public class BeanAdapter extends AbstractMap<String, Object> {
* Represents a bean property or record component.
*/
public static class Property {
private Method accessor = null;
private Method mutator = null;
private Method accessor;
private Method mutator;

private Property() {
private Property(Method accessor, Method mutator) {
this.accessor = accessor;
this.mutator = mutator;
}

/**
Expand Down Expand Up @@ -1189,19 +1191,16 @@ public static Map<String, Property> getProperties(Class<?> type) {
}

private static Map<String, Property> computeProperties(Class<?> type) {
var properties = new HashMap<String, Property>();
var accessors = new HashMap<String, Method>();
var mutatorMap = new HashMap<String, List<Method>>();

if (type.isRecord()) {
var recordComponents = type.getRecordComponents();

for (var i = 0; i < recordComponents.length; i++) {
var recordComponent = recordComponents[i];

var property = new Property();

property.accessor = recordComponent.getAccessor();

properties.put(recordComponent.getName(), property);
accessors.put(recordComponent.getName(), recordComponent.getAccessor());
}
} else {
var methods = type.getMethods();
Expand All @@ -1219,39 +1218,42 @@ private static Map<String, Property> computeProperties(Class<?> type) {
continue;
}

var property = properties.computeIfAbsent(propertyName, key -> new Property());

if (method.getParameterCount() == 0) {
property.accessor = method;
} else if (property.mutator == null) {
property.mutator = method;
accessors.put(propertyName, method);
} else {
throw new UnsupportedOperationException("Duplicate mutator.");
mutatorMap.computeIfAbsent(propertyName, key -> new LinkedList<>()).add(method);
}
}
}

return java.util.Collections.unmodifiableMap(properties.entrySet().stream().peek(entry -> {
var value = entry.getValue();
var properties = new TreeMap<String, Property>();

for (var entry : accessors.entrySet()) {
var propertyName = entry.getKey();

var accessor = value.getAccessor();
var accessor = entry.getValue();

if (accessor == null) {
throw new UnsupportedOperationException("Missing accessor.");
var propertyType = accessor.getReturnType();

var mutatorList = mutatorMap.get(propertyName);

Method mutator;
if (mutatorList != null) {
mutator = mutatorList.stream()
.filter(method -> method.getParameterTypes()[0] == propertyType)
.findFirst().orElse(null);
} else {
mutator = null;
}

var mutator = value.getMutator();
var key = getKey(accessor, propertyName);

if (mutator != null && !accessor.getGenericReturnType().equals(mutator.getGenericParameterTypes()[0])) {
throw new UnsupportedOperationException("Property type mismatch.");
if (properties.put(key, new Property(accessor, mutator)) != null) {
throw new UnsupportedOperationException("Duplicate name.");
}
}).collect(Collectors.toMap(entry -> {
var accessor = entry.getValue().getAccessor();
}

return getKey(accessor, entry.getKey());
}, Map.Entry::getValue, (v1, v2) -> {
throw new UnsupportedOperationException("Duplicate name.");
}, TreeMap::new)));
return java.util.Collections.unmodifiableMap(properties);
}

private static String getPropertyName(Method method) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,28 +59,6 @@ public int getY() {
}
}

public static class MissingAccessor {
public void setX(int value) {
// No-op
}
}

public static class DuplicateMutator {
private double x;

public double getX() {
return x;
}

public void setX(double x) {
this.x = x;
}

public void setX(String x) {
// No-op
}
}

public static class DuplicateName {
@Name("x")
public String getFoo() {
Expand All @@ -93,16 +71,6 @@ public String getBar() {
}
}

public static class PropertyTypeMismatch {
public int getX() {
return 0;
}

public void setX(String x) {
// No-op
}
}

public interface DefaultMethod {
int getX();

Expand Down Expand Up @@ -498,19 +466,6 @@ public String toString() {
assertEquals(map2.toString(), nestedBean2.toString());
}

@Test
public void testDefaultMethod() {
var defaultMethod = BeanAdapter.coerce(mapOf(
entry("x", 1)
), DefaultMethod.class);

assertEquals(2, defaultMethod.getY());

var beanAdapter = new BeanAdapter(defaultMethod);

assertEquals(2, beanAdapter.get("z"));
}

@Test
@SuppressWarnings("unchecked")
public void testRequired() {
Expand Down Expand Up @@ -630,23 +585,21 @@ public void testReadOnly() {
assertEquals(100, readOnly.getY());
}

@Test
public void testMissingAccessor() {
assertThrows(UnsupportedOperationException.class, () -> new BeanAdapter(new MissingAccessor()));
}

@Test
public void testDuplicateMutator() {
assertThrows(UnsupportedOperationException.class, () -> new BeanAdapter(new DuplicateMutator()));
}

@Test
public void testDuplicateName() {
assertThrows(UnsupportedOperationException.class, () -> new BeanAdapter(new DuplicateName()));
}

@Test
public void testPropertyTypeMismatch() {
assertThrows(UnsupportedOperationException.class, () -> new BeanAdapter(new PropertyTypeMismatch()));
public void testDefaultMethod() {
var defaultMethod = BeanAdapter.coerce(mapOf(
entry("x", 1)
), DefaultMethod.class);

assertEquals(2, defaultMethod.getY());

var beanAdapter = new BeanAdapter(defaultMethod);

assertEquals(2, beanAdapter.get("z"));
}
}

0 comments on commit fd0ef7a

Please sign in to comment.