Draft instances map is mutable and so are collection values inside the map, this makes the UPDATE logic straight forward when mutating in-cache draft objects. Also, fix one or two logic bugs with isAssignableFrom().
This commit is contained in:
parent
7a56059036
commit
618a7ea380
5 changed files with 52 additions and 45 deletions
|
@ -17,7 +17,8 @@ public abstract class AbstractEntityDraft<E> implements Drafted<E> {
|
|||
|
||||
public AbstractEntityDraft(MapExportable entity) {
|
||||
this.entity = entity;
|
||||
this.entityMap = entity != null ? entity.toMap() : new HashMap<String, Object>();
|
||||
// Entities can mutate their map.
|
||||
this.entityMap = entity != null ? entity.toMap(true) : new HashMap<String, Object>();
|
||||
}
|
||||
|
||||
public abstract Class<E> getEntityClass();
|
||||
|
|
|
@ -203,9 +203,7 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
facet = new BoundFacet(prop, list);
|
||||
} else if (draft != null) {
|
||||
String key = prop.getPropertyName();
|
||||
list =
|
||||
(List<V>) new ArrayList<V>((List<V>) draftMap.get(key)); // copy immutable -> mutable list
|
||||
draft.put(key, list);
|
||||
list = (List<V>) draftMap.get(key);
|
||||
list.add(0, value);
|
||||
facet = new BoundFacet(prop, list);
|
||||
} else {
|
||||
|
@ -237,9 +235,7 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
facet = new BoundFacet(prop, list);
|
||||
} else if (draft != null && value.size() > 0) {
|
||||
String key = p.getProperty().getPropertyName();
|
||||
list =
|
||||
(List<V>) new ArrayList<V>((List<V>) draftMap.get(key)); // copy immutable -> mutable list
|
||||
draft.put(key, list);
|
||||
list = (List<V>) draftMap.get(key);
|
||||
list.addAll(0, value);
|
||||
facet = new BoundFacet(prop, list);
|
||||
} else {
|
||||
|
@ -270,10 +266,7 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
list = (List<V>) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false);
|
||||
} else {
|
||||
String key = prop.getPropertyName();
|
||||
list =
|
||||
(List<V>)
|
||||
new ArrayList<V>((List<V>) draftMap.get(key)); // copy immutable -> mutable list
|
||||
draft.put(key, list);
|
||||
list = (List<V>) draftMap.get(key);
|
||||
}
|
||||
if (idx < 0) {
|
||||
list.add(0, value);
|
||||
|
@ -312,9 +305,7 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
facet = new BoundFacet(prop, list);
|
||||
} else if (draft != null) {
|
||||
String key = prop.getPropertyName();
|
||||
list =
|
||||
(List<V>) new ArrayList<V>((List<V>) draftMap.get(key)); // copy immutable -> mutable list
|
||||
draft.put(key, list);
|
||||
list = (List<V>) draftMap.get(key);
|
||||
list.add(value);
|
||||
facet = new BoundFacet(prop, list);
|
||||
} else {
|
||||
|
@ -345,9 +336,7 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
facet = new BoundFacet(prop, list);
|
||||
} else if (draft != null && value.size() > 0) {
|
||||
String key = prop.getPropertyName();
|
||||
list =
|
||||
(List<V>) new ArrayList<V>((List<V>) draftMap.get(key)); // copy immutable -> mutable list
|
||||
draft.put(key, list);
|
||||
list = (List<V>) draftMap.get(key);
|
||||
list.addAll(value);
|
||||
facet = new BoundFacet(prop, list);
|
||||
} else {
|
||||
|
@ -378,9 +367,7 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
facet = new BoundFacet(prop, list);
|
||||
} else if (draft != null) {
|
||||
String key = prop.getPropertyName();
|
||||
list =
|
||||
(List<V>) new ArrayList<V>((List<V>) draftMap.get(key)); // copy immutable -> mutable list
|
||||
draft.put(key, list);
|
||||
list = (List<V>) draftMap.get(key);
|
||||
list.remove(value);
|
||||
facet = new BoundFacet(prop, list);
|
||||
} else {
|
||||
|
@ -411,9 +398,7 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
facet = new BoundFacet(prop, list);
|
||||
} else if (draft != null) {
|
||||
String key = prop.getPropertyName();
|
||||
list =
|
||||
(List<V>) new ArrayList<V>((List<V>) draftMap.get(key)); // copy immutable -> mutable list
|
||||
draft.put(key, list);
|
||||
list = (List<V>) draftMap.get(key);
|
||||
list.removeAll(value);
|
||||
facet = new BoundFacet(prop, list);
|
||||
} else {
|
||||
|
@ -482,8 +467,7 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
|||
facet = new BoundFacet(prop, set);
|
||||
} else if (draft != null) {
|
||||
String key = prop.getPropertyName();
|
||||
set = (Set<V>) new HashSet<V>((Set<V>) draftMap.get(key));
|
||||
draft.put(key, set);
|
||||
set = (Set<V>) draftMap.get(key);
|
||||
set.add(value);
|
||||
facet = new BoundFacet(prop, set);
|
||||
} else {
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
*/
|
||||
package net.helenus.core.reflect;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectStreamException;
|
||||
|
@ -24,10 +27,7 @@ import java.lang.reflect.Constructor;
|
|||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import net.helenus.core.Getter;
|
||||
import net.helenus.core.Helenus;
|
||||
import net.helenus.core.cache.CacheUtil;
|
||||
|
@ -168,6 +168,15 @@ public class MapperInvocationHandler<E> implements InvocationHandler, Serializab
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (MapExportable.TO_MAP_METHOD.equals(methodName)) {
|
||||
if (method.getParameterCount() == 1 && args[0] instanceof Boolean) {
|
||||
if ((boolean) args[0] == true) {
|
||||
return fromValueProviderMap(src, true);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableMap(src);
|
||||
}
|
||||
|
||||
if (method.getParameterCount() != 0 || method.getReturnType() == void.class) {
|
||||
throw new HelenusException("invalid getter method " + method);
|
||||
}
|
||||
|
@ -192,15 +201,6 @@ public class MapperInvocationHandler<E> implements InvocationHandler, Serializab
|
|||
return Helenus.dsl(iface);
|
||||
}
|
||||
|
||||
if (MapExportable.TO_MAP_METHOD.equals(methodName)) {
|
||||
if (method.getParameterCount() == 1 && args[0] instanceof Boolean) {
|
||||
if ((boolean) args[0] == true) {
|
||||
return src;
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableMap(src);
|
||||
}
|
||||
|
||||
final Object value = src.get(methodName);
|
||||
|
||||
if (value == null) {
|
||||
|
@ -228,13 +228,33 @@ public class MapperInvocationHandler<E> implements InvocationHandler, Serializab
|
|||
}
|
||||
|
||||
static Map<String, Object> fromValueProviderMap(Map v) {
|
||||
return fromValueProviderMap(v, false);
|
||||
}
|
||||
|
||||
static Map<String, Object> fromValueProviderMap(Map v, boolean mutable) {
|
||||
if (v instanceof ValueProviderMap) {
|
||||
Map<String, Object> m = new HashMap<String, Object>(v.size());
|
||||
Set<String> keys = v.keySet();
|
||||
for (String key : keys) {
|
||||
m.put(key, v.get(key));
|
||||
Object value = v.get(key);
|
||||
if (mutable) {
|
||||
if (ImmutableList.class.isAssignableFrom(value.getClass())) {
|
||||
m.put(key, new ArrayList((List) value));
|
||||
} else if (ImmutableMap.class.isAssignableFrom(value.getClass())) {
|
||||
m.put(key, new HashMap((Map) value));
|
||||
} else if (ImmutableSet.class.isAssignableFrom(value.getClass())) {
|
||||
m.put(key, new HashSet((Set) value));
|
||||
} else {
|
||||
m.put(key, value);
|
||||
}
|
||||
} else {
|
||||
m.put(key, value);
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static class SerializationProxy<E> implements Serializable {
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ public final class HelenusMappingEntity implements HelenusEntity {
|
|||
}
|
||||
for (ConstraintValidator<?, ?> constraint :
|
||||
MappingUtil.getValidators(prop.getGetterMethod())) {
|
||||
if (constraint.getClass().isAssignableFrom(DistinctValidator.class)) {
|
||||
if (constraint instanceof DistinctValidator) {
|
||||
DistinctValidator validator = (DistinctValidator) constraint;
|
||||
String[] values = validator.constraintAnnotation.value();
|
||||
UnboundFacet facet;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package net.helenus.mapping.value;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -153,7 +154,8 @@ public final class ValueProviderMap implements Map<String, Object> {
|
|||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null
|
||||
|| !(o.getClass().isAssignableFrom(Map.class)
|
||||
|| !((Map.class.isAssignableFrom(o.getClass())
|
||||
|| ImmutableMap.class.isAssignableFrom(o.getClass()))
|
||||
|| o.getClass().getSimpleName().equals("UnmodifiableMap"))) return false;
|
||||
|
||||
Map that = (Map) o;
|
||||
|
|
Loading…
Reference in a new issue