diff --git a/src/main/java/net/helenus/core/AbstractEntityDraft.java b/src/main/java/net/helenus/core/AbstractEntityDraft.java index 8479223..1bfd2d1 100644 --- a/src/main/java/net/helenus/core/AbstractEntityDraft.java +++ b/src/main/java/net/helenus/core/AbstractEntityDraft.java @@ -3,13 +3,15 @@ package net.helenus.core; import java.io.Serializable; import java.util.*; +import net.helenus.mapping.value.ValueProviderMap; +import org.apache.commons.lang3.SerializationUtils; + import com.google.common.primitives.Primitives; import net.helenus.core.reflect.DefaultPrimitiveTypes; import net.helenus.core.reflect.Drafted; import net.helenus.core.reflect.MapExportable; import net.helenus.mapping.MappingUtil; -import org.apache.commons.lang3.SerializationUtils; public abstract class AbstractEntityDraft implements Drafted { @@ -38,31 +40,30 @@ public abstract class AbstractEntityDraft implements Drafted { T value = (T) backingMap.get(key); if (value == null) { - value = (T) entityMap.get(key); - if (value == null) { + value = (T) entityMap.get(key); + if (value == null) { - if (Primitives.allPrimitiveTypes().contains(returnType)) { + if (Primitives.allPrimitiveTypes().contains(returnType)) { - DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(returnType); - if (type == null) { - throw new RuntimeException("unknown primitive type " + returnType); - } + DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(returnType); + if (type == null) { + throw new RuntimeException("unknown primitive type " + returnType); + } - return (T) type.getDefaultValue(); - } - } else { - // Collections fetched from the entityMap - if (value instanceof Collection) { - try { - value = MappingUtil.clone(value); - } - catch (CloneNotSupportedException e) { - //TODO(gburd): deep?shallow? copy of List, Map, Set to a mutable collection. - value = (T)SerializationUtils.clone((Serializable)value); - } - } - } - } + return (T) type.getDefaultValue(); + } + } else { + // Collections fetched from the entityMap + if (value instanceof Collection) { + try { + value = MappingUtil.clone(value); + } catch (CloneNotSupportedException e) { + // TODO(gburd): deep?shallow? copy of List, Map, Set to a mutable collection. + value = (T) SerializationUtils.clone((Serializable) value); + } + } + } + } return value; } diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index c2d7013..9182054 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -86,7 +86,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW @Override public synchronized UnitOfWork begin() { elapsedTime = Stopwatch.createStarted(); - // log.recordCacheAndDatabaseOperationCount(txn::start) + // log.record(txn::start) return this; } @@ -306,7 +306,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW uow.committed = false; uow.aborted = true; }); - // log.recordCacheAndDatabaseOperationCount(txn::abort) + // log.record(txn::abort) // cache.invalidateSince(txn::start time) if (!hasAborted()) { elapsedTime.stop(); diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index e67b387..7dd63e9 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -23,23 +23,20 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.*; import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; -import net.helenus.core.cache.SessionCache; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.codahale.metrics.MetricRegistry; import com.datastax.driver.core.*; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; import com.google.common.collect.Table; import brave.Tracer; import net.helenus.core.cache.CacheUtil; import net.helenus.core.cache.Facet; +import net.helenus.core.cache.SessionCache; import net.helenus.core.cache.UnboundFacet; import net.helenus.core.operation.*; import net.helenus.core.reflect.Drafted; @@ -80,8 +77,8 @@ public final class HelenusSession extends AbstractSessionOperations implements C HelenusSession(Session session, String usingKeyspace, CodecRegistry registry, boolean showCql, PrintStream printStream, SessionRepositoryBuilder sessionRepositoryBuilder, Executor executor, boolean dropSchemaOnClose, ConsistencyLevel consistencyLevel, boolean defaultQueryIdempotency, - Class unitOfWorkClass, SessionCache sessionCache, - MetricRegistry metricRegistry, Tracer tracer) { + Class unitOfWorkClass, SessionCache sessionCache, MetricRegistry metricRegistry, + Tracer tracer) { this.session = session; this.registry = registry == null ? CodecRegistry.DEFAULT_INSTANCE : registry; this.usingKeyspace = Objects.requireNonNull(usingKeyspace, @@ -98,10 +95,10 @@ public final class HelenusSession extends AbstractSessionOperations implements C this.zipkinTracer = tracer; if (sessionCache == null) { - this.sessionCache = SessionCache.defaultCache(); - } else { - this.sessionCache = sessionCache; - } + this.sessionCache = SessionCache.defaultCache(); + } else { + this.sessionCache = sessionCache; + } this.valueProvider = new RowColumnValueProvider(this.sessionRepository); this.valuePreparer = new StatementColumnValuePreparer(this.sessionRepository); @@ -242,48 +239,49 @@ public final class HelenusSession extends AbstractSessionOperations implements C @Override public void mergeCache(Table>> uowCache) { - List items = uowCache.values().stream().filter(Either::isLeft).map(Either::getLeft).distinct().collect(Collectors.toList()); + List items = uowCache.values().stream().filter(Either::isLeft).map(Either::getLeft).distinct() + .collect(Collectors.toList()); for (Object pojo : items) { - HelenusEntity entity = Helenus.resolve(MappingUtil.getMappingInterface(pojo)); - Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; - if (entity.isCacheable()) { - List boundFacets = new ArrayList<>(); - for (Facet facet : entity.getFacets()) { - if (facet instanceof UnboundFacet) { - UnboundFacet unboundFacet = (UnboundFacet) facet; - UnboundFacet.Binder binder = unboundFacet.binder(); - unboundFacet.getProperties().forEach(prop -> { - if (valueMap == null) { - Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop); - binder.setValueForProperty(prop, value.toString()); - } else { - binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); - } - }); - if (binder.isBound()) { - boundFacets.add(binder.bind()); - } - } else { - boundFacets.add(facet); - } - } - // NOTE: should equal `String tableName = CacheUtil.schemaName(facets);` - List facetCombinations = CacheUtil.flattenFacets(boundFacets); - String tableName = CacheUtil.schemaName(boundFacets); - mergeAndUpdateCacheValues(pojo, tableName, facetCombinations); - } - } + HelenusEntity entity = Helenus.resolve(MappingUtil.getMappingInterface(pojo)); + Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; + if (entity.isCacheable()) { + List boundFacets = new ArrayList<>(); + for (Facet facet : entity.getFacets()) { + if (facet instanceof UnboundFacet) { + UnboundFacet unboundFacet = (UnboundFacet) facet; + UnboundFacet.Binder binder = unboundFacet.binder(); + unboundFacet.getProperties().forEach(prop -> { + if (valueMap == null) { + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop); + binder.setValueForProperty(prop, value.toString()); + } else { + binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); + } + }); + if (binder.isBound()) { + boundFacets.add(binder.bind()); + } + } else { + boundFacets.add(facet); + } + } + // NOTE: should equal `String tableName = CacheUtil.schemaName(facets);` + List facetCombinations = CacheUtil.flattenFacets(boundFacets); + String tableName = CacheUtil.schemaName(boundFacets); + mergeAndUpdateCacheValues(pojo, tableName, facetCombinations); + } + } - List> deletedFacetSets = uowCache.values().stream().filter(Either::isRight).map(Either::getRight).collect( - Collectors.toList()); - for (List facets : deletedFacetSets) { - String tableName = CacheUtil.schemaName(facets); - List combinations = CacheUtil.flattenFacets(facets); - for (String[] combination : combinations) { - String cacheKey = tableName + "." + Arrays.toString(combination); - sessionCache.invalidate(cacheKey); - } - } + List> deletedFacetSets = uowCache.values().stream().filter(Either::isRight).map(Either::getRight) + .collect(Collectors.toList()); + for (List facets : deletedFacetSets) { + String tableName = CacheUtil.schemaName(facets); + List combinations = CacheUtil.flattenFacets(facets); + for (String[] combination : combinations) { + String cacheKey = tableName + "." + Arrays.toString(combination); + sessionCache.invalidate(cacheKey); + } + } } private void mergeAndUpdateCacheValues(Object pojo, String tableName, List facetCombinations) { @@ -505,20 +503,20 @@ public final class HelenusSession extends AbstractSessionOperations implements C } public UpdateOperation update(Object pojo) { - if (pojo instanceof MapExportable == false) { - throw new HelenusMappingException( - "update of objects that don't implement MapExportable is not yet supported"); - } - return new UpdateOperation(this, pojo); - } + if (pojo instanceof MapExportable == false) { + throw new HelenusMappingException( + "update of objects that don't implement MapExportable is not yet supported"); + } + return new UpdateOperation(this, pojo); + } public UpdateOperation update(Drafted drafted) { - if (drafted instanceof AbstractEntityDraft == false) { - throw new HelenusMappingException( - "update of draft objects that don't inherit from AbstractEntityDraft is not yet supported"); - } + if (drafted instanceof AbstractEntityDraft == false) { + throw new HelenusMappingException( + "update of draft objects that don't inherit from AbstractEntityDraft is not yet supported"); + } AbstractEntityDraft draft = (AbstractEntityDraft) drafted; - UpdateOperation update = new UpdateOperation(this, draft); + UpdateOperation update = new UpdateOperation(this, draft); Map map = draft.toMap(); Set mutatedProperties = draft.mutated(); HelenusEntity entity = Helenus.entity(draft.getEntityClass()); diff --git a/src/main/java/net/helenus/core/SessionInitializer.java b/src/main/java/net/helenus/core/SessionInitializer.java index d5c4117..2559276 100644 --- a/src/main/java/net/helenus/core/SessionInitializer.java +++ b/src/main/java/net/helenus/core/SessionInitializer.java @@ -126,9 +126,9 @@ public final class SessionInitializer extends AbstractSessionOperations { } public SessionInitializer setSessionCache(SessionCache sessionCache) { - this.sessionCache = sessionCache; - return this; - } + this.sessionCache = sessionCache; + return this; + } public ConsistencyLevel getDefaultConsistencyLevel() { return consistencyLevel; @@ -251,7 +251,7 @@ public final class SessionInitializer extends AbstractSessionOperations { initialize(); return new HelenusSession(session, usingKeyspace, registry, showCql, printStream, sessionRepository, executor, autoDdl == AutoDdl.CREATE_DROP, consistencyLevel, idempotent, unitOfWorkClass, sessionCache, - metricRegistry, zipkinTracer); + metricRegistry, zipkinTracer); } private void initialize() { diff --git a/src/main/java/net/helenus/core/cache/BoundFacet.java b/src/main/java/net/helenus/core/cache/BoundFacet.java index 48949ea..0eea23c 100644 --- a/src/main/java/net/helenus/core/cache/BoundFacet.java +++ b/src/main/java/net/helenus/core/cache/BoundFacet.java @@ -25,10 +25,10 @@ public class BoundFacet extends Facet { private final Map properties; public BoundFacet(HelenusProperty property, Object value) { - super(property.getPropertyName(), value == null ? null : value.toString()); - this.properties = new HashMap(1); - this.properties.put(property, value); - } + super(property.getPropertyName(), value == null ? null : value.toString()); + this.properties = new HashMap(1); + this.properties.put(property, value); + } public BoundFacet(String name, Map properties) { super(name, diff --git a/src/main/java/net/helenus/core/cache/CacheUtil.java b/src/main/java/net/helenus/core/cache/CacheUtil.java index 2b08e87..3f2b3a2 100644 --- a/src/main/java/net/helenus/core/cache/CacheUtil.java +++ b/src/main/java/net/helenus/core/cache/CacheUtil.java @@ -1,16 +1,12 @@ package net.helenus.core.cache; -import net.helenus.core.Helenus; -import net.helenus.core.reflect.MapExportable; -import net.helenus.mapping.HelenusEntity; -import net.helenus.mapping.MappingUtil; -import net.helenus.mapping.value.BeanColumnValueProvider; - import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import net.helenus.core.reflect.MapExportable; + public class CacheUtil { public static List combinations(List items) { @@ -45,22 +41,25 @@ public class CacheUtil { } public static Object merge(Object to, Object from) { - if (to == from) { - return to; + if (to == from) { + return to; + } else { + return from; } +/* + // TODO(gburd): take ttl and writeTime into account when merging. + Map toValueMap = to instanceof MapExportable ? ((MapExportable) to).toMap() : null; + Map fromValueMap = to instanceof MapExportable ? ((MapExportable) from).toMap() : null; - //TODO(gburd): take ttl and writeTime into account when merging. - Map toValueMap = to instanceof MapExportable ? ((MapExportable) to).toMap() : null; - Map fromValueMap = to instanceof MapExportable ? ((MapExportable) from).toMap() : null; - - if (toValueMap != null && fromValueMap != null) { - for (String key : fromValueMap.keySet()) { - if (toValueMap.containsKey(key) && toValueMap.get(key) != fromValueMap.get(key)) { - toValueMap.put(key, fromValueMap.get(key)); - } - } - } + if (toValueMap != null && fromValueMap != null) { + for (String key : fromValueMap.keySet()) { + if (toValueMap.containsKey(key) && toValueMap.get(key) != fromValueMap.get(key)) { + toValueMap.put(key, fromValueMap.get(key)); + } + } + } return to; +*/ } public static String schemaName(List facets) { diff --git a/src/main/java/net/helenus/core/cache/GuavaCache.java b/src/main/java/net/helenus/core/cache/GuavaCache.java index 7438c63..4411e7c 100644 --- a/src/main/java/net/helenus/core/cache/GuavaCache.java +++ b/src/main/java/net/helenus/core/cache/GuavaCache.java @@ -20,25 +20,25 @@ import com.google.common.cache.Cache; public class GuavaCache implements SessionCache { - final Cache cache; + final Cache cache; - GuavaCache(Cache cache) { - this.cache = cache; - } + GuavaCache(Cache cache) { + this.cache = cache; + } - @Override - public void invalidate(K key) { - cache.invalidate(key); - } + @Override + public void invalidate(K key) { + cache.invalidate(key); + } - @Override - public V get(K key) { - return cache.getIfPresent(key); - } + @Override + public V get(K key) { + return cache.getIfPresent(key); + } - @Override - public void put(K key, V value) { - cache.put(key, value); - } + @Override + public void put(K key, V value) { + cache.put(key, value); + } } diff --git a/src/main/java/net/helenus/core/cache/SessionCache.java b/src/main/java/net/helenus/core/cache/SessionCache.java index 02b15c6..44717e0 100644 --- a/src/main/java/net/helenus/core/cache/SessionCache.java +++ b/src/main/java/net/helenus/core/cache/SessionCache.java @@ -16,21 +16,21 @@ package net.helenus.core.cache; -import com.google.common.cache.CacheBuilder; - import java.util.concurrent.TimeUnit; +import com.google.common.cache.CacheBuilder; + public interface SessionCache { - static SessionCache defaultCache() { - int MAX_CACHE_SIZE = 10000; - int MAX_CACHE_EXPIRE_SECONDS = 600; - return new GuavaCache(CacheBuilder.newBuilder().maximumSize(MAX_CACHE_SIZE) - .expireAfterAccess(MAX_CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS) - .expireAfterWrite(MAX_CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS).recordStats().build()); - } + static SessionCache defaultCache() { + int MAX_CACHE_SIZE = 10000; + int MAX_CACHE_EXPIRE_SECONDS = 600; + return new GuavaCache(CacheBuilder.newBuilder().maximumSize(MAX_CACHE_SIZE) + .expireAfterAccess(MAX_CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS) + .expireAfterWrite(MAX_CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS).recordStats().build()); + } - void invalidate(K key); - V get(K key); - void put(K key, V value); + void invalidate(K key); + V get(K key); + void put(K key, V value); } diff --git a/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java b/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java index 6eec08d..eb30d37 100644 --- a/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java @@ -20,7 +20,6 @@ import java.util.*; import net.helenus.core.*; import net.helenus.core.cache.Facet; import net.helenus.core.cache.UnboundFacet; -import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusProperty; public abstract class AbstractFilterOperation> @@ -111,38 +110,38 @@ public abstract class AbstractFilterOperation bindFacetValues(List facets) { - if (facets == null) { - return new ArrayList(); - } - List boundFacets = new ArrayList<>(); - Map filterMap = new HashMap<>(filters.size()); - filters.forEach(f -> filterMap.put(f.getNode().getProperty(), f)); + protected List bindFacetValues(List facets) { + if (facets == null) { + return new ArrayList(); + } + List boundFacets = new ArrayList<>(); + Map filterMap = new HashMap<>(filters.size()); + filters.forEach(f -> filterMap.put(f.getNode().getProperty(), f)); - for (Facet facet : facets) { - if (facet instanceof UnboundFacet) { - UnboundFacet unboundFacet = (UnboundFacet) facet; - UnboundFacet.Binder binder = unboundFacet.binder(); - if (filters != null) { - for (HelenusProperty prop : unboundFacet.getProperties()) { + for (Facet facet : facets) { + if (facet instanceof UnboundFacet) { + UnboundFacet unboundFacet = (UnboundFacet) facet; + UnboundFacet.Binder binder = unboundFacet.binder(); + if (filters != null) { + for (HelenusProperty prop : unboundFacet.getProperties()) { - Filter filter = filterMap.get(prop); - if (filter != null) { - Object[] postulates = filter.postulateValues(); - for (Object p : postulates) { - binder.setValueForProperty(prop, p.toString()); - } - } - } + Filter filter = filterMap.get(prop); + if (filter != null) { + Object[] postulates = filter.postulateValues(); + for (Object p : postulates) { + binder.setValueForProperty(prop, p.toString()); + } + } + } - } - if (binder.isBound()) { - boundFacets.add(binder.bind()); - } - } else { - boundFacets.add(facet); - } - } - return boundFacets; - } + } + if (binder.isBound()) { + boundFacets.add(binder.bind()); + } + } else { + boundFacets.add(facet); + } + } + return boundFacets; + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java index 34a1da3..7f9cff3 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java @@ -333,10 +333,10 @@ public abstract class AbstractStatementOperation facets = new ArrayList<>(); Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; - for (Facet facet : identifyingFacets) { - if (facet instanceof UnboundFacet) { - UnboundFacet unboundFacet = (UnboundFacet) facet; - UnboundFacet.Binder binder = unboundFacet.binder(); + for (Facet facet : identifyingFacets) { + if (facet instanceof UnboundFacet) { + UnboundFacet unboundFacet = (UnboundFacet) facet; + UnboundFacet.Binder binder = unboundFacet.binder(); for (HelenusProperty prop : unboundFacet.getProperties()) { Object value; if (valueMap == null) { diff --git a/src/main/java/net/helenus/core/operation/DeleteOperation.java b/src/main/java/net/helenus/core/operation/DeleteOperation.java index e17e0a4..1280f45 100644 --- a/src/main/java/net/helenus/core/operation/DeleteOperation.java +++ b/src/main/java/net/helenus/core/operation/DeleteOperation.java @@ -15,10 +15,7 @@ */ package net.helenus.core.operation; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.concurrent.TimeoutException; import com.datastax.driver.core.ResultSet; @@ -31,10 +28,8 @@ import net.helenus.core.AbstractSessionOperations; import net.helenus.core.Filter; import net.helenus.core.UnitOfWork; import net.helenus.core.cache.Facet; -import net.helenus.core.cache.UnboundFacet; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; -import net.helenus.mapping.HelenusProperty; import net.helenus.support.HelenusMappingException; public final class DeleteOperation extends AbstractFilterOperation { @@ -134,8 +129,8 @@ public final class DeleteOperation extends AbstractFilterOperation bindFacetValues() { - return bindFacetValues(getFacets()); - } + return bindFacetValues(getFacets()); + } @Override public ResultSet sync() throws TimeoutException { @@ -156,9 +151,9 @@ public final class DeleteOperation extends AbstractFilterOperation getFacets() { - return entity.getFacets(); - } + @Override + public List getFacets() { + return entity.getFacets(); + } } diff --git a/src/main/java/net/helenus/core/operation/InsertOperation.java b/src/main/java/net/helenus/core/operation/InsertOperation.java index ff7d3ce..91959ba 100644 --- a/src/main/java/net/helenus/core/operation/InsertOperation.java +++ b/src/main/java/net/helenus/core/operation/InsertOperation.java @@ -44,7 +44,7 @@ public final class InsertOperation extends AbstractOperation> values = new ArrayList>(); private final T pojo; - private final Class resultType; + private final Class resultType; private HelenusEntity entity; private boolean ifNotExists; @@ -56,7 +56,7 @@ public final class InsertOperation extends AbstractOperation resultType, boolean ifNotExists) { @@ -251,14 +251,14 @@ public final class InsertOperation extends AbstractOperation iface = entity.getMappingInterface(); - if (resultType == iface) { + Class iface = entity.getMappingInterface(); + if (resultType == iface) { cacheUpdate(uow, result, entity.getFacets()); } else { - if (entity.isCacheable()) { - sessionOps.cacheEvict(bindFacetValues()); - } - } + if (entity.isCacheable()) { + sessionOps.cacheEvict(bindFacetValues()); + } + } return result; } diff --git a/src/main/java/net/helenus/core/operation/SelectOperation.java b/src/main/java/net/helenus/core/operation/SelectOperation.java index fd05b22..497868b 100644 --- a/src/main/java/net/helenus/core/operation/SelectOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectOperation.java @@ -207,7 +207,7 @@ public final class SelectOperation extends AbstractFilterStreamOperation extends AbstractFilterOperation UpdateOperation set(Getter getter, V v) { + public UpdateOperation set(Getter getter, V v) { Objects.requireNonNull(getter, "getter is empty"); HelenusPropertyNode p = MappingUtil.resolveMappingProperty(getter); @@ -91,23 +90,23 @@ public final class UpdateOperation extends AbstractFilterOperation map = ((MapExportable) pojo).toMap(); - if (!(map instanceof ValueProviderMap)) { - if (map.get(key) != value) { - map.put(key, value); - } - } - } - } + if (entity != null) { + if (entity.isCacheable() && pojo != null && pojo instanceof MapExportable) { + String key = prop.getPropertyName(); + Map map = ((MapExportable) pojo).toMap(); + if (!(map instanceof ValueProviderMap)) { + if (map.get(key) != value) { + map.put(key, value); + } + } + } + } addPropertyNode(p); @@ -132,15 +131,15 @@ public final class UpdateOperation extends AbstractFilterOperation extends AbstractFilterOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - list.add(0, value); - facet = new BoundFacet(prop, list); - } else if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.add(0, value); - } + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + List list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.add(0, value); + facet = new BoundFacet(prop, list); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.add(0, value); + } - assignments.put(QueryBuilder.prepend(p.getColumnName(), valueObj), facet); + assignments.put(QueryBuilder.prepend(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -218,19 +217,19 @@ public final class UpdateOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - list.addAll(0, value); - facet = new BoundFacet(prop, list); - } else if (draft != null && value.size() > 0) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.addAll(0, value); - } + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + List list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.addAll(0, value); + facet = new BoundFacet(prop, list); + } else if (draft != null && value.size() > 0) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.addAll(0, value); + } - assignments.put(QueryBuilder.prependAll(p.getColumnName(), valueObj), facet); + assignments.put(QueryBuilder.prependAll(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -245,28 +244,28 @@ public final class UpdateOperation extends AbstractFilterOperation list; - HelenusProperty prop = p.getProperty(); - if (pojo != null) { - list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - } else { - String key = p.getProperty().getPropertyName(); - list = (List) draftMap.get(key); - } - if (idx < 0) { - list.add(0, value); - } else if (idx > list.size()) { - list.add(list.size(), value); - } else { - list.add(idx, value); - } - list.add(0, value); - facet = new BoundFacet(prop, list); - } + BoundFacet facet = null; + if (pojo != null || draft != null) { + List list; + HelenusProperty prop = p.getProperty(); + if (pojo != null) { + list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + } else { + String key = p.getProperty().getPropertyName(); + list = (List) draftMap.get(key); + } + if (idx < 0) { + list.add(0, value); + } else if (idx > list.size()) { + list.add(list.size(), value); + } else { + list.add(idx, value); + } + list.add(0, value); + facet = new BoundFacet(prop, list); + } - assignments.put(QueryBuilder.setIdx(p.getColumnName(), idx, valueObj), facet); + assignments.put(QueryBuilder.setIdx(p.getColumnName(), idx, valueObj), facet); addPropertyNode(p); @@ -281,18 +280,18 @@ public final class UpdateOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - list.add(value); - facet = new BoundFacet(prop, list); - } else if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.add(value); - } - assignments.put(QueryBuilder.append(p.getColumnName(), valueObj), facet); + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + List list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.add(value); + facet = new BoundFacet(prop, list); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.add(value); + } + assignments.put(QueryBuilder.append(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -307,18 +306,18 @@ public final class UpdateOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - list.addAll(value); - facet = new BoundFacet(prop, list); - } else if (draft != null && value.size() > 0) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.addAll(value); - } - assignments.put(QueryBuilder.appendAll(p.getColumnName(), valueObj), facet); + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + List list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.addAll(value); + facet = new BoundFacet(prop, list); + } else if (draft != null && value.size() > 0) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.addAll(value); + } + assignments.put(QueryBuilder.appendAll(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -333,18 +332,18 @@ public final class UpdateOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - list.remove(value); - facet = new BoundFacet(prop, list); - } else if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.remove(value); - } - assignments.put(QueryBuilder.discard(p.getColumnName(), valueObj), facet); + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + List list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.remove(value); + facet = new BoundFacet(prop, list); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.remove(value); + } + assignments.put(QueryBuilder.discard(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -359,18 +358,18 @@ public final class UpdateOperation extends AbstractFilterOperation list = new ArrayList((List)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - list.removeAll(value); - facet = new BoundFacet(prop, list); - } else if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.removeAll(value); - } - assignments.put(QueryBuilder.discardAll(p.getColumnName(), valueObj), facet); + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + List list = new ArrayList((List) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + list.removeAll(value); + facet = new BoundFacet(prop, list); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.removeAll(value); + } + assignments.put(QueryBuilder.discardAll(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -421,18 +420,18 @@ public final class UpdateOperation extends AbstractFilterOperation set = new HashSet((Set)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - set.add(value); - facet = new BoundFacet(prop, set); - } else if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.add(value); - } - assignments.put(QueryBuilder.add(p.getColumnName(), valueObj), facet); + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + Set set = new HashSet((Set) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + set.add(value); + facet = new BoundFacet(prop, set); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.add(value); + } + assignments.put(QueryBuilder.add(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -447,17 +446,17 @@ public final class UpdateOperation extends AbstractFilterOperation set = new HashSet((Set)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - set.addAll(value); - facet = new BoundFacet(prop, set); - } else if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.addAll(value); - } + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + Set set = new HashSet((Set) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + set.addAll(value); + facet = new BoundFacet(prop, set); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.addAll(value); + } assignments.put(QueryBuilder.addAll(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -473,17 +472,17 @@ public final class UpdateOperation extends AbstractFilterOperation set = new HashSet((Set)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - set.remove(value); - facet = new BoundFacet(prop, set); - } else if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.remove(value); - } + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + Set set = new HashSet((Set) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + set.remove(value); + facet = new BoundFacet(prop, set); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.remove(value); + } assignments.put(QueryBuilder.remove(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -499,17 +498,17 @@ public final class UpdateOperation extends AbstractFilterOperation set = new HashSet((Set)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - set.removeAll(value); - facet = new BoundFacet(prop, set); - } else if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.removeAll(value); - } + BoundFacet facet = null; + if (pojo != null) { + HelenusProperty prop = p.getProperty(); + Set set = new HashSet((Set) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + set.removeAll(value); + facet = new BoundFacet(prop, set); + } else if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.removeAll(value); + } assignments.put(QueryBuilder.removeAll(p.getColumnName(), valueObj), facet); addPropertyNode(p); @@ -560,14 +559,15 @@ public final class UpdateOperation extends AbstractFilterOperation map = new HashMap((Map)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - map.put(key, value); - facet = new BoundFacet(prop, map); - } else if (draft != null) { - ((Map) draftMap.get(prop.getPropertyName())).put(key, value); - } + BoundFacet facet = null; + if (pojo != null) { + Map map = new HashMap( + (Map) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + map.put(key, value); + facet = new BoundFacet(prop, map); + } else if (draft != null) { + ((Map) draftMap.get(prop.getPropertyName())).put(key, value); + } Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); if (converter.isPresent()) { @@ -593,14 +593,15 @@ public final class UpdateOperation extends AbstractFilterOperation newMap = new HashMap((Map)BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); - newMap.putAll(map); - facet = new BoundFacet(prop, newMap); - } else if (draft != null) { - ((Map) draftMap.get(prop.getPropertyName())).putAll(map); - } + BoundFacet facet = null; + if (pojo != null) { + Map newMap = new HashMap( + (Map) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop)); + newMap.putAll(map); + facet = new BoundFacet(prop, newMap); + } else if (draft != null) { + ((Map) draftMap.get(prop.getPropertyName())).putAll(map); + } Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); if (converter.isPresent()) { @@ -687,13 +688,13 @@ public final class UpdateOperation extends AbstractFilterOperation extends AbstractFilterOperation bindFacetValues() { - List facets = bindFacetValues(entity.getFacets()); - facets.addAll(assignments.values().stream().distinct().filter(o -> o != null).collect(Collectors.toList())); - return facets; - } + @Override + public List bindFacetValues() { + List facets = bindFacetValues(entity.getFacets()); + facets.addAll(assignments.values().stream().distinct().filter(o -> o != null).collect(Collectors.toList())); + return facets; + } - @Override + @Override public List getFacets() { if (entity != null) { return entity.getFacets(); diff --git a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java index 42af52a..9bde57c 100644 --- a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java +++ b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java @@ -21,7 +21,6 @@ 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.Map; import net.helenus.core.Helenus; @@ -102,8 +101,8 @@ public class MapperInvocationHandler implements InvocationHandler, Serializab } if (MapExportable.TO_MAP_METHOD.equals(methodName)) { - //return Collections.unmodifiableMap(src); - return src; + // return Collections.unmodifiableMap(src); + return src; } Object value = src.get(methodName); diff --git a/src/main/java/net/helenus/mapping/MappingUtil.java b/src/main/java/net/helenus/mapping/MappingUtil.java index f554b72..f421c40 100644 --- a/src/main/java/net/helenus/mapping/MappingUtil.java +++ b/src/main/java/net/helenus/mapping/MappingUtil.java @@ -285,41 +285,39 @@ public final class MappingUtil { } // https://stackoverflow.com/a/4882306/366692 - public static T clone(T object) - throws CloneNotSupportedException { - Object clone = null; + public static T clone(T object) throws CloneNotSupportedException { + Object clone = null; - // Use reflection, because there is no other way - try { - Method method = object.getClass().getMethod("clone"); - clone = method.invoke(object); - } catch (InvocationTargetException e) { - rethrow(e.getCause()); - } catch (Exception cause) { - rethrow(cause); - } - if (object.getClass().isInstance(clone)) { - @SuppressWarnings("unchecked") // clone class <= object class <= T - T t = (T) clone; - return t; - } else { - throw new ClassCastException(clone.getClass().getName()); - } - } + // Use reflection, because there is no other way + try { + Method method = object.getClass().getMethod("clone"); + clone = method.invoke(object); + } catch (InvocationTargetException e) { + rethrow(e.getCause()); + } catch (Exception cause) { + rethrow(cause); + } + if (object.getClass().isInstance(clone)) { + @SuppressWarnings("unchecked") // clone class <= object class <= T + T t = (T) clone; + return t; + } else { + throw new ClassCastException(clone.getClass().getName()); + } + } - private static void rethrow(Throwable cause) - throws CloneNotSupportedException { - if (cause instanceof RuntimeException) { - throw (RuntimeException) cause; - } - if (cause instanceof Error) { - throw (Error) cause; - } - if (cause instanceof CloneNotSupportedException) { - throw (CloneNotSupportedException) cause; - } - CloneNotSupportedException e = new CloneNotSupportedException(); - e.initCause(cause); - throw e; - } + private static void rethrow(Throwable cause) throws CloneNotSupportedException { + if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } + if (cause instanceof Error) { + throw (Error) cause; + } + if (cause instanceof CloneNotSupportedException) { + throw (CloneNotSupportedException) cause; + } + CloneNotSupportedException e = new CloneNotSupportedException(); + e.initCause(cause); + throw e; + } }