From efa87b2d4f4fc50b2fe4a399d0b144aa9c351c23 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Tue, 26 Sep 2017 10:37:08 -0400 Subject: [PATCH 1/9] WIP: working toward a faceted cache. --- NOTES | 5 ++ .../java/net/helenus/core/HelenusSession.java | 6 +- ...UnitOfWorkAspect.java => RetryAspect.java} | 4 +- .../core/cache/EntityIdentifyingFacet.java | 14 +++ .../java/net/helenus/core/cache/Facet.java | 21 +++++ .../operation/AbstractOptionalOperation.java | 85 ++++++++++++++++--- .../net/helenus/core/operation/Operation.java | 5 +- .../core/operation/SelectOperation.java | 42 +++++---- .../net/helenus/mapping/HelenusEntity.java | 6 ++ .../helenus/mapping/HelenusMappingEntity.java | 33 +++++++ 10 files changed, 179 insertions(+), 42 deletions(-) rename src/main/java/net/helenus/core/aspect/{RetryConcurrentUnitOfWorkAspect.java => RetryAspect.java} (97%) create mode 100644 src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java create mode 100644 src/main/java/net/helenus/core/cache/Facet.java diff --git a/NOTES b/NOTES index 04dd989..038b1e9 100644 --- a/NOTES +++ b/NOTES @@ -1,3 +1,8 @@ + + + + + --- Cache // `E` is the type of the Entity class or one of: // - ResultSet diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index db08f8e..785fba6 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -181,11 +181,11 @@ public final class HelenusSession extends AbstractSessionOperations implements C public Metadata getMetadata() { return metadata; } - public synchronized UnitOfWork begin() { + public synchronized T begin() { return begin(null); } - public synchronized UnitOfWork begin(UnitOfWork parent) { + public synchronized T begin(T parent) { try { Class clazz = unitOfWorkClass; Constructor ctor = clazz.getConstructor(HelenusSession.class, UnitOfWork.class); @@ -193,7 +193,7 @@ public final class HelenusSession extends AbstractSessionOperations implements C if (parent != null) { parent.addNestedUnitOfWork(uow); } - return uow.begin(); + return (T) uow.begin(); } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) { throw new HelenusException(String.format("Unable to instantiate {} as a UnitOfWork.", unitOfWorkClass.getSimpleName()), e); diff --git a/src/main/java/net/helenus/core/aspect/RetryConcurrentUnitOfWorkAspect.java b/src/main/java/net/helenus/core/aspect/RetryAspect.java similarity index 97% rename from src/main/java/net/helenus/core/aspect/RetryConcurrentUnitOfWorkAspect.java rename to src/main/java/net/helenus/core/aspect/RetryAspect.java index 7d52f16..e828f8b 100644 --- a/src/main/java/net/helenus/core/aspect/RetryConcurrentUnitOfWorkAspect.java +++ b/src/main/java/net/helenus/core/aspect/RetryAspect.java @@ -14,9 +14,9 @@ import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.Assert; @Aspect -public class RetryConcurrentUnitOfWorkAspect { +public class RetryAspect { - private static final Logger log = LoggerFactory.getLogger(RetryConcurrentUnitOfWorkAspect.class); + private static final Logger log = LoggerFactory.getLogger(RetryAspect.class); @Around("@annotation(net.helenus.core.annotations.Retry)") public Object retry(ProceedingJoinPoint pjp) throws Throwable { diff --git a/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java b/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java new file mode 100644 index 0000000..8bf3b8b --- /dev/null +++ b/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java @@ -0,0 +1,14 @@ +package net.helenus.core.cache; + +import net.helenus.mapping.HelenusProperty; + +public class EntityIdentifyingFacet extends Facet { + + public EntityIdentifyingFacet(HelenusProperty prop) { + + } + + public EntityIdentifyingFacet(HelenusProperty[]... props) { + + } +} diff --git a/src/main/java/net/helenus/core/cache/Facet.java b/src/main/java/net/helenus/core/cache/Facet.java new file mode 100644 index 0000000..eb521b1 --- /dev/null +++ b/src/main/java/net/helenus/core/cache/Facet.java @@ -0,0 +1,21 @@ +package net.helenus.core.cache; + +public class Facet { +} +/* + +An Entity is identifiable via one or more Facets + +A Facet is is a set of Properties and bound Facets + +An Entity will have it's Keyspace, Table and Schema Version Facets bound. + +A property may also have a TTL or write time bound. + +The cache contains key->value mappings of merkel-hash -> Entity or Set +The only way a Set is put into the cache is with a key = hash([Entity's bound Facets, hash(filter clause from SELECT)]) + +REMEMBER to update the cache on build() for all impacted facets, delete existing keys and add new keys + + + */ diff --git a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java index 93ec79d..221fcf7 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java @@ -23,12 +23,22 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import java.util.HashSet; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletableFuture; import net.helenus.core.AbstractSessionOperations; +import net.helenus.core.Filter; +import net.helenus.core.Helenus; import net.helenus.core.UnitOfWork; +import net.helenus.core.cache.EntityIdentifyingFacet; +import net.helenus.mapping.HelenusEntity; +import net.helenus.mapping.HelenusProperty; +import net.helenus.mapping.value.BeanColumnValueProvider; +import net.helenus.support.Either; + +import javax.swing.text.html.parser.Entity; public abstract class AbstractOptionalOperation> extends AbstractStatementOperation { @@ -72,25 +82,74 @@ public abstract class AbstractOptionalOperation result = null; - String key = getStatementCacheKey(); - if (enableCache && key != null) { - Set cachedResult = (Set) uow.cacheLookup(key); - if (cachedResult != null) { - //TODO(gburd): what about select ResultSet, Tuple... etc.? - uowCacheHits.mark(); - logger.info("UOW({}) cache hit, {}", uow.hashCode(), key); - result = cachedResult.stream().findFirst(); - } else { - uowCacheMiss.mark(); - } + String stmtKey = null; + if (enableCache) { + Set facets = getIdentifyingFacets(); + if (!facets.isEmpty()) { + for (EntityIdentifyingFacet facet : facets) { + //TODO(gburd): what about select ResultSet, Tuple... etc.? + Optional, E>> optionalCachedResult = uow.cacheLookup(facet.hashCode()); + if (optionalCachedResult.isPresent()) { + uowCacheHits.mark(); + logger.info("UnitOfWork({}) cache hit for facet: {} with key: {}", uow.hashCode(), facet.toString(), facet.hashCode()); + Either, E> eitherCachedResult = optionalCachedResult.get(); + if (eitherCachedResult.isRight()) { + E cachedResult = eitherCachedResult.getRight(); + result = Optional.of(cachedResult); + } + break; + } + } + } else { + // The operation didn't provide enough information to uniquely identify the entity object + // using one of the facets, but that doesn't mean a filtering query won't return a proper + // result. Look in the cache to see if this statement has been executed before. + stmtKey = getStatementCacheKey(); + Optional, E>> optionalCachedResult = uow.cacheLookup(stmtKey.hashCode()); + if (optionalCachedResult.isPresent()) { + Either, E> eitherCachedResult = optionalCachedResult.get(); + if (eitherCachedResult.isLeft()) { + Set cachedResult = eitherCachedResult.getLeft(); + // Ensure that this non-indexed selection uniquely identified an Entity. + if (!(cachedResult.isEmpty() || cachedResult.size() > 1)) { + uowCacheHits.mark(); + logger.info("UnitOfWork({}) cache hit for stmt {} {}", uow.hashCode(), stmtKey, + stmtKey.hashCode()); + result = cachedResult.stream().findFirst(); + } + } + } } if (result == null) { + uowCacheMiss.mark(); ResultSet resultSet = execute(sessionOps, uow, traceContext, showValues, true); result = transform(resultSet); - if (key != null) { - if (result.isPresent()) { + if (enableCache && result.isPresent()) { + // If we executed a query that didn't depend on an we have a stmtKey for the filters, add that to the cache. + if (stmtKey != null) { + Set set = new HashSet(1); + set.add(result.get()); + uow.getCache().put(stmtKey.hashCode(), set); + } + // Now insert this entity into the cache for each facet for this entity that we can fully bind. + E entity = result.get(); + Map facetMap = Helenus.entity(result.get().getClass()).getIdentityFacets(); + facetMap.forEach((facetName, facet) -> { + EntityIdentifyingFacet boundFacet = null; + if (!facet.isFullyBound()) { + boundFacet = new EntityIdentifyingFacet(facet); + for (HelenusProperty prop : facet.getUnboundEntityProperties()) { + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(entity, -1, prop); + if (value == null) { break; } + boundFacet.setValueForProperty(prop, value); + } + } + if (boundFacet != null && boundFacet.isFullyBound()) { + uow.getCache().put(boundFacet.hashCode(), Either) + } + }); Set set = new HashSet(1); set.add(result.get()); uow.getCache().put(key, set); diff --git a/src/main/java/net/helenus/core/operation/Operation.java b/src/main/java/net/helenus/core/operation/Operation.java index d349ada..d6e1b48 100644 --- a/src/main/java/net/helenus/core/operation/Operation.java +++ b/src/main/java/net/helenus/core/operation/Operation.java @@ -1,5 +1,6 @@ package net.helenus.core.operation; +import java.util.Set; import java.util.concurrent.ExecutionException; import com.codahale.metrics.Meter; @@ -14,7 +15,7 @@ import brave.Tracer; import brave.propagation.TraceContext; import net.helenus.core.AbstractSessionOperations; import net.helenus.core.UnitOfWork; - +import net.helenus.core.cache.EntityIdentifyingFacet; public abstract class Operation { @@ -68,6 +69,6 @@ public abstract class Operation { public Statement buildStatement(boolean cached) { return null; } - public String getStatementCacheKey() { return null; } + public Set getIdentifyingFacets() { return null; } } diff --git a/src/main/java/net/helenus/core/operation/SelectOperation.java b/src/main/java/net/helenus/core/operation/SelectOperation.java index 05403d1..63619b6 100644 --- a/src/main/java/net/helenus/core/operation/SelectOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectOperation.java @@ -15,7 +15,6 @@ */ package net.helenus.core.operation; -import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.Ordering; @@ -31,8 +30,11 @@ import java.util.stream.StreamSupport; import com.google.common.base.Joiner; import com.google.common.collect.Iterables; import net.helenus.core.*; +import net.helenus.core.cache.Facet; +import net.helenus.core.cache.EntityIdentifyingFacet; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; +import net.helenus.mapping.HelenusProperty; import net.helenus.mapping.MappingUtil; import net.helenus.mapping.OrderingDirection; import net.helenus.mapping.value.ColumnValueProvider; @@ -181,30 +183,26 @@ public final class SelectOperation extends AbstractFilterStreamOperation keys = new ArrayList<>(filters.size()); + public Set getIdentityFacets() { HelenusEntity entity = props.get(0).getEntity(); - - for (HelenusPropertyNode prop : props) { - switch (prop.getProperty().getColumnType()) { - case PARTITION_KEY: - case CLUSTERING_COLUMN: - - Filter filter = filters.get(prop.getProperty()); - if (filter != null) { - keys.add(filter.toString()); - } else { - return null; + final Set facets = new HashSet<>(filters.size()); + // Check to see if this select statement has enough information to build one or + // more identifying facets. + entity.getIdentityFacets().forEach((facetName, facet) -> { + EntityIdentifyingFacet boundFacet = null; + if (!facet.isFullyBound()) { + boundFacet = new EntityIdentifyingFacet(facet); + for (HelenusProperty prop : facet.getUnboundEntityProperties()) { + Filter filter = filters.get(facet.getProperty()); + if (filter == null) { break; } + boundFacet.setValueForProperty(prop, filter.toString()); } - break; - default: - if (keys.size() > 0) { - return entity.getName() + ": " + Joiner.on(",").join(keys); - } - return null; } - } - return null; + if (boundFacet != null && boundFacet.isFullyBound()) { + facets.add(boundFacet); + } + }); + return facets; } @Override diff --git a/src/main/java/net/helenus/mapping/HelenusEntity.java b/src/main/java/net/helenus/mapping/HelenusEntity.java index 6953d2e..ef63078 100644 --- a/src/main/java/net/helenus/mapping/HelenusEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusEntity.java @@ -15,7 +15,10 @@ */ package net.helenus.mapping; +import net.helenus.core.cache.EntityIdentifyingFacet; + import java.util.Collection; +import java.util.Map; public interface HelenusEntity { @@ -30,4 +33,7 @@ public interface HelenusEntity { Collection getOrderedProperties(); HelenusProperty getProperty(String name); + + Map getIdentityFacets(); + } diff --git a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java index f1d57c3..eaee3fe 100644 --- a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java @@ -20,9 +20,11 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import java.lang.reflect.Method; import java.util.*; + import net.helenus.config.HelenusSettings; import net.helenus.core.Helenus; import net.helenus.core.annotation.Cacheable; +import net.helenus.core.cache.EntityIdentifyingFacet; import net.helenus.mapping.annotation.*; import net.helenus.support.HelenusMappingException; import org.apache.commons.lang3.ClassUtils; @@ -36,6 +38,9 @@ public final class HelenusMappingEntity implements HelenusEntity { private final ImmutableMap methods; private final ImmutableMap props; private final ImmutableList orderedProps; + private final EntityIdentifyingFacet primaryIdentityFacet; + private final ImmutableMap allIdentityFacets; + private final ImmutableMap ancillaryIdentityFacets; public HelenusMappingEntity(Class iface, Metadata metadata) { this(iface, autoDetectType(iface), metadata); @@ -101,7 +106,35 @@ public final class HelenusMappingEntity implements HelenusEntity { validateOrdinals(); + // Caching cacheable = (null != iface.getDeclaredAnnotation(Cacheable.class)); + + ImmutableMap.Builder allFacetsBuilder = ImmutableMap.builder(); + ImmutableMap.Builder ancillaryFacetsBuilder = ImmutableMap.builder(); + EntityIdentifyingFacet primaryFacet = null; + List primaryProperties = new ArrayList(4); + for (HelenusProperty prop : propsLocal) { + switch(prop.getColumnType()) { + case PARTITION_KEY: + case CLUSTERING_COLUMN: + primaryProperties.add(prop); + break; + default: + if (primaryProperties != null) { + primaryFacet = new EntityIdentifyingFacet(keyspace, table, schemaVersion, primaryProperties.toArray(new HelenusProperty[props.size()])); + allFacetsBuilder.put("*", primaryFacet); + primaryProperties = null; + } + Optional optionalIndexName = prop.getIndexName(); + if (optionalIndexName.isPresent()) { + EntityIdentifyingFacet facet = new EntityIdentifyingFacet(keyspace, table, schemaVersion, prop); + ancillaryFacetsBuilder.put(prop.getPropertyName(), facet); + } + } + } + this.primaryIdentityFacet = primaryFacet; + this.ancillaryIdentityFacets = ancillaryFacetsBuilder.build(); + this.allIdentityFacets = allFacetsBuilder.build(); } @Override From be8d1bf029dac0e6d9dec0de3a77d5b33f420d2e Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Fri, 29 Sep 2017 10:48:37 -0400 Subject: [PATCH 2/9] Use backingMap for the mutated key set (and save some space/overhead). --- src/main/java/net/helenus/core/AbstractEntityDraft.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractEntityDraft.java b/src/main/java/net/helenus/core/AbstractEntityDraft.java index 7054739..661e9b7 100644 --- a/src/main/java/net/helenus/core/AbstractEntityDraft.java +++ b/src/main/java/net/helenus/core/AbstractEntityDraft.java @@ -13,7 +13,6 @@ import net.helenus.mapping.MappingUtil; public abstract class AbstractEntityDraft implements Drafted { private final Map backingMap = new HashMap(); - private final Set mutatedSet = new HashSet(); private final MapExportable entity; private final Map entityMap; @@ -56,7 +55,6 @@ public abstract class AbstractEntityDraft implements Drafted { } backingMap.put(key, value); - mutatedSet.add(key); return value; } @@ -72,14 +70,12 @@ public abstract class AbstractEntityDraft implements Drafted { if (map.containsKey(key) && !value.equals(map.get(key))) { backingMap.put(key, value); - mutatedSet.add(key); return value; } return map.get(key); } else { backingMap.put(key, value); - mutatedSet.add(key); return null; } @@ -99,7 +95,6 @@ public abstract class AbstractEntityDraft implements Drafted { if (key != null) { Object value = backingMap.get(key); backingMap.put(key, null); - mutatedSet.add(key); return value; } return null; @@ -136,7 +131,7 @@ public abstract class AbstractEntityDraft implements Drafted { } else { combined = new HashMap(backingMap.size()); } - for (String key : mutatedSet) { + for (String key : mutated()) { combined.put(key, backingMap.get(key)); } return combined; @@ -144,7 +139,7 @@ public abstract class AbstractEntityDraft implements Drafted { @Override public Set mutated() { - return mutatedSet; + return backingMap.keySet(); } @Override From 25c5c6b9692796e3ec2ab38ad92e248c859d2f83 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Wed, 4 Oct 2017 15:46:01 -0400 Subject: [PATCH 3/9] Enabled Helenus.dsl() to return a valid object even when the cluster metadata isn't known in advance and later learn more when it is. Changed the AbstractEntityDraft to have both by-string and by-getter mutation/accessor methods. These two combine to make Draft objects more type safe. --- .../net/helenus/core/AbstractEntityDraft.java | 24 +++- src/main/java/net/helenus/core/Helenus.java | 9 +- .../net/helenus/core/SessionInitializer.java | 25 ++++- .../helenus/core/reflect/DslExportable.java | 4 + .../core/reflect/DslInvocationHandler.java | 104 ++++++++++++------ .../core/reflect/MapperInvocationHandler.java | 6 + .../integration/core/draft/Inventory.java | 19 ++-- .../test/integration/core/draft/Supply.java | 32 +++--- 8 files changed, 155 insertions(+), 68 deletions(-) diff --git a/src/main/java/net/helenus/core/AbstractEntityDraft.java b/src/main/java/net/helenus/core/AbstractEntityDraft.java index 661e9b7..58a575d 100644 --- a/src/main/java/net/helenus/core/AbstractEntityDraft.java +++ b/src/main/java/net/helenus/core/AbstractEntityDraft.java @@ -26,6 +26,12 @@ public abstract class AbstractEntityDraft implements Drafted { public E build() { return Helenus.map(getEntityClass(), toMap()); } + @SuppressWarnings("unchecked") + protected T get(Getter getter, Class returnType) { + return (T) get(this.methodNameFor(getter), returnType); + } + + @SuppressWarnings("unchecked") protected T get(String key, Class returnType) { T value = (T) backingMap.get(key); @@ -48,8 +54,11 @@ public abstract class AbstractEntityDraft implements Drafted { return value; } - protected Object set(String key, Object value) { + protected Object set(Getter getter, Object value) { + return set(this.methodNameFor(getter), value); + } + protected Object set(String key, Object value) { if (key == null || value == null) { return null; } @@ -58,6 +67,11 @@ public abstract class AbstractEntityDraft implements Drafted { return value; } + @SuppressWarnings("unchecked") + protected T mutate(Getter getter, T value) { + return (T) mutate(this.methodNameFor(getter), value); + } + protected Object mutate(String key, Object value) { Objects.requireNonNull(key); @@ -81,13 +95,13 @@ public abstract class AbstractEntityDraft implements Drafted { } } - private String methodNameFor(Getter getter) { + private String methodNameFor(Getter getter) { return MappingUtil.resolveMappingProperty(getter) .getProperty() .getPropertyName(); } - public Object unset(Getter getter) { + public Object unset(Getter getter) { return unset(methodNameFor(getter)); } @@ -100,8 +114,8 @@ public abstract class AbstractEntityDraft implements Drafted { return null; } - public boolean reset(Getter getter, T desiredValue) { - return this.reset(methodNameFor(getter), desiredValue); + public boolean reset(Getter getter, T desiredValue) { + return this.reset(this.methodNameFor(getter), desiredValue); } public boolean reset(String key, T desiredValue) { diff --git a/src/main/java/net/helenus/core/Helenus.java b/src/main/java/net/helenus/core/Helenus.java index 26a453b..48c1aba 100644 --- a/src/main/java/net/helenus/core/Helenus.java +++ b/src/main/java/net/helenus/core/Helenus.java @@ -140,7 +140,14 @@ public final class Helenus { } public static HelenusEntity entity(Class iface) { - return entity(iface, metadataForEntity.get(iface)); + Metadata metadata = metadataForEntity.get(iface); + if (metadata == null) { + HelenusSession session = session(); + if (session != null) { + metadata = session.getMetadata(); + } + } + return entity(iface, metadata); } public static HelenusEntity entity(Class iface, Metadata metadata) { diff --git a/src/main/java/net/helenus/core/SessionInitializer.java b/src/main/java/net/helenus/core/SessionInitializer.java index bdfd23e..d7f0d7e 100644 --- a/src/main/java/net/helenus/core/SessionInitializer.java +++ b/src/main/java/net/helenus/core/SessionInitializer.java @@ -25,10 +25,14 @@ import java.util.*; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.function.Consumer; + +import net.helenus.core.reflect.DslExportable; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusEntityType; +import net.helenus.mapping.MappingUtil; import net.helenus.mapping.value.ColumnValuePreparer; import net.helenus.mapping.value.ColumnValueProvider; +import net.helenus.support.Either; import net.helenus.support.HelenusException; import net.helenus.support.PackageUtil; @@ -53,7 +57,7 @@ public final class SessionInitializer extends AbstractSessionOperations { private KeyspaceMetadata keyspaceMetadata; - private final List initList = new ArrayList(); + private final List>> initList = new ArrayList>>(); private AutoDdl autoDdl = AutoDdl.UPDATE; SessionInitializer(Session session) { @@ -181,7 +185,9 @@ public final class SessionInitializer extends AbstractSessionOperations { PackageUtil.getClasses(packageName) .stream() .filter(c -> c.isInterface() && !c.isAnnotation()) - .forEach(initList::add); + .forEach(clazz -> { + initList.add(Either.right(clazz)); + }); } catch (IOException | ClassNotFoundException e) { throw new HelenusException("fail to add package " + packageName, e); } @@ -193,7 +199,7 @@ public final class SessionInitializer extends AbstractSessionOperations { int len = dsls.length; for (int i = 0; i != len; ++i) { Object obj = Objects.requireNonNull(dsls[i], "element " + i + " is empty"); - initList.add(obj); + initList.add(Either.left(obj)); } return this; } @@ -261,7 +267,18 @@ public final class SessionInitializer extends AbstractSessionOperations { Objects.requireNonNull(usingKeyspace, "please define keyspace by 'use' operator"); - initList.forEach(dsl -> sessionRepository.add(dsl)); + initList.forEach((either) -> { + Class iface = null; + if (either.isLeft()) { + iface = MappingUtil.getMappingInterface(either.getLeft()); + } else { + iface = either.getRight(); + } + + DslExportable dsl = (DslExportable) Helenus.dsl(iface); + dsl.setMetadata(session.getCluster().getMetadata()); + sessionRepository.add(dsl); + }); TableOperations tableOps = new TableOperations(this, dropUnusedColumns, dropUnusedIndexes); UserTypeOperations userTypeOps = new UserTypeOperations(this, dropUnusedColumns); diff --git a/src/main/java/net/helenus/core/reflect/DslExportable.java b/src/main/java/net/helenus/core/reflect/DslExportable.java index 88cc117..e3d2e4a 100644 --- a/src/main/java/net/helenus/core/reflect/DslExportable.java +++ b/src/main/java/net/helenus/core/reflect/DslExportable.java @@ -15,14 +15,18 @@ */ package net.helenus.core.reflect; +import com.datastax.driver.core.Metadata; import net.helenus.mapping.HelenusEntity; public interface DslExportable { public static final String GET_ENTITY_METHOD = "getHelenusMappingEntity"; public static final String GET_PARENT_METHOD = "getParentDslHelenusPropertyNode"; + public static final String SET_METADATA_METHOD = "setMetadata"; HelenusEntity getHelenusMappingEntity(); HelenusPropertyNode getParentDslHelenusPropertyNode(); + + void setMetadata(Metadata metadata); } diff --git a/src/main/java/net/helenus/core/reflect/DslInvocationHandler.java b/src/main/java/net/helenus/core/reflect/DslInvocationHandler.java index 8f2fb83..608a5b8 100644 --- a/src/main/java/net/helenus/core/reflect/DslInvocationHandler.java +++ b/src/main/java/net/helenus/core/reflect/DslInvocationHandler.java @@ -34,7 +34,12 @@ import net.helenus.support.HelenusException; public class DslInvocationHandler implements InvocationHandler { - private final HelenusEntity entity; + private HelenusEntity entity = null; + private Metadata metadata = null; + + private final Class iface; + private final ClassLoader classLoader; + private final Optional parent; private final Map map = new HashMap(); @@ -48,52 +53,66 @@ public class DslInvocationHandler implements InvocationHandler { Optional parent, Metadata metadata) { - this.entity = new HelenusMappingEntity(iface, metadata); + this.metadata = metadata; this.parent = parent; + this.iface = iface; + this.classLoader = classLoader; + } + + public void setMetadata(Metadata metadata) { + if (metadata != null) { + this.metadata = metadata; + entity = init(metadata); + } + } + + private HelenusEntity init(Metadata metadata) { + HelenusEntity entity = new HelenusMappingEntity(iface, metadata); - if (this.entity != null) { for (HelenusProperty prop : entity.getOrderedProperties()) { - map.put(prop.getGetterMethod(), prop); + map.put(prop.getGetterMethod(), prop); - AbstractDataType type = prop.getDataType(); - Class javaType = prop.getJavaType(); + AbstractDataType type = prop.getDataType(); + Class javaType = prop.getJavaType(); - if (type instanceof UDTDataType && !UDTValue.class.isAssignableFrom(javaType)) { + if (type instanceof UDTDataType && !UDTValue.class.isAssignableFrom(javaType)) { - Object childDsl = - Helenus.dsl( - javaType, - classLoader, - Optional.of(new HelenusPropertyNode(prop, parent)), - metadata); + Object childDsl = + Helenus.dsl( + javaType, + classLoader, + Optional.of(new HelenusPropertyNode(prop, parent)), + metadata); - udtMap.put(prop.getGetterMethod(), childDsl); - } - - if (type instanceof DTDataType) { - DTDataType dataType = (DTDataType) type; - - if (dataType.getDataType() instanceof TupleType - && !TupleValue.class.isAssignableFrom(javaType)) { - - Object childDsl = - Helenus.dsl( - javaType, - classLoader, - Optional.of(new HelenusPropertyNode(prop, parent)), - metadata); - - tupleMap.put(prop.getGetterMethod(), childDsl); + udtMap.put(prop.getGetterMethod(), childDsl); + } + + if (type instanceof DTDataType) { + DTDataType dataType = (DTDataType) type; + + if (dataType.getDataType() instanceof TupleType + && !TupleValue.class.isAssignableFrom(javaType)) { + + Object childDsl = + Helenus.dsl( + javaType, + classLoader, + Optional.of(new HelenusPropertyNode(prop, parent)), + metadata); + + tupleMap.put(prop.getGetterMethod(), childDsl); + } } - } } - } + + return entity; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + HelenusEntity entity = this.entity; String methodName = method.getName(); if ("equals".equals(methodName) && method.getParameterCount() == 1) { @@ -107,6 +126,15 @@ public class DslInvocationHandler implements InvocationHandler { return false; } + if (DslExportable.SET_METADATA_METHOD.equals(methodName) + && args.length == 1 + && args[0] instanceof Metadata) { + if (metadata == null) { + this.setMetadata((Metadata) args[0]); + } + return null; + } + if (method.getParameterCount() != 0 || method.getReturnType() == void.class) { throw new HelenusException("invalid getter method " + method); } @@ -115,6 +143,14 @@ public class DslInvocationHandler implements InvocationHandler { return hashCode(); } + if (DslExportable.GET_PARENT_METHOD.equals(methodName)) { + return parent.get(); + } + + if (entity == null) { + entity = init(metadata); + } + if ("toString".equals(methodName)) { return entity.toString(); } @@ -123,10 +159,6 @@ public class DslInvocationHandler implements InvocationHandler { return entity; } - if (DslExportable.GET_PARENT_METHOD.equals(methodName)) { - return parent.get(); - } - HelenusProperty prop = map.get(method); if (prop == null) { prop = entity.getProperty(methodName); diff --git a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java index 7df8a51..27d48cf 100644 --- a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java +++ b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java @@ -23,6 +23,8 @@ import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Collections; import java.util.Map; + +import net.helenus.core.Helenus; import net.helenus.mapping.annotation.Transient; import net.helenus.support.HelenusException; @@ -91,6 +93,10 @@ public class MapperInvocationHandler implements InvocationHandler, Serializab return iface.getSimpleName() + ": " + src.toString(); } + if ("dsl".equals(methodName)) { + return Helenus.dsl(iface); + } + if (MapExportable.TO_MAP_METHOD.equals(methodName)) { return Collections.unmodifiableMap(src); } diff --git a/src/test/java/net/helenus/test/integration/core/draft/Inventory.java b/src/test/java/net/helenus/test/integration/core/draft/Inventory.java index a4f7a12..52448d2 100644 --- a/src/test/java/net/helenus/test/integration/core/draft/Inventory.java +++ b/src/test/java/net/helenus/test/integration/core/draft/Inventory.java @@ -3,6 +3,7 @@ package net.helenus.test.integration.core.draft; import java.util.UUID; import net.helenus.core.AbstractAuditedEntityDraft; +import net.helenus.core.Helenus; import net.helenus.core.reflect.MapExportable; import net.helenus.mapping.annotation.*; @@ -10,6 +11,8 @@ import net.helenus.mapping.annotation.*; @Table public interface Inventory { + static Inventory inventory = Helenus.dsl(Inventory.class); + @PartitionKey UUID id(); @Column("emea") @Types.Counter long EMEA(); @Column("noram") @Types.Counter long NORAM(); @@ -27,7 +30,7 @@ public interface Inventory { super(null); // Primary Key: - set("id", id); + set(inventory::id, id); } Draft(Inventory inventory) { @@ -40,33 +43,33 @@ public interface Inventory { // Immutable properties: public UUID id() { - return this.get("id", UUID.class); + return this.get(inventory::id, UUID.class); } public long EMEA() { - return this.get("EMEA", long.class); + return this.get(inventory::EMEA, long.class); } public Draft EMEA(long count) { - mutate("EMEA", count); + mutate(inventory::EMEA, count); return this; } public long APAC() { - return this.get("APAC", long.class); + return this.get(inventory::APAC, long.class); } public Draft APAC(long count) { - mutate("APAC", count); + mutate(inventory::APAC, count); return this; } public long NORAM() { - return this.get("NORAM", long.class); + return this.get(inventory::NORAM, long.class); } public Draft NORAM(long count) { - mutate("NORAM", count); + mutate(inventory::NORAM, count); return this; } diff --git a/src/test/java/net/helenus/test/integration/core/draft/Supply.java b/src/test/java/net/helenus/test/integration/core/draft/Supply.java index 1b09724..91f1689 100644 --- a/src/test/java/net/helenus/test/integration/core/draft/Supply.java +++ b/src/test/java/net/helenus/test/integration/core/draft/Supply.java @@ -1,5 +1,6 @@ package net.helenus.test.integration.core.draft; +import java.lang.reflect.Proxy; import java.util.List; import java.util.Map; import java.util.Set; @@ -8,6 +9,7 @@ import java.util.UUID; import com.datastax.driver.core.utils.UUIDs; import net.helenus.core.AbstractEntityDraft; +import net.helenus.core.Helenus; import net.helenus.core.reflect.MapExportable; import net.helenus.mapping.annotation.*; @@ -15,6 +17,8 @@ import net.helenus.mapping.annotation.*; @Table public interface Supply { + static Supply supply = Helenus.dsl(Supply.class); + @PartitionKey UUID id(); @ClusteringColumn(ordinal=0) default String region() { return "NORAM"; } @@ -36,8 +40,8 @@ public interface Supply { super(null); // Primary Key: - set("id", UUIDs.timeBased()); - set("region", region); + set(supply::id, UUIDs.timeBased()); + set(supply::region, region); } Draft(Supply supply) { @@ -48,20 +52,20 @@ public interface Supply { // Immutable properties: public UUID id() { - return this.get("id", UUID.class); + return this.get(supply::id, UUID.class); } public String region() { - return this.get("region", String.class); + return this.get(supply::region, String.class); } // Mutable properties: public String code() { - return this.get("code", String.class); + return this.get(supply::code, String.class); } public Draft code(String code) { - mutate("code", code); + mutate(supply::code, code); return this; } @@ -70,11 +74,11 @@ public interface Supply { } public String description() { - return this.get("description", String.class); + return this.get(supply::description, String.class); } public Draft description(String description) { - mutate("description", description); + mutate(supply::description, description); return this; } @@ -83,11 +87,11 @@ public interface Supply { } public Map demand() { - return this.>get("demand", Map.class); + return this.>get(supply::demand, Map.class); } public Draft demand(Map demand) { - mutate("demand", demand); + mutate(supply::demand, demand); return this; } @@ -96,11 +100,11 @@ public interface Supply { } public List suppliers() { - return this.>get("suppliers", List.class); + return this.>get(supply::suppliers, List.class); } public Draft suppliers(List suppliers) { - mutate("suppliers", suppliers); + mutate(supply::suppliers, suppliers); return this; } @@ -109,11 +113,11 @@ public interface Supply { } public Set shipments() { - return this.>get("shipments", Set.class); + return this.>get(supply::shipments, Set.class); } public Draft shipments(Set shipments) { - mutate("shipments", shipments); + mutate(supply::shipments, shipments); return this; } From 74832a32dd4138f1508823f7492f66204fb94cdd Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Thu, 12 Oct 2017 16:18:17 -0400 Subject: [PATCH 4/9] Formatting --- .../helenus/config/GetterMethodDetector.java | 2 +- .../core/AbstractAuditedEntityDraft.java | 47 ++- .../net/helenus/core/AbstractEntityDraft.java | 245 ++++++++-------- .../core/AbstractSessionOperations.java | 2 - .../net/helenus/core/AbstractUnitOfWork.java | 48 ++-- .../java/net/helenus/core/CommitThunk.java | 3 +- src/main/java/net/helenus/core/Helenus.java | 8 +- .../java/net/helenus/core/HelenusSession.java | 215 ++++++++------ .../net/helenus/core/PostCommitFunction.java | 37 ++- .../net/helenus/core/SessionInitializer.java | 33 +-- .../java/net/helenus/core/UnitOfWork.java | 52 ++-- .../java/net/helenus/core/UnitOfWorkImpl.java | 9 +- .../core/cache/EntityIdentifyingFacet.java | 8 +- .../java/net/helenus/core/cache/Facet.java | 3 +- .../AbstractFilterOptionalOperation.java | 4 +- .../AbstractFilterStreamOperation.java | 4 +- .../core/operation/AbstractOperation.java | 4 - .../operation/AbstractStatementOperation.java | 10 +- .../operation/AbstractStreamOperation.java | 10 - .../operation/BoundOptionalOperation.java | 4 +- .../core/operation/BoundStreamOperation.java | 11 +- .../core/operation/InsertOperation.java | 38 +-- .../net/helenus/core/operation/Operation.java | 99 ++++--- .../operation/PreparedStreamOperation.java | 1 - .../core/operation/SelectFirstOperation.java | 4 +- .../SelectFirstTransformingOperation.java | 4 +- .../core/operation/SelectOperation.java | 58 ++-- .../SelectTransformingOperation.java | 5 +- .../core/operation/UpdateOperation.java | 25 +- .../net/helenus/core/reflect/Drafted.java | 1 - .../core/reflect/DslInvocationHandler.java | 70 ++--- .../core/reflect/MapperInvocationHandler.java | 3 +- .../net/helenus/mapping/HelenusEntity.java | 4 +- .../helenus/mapping/HelenusMappingEntity.java | 59 ++-- .../javatype/AbstractCollectionJavaType.java | 5 +- .../mapping/javatype/AbstractJavaType.java | 4 +- .../helenus/mapping/javatype/MapJavaType.java | 1 - .../type/AbstractCollectionDataType.java | 11 +- .../mapping/type/AbstractDataType.java | 5 +- .../mapping/type/UDTKeyMapDataType.java | 2 - .../value/BeanColumnValueProvider.java | 2 +- .../core/collection/CollectionTest.java | 41 +-- .../core/draft/EntityDraftBuilderTest.java | 99 ++++--- .../integration/core/draft/Inventory.java | 125 ++++---- .../test/integration/core/draft/Supply.java | 218 +++++++------- .../core/hierarchy/HierarchyTest.java | 3 +- .../integration/core/hierarchy/Mammal.java | 5 +- .../core/simple/SimpleUserTest.java | 73 ++--- .../core/tuplecollection/TupleMapTest.java | 16 +- .../core/unitofwork/AndThenOrderTest.java | 182 +++++++----- .../core/unitofwork/Directory.java | 9 +- .../integration/core/unitofwork/File.java | 6 +- .../core/unitofwork/FileAttributes.java | 3 +- .../core/unitofwork/FilesystemNode.java | 16 +- .../core/unitofwork/UnitOfWorkTest.java | 271 +++++++++--------- .../helenus/test/unit/core/dsl/Account.java | 1 - 56 files changed, 1133 insertions(+), 1095 deletions(-) diff --git a/src/main/java/net/helenus/config/GetterMethodDetector.java b/src/main/java/net/helenus/config/GetterMethodDetector.java index 266a7e7..60a9ec0 100644 --- a/src/main/java/net/helenus/config/GetterMethodDetector.java +++ b/src/main/java/net/helenus/config/GetterMethodDetector.java @@ -35,7 +35,7 @@ public enum GetterMethodDetector implements Function { } if (Modifier.isStatic(method.getModifiers())) { - return false; + return false; } // Methods marked "Transient" are not mapped, skip them. diff --git a/src/main/java/net/helenus/core/AbstractAuditedEntityDraft.java b/src/main/java/net/helenus/core/AbstractAuditedEntityDraft.java index 5ec76d3..a9a09e2 100644 --- a/src/main/java/net/helenus/core/AbstractAuditedEntityDraft.java +++ b/src/main/java/net/helenus/core/AbstractAuditedEntityDraft.java @@ -1,41 +1,38 @@ package net.helenus.core; -import net.helenus.core.reflect.MapExportable; - import java.time.LocalDateTime; import java.time.ZoneId; import java.util.Date; - +import net.helenus.core.reflect.MapExportable; public abstract class AbstractAuditedEntityDraft extends AbstractEntityDraft { - public AbstractAuditedEntityDraft(MapExportable entity) { - super(entity); + public AbstractAuditedEntityDraft(MapExportable entity) { + super(entity); - Date in = new Date(); - LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault()); - Date now = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant()); + Date in = new Date(); + LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault()); + Date now = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant()); - String who = getCurrentAuditor(); + String who = getCurrentAuditor(); - if (entity == null) { - if (who != null) { - set("createdBy", who); - } - set("createdAt", now); - } - if (who != null) { - set("modifiedBy", who); - } - set("modifiedAt", now); + if (entity == null) { + if (who != null) { + set("createdBy", who); + } + set("createdAt", now); } - - protected String getCurrentAuditor() { - return null; + if (who != null) { + set("modifiedBy", who); } + set("modifiedAt", now); + } - public Date createdAt() { - return (Date) get("createdAt", Date.class); - } + protected String getCurrentAuditor() { + return null; + } + public Date createdAt() { + return (Date) get("createdAt", Date.class); + } } diff --git a/src/main/java/net/helenus/core/AbstractEntityDraft.java b/src/main/java/net/helenus/core/AbstractEntityDraft.java index 58a575d..fbccb3b 100644 --- a/src/main/java/net/helenus/core/AbstractEntityDraft.java +++ b/src/main/java/net/helenus/core/AbstractEntityDraft.java @@ -1,164 +1,159 @@ package net.helenus.core; -import java.util.*; - import com.google.common.primitives.Primitives; - +import java.util.*; import net.helenus.core.reflect.DefaultPrimitiveTypes; import net.helenus.core.reflect.Drafted; import net.helenus.core.reflect.MapExportable; import net.helenus.mapping.MappingUtil; - public abstract class AbstractEntityDraft implements Drafted { - private final Map backingMap = new HashMap(); - private final MapExportable entity; - private final Map entityMap; + private final Map backingMap = new HashMap(); + private final MapExportable entity; + private final Map entityMap; + public AbstractEntityDraft(MapExportable entity) { + this.entity = entity; + this.entityMap = entity != null ? entity.toMap() : new HashMap(); + } - public AbstractEntityDraft(MapExportable entity) { - this.entity = entity; - this.entityMap = entity != null ? entity.toMap() : new HashMap(); - } + public abstract Class getEntityClass(); - public abstract Class getEntityClass(); + public E build() { + return Helenus.map(getEntityClass(), toMap()); + } - public E build() { return Helenus.map(getEntityClass(), toMap()); } + @SuppressWarnings("unchecked") + protected T get(Getter getter, Class returnType) { + return (T) get(this.methodNameFor(getter), returnType); + } - @SuppressWarnings("unchecked") - protected T get(Getter getter, Class returnType) { - return (T) get(this.methodNameFor(getter), returnType); - } + @SuppressWarnings("unchecked") + protected T get(String key, Class returnType) { + T value = (T) backingMap.get(key); - @SuppressWarnings("unchecked") - protected T get(String key, Class returnType) { - T value = (T) backingMap.get(key); + if (value == null) { + value = (T) entityMap.get(key); + if (value == null) { - 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(); - } - } + return (T) type.getDefaultValue(); } - - return value; + } } - protected Object set(Getter getter, Object value) { - return set(this.methodNameFor(getter), value); + return value; + } + + protected Object set(Getter getter, Object value) { + return set(this.methodNameFor(getter), value); + } + + protected Object set(String key, Object value) { + if (key == null || value == null) { + return null; } - protected Object set(String key, Object value) { - if (key == null || value == null) { - return null; - } + backingMap.put(key, value); + return value; + } + @SuppressWarnings("unchecked") + protected T mutate(Getter getter, T value) { + return (T) mutate(this.methodNameFor(getter), value); + } + + protected Object mutate(String key, Object value) { + Objects.requireNonNull(key); + + if (value == null) { + return null; + } + + if (entity != null) { + Map map = entity.toMap(); + + if (map.containsKey(key) && !value.equals(map.get(key))) { backingMap.put(key, value); return value; + } + + return map.get(key); + } else { + backingMap.put(key, value); + + return null; } + } - @SuppressWarnings("unchecked") - protected T mutate(Getter getter, T value) { - return (T) mutate(this.methodNameFor(getter), value); + private String methodNameFor(Getter getter) { + return MappingUtil.resolveMappingProperty(getter).getProperty().getPropertyName(); + } + + public Object unset(Getter getter) { + return unset(methodNameFor(getter)); + } + + public Object unset(String key) { + if (key != null) { + Object value = backingMap.get(key); + backingMap.put(key, null); + return value; } + return null; + } - protected Object mutate(String key, Object value) { - Objects.requireNonNull(key); + public boolean reset(Getter getter, T desiredValue) { + return this.reset(this.methodNameFor(getter), desiredValue); + } - if (value == null) { - return null; - } - - if (entity != null) { - Map map = entity.toMap(); - - if (map.containsKey(key) && !value.equals(map.get(key))) { - backingMap.put(key, value); - return value; - } - - return map.get(key); - } else { - backingMap.put(key, value); - - return null; - } + public boolean reset(String key, T desiredValue) { + if (key != null && desiredValue != null) { + @SuppressWarnings("unchecked") + T currentValue = (T) backingMap.get(key); + if (currentValue == null || !currentValue.equals(desiredValue)) { + set(key, desiredValue); + return true; + } } + return false; + } - private String methodNameFor(Getter getter) { - return MappingUtil.resolveMappingProperty(getter) - .getProperty() - .getPropertyName(); + @Override + public Map toMap() { + return toMap(entityMap); + } + + public Map toMap(Map entityMap) { + Map combined; + if (entityMap != null && entityMap.size() > 0) { + combined = new HashMap(entityMap.size()); + for (String key : entityMap.keySet()) { + combined.put(key, entityMap.get(key)); + } + } else { + combined = new HashMap(backingMap.size()); } - - public Object unset(Getter getter) { - return unset(methodNameFor(getter)); + for (String key : mutated()) { + combined.put(key, backingMap.get(key)); } + return combined; + } - public Object unset(String key) { - if (key != null) { - Object value = backingMap.get(key); - backingMap.put(key, null); - return value; - } - return null; - } - - public boolean reset(Getter getter, T desiredValue) { - return this.reset(this.methodNameFor(getter), desiredValue); - } - - public boolean reset(String key, T desiredValue) { - if (key != null && desiredValue != null) { - @SuppressWarnings("unchecked") - T currentValue = (T) backingMap.get(key); - if (currentValue == null || !currentValue.equals(desiredValue)) { - set(key, desiredValue); - return true; - } - } - return false; - } - - @Override - public Map toMap() { - return toMap(entityMap); - } - - public Map toMap(MapentityMap) { - Map combined; - if (entityMap != null && entityMap.size() > 0) { - combined = new HashMap(entityMap.size()); - for (String key : entityMap.keySet()) { - combined.put(key, entityMap.get(key)); - } - } else { - combined = new HashMap(backingMap.size()); - } - for (String key : mutated()) { - combined.put(key, backingMap.get(key)); - } - return combined; - } - - @Override - public Set mutated() { - return backingMap.keySet(); - } - - @Override - public String toString() { - return backingMap.toString(); - } + @Override + public Set mutated() { + return backingMap.keySet(); + } + @Override + public String toString() { + return backingMap.toString(); + } } diff --git a/src/main/java/net/helenus/core/AbstractSessionOperations.java b/src/main/java/net/helenus/core/AbstractSessionOperations.java index 1bba0ab..5721051 100644 --- a/src/main/java/net/helenus/core/AbstractSessionOperations.java +++ b/src/main/java/net/helenus/core/AbstractSessionOperations.java @@ -22,7 +22,6 @@ import com.datastax.driver.core.querybuilder.BuiltStatement; import com.google.common.util.concurrent.ListenableFuture; import java.io.PrintStream; import java.util.concurrent.Executor; - import net.helenus.mapping.value.ColumnValuePreparer; import net.helenus.mapping.value.ColumnValueProvider; import net.helenus.support.HelenusException; @@ -124,5 +123,4 @@ public abstract class AbstractSessionOperations { void printCql(String cql) { getPrintStream().println(cql); } - } diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index dfb1ff7..c621770 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -17,10 +17,8 @@ package net.helenus.core; import com.diffplug.common.base.Errors; import com.google.common.collect.TreeTraverser; - import java.util.*; - /** Encapsulates the concept of a "transaction" as a unit-of-work. */ public abstract class AbstractUnitOfWork implements UnitOfWork, AutoCloseable { private final List> nested = new ArrayList<>(); @@ -70,22 +68,25 @@ public abstract class AbstractUnitOfWork implements UnitOfW return null; } - public Map> getCache() { return cache; } + public Map> getCache() { + return cache; + } private Iterator> getChildNodes() { return nested.iterator(); } - /** - * Checks to see if the work performed between calling begin and now can be committed or not. - * - * @return a function from which to chain work that only happens when commit is successful - * @throws E when the work overlaps with other concurrent writers. - */ + /** + * Checks to see if the work performed between calling begin and now can be committed or not. + * + * @return a function from which to chain work that only happens when commit is successful + * @throws E when the work overlaps with other concurrent writers. + */ public PostCommitFunction commit() throws E { // All nested UnitOfWork should be committed (not aborted) before calls to commit, check. boolean canCommit = true; - TreeTraverser> traverser = TreeTraverser.using(node -> node::getChildNodes); + TreeTraverser> traverser = + TreeTraverser.using(node -> node::getChildNodes); for (AbstractUnitOfWork uow : traverser.postOrderTraversal(this)) { if (this != uow) { canCommit &= (!uow.aborted && uow.committed); @@ -112,7 +113,8 @@ public abstract class AbstractUnitOfWork implements UnitOfW if (parentCache.containsKey(key)) { // merge the sets Set ps = parentCache.get(key); - ps.addAll(cache.get(key)); //TODO(gburd): review this, likely not correct in all cases as-is. + ps.addAll( + cache.get(key)); //TODO(gburd): review this, likely not correct in all cases as-is. } else { // add the missing set parentCache.put(key, cache.get(key)); @@ -122,9 +124,12 @@ public abstract class AbstractUnitOfWork implements UnitOfW // Apply all post-commit functions for if (parent == null) { - traverser.postOrderTraversal(this).forEach(uow -> { - uow.applyPostCommitFunctions(); - }); + traverser + .postOrderTraversal(this) + .forEach( + uow -> { + uow.applyPostCommitFunctions(); + }); return new PostCommitFunction(this, null); } } @@ -137,11 +142,15 @@ public abstract class AbstractUnitOfWork implements UnitOfW /* Explicitly discard the work and mark it as as such in the log. */ public void abort() { - TreeTraverser> traverser = TreeTraverser.using(node -> node::getChildNodes); - traverser.postOrderTraversal(this).forEach(uow -> { - uow.committed = false; - uow.aborted = true; - }); + TreeTraverser> traverser = + TreeTraverser.using(node -> node::getChildNodes); + traverser + .postOrderTraversal(this) + .forEach( + uow -> { + uow.committed = false; + uow.aborted = true; + }); // log.record(txn::abort) // cache.invalidateSince(txn::start time) } @@ -165,5 +174,4 @@ public abstract class AbstractUnitOfWork implements UnitOfW public boolean hasCommitted() { return committed; } - } diff --git a/src/main/java/net/helenus/core/CommitThunk.java b/src/main/java/net/helenus/core/CommitThunk.java index c200061..ff50f4a 100644 --- a/src/main/java/net/helenus/core/CommitThunk.java +++ b/src/main/java/net/helenus/core/CommitThunk.java @@ -1,8 +1,7 @@ package net.helenus.core; -import java.util.function.Function; @FunctionalInterface public interface CommitThunk { - void apply(); + void apply(); } diff --git a/src/main/java/net/helenus/core/Helenus.java b/src/main/java/net/helenus/core/Helenus.java index 48c1aba..c0d9bc6 100644 --- a/src/main/java/net/helenus/core/Helenus.java +++ b/src/main/java/net/helenus/core/Helenus.java @@ -142,10 +142,10 @@ public final class Helenus { public static HelenusEntity entity(Class iface) { Metadata metadata = metadataForEntity.get(iface); if (metadata == null) { - HelenusSession session = session(); - if (session != null) { - metadata = session.getMetadata(); - } + HelenusSession session = session(); + if (session != null) { + metadata = session.getMetadata(); + } } return entity(iface, metadata); } diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index 785fba6..8fe9f90 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -15,10 +15,21 @@ */ package net.helenus.core; +import static net.helenus.core.Query.eq; + import brave.Tracer; -import com.codahale.metrics.Meter; import com.codahale.metrics.MetricRegistry; import com.datastax.driver.core.*; +import java.io.Closeable; +import java.io.PrintStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.Executor; +import java.util.function.Function; import net.helenus.core.operation.*; import net.helenus.core.reflect.Drafted; import net.helenus.core.reflect.HelenusPropertyNode; @@ -33,19 +44,6 @@ import net.helenus.support.Fun.Tuple6; import net.helenus.support.HelenusException; import net.helenus.support.HelenusMappingException; -import java.io.Closeable; -import java.io.PrintStream; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.Executor; -import java.util.function.Function; - -import static net.helenus.core.Query.eq; - public final class HelenusSession extends AbstractSessionOperations implements Closeable { private final int MAX_CACHE_SIZE = 10000; @@ -69,26 +67,25 @@ public final class HelenusSession extends AbstractSessionOperations implements C private final StatementColumnValuePreparer valuePreparer; private final Metadata metadata; - HelenusSession( - Session session, - String usingKeyspace, - CodecRegistry registry, - boolean showCql, - PrintStream printStream, - SessionRepositoryBuilder sessionRepositoryBuilder, - Executor executor, - boolean dropSchemaOnClose, - ConsistencyLevel consistencyLevel, - boolean defaultQueryIdempotency, - Class unitOfWorkClass, - MetricRegistry metricRegistry, - Tracer tracer) { + Session session, + String usingKeyspace, + CodecRegistry registry, + boolean showCql, + PrintStream printStream, + SessionRepositoryBuilder sessionRepositoryBuilder, + Executor executor, + boolean dropSchemaOnClose, + ConsistencyLevel consistencyLevel, + boolean defaultQueryIdempotency, + Class unitOfWorkClass, + MetricRegistry metricRegistry, + Tracer tracer) { this.session = session; this.registry = registry == null ? CodecRegistry.DEFAULT_INSTANCE : registry; this.usingKeyspace = - Objects.requireNonNull( - usingKeyspace, "keyspace needs to be selected before creating session"); + Objects.requireNonNull( + usingKeyspace, "keyspace needs to be selected before creating session"); this.showCql = showCql; this.printStream = printStream; this.sessionRepository = sessionRepositoryBuilder.build(); @@ -177,42 +174,53 @@ public final class HelenusSession extends AbstractSessionOperations implements C } @Override - public boolean getDefaultQueryIdempotency() { return defaultQueryIdempotency; } + public boolean getDefaultQueryIdempotency() { + return defaultQueryIdempotency; + } - public Metadata getMetadata() { return metadata; } + public Metadata getMetadata() { + return metadata; + } public synchronized T begin() { - return begin(null); + return begin(null); } public synchronized T begin(T parent) { try { Class clazz = unitOfWorkClass; - Constructor ctor = clazz.getConstructor(HelenusSession.class, UnitOfWork.class); + Constructor ctor = + clazz.getConstructor(HelenusSession.class, UnitOfWork.class); UnitOfWork uow = ctor.newInstance(this, parent); if (parent != null) { parent.addNestedUnitOfWork(uow); } return (T) uow.begin(); - } - catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) { - throw new HelenusException(String.format("Unable to instantiate {} as a UnitOfWork.", unitOfWorkClass.getSimpleName()), e); + } catch (NoSuchMethodException + | InvocationTargetException + | InstantiationException + | IllegalAccessException e) { + throw new HelenusException( + String.format( + "Unable to instantiate {} as a UnitOfWork.", unitOfWorkClass.getSimpleName()), + e); } } public SelectOperation select(E pojo) { - Objects.requireNonNull(pojo, "supplied object must be a dsl for a registered entity but cannot be null"); + Objects.requireNonNull( + pojo, "supplied object must be a dsl for a registered entity but cannot be null"); ColumnValueProvider valueProvider = getValueProvider(); HelenusEntity entity = Helenus.resolve(pojo); Class entityClass = entity.getMappingInterface(); return new SelectOperation( - this, - entity, - (r) -> { - Map map = new ValueProviderMap(r, valueProvider, entity); - return (E) Helenus.map(entityClass, map); - }); + this, + entity, + (r) -> { + Map map = new ValueProviderMap(r, valueProvider, entity); + return (E) Helenus.map(entityClass, map); + }); } public SelectOperation select(Class entityClass) { @@ -221,12 +229,12 @@ public final class HelenusSession extends AbstractSessionOperations implements C HelenusEntity entity = Helenus.entity(entityClass); return new SelectOperation( - this, - entity, - (r) -> { - Map map = new ValueProviderMap(r, valueProvider, entity); - return (E) Helenus.map(entityClass, map); - }); + this, + entity, + (r) -> { + Map map = new ValueProviderMap(r, valueProvider, entity); + return (E) Helenus.map(entityClass, map); + }); } public SelectOperation select() { @@ -239,7 +247,8 @@ public final class HelenusSession extends AbstractSessionOperations implements C } public SelectOperation selectAll(E pojo) { - Objects.requireNonNull(pojo, "supplied object must be a dsl for a registered entity but cannot be null"); + Objects.requireNonNull( + pojo, "supplied object must be a dsl for a registered entity but cannot be null"); HelenusEntity entity = Helenus.resolve(pojo); return new SelectOperation(this, entity); } @@ -411,51 +420,62 @@ public final class HelenusSession extends AbstractSessionOperations implements C 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"); + throw new HelenusMappingException( + "update of draft objects that don't inherit from AbstractEntityDraft is not yet supported"); } - AbstractEntityDraft draft = (AbstractEntityDraft)drafted; + AbstractEntityDraft draft = (AbstractEntityDraft) drafted; UpdateOperation update = new UpdateOperation(this, draft); Map map = draft.toMap(); Set mutatedProperties = draft.mutated(); HelenusEntity entity = Helenus.entity(draft.getEntityClass()); // Add all the mutated values contained in the draft. - entity.getOrderedProperties().forEach(property -> { - switch (property.getColumnType()) { - case PARTITION_KEY: - case CLUSTERING_COLUMN: - break; - default: - String propertyName = property.getPropertyName(); - if (mutatedProperties.contains(propertyName)) { - Object value = map.get(propertyName); - Getter getter = new Getter() { - @Override - public Object get() { - throw new DslPropertyException(new HelenusPropertyNode(property, Optional.empty())); + entity + .getOrderedProperties() + .forEach( + property -> { + switch (property.getColumnType()) { + case PARTITION_KEY: + case CLUSTERING_COLUMN: + break; + default: + String propertyName = property.getPropertyName(); + if (mutatedProperties.contains(propertyName)) { + Object value = map.get(propertyName); + Getter getter = + new Getter() { + @Override + public Object get() { + throw new DslPropertyException( + new HelenusPropertyNode(property, Optional.empty())); + } + }; + update.set(getter, value); + } } - }; - update.set(getter, value); - } - } - }); + }); // Add the partition and clustering keys if they were in the draft (normally the case). - entity.getOrderedProperties().forEach(property -> { - switch (property.getColumnType()) { - case PARTITION_KEY: - case CLUSTERING_COLUMN: - String propertyName = property.getPropertyName(); - Object value = map.get(propertyName); - Getter getter = new Getter() { - @Override - public Object get() { - throw new DslPropertyException(new HelenusPropertyNode(property, Optional.empty())); - } - }; - update.where(getter, eq(value)); - } - }); + entity + .getOrderedProperties() + .forEach( + property -> { + switch (property.getColumnType()) { + case PARTITION_KEY: + case CLUSTERING_COLUMN: + String propertyName = property.getPropertyName(); + Object value = map.get(propertyName); + Getter getter = + new Getter() { + @Override + public Object get() { + throw new DslPropertyException( + new HelenusPropertyNode(property, Optional.empty())); + } + }; + update.where(getter, eq(value)); + } + }); return update; } @@ -478,9 +498,14 @@ public final class HelenusSession extends AbstractSessionOperations implements C } public InsertOperation insert(T pojo) { - Objects.requireNonNull(pojo, "supplied object must be either an instance of the entity class or a dsl for it, but cannot be null"); + Objects.requireNonNull( + pojo, + "supplied object must be either an instance of the entity class or a dsl for it, but cannot be null"); HelenusEntity entity = null; - try { entity = Helenus.resolve(pojo); } catch (HelenusMappingException e) {} + try { + entity = Helenus.resolve(pojo); + } catch (HelenusMappingException e) { + } if (entity != null) { return new InsertOperation(this, entity.getMappingInterface(), true); } else { @@ -488,7 +513,9 @@ public final class HelenusSession extends AbstractSessionOperations implements C } } - public InsertOperation insert(Drafted draft) { return insert(draft.build(), draft.mutated()); } + public InsertOperation insert(Drafted draft) { + return insert(draft.build(), draft.mutated()); + } private InsertOperation insert(T pojo, Set mutations) { Objects.requireNonNull(pojo, "pojo is empty"); @@ -512,9 +539,14 @@ public final class HelenusSession extends AbstractSessionOperations implements C } public InsertOperation upsert(T pojo) { - Objects.requireNonNull(pojo, "supplied object must be either an instance of the entity class or a dsl for it, but cannot be null"); + Objects.requireNonNull( + pojo, + "supplied object must be either an instance of the entity class or a dsl for it, but cannot be null"); HelenusEntity entity = null; - try { entity = Helenus.resolve(pojo); } catch (HelenusMappingException e) {} + try { + entity = Helenus.resolve(pojo); + } catch (HelenusMappingException e) { + } if (entity != null) { return new InsertOperation(this, entity.getMappingInterface(), false); } else { @@ -587,5 +619,4 @@ public final class HelenusSession extends AbstractSessionOperations implements C break; } } - } diff --git a/src/main/java/net/helenus/core/PostCommitFunction.java b/src/main/java/net/helenus/core/PostCommitFunction.java index 22835c5..3ba2b8b 100644 --- a/src/main/java/net/helenus/core/PostCommitFunction.java +++ b/src/main/java/net/helenus/core/PostCommitFunction.java @@ -1,30 +1,29 @@ package net.helenus.core; - -import java.util.Objects; import java.util.*; +import java.util.Objects; public class PostCommitFunction implements java.util.function.Function { - private final UnitOfWork uow; - private final List postCommit; + private final UnitOfWork uow; + private final List postCommit; - PostCommitFunction(UnitOfWork uow, List postCommit) { - this.uow = uow; - this.postCommit = postCommit; - } + PostCommitFunction(UnitOfWork uow, List postCommit) { + this.uow = uow; + this.postCommit = postCommit; + } - public void andThen(CommitThunk after) { - Objects.requireNonNull(after); - if (postCommit == null) { - after.apply(); - } else { - postCommit.add(after); - } + public void andThen(CommitThunk after) { + Objects.requireNonNull(after); + if (postCommit == null) { + after.apply(); + } else { + postCommit.add(after); } + } - @Override - public R apply(T t) { - return null; - } + @Override + public R apply(T t) { + return null; + } } diff --git a/src/main/java/net/helenus/core/SessionInitializer.java b/src/main/java/net/helenus/core/SessionInitializer.java index d7f0d7e..27a0312 100644 --- a/src/main/java/net/helenus/core/SessionInitializer.java +++ b/src/main/java/net/helenus/core/SessionInitializer.java @@ -25,7 +25,6 @@ import java.util.*; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.function.Consumer; - import net.helenus.core.reflect.DslExportable; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusEntityType; @@ -131,12 +130,12 @@ public final class SessionInitializer extends AbstractSessionOperations { } public SessionInitializer idempotentQueryExecution(boolean idempotent) { - this.idempotent = idempotent; - return this; + this.idempotent = idempotent; + return this; } public boolean getDefaultQueryIdempotency() { - return idempotent; + return idempotent; } @Override @@ -185,9 +184,10 @@ public final class SessionInitializer extends AbstractSessionOperations { PackageUtil.getClasses(packageName) .stream() .filter(c -> c.isInterface() && !c.isAnnotation()) - .forEach(clazz -> { - initList.add(Either.right(clazz)); - }); + .forEach( + clazz -> { + initList.add(Either.right(clazz)); + }); } catch (IOException | ClassNotFoundException e) { throw new HelenusException("fail to add package " + packageName, e); } @@ -267,18 +267,19 @@ public final class SessionInitializer extends AbstractSessionOperations { Objects.requireNonNull(usingKeyspace, "please define keyspace by 'use' operator"); - initList.forEach((either) -> { - Class iface = null; - if (either.isLeft()) { + initList.forEach( + (either) -> { + Class iface = null; + if (either.isLeft()) { iface = MappingUtil.getMappingInterface(either.getLeft()); - } else { + } else { iface = either.getRight(); - } + } - DslExportable dsl = (DslExportable) Helenus.dsl(iface); - dsl.setMetadata(session.getCluster().getMetadata()); - sessionRepository.add(dsl); - }); + DslExportable dsl = (DslExportable) Helenus.dsl(iface); + dsl.setMetadata(session.getCluster().getMetadata()); + sessionRepository.add(dsl); + }); TableOperations tableOps = new TableOperations(this, dropUnusedColumns, dropUnusedIndexes); UserTypeOperations userTypeOps = new UserTypeOperations(this, dropUnusedColumns); diff --git a/src/main/java/net/helenus/core/UnitOfWork.java b/src/main/java/net/helenus/core/UnitOfWork.java index 0cfa536..f27b76c 100644 --- a/src/main/java/net/helenus/core/UnitOfWork.java +++ b/src/main/java/net/helenus/core/UnitOfWork.java @@ -15,44 +15,42 @@ */ package net.helenus.core; -import net.helenus.support.Either; import java.util.Map; import java.util.Set; public interface UnitOfWork extends AutoCloseable { - /** - * Marks the beginning of a transactional section of work. Will write a record to the shared - * write-ahead log. - * - * @return the handle used to commit or abort the work. - */ - UnitOfWork begin(); + /** + * Marks the beginning of a transactional section of work. Will write a record to the shared + * write-ahead log. + * + * @return the handle used to commit or abort the work. + */ + UnitOfWork begin(); - UnitOfWork addNestedUnitOfWork(UnitOfWork uow); + UnitOfWork addNestedUnitOfWork(UnitOfWork uow); - /** - * Checks to see if the work performed between calling begin and now can be committed or not. - * - * @return a function from which to chain work that only happens when commit is successful - * @throws E when the work overlaps with other concurrent writers. - */ - PostCommitFunction commit() throws E; + /** + * Checks to see if the work performed between calling begin and now can be committed or not. + * + * @return a function from which to chain work that only happens when commit is successful + * @throws E when the work overlaps with other concurrent writers. + */ + PostCommitFunction commit() throws E; - /** - * Explicitly abort the work within this unit of work. Any nested aborted unit of work - * will trigger the entire unit of work to commit. - */ - void abort(); + /** + * Explicitly abort the work within this unit of work. Any nested aborted unit of work will + * trigger the entire unit of work to commit. + */ + void abort(); + boolean hasAborted(); - boolean hasAborted(); + boolean hasCommitted(); - boolean hasCommitted(); + //Either> cacheLookup(String key); + Set cacheLookup(String key); - //Either> cacheLookup(String key); - Set cacheLookup(String key); - - Map> getCache(); + Map> getCache(); } diff --git a/src/main/java/net/helenus/core/UnitOfWorkImpl.java b/src/main/java/net/helenus/core/UnitOfWorkImpl.java index b9aab3b..52cae59 100644 --- a/src/main/java/net/helenus/core/UnitOfWorkImpl.java +++ b/src/main/java/net/helenus/core/UnitOfWorkImpl.java @@ -19,9 +19,8 @@ import net.helenus.support.HelenusException; class UnitOfWorkImpl extends AbstractUnitOfWork { - @SuppressWarnings("unchecked") - public UnitOfWorkImpl(HelenusSession session, UnitOfWork parent) { - super(session, (AbstractUnitOfWork) parent); - } - + @SuppressWarnings("unchecked") + public UnitOfWorkImpl(HelenusSession session, UnitOfWork parent) { + super(session, (AbstractUnitOfWork) parent); + } } diff --git a/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java b/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java index 8bf3b8b..b4a7cf9 100644 --- a/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java +++ b/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java @@ -4,11 +4,7 @@ import net.helenus.mapping.HelenusProperty; public class EntityIdentifyingFacet extends Facet { - public EntityIdentifyingFacet(HelenusProperty prop) { + public EntityIdentifyingFacet(HelenusProperty prop) {} - } - - public EntityIdentifyingFacet(HelenusProperty[]... props) { - - } + public EntityIdentifyingFacet(HelenusProperty[]... props) {} } diff --git a/src/main/java/net/helenus/core/cache/Facet.java b/src/main/java/net/helenus/core/cache/Facet.java index eb521b1..31fdb2c 100644 --- a/src/main/java/net/helenus/core/cache/Facet.java +++ b/src/main/java/net/helenus/core/cache/Facet.java @@ -1,7 +1,6 @@ package net.helenus.core.cache; -public class Facet { -} +public class Facet {} /* An Entity is identifiable via one or more Facets diff --git a/src/main/java/net/helenus/core/operation/AbstractFilterOptionalOperation.java b/src/main/java/net/helenus/core/operation/AbstractFilterOptionalOperation.java index 8ed14af..6abfd81 100644 --- a/src/main/java/net/helenus/core/operation/AbstractFilterOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractFilterOptionalOperation.java @@ -19,11 +19,11 @@ import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; - import net.helenus.core.*; import net.helenus.mapping.HelenusProperty; -public abstract class AbstractFilterOptionalOperation> +public abstract class AbstractFilterOptionalOperation< + E, O extends AbstractFilterOptionalOperation> extends AbstractOptionalOperation { protected Map> filters = null; diff --git a/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java b/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java index 755e220..b78daf1 100644 --- a/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java @@ -19,11 +19,11 @@ import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; - import net.helenus.core.*; import net.helenus.mapping.HelenusProperty; -public abstract class AbstractFilterStreamOperation> +public abstract class AbstractFilterStreamOperation< + E, O extends AbstractFilterStreamOperation> extends AbstractStreamOperation { protected Map> filters = null; diff --git a/src/main/java/net/helenus/core/operation/AbstractOperation.java b/src/main/java/net/helenus/core/operation/AbstractOperation.java index 46739b9..8eb7961 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOperation.java @@ -17,8 +17,6 @@ package net.helenus.core.operation; import com.codahale.metrics.Timer; import com.datastax.driver.core.ResultSet; - -import java.util.Objects; import java.util.concurrent.CompletableFuture; import net.helenus.core.AbstractSessionOperations; import net.helenus.core.UnitOfWork; @@ -40,7 +38,6 @@ public abstract class AbstractOperation> return new PreparedOperation(prepareStatement(), this); } - public E sync() { final Timer.Context context = requestLatency.time(); try { @@ -72,5 +69,4 @@ public abstract class AbstractOperation> if (uow == null) return async(); return CompletableFuture.supplyAsync(() -> sync(uow)); } - } diff --git a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java index 6a287f0..5177724 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java @@ -32,7 +32,8 @@ import net.helenus.support.HelenusException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public abstract class AbstractStatementOperation> extends Operation { +public abstract class AbstractStatementOperation> + extends Operation { final Logger logger = LoggerFactory.getLogger(getClass()); @@ -55,7 +56,6 @@ public abstract class AbstractStatementOperation> extends AbstractStatementOperation { @@ -113,5 +104,4 @@ public abstract class AbstractStreamOperation>supplyAsync(() -> sync(uow)); } - } diff --git a/src/main/java/net/helenus/core/operation/BoundOptionalOperation.java b/src/main/java/net/helenus/core/operation/BoundOptionalOperation.java index 4230bab..c3f5332 100644 --- a/src/main/java/net/helenus/core/operation/BoundOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/BoundOptionalOperation.java @@ -34,7 +34,9 @@ public final class BoundOptionalOperation } @Override - public Optional transform(ResultSet resultSet) { return delegate.transform(resultSet); } + public Optional transform(ResultSet resultSet) { + return delegate.transform(resultSet); + } @Override public Statement buildStatement(boolean cached) { diff --git a/src/main/java/net/helenus/core/operation/BoundStreamOperation.java b/src/main/java/net/helenus/core/operation/BoundStreamOperation.java index 4210b04..7a3cf2c 100644 --- a/src/main/java/net/helenus/core/operation/BoundStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/BoundStreamOperation.java @@ -26,14 +26,17 @@ public final class BoundStreamOperation private final BoundStatement boundStatement; private final AbstractStreamOperation delegate; - public BoundStreamOperation(BoundStatement boundStatement, AbstractStreamOperation operation) { + public BoundStreamOperation( + BoundStatement boundStatement, AbstractStreamOperation operation) { super(operation.sessionOps); this.boundStatement = boundStatement; this.delegate = operation; } @Override - public String getStatementCacheKey() { return delegate.getStatementCacheKey(); } + public String getStatementCacheKey() { + return delegate.getStatementCacheKey(); + } @Override public Stream transform(ResultSet resultSet) { @@ -41,5 +44,7 @@ public final class BoundStreamOperation } @Override - public Statement buildStatement(boolean cached) { return boundStatement; } + public Statement buildStatement(boolean cached) { + return boundStatement; + } } diff --git a/src/main/java/net/helenus/core/operation/InsertOperation.java b/src/main/java/net/helenus/core/operation/InsertOperation.java index f05bf87..3ee0c8a 100644 --- a/src/main/java/net/helenus/core/operation/InsertOperation.java +++ b/src/main/java/net/helenus/core/operation/InsertOperation.java @@ -19,10 +19,9 @@ import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.Insert; import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.google.common.base.Joiner; import java.util.*; import java.util.function.Function; - -import com.google.common.base.Joiner; import net.helenus.core.AbstractSessionOperations; import net.helenus.core.Getter; import net.helenus.core.Helenus; @@ -41,7 +40,8 @@ public final class InsertOperation extends AbstractOperation> values = new ArrayList>(); + private final List> values = + new ArrayList>(); private final T pojo; private final Class resultType; private boolean ifNotExists; @@ -57,7 +57,8 @@ public final class InsertOperation extends AbstractOperation resultType, boolean ifNotExists) { + public InsertOperation( + AbstractSessionOperations sessionOperations, Class resultType, boolean ifNotExists) { super(sessionOperations); this.ifNotExists = ifNotExists; @@ -172,7 +173,7 @@ public final class InsertOperation extends AbstractOperation> converter = - prop.getReadConverter(sessionOps.getSessionRepository()); + prop.getReadConverter(sessionOps.getSessionRepository()); if (converter.isPresent()) { backingMap.put(key, converter.get().apply(backingMap.get(key))); } @@ -232,23 +233,25 @@ public final class InsertOperation extends AbstractOperation keys = new ArrayList<>(values.size()); values.forEach( - t -> { - HelenusPropertyNode prop = t._1; - switch (prop.getProperty().getColumnType()) { - case PARTITION_KEY: - case CLUSTERING_COLUMN: - keys.add(prop.getColumnName() + "==" + t._2.toString()); - break; - default: - break; - } - }); + t -> { + HelenusPropertyNode prop = t._1; + switch (prop.getProperty().getColumnType()) { + case PARTITION_KEY: + case CLUSTERING_COLUMN: + keys.add(prop.getColumnName() + "==" + t._2.toString()); + break; + default: + break; + } + }); return entity.getName() + ": " + Joiner.on(",").join(keys); } @Override public T sync(UnitOfWork uow) { - if (uow == null) { return sync(); } + if (uow == null) { + return sync(); + } T result = super.sync(uow); Class iface = entity.getMappingInterface(); if (resultType == iface) { @@ -261,5 +264,4 @@ public final class InsertOperation extends AbstractOperation { - protected final AbstractSessionOperations sessionOps; - protected final Meter uowCacheHits; - protected final Meter uowCacheMiss; - protected final Timer requestLatency; + protected final AbstractSessionOperations sessionOps; + protected final Meter uowCacheHits; + protected final Meter uowCacheMiss; + protected final Timer requestLatency; - Operation(AbstractSessionOperations sessionOperations) { - this.sessionOps = sessionOperations; - MetricRegistry metrics = sessionOperations.getMetricRegistry(); - this.uowCacheHits = metrics.meter("net.helenus.UOW-cache-hits"); - this.uowCacheMiss = metrics.meter("net.helenus.UOW-cache-miss"); - this.requestLatency = metrics.timer("net.helenus.request-latency"); + Operation(AbstractSessionOperations sessionOperations) { + this.sessionOps = sessionOperations; + MetricRegistry metrics = sessionOperations.getMetricRegistry(); + this.uowCacheHits = metrics.meter("net.helenus.UOW-cache-hits"); + this.uowCacheMiss = metrics.meter("net.helenus.UOW-cache-miss"); + this.requestLatency = metrics.timer("net.helenus.request-latency"); + } + + public ResultSet execute( + AbstractSessionOperations session, + UnitOfWork uow, + TraceContext traceContext, + boolean showValues, + boolean cached) { + + // Start recording in a Zipkin sub-span our execution time to perform this operation. + Tracer tracer = session.getZipkinTracer(); + Span span = null; + if (tracer != null && traceContext != null) { + span = tracer.newChild(traceContext); } - public ResultSet execute(AbstractSessionOperations session, UnitOfWork uow, TraceContext traceContext, boolean showValues, boolean cached) { + try { - // Start recording in a Zipkin sub-span our execution time to perform this operation. - Tracer tracer = session.getZipkinTracer(); - Span span = null; - if (tracer != null && traceContext != null) { - span = tracer.newChild(traceContext); - } + if (span != null) { + span.name("cassandra"); + span.start(); + } - try { + Statement statement = options(buildStatement(cached)); + ResultSetFuture futureResultSet = session.executeAsync(statement, showValues); + return futureResultSet.get(); - if (span != null) { - span.name("cassandra"); - span.start(); - } + } catch (InterruptedException | ExecutionException e) { - Statement statement = options(buildStatement(cached)); - ResultSetFuture futureResultSet = session.executeAsync(statement, showValues); - return futureResultSet.get(); + throw new RuntimeException(e); - } catch (InterruptedException | ExecutionException e) { + } finally { - throw new RuntimeException(e); - - } finally { - - if (span != null) { - span.finish(); - } - - } + if (span != null) { + span.finish(); + } } + } - public Statement options(Statement statement) { return statement; } + public Statement options(Statement statement) { + return statement; + } - public Statement buildStatement(boolean cached) { return null; } - - public Set getIdentifyingFacets() { return null; } + public Statement buildStatement(boolean cached) { + return null; + } + public Set getIdentifyingFacets() { + return null; + } } diff --git a/src/main/java/net/helenus/core/operation/PreparedStreamOperation.java b/src/main/java/net/helenus/core/operation/PreparedStreamOperation.java index b622874..cd0f6be 100644 --- a/src/main/java/net/helenus/core/operation/PreparedStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/PreparedStreamOperation.java @@ -17,7 +17,6 @@ package net.helenus.core.operation; import com.datastax.driver.core.BoundStatement; import com.datastax.driver.core.PreparedStatement; -import java.util.regex.Pattern; public final class PreparedStreamOperation { diff --git a/src/main/java/net/helenus/core/operation/SelectFirstOperation.java b/src/main/java/net/helenus/core/operation/SelectFirstOperation.java index ff88555..d5cf01e 100644 --- a/src/main/java/net/helenus/core/operation/SelectFirstOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectFirstOperation.java @@ -38,7 +38,9 @@ public final class SelectFirstOperation } @Override - public String getStatementCacheKey() { return delegate.getStatementCacheKey(); } + public String getStatementCacheKey() { + return delegate.getStatementCacheKey(); + } @Override public BuiltStatement buildStatement(boolean cached) { diff --git a/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java b/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java index 1d95256..8ef4f60 100644 --- a/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java @@ -36,7 +36,9 @@ public final class SelectFirstTransformingOperation } @Override - public String getStatementCacheKey() { return delegate.getStatementCacheKey(); } + public String getStatementCacheKey() { + return delegate.getStatementCacheKey(); + } @Override public BuiltStatement buildStatement(boolean cached) { diff --git a/src/main/java/net/helenus/core/operation/SelectOperation.java b/src/main/java/net/helenus/core/operation/SelectOperation.java index 63619b6..4204c29 100644 --- a/src/main/java/net/helenus/core/operation/SelectOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectOperation.java @@ -22,15 +22,12 @@ import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Select; import com.datastax.driver.core.querybuilder.Select.Selection; import com.datastax.driver.core.querybuilder.Select.Where; +import com.google.common.collect.Iterables; import java.util.*; import java.util.function.Function; import java.util.stream.Stream; import java.util.stream.StreamSupport; - -import com.google.common.base.Joiner; -import com.google.common.collect.Iterables; import net.helenus.core.*; -import net.helenus.core.cache.Facet; import net.helenus.core.cache.EntityIdentifyingFacet; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; @@ -56,7 +53,7 @@ public final class SelectOperation extends AbstractFilterStreamOperation() { + new Function() { @Override public E apply(Row source) { @@ -188,20 +185,25 @@ public final class SelectOperation extends AbstractFilterStreamOperation facets = new HashSet<>(filters.size()); // Check to see if this select statement has enough information to build one or // more identifying facets. - entity.getIdentityFacets().forEach((facetName, facet) -> { - EntityIdentifyingFacet boundFacet = null; - if (!facet.isFullyBound()) { - boundFacet = new EntityIdentifyingFacet(facet); - for (HelenusProperty prop : facet.getUnboundEntityProperties()) { - Filter filter = filters.get(facet.getProperty()); - if (filter == null) { break; } - boundFacet.setValueForProperty(prop, filter.toString()); - } - } - if (boundFacet != null && boundFacet.isFullyBound()) { - facets.add(boundFacet); - } - }); + entity + .getIdentityFacets() + .forEach( + (facetName, facet) -> { + EntityIdentifyingFacet boundFacet = null; + if (!facet.isFullyBound()) { + boundFacet = new EntityIdentifyingFacet(facet); + for (HelenusProperty prop : facet.getUnboundEntityProperties()) { + Filter filter = filters.get(facet.getProperty()); + if (filter == null) { + break; + } + boundFacet.setValueForProperty(prop, filter.toString()); + } + } + if (boundFacet != null && boundFacet.isFullyBound()) { + facets.add(boundFacet); + } + }); return facets; } @@ -223,14 +225,14 @@ public final class SelectOperation extends AbstractFilterStreamOperation extends AbstractFilterStreamOperation transform(ResultSet resultSet) { if (rowMapper != null) { - return StreamSupport.stream(Spliterators.spliteratorUnknownSize(resultSet.iterator(), Spliterator.ORDERED), false).map(rowMapper); + return StreamSupport.stream( + Spliterators.spliteratorUnknownSize(resultSet.iterator(), Spliterator.ORDERED), false) + .map(rowMapper); } else { return (Stream) - StreamSupport.stream(Spliterators.spliteratorUnknownSize(resultSet.iterator(), Spliterator.ORDERED),false); + StreamSupport.stream( + Spliterators.spliteratorUnknownSize(resultSet.iterator(), Spliterator.ORDERED), + false); } } diff --git a/src/main/java/net/helenus/core/operation/SelectTransformingOperation.java b/src/main/java/net/helenus/core/operation/SelectTransformingOperation.java index 8883f7e..f93ca41 100644 --- a/src/main/java/net/helenus/core/operation/SelectTransformingOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectTransformingOperation.java @@ -36,7 +36,9 @@ public final class SelectTransformingOperation } @Override - public String getStatementCacheKey() { return delegate.getStatementCacheKey(); } + public String getStatementCacheKey() { + return delegate.getStatementCacheKey(); + } @Override public BuiltStatement buildStatement(boolean cached) { @@ -47,5 +49,4 @@ public final class SelectTransformingOperation public Stream transform(ResultSet resultSet) { return delegate.transform(resultSet).map(fn); } - } diff --git a/src/main/java/net/helenus/core/operation/UpdateOperation.java b/src/main/java/net/helenus/core/operation/UpdateOperation.java index ba358d6..b918bc6 100644 --- a/src/main/java/net/helenus/core/operation/UpdateOperation.java +++ b/src/main/java/net/helenus/core/operation/UpdateOperation.java @@ -15,15 +15,13 @@ */ package net.helenus.core.operation; -import java.util.*; -import java.util.function.Function; - import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.Assignment; import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Update; - +import java.util.*; +import java.util.function.Function; import net.helenus.core.*; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; @@ -43,19 +41,21 @@ public final class UpdateOperation extends AbstractFilterOperation draft) { + public UpdateOperation( + AbstractSessionOperations sessionOperations, AbstractEntityDraft draft) { super(sessionOperations); this.draft = draft; this.draftMap = draft.toMap(); } - public UpdateOperation(AbstractSessionOperations sessionOperations, HelenusPropertyNode p, Object v) { + public UpdateOperation( + AbstractSessionOperations sessionOperations, HelenusPropertyNode p, Object v) { super(sessionOperations); this.draft = null; this.draftMap = null; @@ -152,7 +152,7 @@ public final class UpdateOperation extends AbstractFilterOperation list = (List)draftMap.get(key); + List list = (List) draftMap.get(key); list.add(0, value); } @@ -194,7 +194,7 @@ public final class UpdateOperation extends AbstractFilterOperation list = (List)draftMap.get(key); + List list = (List) draftMap.get(key); if (idx < 0) { list.add(0, value); } else if (idx > list.size()) { @@ -222,7 +222,7 @@ public final class UpdateOperation extends AbstractFilterOperation list = (List)draftMap.get(key); + List list = (List) draftMap.get(key); list.add(value); } @@ -579,7 +579,9 @@ public final class UpdateOperation extends AbstractFilterOperation extends AbstractFilterOperation implements InvocationHandler { } private HelenusEntity init(Metadata metadata) { - HelenusEntity entity = new HelenusMappingEntity(iface, metadata); + HelenusEntity entity = new HelenusMappingEntity(iface, metadata); - for (HelenusProperty prop : entity.getOrderedProperties()) { + for (HelenusProperty prop : entity.getOrderedProperties()) { - map.put(prop.getGetterMethod(), prop); + map.put(prop.getGetterMethod(), prop); - AbstractDataType type = prop.getDataType(); - Class javaType = prop.getJavaType(); + AbstractDataType type = prop.getDataType(); + Class javaType = prop.getJavaType(); - if (type instanceof UDTDataType && !UDTValue.class.isAssignableFrom(javaType)) { + if (type instanceof UDTDataType && !UDTValue.class.isAssignableFrom(javaType)) { - Object childDsl = - Helenus.dsl( - javaType, - classLoader, - Optional.of(new HelenusPropertyNode(prop, parent)), - metadata); + Object childDsl = + Helenus.dsl( + javaType, + classLoader, + Optional.of(new HelenusPropertyNode(prop, parent)), + metadata); - udtMap.put(prop.getGetterMethod(), childDsl); - } - - if (type instanceof DTDataType) { - DTDataType dataType = (DTDataType) type; - - if (dataType.getDataType() instanceof TupleType - && !TupleValue.class.isAssignableFrom(javaType)) { - - Object childDsl = - Helenus.dsl( - javaType, - classLoader, - Optional.of(new HelenusPropertyNode(prop, parent)), - metadata); - - tupleMap.put(prop.getGetterMethod(), childDsl); - } - } + udtMap.put(prop.getGetterMethod(), childDsl); } - return entity; + if (type instanceof DTDataType) { + DTDataType dataType = (DTDataType) type; + + if (dataType.getDataType() instanceof TupleType + && !TupleValue.class.isAssignableFrom(javaType)) { + + Object childDsl = + Helenus.dsl( + javaType, + classLoader, + Optional.of(new HelenusPropertyNode(prop, parent)), + metadata); + + tupleMap.put(prop.getGetterMethod(), childDsl); + } + } + } + + return entity; } @Override @@ -127,10 +127,10 @@ public class DslInvocationHandler implements InvocationHandler { } if (DslExportable.SET_METADATA_METHOD.equals(methodName) - && args.length == 1 - && args[0] instanceof Metadata) { + && args.length == 1 + && args[0] instanceof Metadata) { if (metadata == null) { - this.setMetadata((Metadata) args[0]); + this.setMetadata((Metadata) args[0]); } return null; } diff --git a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java index 27d48cf..4845c11 100644 --- a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java +++ b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java @@ -23,7 +23,6 @@ import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Collections; import java.util.Map; - import net.helenus.core.Helenus; import net.helenus.mapping.annotation.Transient; import net.helenus.support.HelenusException; @@ -94,7 +93,7 @@ public class MapperInvocationHandler implements InvocationHandler, Serializab } if ("dsl".equals(methodName)) { - return Helenus.dsl(iface); + return Helenus.dsl(iface); } if (MapExportable.TO_MAP_METHOD.equals(methodName)) { diff --git a/src/main/java/net/helenus/mapping/HelenusEntity.java b/src/main/java/net/helenus/mapping/HelenusEntity.java index ef63078..fa84c7b 100644 --- a/src/main/java/net/helenus/mapping/HelenusEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusEntity.java @@ -15,10 +15,9 @@ */ package net.helenus.mapping; -import net.helenus.core.cache.EntityIdentifyingFacet; - import java.util.Collection; import java.util.Map; +import net.helenus.core.cache.EntityIdentifyingFacet; public interface HelenusEntity { @@ -35,5 +34,4 @@ public interface HelenusEntity { HelenusProperty getProperty(String name); Map getIdentityFacets(); - } diff --git a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java index eaee3fe..b7fd8c3 100644 --- a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java @@ -20,7 +20,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import java.lang.reflect.Method; import java.util.*; - import net.helenus.config.HelenusSettings; import net.helenus.core.Helenus; import net.helenus.core.annotation.Cacheable; @@ -60,21 +59,22 @@ public final class HelenusMappingEntity implements HelenusEntity { Map methods = new HashMap(); for (Method m : iface.getDeclaredMethods()) { - methods.put(m.getName(), m); + methods.put(m.getName(), m); } for (Class c : ClassUtils.getAllInterfaces(iface)) { - if (c.getDeclaredAnnotation(Table.class) != null || c.getDeclaredAnnotation(InheritedTable.class) != null) { + if (c.getDeclaredAnnotation(Table.class) != null + || c.getDeclaredAnnotation(InheritedTable.class) != null) { for (Method m : c.getDeclaredMethods()) { - Method o = methods.get(m.getName()); - if (o != null) { - // Prefer overridden method implementation. - if (o.getDeclaringClass().isAssignableFrom(m.getDeclaringClass())) { - methods.put(m.getName(), m); - } - } else { - methods.put(m.getName(), m); + Method o = methods.get(m.getName()); + if (o != null) { + // Prefer overridden method implementation. + if (o.getDeclaringClass().isAssignableFrom(m.getDeclaringClass())) { + methods.put(m.getName(), m); } + } else { + methods.put(m.getName(), m); + } } } } @@ -110,27 +110,34 @@ public final class HelenusMappingEntity implements HelenusEntity { cacheable = (null != iface.getDeclaredAnnotation(Cacheable.class)); ImmutableMap.Builder allFacetsBuilder = ImmutableMap.builder(); - ImmutableMap.Builder ancillaryFacetsBuilder = ImmutableMap.builder(); + ImmutableMap.Builder ancillaryFacetsBuilder = + ImmutableMap.builder(); EntityIdentifyingFacet primaryFacet = null; List primaryProperties = new ArrayList(4); for (HelenusProperty prop : propsLocal) { - switch(prop.getColumnType()) { + switch (prop.getColumnType()) { case PARTITION_KEY: case CLUSTERING_COLUMN: - primaryProperties.add(prop); - break; + primaryProperties.add(prop); + break; default: - if (primaryProperties != null) { - primaryFacet = new EntityIdentifyingFacet(keyspace, table, schemaVersion, primaryProperties.toArray(new HelenusProperty[props.size()])); - allFacetsBuilder.put("*", primaryFacet); - primaryProperties = null; - } - Optional optionalIndexName = prop.getIndexName(); - if (optionalIndexName.isPresent()) { - EntityIdentifyingFacet facet = new EntityIdentifyingFacet(keyspace, table, schemaVersion, prop); - ancillaryFacetsBuilder.put(prop.getPropertyName(), facet); - } - } + if (primaryProperties != null) { + primaryFacet = + new EntityIdentifyingFacet( + keyspace, + table, + schemaVersion, + primaryProperties.toArray(new HelenusProperty[props.size()])); + allFacetsBuilder.put("*", primaryFacet); + primaryProperties = null; + } + Optional optionalIndexName = prop.getIndexName(); + if (optionalIndexName.isPresent()) { + EntityIdentifyingFacet facet = + new EntityIdentifyingFacet(keyspace, table, schemaVersion, prop); + ancillaryFacetsBuilder.put(prop.getPropertyName(), facet); + } + } } this.primaryIdentityFacet = primaryFacet; this.ancillaryIdentityFacets = ancillaryFacetsBuilder.build(); diff --git a/src/main/java/net/helenus/mapping/javatype/AbstractCollectionJavaType.java b/src/main/java/net/helenus/mapping/javatype/AbstractCollectionJavaType.java index 61a764a..a882398 100644 --- a/src/main/java/net/helenus/mapping/javatype/AbstractCollectionJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/AbstractCollectionJavaType.java @@ -2,6 +2,7 @@ package net.helenus.mapping.javatype; public abstract class AbstractCollectionJavaType extends AbstractJavaType { - public static boolean isCollectionType() { return true; } - + public static boolean isCollectionType() { + return true; + } } diff --git a/src/main/java/net/helenus/mapping/javatype/AbstractJavaType.java b/src/main/java/net/helenus/mapping/javatype/AbstractJavaType.java index 806fc2e..abd7e21 100644 --- a/src/main/java/net/helenus/mapping/javatype/AbstractJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/AbstractJavaType.java @@ -33,7 +33,9 @@ import net.helenus.support.HelenusMappingException; public abstract class AbstractJavaType { - public static boolean isCollectionType() { return false; } + public static boolean isCollectionType() { + return false; + } public abstract Class getJavaClass(); diff --git a/src/main/java/net/helenus/mapping/javatype/MapJavaType.java b/src/main/java/net/helenus/mapping/javatype/MapJavaType.java index 4d6e38f..2a5d187 100644 --- a/src/main/java/net/helenus/mapping/javatype/MapJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/MapJavaType.java @@ -18,7 +18,6 @@ package net.helenus.mapping.javatype; import com.datastax.driver.core.*; import java.lang.reflect.Method; import java.lang.reflect.Type; -import java.util.AbstractCollection; import java.util.Map; import java.util.Optional; import java.util.function.Function; diff --git a/src/main/java/net/helenus/mapping/type/AbstractCollectionDataType.java b/src/main/java/net/helenus/mapping/type/AbstractCollectionDataType.java index d138263..7e76d92 100644 --- a/src/main/java/net/helenus/mapping/type/AbstractCollectionDataType.java +++ b/src/main/java/net/helenus/mapping/type/AbstractCollectionDataType.java @@ -4,10 +4,11 @@ import net.helenus.mapping.ColumnType; public abstract class AbstractCollectionDataType extends AbstractDataType { - public AbstractCollectionDataType(ColumnType columnType) { - super(columnType); - } - - public boolean isCollectionType() { return true; } + public AbstractCollectionDataType(ColumnType columnType) { + super(columnType); + } + public boolean isCollectionType() { + return true; + } } diff --git a/src/main/java/net/helenus/mapping/type/AbstractDataType.java b/src/main/java/net/helenus/mapping/type/AbstractDataType.java index 8be0fd1..cc65d68 100644 --- a/src/main/java/net/helenus/mapping/type/AbstractDataType.java +++ b/src/main/java/net/helenus/mapping/type/AbstractDataType.java @@ -55,6 +55,7 @@ public abstract class AbstractDataType { "wrong column type " + columnType + " for UserDefinedType in columnName " + columnName); } - public boolean isCollectionType() { return false; } - + public boolean isCollectionType() { + return false; + } } diff --git a/src/main/java/net/helenus/mapping/type/UDTKeyMapDataType.java b/src/main/java/net/helenus/mapping/type/UDTKeyMapDataType.java index b9724aa..e04685c 100644 --- a/src/main/java/net/helenus/mapping/type/UDTKeyMapDataType.java +++ b/src/main/java/net/helenus/mapping/type/UDTKeyMapDataType.java @@ -18,8 +18,6 @@ package net.helenus.mapping.type; import com.datastax.driver.core.DataType; import com.datastax.driver.core.UserType; import com.datastax.driver.core.schemabuilder.*; - -import java.util.AbstractCollection; import java.util.List; import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; diff --git a/src/main/java/net/helenus/mapping/value/BeanColumnValueProvider.java b/src/main/java/net/helenus/mapping/value/BeanColumnValueProvider.java index 2381514..a87fd15 100644 --- a/src/main/java/net/helenus/mapping/value/BeanColumnValueProvider.java +++ b/src/main/java/net/helenus/mapping/value/BeanColumnValueProvider.java @@ -33,7 +33,7 @@ public enum BeanColumnValueProvider implements ColumnValueProvider { try { value = getter.invoke(bean, new Object[] {}); } catch (InvocationTargetException e) { - if (e.getCause() != null ) { + if (e.getCause() != null) { throw new HelenusException("getter threw an exception", e.getCause()); } } catch (ReflectiveOperationException e) { diff --git a/src/test/java/net/helenus/test/integration/core/collection/CollectionTest.java b/src/test/java/net/helenus/test/integration/core/collection/CollectionTest.java index 5b437eb..e838ad3 100644 --- a/src/test/java/net/helenus/test/integration/core/collection/CollectionTest.java +++ b/src/test/java/net/helenus/test/integration/core/collection/CollectionTest.java @@ -67,11 +67,8 @@ public class CollectionTest extends AbstractEmbeddedCassandraTest { // read full object - Customer actual = session.select(customer) - .where(customer::id, eq(id)) - .single() - .sync() - .orElse(null); + Customer actual = + session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); Assert.assertEquals(id, actual.id()); Assert.assertEquals(aliases, actual.aliases()); Assert.assertNull(actual.names()); @@ -90,11 +87,8 @@ public class CollectionTest extends AbstractEmbeddedCassandraTest { session.update().set(customer::aliases, expected).where(customer::id, eq(id)).sync(); - actual = session.select(customer) - .where(customer::id, eq(id)) - .single() - .sync() - .orElse(null); + actual = + session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); Assert.assertEquals(id, actual.id()); Assert.assertEquals(expected, actual.aliases()); @@ -170,11 +164,8 @@ public class CollectionTest extends AbstractEmbeddedCassandraTest { // read full object - Customer actual = session.select(customer) - .where(customer::id, eq(id)) - .single() - .sync() - .orElse(null); + Customer actual = + session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); Assert.assertEquals(id, actual.id()); Assert.assertEquals(names, actual.names()); @@ -200,11 +191,8 @@ public class CollectionTest extends AbstractEmbeddedCassandraTest { session.update().set(customer::names, expected).where(customer::id, eq(id)).sync(); - actual = session.select(customer) - .where(customer::id, eq(id)) - .single() - .sync() - .orElse(null); + actual = + session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); Assert.assertEquals(id, actual.id()); Assert.assertEquals(expected, actual.names()); @@ -306,10 +294,8 @@ public class CollectionTest extends AbstractEmbeddedCassandraTest { // read full object - Customer actual = session.select(customer) - .where(customer::id, eq(id)).single() - .sync() - .orElse(null); + Customer actual = + session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); Assert.assertEquals(id, actual.id()); Assert.assertEquals(props, actual.properties()); @@ -343,11 +329,8 @@ public class CollectionTest extends AbstractEmbeddedCassandraTest { session.update().set(customer::properties, expected).where(customer::id, eq(id)).sync(); - actual = session.select(customer) - .where(customer::id, eq(id)) - .single() - .sync() - .orElse(null); + actual = + session.select(customer).where(customer::id, eq(id)).single().sync().orElse(null); Assert.assertEquals(id, actual.id()); Assert.assertEquals(expected, actual.properties()); diff --git a/src/test/java/net/helenus/test/integration/core/draft/EntityDraftBuilderTest.java b/src/test/java/net/helenus/test/integration/core/draft/EntityDraftBuilderTest.java index 2be5381..3296488 100644 --- a/src/test/java/net/helenus/test/integration/core/draft/EntityDraftBuilderTest.java +++ b/src/test/java/net/helenus/test/integration/core/draft/EntityDraftBuilderTest.java @@ -18,76 +18,73 @@ package net.helenus.test.integration.core.draft; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; - +import net.helenus.core.Helenus; +import net.helenus.core.HelenusSession; +import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import net.helenus.core.Helenus; -import net.helenus.core.HelenusSession; -import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; - -import static net.helenus.core.Query.eq; public class EntityDraftBuilderTest extends AbstractEmbeddedCassandraTest { + static Supply supply; + static HelenusSession session; - static Supply supply; - static HelenusSession session; + @BeforeClass + public static void beforeTest() { + session = Helenus.init(getSession()).showCql().add(Supply.class).autoCreateDrop().get(); + supply = session.dsl(Supply.class); + } + @Test + public void testFoo() throws Exception { + Supply.Draft draft = null; - @BeforeClass - public static void beforeTest() { - session = Helenus.init(getSession()) - .showCql() - .add(Supply.class) - .autoCreateDrop() - .get(); - supply = session.dsl(Supply.class); - } - - @Test - public void testFoo() throws Exception { - Supply.Draft draft = null; - - draft = Supply.draft("APAC") - .code("WIDGET-002") - .description("Our second Widget!") - .demand(new HashMap() {{ + draft = + Supply.draft("APAC") + .code("WIDGET-002") + .description("Our second Widget!") + .demand( + new HashMap() { + { put("APAC", 100L); put("EMEA", 10000L); put("NORAM", 2000000L); - }}) - .shipments(new HashSet() {{ + } + }) + .shipments( + new HashSet() { + { add("HMS Puddle in transit to APAC, 100 units."); add("Frigate Jimmy in transit to EMEA, 10000 units."); - }}) - .suppliers(new ArrayList() {{ + } + }) + .suppliers( + new ArrayList() { + { add("Puddle, Inc."); add("Jimmy Town, LTD."); - }}); + } + }); - Supply s1 = session.insert(draft) - .sync(); + Supply s1 = session.insert(draft).sync(); - // List - Supply s2 = session.update(s1.update()) - .prepend(supply::suppliers, "Pignose Supply, LLC.") - .sync(); - Assert.assertEquals(s2.suppliers().get(0), "Pignose Supply, LLC."); + // List + Supply s2 = + session + .update(s1.update()) + .prepend(supply::suppliers, "Pignose Supply, LLC.") + .sync(); + Assert.assertEquals(s2.suppliers().get(0), "Pignose Supply, LLC."); - // Set - String shipment = "Pignose, on the way! (1M units)"; - Supply s3 = session.update(s2.update()) - .add(supply::shipments, shipment) - .sync(); - Assert.assertTrue(s3.shipments().contains(shipment)); + // Set + String shipment = "Pignose, on the way! (1M units)"; + Supply s3 = session.update(s2.update()).add(supply::shipments, shipment).sync(); + Assert.assertTrue(s3.shipments().contains(shipment)); - // Map - Supply s4 = session.update(s3.update()) - .put(supply::demand, "NORAM", 10L) - .sync(); - Assert.assertEquals((long)s4.demand().get("NORAM"), 10L); - - } + // Map + Supply s4 = session.update(s3.update()).put(supply::demand, "NORAM", 10L).sync(); + Assert.assertEquals((long) s4.demand().get("NORAM"), 10L); + } } diff --git a/src/test/java/net/helenus/test/integration/core/draft/Inventory.java b/src/test/java/net/helenus/test/integration/core/draft/Inventory.java index 52448d2..a8b5945 100644 --- a/src/test/java/net/helenus/test/integration/core/draft/Inventory.java +++ b/src/test/java/net/helenus/test/integration/core/draft/Inventory.java @@ -1,78 +1,93 @@ package net.helenus.test.integration.core.draft; import java.util.UUID; - import net.helenus.core.AbstractAuditedEntityDraft; import net.helenus.core.Helenus; import net.helenus.core.reflect.MapExportable; import net.helenus.mapping.annotation.*; - @Table public interface Inventory { - static Inventory inventory = Helenus.dsl(Inventory.class); + static Inventory inventory = Helenus.dsl(Inventory.class); - @PartitionKey UUID id(); - @Column("emea") @Types.Counter long EMEA(); - @Column("noram") @Types.Counter long NORAM(); - @Column("apac") @Types.Counter long APAC(); + @PartitionKey + UUID id(); - @Transient static Draft draft(UUID id) { return new Draft(id); } + @Column("emea") + @Types.Counter + long EMEA(); - @Transient default Draft update() { return new Draft(this); } + @Column("noram") + @Types.Counter + long NORAM(); + @Column("apac") + @Types.Counter + long APAC(); - class Draft extends AbstractAuditedEntityDraft { + @Transient + static Draft draft(UUID id) { + return new Draft(id); + } - // Entity/Draft pattern-enabling methods: - Draft(UUID id) { - super(null); + @Transient + default Draft update() { + return new Draft(this); + } - // Primary Key: - set(inventory::id, id); - } + class Draft extends AbstractAuditedEntityDraft { - Draft(Inventory inventory) { - super((MapExportable) inventory); - } - - public Class getEntityClass() { return Inventory.class; } - - protected String getCurrentAuditor() { return "unknown"; } - - // Immutable properties: - public UUID id() { - return this.get(inventory::id, UUID.class); - } - - public long EMEA() { - return this.get(inventory::EMEA, long.class); - } - - public Draft EMEA(long count) { - mutate(inventory::EMEA, count); - return this; - } - - public long APAC() { - return this.get(inventory::APAC, long.class); - } - - public Draft APAC(long count) { - mutate(inventory::APAC, count); - return this; - } - - public long NORAM() { - return this.get(inventory::NORAM, long.class); - } - - public Draft NORAM(long count) { - mutate(inventory::NORAM, count); - return this; - } + // Entity/Draft pattern-enabling methods: + Draft(UUID id) { + super(null); + // Primary Key: + set(inventory::id, id); } + Draft(Inventory inventory) { + super((MapExportable) inventory); + } + + public Class getEntityClass() { + return Inventory.class; + } + + protected String getCurrentAuditor() { + return "unknown"; + } + + // Immutable properties: + public UUID id() { + return this.get(inventory::id, UUID.class); + } + + public long EMEA() { + return this.get(inventory::EMEA, long.class); + } + + public Draft EMEA(long count) { + mutate(inventory::EMEA, count); + return this; + } + + public long APAC() { + return this.get(inventory::APAC, long.class); + } + + public Draft APAC(long count) { + mutate(inventory::APAC, count); + return this; + } + + public long NORAM() { + return this.get(inventory::NORAM, long.class); + } + + public Draft NORAM(long count) { + mutate(inventory::NORAM, count); + return this; + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/draft/Supply.java b/src/test/java/net/helenus/test/integration/core/draft/Supply.java index 91f1689..72c0ba7 100644 --- a/src/test/java/net/helenus/test/integration/core/draft/Supply.java +++ b/src/test/java/net/helenus/test/integration/core/draft/Supply.java @@ -1,129 +1,145 @@ package net.helenus.test.integration.core.draft; -import java.lang.reflect.Proxy; +import com.datastax.driver.core.utils.UUIDs; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; - -import com.datastax.driver.core.utils.UUIDs; - import net.helenus.core.AbstractEntityDraft; import net.helenus.core.Helenus; import net.helenus.core.reflect.MapExportable; import net.helenus.mapping.annotation.*; - @Table public interface Supply { - static Supply supply = Helenus.dsl(Supply.class); + static Supply supply = Helenus.dsl(Supply.class); - @PartitionKey UUID id(); - @ClusteringColumn(ordinal=0) default String region() { return "NORAM"; } + @PartitionKey + UUID id(); - @Index(caseSensitive = false) String code(); - @Index String description(); // @IndexText == lucene index - @Index Map demand(); - @Index List suppliers(); - @Index Set shipments(); + @ClusteringColumn(ordinal = 0) + default String region() { + return "NORAM"; + } - @Transient static Draft draft(String region) { return new Draft(region); } + @Index(caseSensitive = false) + String code(); - @Transient default Draft update() { return new Draft(this); } + @Index + String description(); // @IndexText == lucene index + @Index + Map demand(); - class Draft extends AbstractEntityDraft { + @Index + List suppliers(); - // Entity/Draft pattern-enabling methods: - Draft(String region) { - super(null); + @Index + Set shipments(); - // Primary Key: - set(supply::id, UUIDs.timeBased()); - set(supply::region, region); - } + @Transient + static Draft draft(String region) { + return new Draft(region); + } - Draft(Supply supply) { - super((MapExportable) supply); - } + @Transient + default Draft update() { + return new Draft(this); + } - public Class getEntityClass() { return Supply.class; } + class Draft extends AbstractEntityDraft { - // Immutable properties: - public UUID id() { - return this.get(supply::id, UUID.class); - } - - public String region() { - return this.get(supply::region, String.class); - } - - // Mutable properties: - public String code() { - return this.get(supply::code, String.class); - } - - public Draft code(String code) { - mutate(supply::code, code); - return this; - } - - public Draft setCode(String code) { - return code(code); - } - - public String description() { - return this.get(supply::description, String.class); - } - - public Draft description(String description) { - mutate(supply::description, description); - return this; - } - - public Draft setDescription(String description) { - return description(description); - } - - public Map demand() { - return this.>get(supply::demand, Map.class); - } - - public Draft demand(Map demand) { - mutate(supply::demand, demand); - return this; - } - - public Draft setDemand(Map demand) { - return demand(demand); - } - - public List suppliers() { - return this.>get(supply::suppliers, List.class); - } - - public Draft suppliers(List suppliers) { - mutate(supply::suppliers, suppliers); - return this; - } - - public Draft setSuppliers(List suppliers) { - return suppliers(suppliers); - } - - public Set shipments() { - return this.>get(supply::shipments, Set.class); - } - - public Draft shipments(Set shipments) { - mutate(supply::shipments, shipments); - return this; - } - - public Draft setshipments(Set shipments) { - return shipments(shipments); - } + // Entity/Draft pattern-enabling methods: + Draft(String region) { + super(null); + // Primary Key: + set(supply::id, UUIDs.timeBased()); + set(supply::region, region); } + + Draft(Supply supply) { + super((MapExportable) supply); + } + + public Class getEntityClass() { + return Supply.class; + } + + // Immutable properties: + public UUID id() { + return this.get(supply::id, UUID.class); + } + + public String region() { + return this.get(supply::region, String.class); + } + + // Mutable properties: + public String code() { + return this.get(supply::code, String.class); + } + + public Draft code(String code) { + mutate(supply::code, code); + return this; + } + + public Draft setCode(String code) { + return code(code); + } + + public String description() { + return this.get(supply::description, String.class); + } + + public Draft description(String description) { + mutate(supply::description, description); + return this; + } + + public Draft setDescription(String description) { + return description(description); + } + + public Map demand() { + return this.>get(supply::demand, Map.class); + } + + public Draft demand(Map demand) { + mutate(supply::demand, demand); + return this; + } + + public Draft setDemand(Map demand) { + return demand(demand); + } + + public List suppliers() { + return this.>get(supply::suppliers, List.class); + } + + public Draft suppliers(List suppliers) { + mutate(supply::suppliers, suppliers); + return this; + } + + public Draft setSuppliers(List suppliers) { + return suppliers(suppliers); + } + + public Set shipments() { + return this.>get(supply::shipments, Set.class); + } + + public Draft shipments(Set shipments) { + mutate(supply::shipments, shipments); + return this; + } + + public Draft setshipments(Set shipments) { + return shipments(shipments); + } + } } diff --git a/src/test/java/net/helenus/test/integration/core/hierarchy/HierarchyTest.java b/src/test/java/net/helenus/test/integration/core/hierarchy/HierarchyTest.java index 0aaeceb..dce32b3 100644 --- a/src/test/java/net/helenus/test/integration/core/hierarchy/HierarchyTest.java +++ b/src/test/java/net/helenus/test/integration/core/hierarchy/HierarchyTest.java @@ -65,7 +65,8 @@ public class HierarchyTest extends AbstractEmbeddedCassandraTest { .value(cat::nickname, "garfield") .value(cat::eatable, false) .sync(); - Optional animal = session.select(Cat.class).where(cat::nickname, eq("garfield")).single().sync(); + Optional animal = + session.select(Cat.class).where(cat::nickname, eq("garfield")).single().sync(); Assert.assertTrue(animal.isPresent()); Cat cat = animal.get(); diff --git a/src/test/java/net/helenus/test/integration/core/hierarchy/Mammal.java b/src/test/java/net/helenus/test/integration/core/hierarchy/Mammal.java index 203ea66..950287a 100644 --- a/src/test/java/net/helenus/test/integration/core/hierarchy/Mammal.java +++ b/src/test/java/net/helenus/test/integration/core/hierarchy/Mammal.java @@ -20,6 +20,7 @@ import net.helenus.mapping.annotation.InheritedTable; @InheritedTable public interface Mammal extends Animal { - default boolean warmBlodded() { return true; } - + default boolean warmBlodded() { + return true; + } } diff --git a/src/test/java/net/helenus/test/integration/core/simple/SimpleUserTest.java b/src/test/java/net/helenus/test/integration/core/simple/SimpleUserTest.java index 9773ad1..da7997d 100644 --- a/src/test/java/net/helenus/test/integration/core/simple/SimpleUserTest.java +++ b/src/test/java/net/helenus/test/integration/core/simple/SimpleUserTest.java @@ -18,21 +18,17 @@ package net.helenus.test.integration.core.simple; import static net.helenus.core.Query.eq; import com.datastax.driver.core.ResultSet; +import java.util.*; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.Operator; import net.helenus.core.operation.UpdateOperation; -import net.helenus.core.reflect.Drafted; -import net.helenus.mapping.HelenusEntity; import net.helenus.support.Fun; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import java.util.*; - - public class SimpleUserTest extends AbstractEmbeddedCassandraTest { static User user; @@ -102,11 +98,7 @@ public class SimpleUserTest extends AbstractEmbeddedCassandraTest { // select as object - actual = session.select(user) - .where(user::id, eq(100L)) - .single() - .sync() - .orElse(null); + actual = session.select(user).where(user::id, eq(100L)).single().sync().orElse(null); assertUsers(newUser, actual); // select by columns @@ -192,11 +184,7 @@ public class SimpleUserTest extends AbstractEmbeddedCassandraTest { Assert.assertEquals("_albert", name); - User u2 = session.select(user) - .where(user::id, eq(100L)) - .single() - .sync() - .orElse(null); + User u2 = session.select(user).where(user::id, eq(100L)).single().sync().orElse(null); Assert.assertEquals(Long.valueOf(100L), u2.id()); Assert.assertEquals("albert", u2.name()); @@ -204,31 +192,27 @@ public class SimpleUserTest extends AbstractEmbeddedCassandraTest { // User greg = - session - .insert(user) - .value(user::name, "greg") - .value(user::age, 44) - .value(user::type, UserType.USER) - .value(user::id, 1234L) - .sync(); + session + .insert(user) + .value(user::name, "greg") + .value(user::age, 44) + .value(user::type, UserType.USER) + .value(user::id, 1234L) + .sync(); Optional maybeGreg = - session - .select(user) - .where(user::id, eq(1234L)) - .single() - .sync(); + session.select(user).where(user::id, eq(1234L)).single().sync(); // INSERT session - .update() - .set(user::name, null) - .set(user::age, null) - .set(user::type, null) - .where(user::id, eq(100L)) - .zipkinContext(null) - .sync(); + .update() + .set(user::name, null) + .set(user::age, null) + .set(user::type, null) + .where(user::id, eq(100L)) + .zipkinContext(null) + .sync(); Fun.Tuple3 tuple = session @@ -252,21 +236,16 @@ public class SimpleUserTest extends AbstractEmbeddedCassandraTest { public void testZipkin() throws Exception { session - .update() - .set(user::name, null) - .set(user::age, null) - .set(user::type, null) - .where(user::id, eq(100L)) - .zipkinContext(null) - .sync(); - + .update() + .set(user::name, null) + .set(user::age, null) + .set(user::type, null) + .where(user::id, eq(100L)) + .zipkinContext(null) + .sync(); UpdateOperation update = session.update(); - update - .set(user::name, null) - .zipkinContext(null) - .sync(); - + update.set(user::name, null).zipkinContext(null).sync(); } private void assertUsers(User expected, User actual) { diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleMapTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleMapTest.java index 143e4f0..a77276d 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleMapTest.java @@ -42,11 +42,8 @@ public class TupleMapTest extends TupleCollectionTest { // read full object - Book actual = session.select(book) - .where(book::id, Query.eq(id)) - .single() - .sync() - .orElse(null); + Book actual = + session.select(book).where(book::id, Query.eq(id)).single().sync().orElse(null); Assert.assertEquals(id, actual.id()); assertEqualMaps(writers, actual.writers()); Assert.assertNull(actual.reviewers()); @@ -77,11 +74,7 @@ public class TupleMapTest extends TupleCollectionTest { session.update().set(book::writers, expected).where(book::id, Query.eq(id)).sync(); - actual = session.select(book) - .where(book::id, Query.eq(id)) - .single() - .sync() - .orElse(null); + actual = session.select(book).where(book::id, Query.eq(id)).single().sync().orElse(null); Assert.assertEquals(id, actual.id()); assertEqualMaps(expected, actual.writers()); @@ -96,7 +89,8 @@ public class TupleMapTest extends TupleCollectionTest { expected.put(third, unk); session.update().put(book::writers, third, unk).where(book::id, Query.eq(id)).sync(); - actualMap = session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; + actualMap = + session.select(book::writers).where(book::id, Query.eq(id)).sync().findFirst().get()._1; assertEqualMaps(expected, actualMap); // putAll operation diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/AndThenOrderTest.java b/src/test/java/net/helenus/test/integration/core/unitofwork/AndThenOrderTest.java index 37ba96a..2b3ebcd 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/AndThenOrderTest.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/AndThenOrderTest.java @@ -15,6 +15,9 @@ */ package net.helenus.test.integration.core.unitofwork; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.UnitOfWork; @@ -23,102 +26,125 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - - public class AndThenOrderTest extends AbstractEmbeddedCassandraTest { - static HelenusSession session; + static HelenusSession session; - @BeforeClass - public static void beforeTest() { - session = Helenus.init(getSession()) - .showCql() - .autoCreateDrop() - .get(); - } + @BeforeClass + public static void beforeTest() { + session = Helenus.init(getSession()).showCql().autoCreateDrop().get(); + } - @Test - public void testAndThenOrdering() throws Exception { - List q = new ArrayList(5); - UnitOfWork uow1, uow2, uow3, uow4, uow5; + @Test + public void testAndThenOrdering() throws Exception { + List q = new ArrayList(5); + UnitOfWork uow1, uow2, uow3, uow4, uow5; - uow5 = session.begin(); - uow3 = session.begin(uow5); - uow1 = session.begin(uow3); - uow1.commit().andThen(() -> { q.add("1"); }); - uow2 = session.begin(uow3); - uow2.commit().andThen(() -> { q.add("2"); }); - uow3.commit().andThen(() -> { q.add("3"); }); - uow4 = session.begin(uow5); - uow4.commit().andThen(() -> { q.add("4"); }); - uow5.commit().andThen(() -> { q.add("5"); }); + uow5 = session.begin(); + uow3 = session.begin(uow5); + uow1 = session.begin(uow3); + uow1.commit() + .andThen( + () -> { + q.add("1"); + }); + uow2 = session.begin(uow3); + uow2.commit() + .andThen( + () -> { + q.add("2"); + }); + uow3.commit() + .andThen( + () -> { + q.add("3"); + }); + uow4 = session.begin(uow5); + uow4.commit() + .andThen( + () -> { + q.add("4"); + }); + uow5.commit() + .andThen( + () -> { + q.add("5"); + }); - System.out.println(q); - Assert.assertTrue(Arrays.equals(q.toArray(new String[5]), new String[] {"1", "2", "3", "4", "5"})); + System.out.println(q); + Assert.assertTrue( + Arrays.equals(q.toArray(new String[5]), new String[] {"1", "2", "3", "4", "5"})); + } - } + @Test + public void testExceptionWithinAndThen() throws Exception { + List q = new ArrayList(5); + UnitOfWork uow1, uow2, uow3, uow4, uow5; - @Test - public void testExceptionWithinAndThen() throws Exception { - List q = new ArrayList(5); - UnitOfWork uow1, uow2, uow3, uow4, uow5; - - uow5 = session.begin(); - uow4 = session.begin(uow5); - try { - uow3 = session.begin(uow4); - uow1 = session.begin(uow3); - uow1.commit().andThen(() -> { + uow5 = session.begin(); + uow4 = session.begin(uow5); + try { + uow3 = session.begin(uow4); + uow1 = session.begin(uow3); + uow1.commit() + .andThen( + () -> { q.add("1"); - }); - uow2 = session.begin(uow3); - uow2.commit().andThen(() -> { + }); + uow2 = session.begin(uow3); + uow2.commit() + .andThen( + () -> { q.add("2"); - }); - uow3.commit().andThen(() -> { + }); + uow3.commit() + .andThen( + () -> { q.add("3"); - }); - uow4.commit().andThen(() -> { + }); + uow4.commit() + .andThen( + () -> { q.add("4"); + }); + throw new Exception(); + } catch (Exception e) { + uow4.abort(); + } + uow5.commit() + .andThen( + () -> { + q.add("5"); }); - throw new Exception(); - } catch(Exception e) { - uow4.abort(); - } - uow5.commit().andThen(() -> { q.add("5"); }); - System.out.println(q); - Assert.assertTrue(q.isEmpty() == true); + System.out.println(q); + Assert.assertTrue(q.isEmpty() == true); + } + @Test + public void testClosableWillAbortWhenNotCommitted() throws Exception { + UnitOfWork unitOfWork; + try (UnitOfWork uow = session.begin()) { + unitOfWork = uow; + Assert.assertFalse(uow.hasAborted()); } + Assert.assertTrue(unitOfWork.hasAborted()); + } - @Test - public void testClosableWillAbortWhenNotCommitted() throws Exception { - UnitOfWork unitOfWork; - try(UnitOfWork uow = session.begin()) { - unitOfWork = uow; - Assert.assertFalse(uow.hasAborted()); - } - Assert.assertTrue(unitOfWork.hasAborted()); - - } - - @Test - public void testClosable() throws Exception { - UnitOfWork unitOfWork; - try(UnitOfWork uow = session.begin()) { - unitOfWork = uow; - Assert.assertFalse(uow.hasAborted()); - uow.commit().andThen(() -> { + @Test + public void testClosable() throws Exception { + UnitOfWork unitOfWork; + try (UnitOfWork uow = session.begin()) { + unitOfWork = uow; + Assert.assertFalse(uow.hasAborted()); + uow.commit() + .andThen( + () -> { Assert.assertFalse(uow.hasAborted()); Assert.assertTrue(uow.hasCommitted()); - }); - } - Assert.assertFalse(unitOfWork.hasAborted()); - Assert.assertTrue(unitOfWork.hasCommitted()); + }); } - + Assert.assertFalse(unitOfWork.hasAborted()); + Assert.assertTrue(unitOfWork.hasCommitted()); + } } diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/Directory.java b/src/test/java/net/helenus/test/integration/core/unitofwork/Directory.java index 4984d9d..70cf9e9 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/Directory.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/Directory.java @@ -15,16 +15,13 @@ */ package net.helenus.test.integration.core.unitofwork; -import net.helenus.mapping.annotation.*; - import com.datastax.driver.core.DataType.Name; import java.util.Set; - +import net.helenus.mapping.annotation.*; @UDT public interface Directory extends FilesystemNode { - @Types.Set(Name.TIMEUUID) - Set inodes(); - + @Types.Set(Name.TIMEUUID) + Set inodes(); } diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/File.java b/src/test/java/net/helenus/test/integration/core/unitofwork/File.java index 4e8ff6f..a0ccebd 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/File.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/File.java @@ -17,11 +17,9 @@ package net.helenus.test.integration.core.unitofwork; import net.helenus.mapping.annotation.*; - @UDT public interface File extends FilesystemNode { - @Column - byte[] data(); - + @Column + byte[] data(); } diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/FileAttributes.java b/src/test/java/net/helenus/test/integration/core/unitofwork/FileAttributes.java index 6d2db6d..f2eaccc 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/FileAttributes.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/FileAttributes.java @@ -20,6 +20,5 @@ import net.helenus.mapping.annotation.UDT; @UDT public interface FileAttributes { - String owner(); - + String owner(); } diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/FilesystemNode.java b/src/test/java/net/helenus/test/integration/core/unitofwork/FilesystemNode.java index a57f296..7907fbd 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/FilesystemNode.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/FilesystemNode.java @@ -15,20 +15,18 @@ */ package net.helenus.test.integration.core.unitofwork; -import net.helenus.mapping.annotation.*; - import java.util.UUID; +import net.helenus.mapping.annotation.*; @Table("fs") public interface FilesystemNode { - @PartitionKey - UUID inode(); + @PartitionKey + UUID inode(); - @ClusteringColumn - String name(); - - @Column - FileAttributes attr(); + @ClusteringColumn + String name(); + @Column + FileAttributes attr(); } diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java b/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java index 762c668..4e45fff 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java @@ -15,7 +15,10 @@ */ package net.helenus.test.integration.core.unitofwork; +import static net.helenus.core.Query.eq; + import com.datastax.driver.core.utils.UUIDs; +import java.util.UUID; import net.bytebuddy.utility.RandomString; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; @@ -29,167 +32,161 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import java.util.UUID; - -import static net.helenus.core.Query.eq; - - @Table @Cacheable interface Widget { - @PartitionKey - UUID id(); - @Column - String name(); -} + @PartitionKey + UUID id(); + @Column + String name(); +} public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest { - static Widget widget; - static HelenusSession session; + static Widget widget; + static HelenusSession session; + @BeforeClass + public static void beforeTest() { + session = Helenus.init(getSession()).showCql().add(Widget.class).autoCreateDrop().get(); + widget = session.dsl(Widget.class); + } - @BeforeClass - public static void beforeTest() { - session = Helenus.init(getSession()) - .showCql() - .add(Widget.class) - .autoCreateDrop() - .get(); - widget = session.dsl(Widget.class); - } + @Test + public void testSelectAfterSelect() throws Exception { + Widget w1, w2; + UUID key = UUIDs.timeBased(); - @Test - public void testSelectAfterSelect() throws Exception { - Widget w1, w2; - UUID key = UUIDs.timeBased(); + // This should inserted Widget, but not cache it. + session + .insert(widget) + .value(widget::id, key) + .value(widget::name, RandomString.make(20)) + .sync(); - // This should inserted Widget, but not cache it. - session.insert(widget) - .value(widget::id, key) - .value(widget::name, RandomString.make(20)) - .sync(); + try (UnitOfWork uow = session.begin()) { - try (UnitOfWork uow = session.begin()) { + // This should read from the database and return a Widget. + w1 = + session.select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null); - // This should read from the database and return a Widget. - w1 = session.select(widget) - .where(widget::id, eq(key)) - .single() - .sync(uow) - .orElse(null); - - // This should read from the cache and get the same instance of a Widget. - w2 = session.select(widget) - .where(widget::id, eq(key)) - .single() - .sync(uow) - .orElse(null); - - uow.commit() - .andThen(() -> { - Assert.assertEquals(w1, w2); - }); - } - - } - - @Test - public void testSelectAfterNestedSelect() throws Exception { - Widget w1, w2, w3, w4; - UUID key1 = UUIDs.timeBased(); - UUID key2 = UUIDs.timeBased(); - - // This should inserted Widget, and not cache it in uow1. - try (UnitOfWork uow1 = session.begin()) { - w1 = session.insert(widget) - .value(widget::id, key1) - .value(widget::name, RandomString.make(20)) - .sync(uow1); - - try (UnitOfWork uow2 = session.begin(uow1)) { - - // This should read from uow1's cache and return the same Widget. - w2 = session.select(widget) - .where(widget::id, eq(key1)) - .single() - .sync(uow2) - .orElse(null); + // This should read from the cache and get the same instance of a Widget. + w2 = + session.select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null); + uow.commit() + .andThen( + () -> { Assert.assertEquals(w1, w2); - - w3 = session.insert(widget) - .value(widget::id, key2) - .value(widget::name, RandomString.make(20)) - .sync(uow2); - - uow2.commit() - .andThen(() -> { - Assert.assertEquals(w1, w2); - }); - } - - // This should read from the cache and get the same instance of a Widget. - w4 = session.select(widget) - .where(widget::id, eq(key2)) - .single() - .sync(uow1) - .orElse(null); - - uow1.commit() - .andThen(() -> { - Assert.assertEquals(w3, w4); - }); - } - + }); } -/* - @Test - public void testSelectAfterInsertProperlyCachesEntity() throws Exception { - Widget w1, w2, w3, w4; - UUID key = UUIDs.timeBased(); + } - try (UnitOfWork uow = session.begin()) { + @Test + public void testSelectAfterNestedSelect() throws Exception { + Widget w1, w2, w3, w4; + UUID key1 = UUIDs.timeBased(); + UUID key2 = UUIDs.timeBased(); - // This should cache the inserted Widget. - w1 = session.insert(widget) - .value(widget::id, key) - .value(widget::name, RandomString.make(20)) - .sync(uow); + // This should inserted Widget, and not cache it in uow1. + try (UnitOfWork uow1 = session.begin()) { + w1 = + session + .insert(widget) + .value(widget::id, key1) + .value(widget::name, RandomString.make(20)) + .sync(uow1); - // This should read from the cache and get the same instance of a Widget. - w2 = session.select(widget) - .where(widget::id, eq(key)) - .single() - .sync(uow) - .orElse(null); + try (UnitOfWork uow2 = session.begin(uow1)) { - uow.commit() - .andThen(() -> { - Assert.assertEquals(w1, w2); - }); - } - - // This should read the widget from the session cache and maintain object identity. - w3 = session.select(widget) - .where(widget::id, eq(key)) + // This should read from uow1's cache and return the same Widget. + w2 = + session + .select(widget) + .where(widget::id, eq(key1)) .single() - .sync() + .sync(uow2) .orElse(null); - Assert.assertEquals(w1, w3); + Assert.assertEquals(w1, w2); - // This should read the widget from the database, no object identity but values should match. - w4 = session.select(widget) - .where(widget::id, eq(key)) - .ignoreCache() - .single() - .sync() - .orElse(null); + w3 = + session + .insert(widget) + .value(widget::id, key2) + .value(widget::name, RandomString.make(20)) + .sync(uow2); - Assert.assertNotEquals(w1, w4); - Assert.assertTrue(w1.equals(w4)); + uow2.commit() + .andThen( + () -> { + Assert.assertEquals(w1, w2); + }); + } + + // This should read from the cache and get the same instance of a Widget. + w4 = + session + .select(widget) + .where(widget::id, eq(key2)) + .single() + .sync(uow1) + .orElse(null); + + uow1.commit() + .andThen( + () -> { + Assert.assertEquals(w3, w4); + }); } -*/ + } + /* + @Test + public void testSelectAfterInsertProperlyCachesEntity() throws Exception { + Widget w1, w2, w3, w4; + UUID key = UUIDs.timeBased(); + + try (UnitOfWork uow = session.begin()) { + + // This should cache the inserted Widget. + w1 = session.insert(widget) + .value(widget::id, key) + .value(widget::name, RandomString.make(20)) + .sync(uow); + + // This should read from the cache and get the same instance of a Widget. + w2 = session.select(widget) + .where(widget::id, eq(key)) + .single() + .sync(uow) + .orElse(null); + + uow.commit() + .andThen(() -> { + Assert.assertEquals(w1, w2); + }); + } + + // This should read the widget from the session cache and maintain object identity. + w3 = session.select(widget) + .where(widget::id, eq(key)) + .single() + .sync() + .orElse(null); + + Assert.assertEquals(w1, w3); + + // This should read the widget from the database, no object identity but values should match. + w4 = session.select(widget) + .where(widget::id, eq(key)) + .ignoreCache() + .single() + .sync() + .orElse(null); + + Assert.assertNotEquals(w1, w4); + Assert.assertTrue(w1.equals(w4)); + } + */ } diff --git a/src/test/java/net/helenus/test/unit/core/dsl/Account.java b/src/test/java/net/helenus/test/unit/core/dsl/Account.java index 2725f16..10fc9fd 100644 --- a/src/test/java/net/helenus/test/unit/core/dsl/Account.java +++ b/src/test/java/net/helenus/test/unit/core/dsl/Account.java @@ -19,7 +19,6 @@ import java.util.Date; import java.util.Map; import java.util.Set; import net.helenus.core.reflect.Drafted; -import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.annotation.*; @Table From 896748a2eca13cc3caa1f83e6dc925f7005b87e0 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Fri, 13 Oct 2017 10:41:21 -0400 Subject: [PATCH 5/9] Formatting. --- .../driver/core/schemabuilder/CreateMaterializedView.java | 8 ++++++-- src/main/java/net/helenus/core/CommitThunk.java | 1 - src/main/java/net/helenus/core/SchemaUtil.java | 8 ++++---- src/main/java/net/helenus/core/UnitOfWork.java | 1 - .../java/net/helenus/core/operation/SelectOperation.java | 2 -- src/main/java/net/helenus/core/reflect/Drafted.java | 1 - .../integration/core/draft/EntityDraftBuilderTest.java | 1 - .../test/integration/core/views/CyclistsByAge.java | 1 - .../test/integration/core/views/MaterializedViewTest.java | 6 +----- 9 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/datastax/driver/core/schemabuilder/CreateMaterializedView.java b/src/main/java/com/datastax/driver/core/schemabuilder/CreateMaterializedView.java index 919becc..d6ba093 100644 --- a/src/main/java/com/datastax/driver/core/schemabuilder/CreateMaterializedView.java +++ b/src/main/java/com/datastax/driver/core/schemabuilder/CreateMaterializedView.java @@ -11,7 +11,11 @@ public class CreateMaterializedView extends Create { private String clustering; public CreateMaterializedView( - String keyspaceName, String viewName, Select.Where selection, String primaryKey, String clustering) { + String keyspaceName, + String viewName, + Select.Where selection, + String primaryKey, + String clustering) { super(keyspaceName, viewName); this.viewName = viewName; this.selection = selection; @@ -40,7 +44,7 @@ public class CreateMaterializedView extends Create { createStatement.append(" "); createStatement.append(primaryKey); if (clustering != null) { - createStatement.append(" ").append(clustering); + createStatement.append(" ").append(clustering); } createStatement.append(";"); diff --git a/src/main/java/net/helenus/core/CommitThunk.java b/src/main/java/net/helenus/core/CommitThunk.java index ff50f4a..1ad9e05 100644 --- a/src/main/java/net/helenus/core/CommitThunk.java +++ b/src/main/java/net/helenus/core/CommitThunk.java @@ -1,6 +1,5 @@ package net.helenus.core; - @FunctionalInterface public interface CommitThunk { void apply(); diff --git a/src/main/java/net/helenus/core/SchemaUtil.java b/src/main/java/net/helenus/core/SchemaUtil.java index 5e33b3d..02fb929 100644 --- a/src/main/java/net/helenus/core/SchemaUtil.java +++ b/src/main/java/net/helenus/core/SchemaUtil.java @@ -32,7 +32,6 @@ import net.helenus.mapping.type.OptionalColumnMetadata; import net.helenus.support.CqlUtil; import net.helenus.support.HelenusMappingException; - public final class SchemaUtil { private SchemaUtil() {} @@ -191,7 +190,8 @@ public final class SchemaUtil { c.add(columnName); where = where.and(new IsNotNullClause(columnName)); - ClusteringColumn clusteringColumn = prop.getProperty().getGetterMethod().getAnnotation(ClusteringColumn.class); + ClusteringColumn clusteringColumn = + prop.getProperty().getGetterMethod().getAnnotation(ClusteringColumn.class); if (clusteringColumn != null && clusteringColumn.ordering() != null) { o.add(columnName + " " + clusteringColumn.ordering().cql()); } @@ -211,10 +211,10 @@ public final class SchemaUtil { String clustering = ""; if (o.size() > 0) { - clustering = "WITH CLUSTERING ORDER BY (" + String.join(", ", o) + ")"; + clustering = "WITH CLUSTERING ORDER BY (" + String.join(", ", o) + ")"; } return new CreateMaterializedView(keyspace, viewName, where, primaryKey, clustering) - .ifNotExists(); + .ifNotExists(); } public static SchemaStatement dropMaterializedView( diff --git a/src/main/java/net/helenus/core/UnitOfWork.java b/src/main/java/net/helenus/core/UnitOfWork.java index f27b76c..6bc630a 100644 --- a/src/main/java/net/helenus/core/UnitOfWork.java +++ b/src/main/java/net/helenus/core/UnitOfWork.java @@ -15,7 +15,6 @@ */ package net.helenus.core; - import java.util.Map; import java.util.Set; diff --git a/src/main/java/net/helenus/core/operation/SelectOperation.java b/src/main/java/net/helenus/core/operation/SelectOperation.java index cfc54f2..ea23ca5 100644 --- a/src/main/java/net/helenus/core/operation/SelectOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectOperation.java @@ -22,8 +22,6 @@ import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Select; import com.datastax.driver.core.querybuilder.Select.Selection; import com.datastax.driver.core.querybuilder.Select.Where; -import com.google.common.base.Joiner; -import com.google.common.collect.Iterables; import java.util.*; import java.util.function.Function; import java.util.stream.Stream; diff --git a/src/main/java/net/helenus/core/reflect/Drafted.java b/src/main/java/net/helenus/core/reflect/Drafted.java index ac134d2..b0a187d 100644 --- a/src/main/java/net/helenus/core/reflect/Drafted.java +++ b/src/main/java/net/helenus/core/reflect/Drafted.java @@ -1,6 +1,5 @@ package net.helenus.core.reflect; - import java.util.Set; public interface Drafted extends MapExportable { diff --git a/src/test/java/net/helenus/test/integration/core/draft/EntityDraftBuilderTest.java b/src/test/java/net/helenus/test/integration/core/draft/EntityDraftBuilderTest.java index 3296488..64f9c7b 100644 --- a/src/test/java/net/helenus/test/integration/core/draft/EntityDraftBuilderTest.java +++ b/src/test/java/net/helenus/test/integration/core/draft/EntityDraftBuilderTest.java @@ -25,7 +25,6 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; - public class EntityDraftBuilderTest extends AbstractEmbeddedCassandraTest { static Supply supply; diff --git a/src/test/java/net/helenus/test/integration/core/views/CyclistsByAge.java b/src/test/java/net/helenus/test/integration/core/views/CyclistsByAge.java index 02b414c..555155f 100644 --- a/src/test/java/net/helenus/test/integration/core/views/CyclistsByAge.java +++ b/src/test/java/net/helenus/test/integration/core/views/CyclistsByAge.java @@ -2,7 +2,6 @@ package net.helenus.test.integration.core.views; import java.util.Date; import java.util.UUID; - import net.helenus.mapping.OrderingDirection; import net.helenus.mapping.annotation.*; diff --git a/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java b/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java index 41c8eff..a580062 100644 --- a/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java +++ b/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java @@ -68,10 +68,6 @@ public class MaterializedViewTest extends AbstractEmbeddedCassandraTest { @Test public void testMv() throws Exception { - session - .select(Cyclist.class) - .from(CyclistsByAge.class) - .where(cyclist::age, eq(18)) - .sync(); + session.select(Cyclist.class).from(CyclistsByAge.class).where(cyclist::age, eq(18)).sync(); } } From f64d5edd7c2d93ed8269c252443b1ece2d901835 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Wed, 18 Oct 2017 12:17:00 -0400 Subject: [PATCH 6/9] wip: good progress toward new multi-key index for cache --- build.gradle | 2 +- helenus-core.iml | 1 + pom.xml | 6 + .../net/helenus/core/AbstractUnitOfWork.java | 113 +++- .../java/net/helenus/core/UnitOfWork.java | 22 +- .../core/cache/EntityIdentifyingFacet.java | 18 + .../AbstractFilterStreamOperation.java | 4 +- .../operation/AbstractOptionalOperation.java | 229 +++---- .../operation/AbstractStatementOperation.java | 576 ++++++++++-------- .../operation/AbstractStreamOperation.java | 54 +- .../core/operation/BoundStreamOperation.java | 10 +- .../core/operation/InsertOperation.java | 13 +- .../net/helenus/core/operation/Operation.java | 8 +- .../core/operation/SelectFirstOperation.java | 10 +- .../SelectFirstTransformingOperation.java | 10 +- .../core/operation/SelectOperation.java | 32 +- .../SelectTransformingOperation.java | 10 +- .../core/operation/UpdateOperation.java | 8 +- .../net/helenus/mapping/HelenusEntity.java | 2 +- .../helenus/mapping/HelenusMappingEntity.java | 10 +- 20 files changed, 633 insertions(+), 505 deletions(-) diff --git a/build.gradle b/build.gradle index 1c1b7de..c18e085 100644 --- a/build.gradle +++ b/build.gradle @@ -64,7 +64,7 @@ dependencies { compile group: 'org.aspectj', name: 'aspectjweaver', version: '1.8.10' compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.6' compile group: 'org.springframework', name: 'spring-core', version: '4.3.10.RELEASE' - + compile group: 'org.ahocorasick', name: 'ahocorasick', version: '0.4.0' compile group: 'com.google.guava', name: 'guava', version: '20.0' compile group: 'com.diffplug.durian', name: 'durian', version: '3.+' compile group: 'io.zipkin.java', name: 'zipkin', version: '1.29.2' diff --git a/helenus-core.iml b/helenus-core.iml index be96637..1f3247f 100644 --- a/helenus-core.iml +++ b/helenus-core.iml @@ -35,6 +35,7 @@ + diff --git a/pom.xml b/pom.xml index 71feca8..8e4391b 100644 --- a/pom.xml +++ b/pom.xml @@ -148,6 +148,12 @@ 20.0 + + org.ahocorasick + ahocorasick + 0.4.0 + + io.zipkin.java diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index c621770..3d505dd 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -17,15 +17,22 @@ package net.helenus.core; import com.diffplug.common.base.Errors; import com.google.common.collect.TreeTraverser; +import net.helenus.core.cache.EntityIdentifyingFacet; +import net.helenus.support.Either; +import org.ahocorasick.trie.Emit; +import org.ahocorasick.trie.Trie; + import java.util.*; +import java.util.stream.Collectors; /** Encapsulates the concept of a "transaction" as a unit-of-work. */ -public abstract class AbstractUnitOfWork implements UnitOfWork, AutoCloseable { +public abstract class AbstractUnitOfWork implements UnitOfWork, AutoCloseable { private final List> nested = new ArrayList<>(); private final HelenusSession session; private final AbstractUnitOfWork parent; private List postCommit = new ArrayList(); - private final Map> cache = new HashMap>(); + private final Map>> cache = new HashMap>>(); + private Trie cacheIndex = Trie.builder().ignoreOverlaps().onlyWholeWordsWhiteSpaceSeparated().build(); private boolean aborted = false; private boolean committed = false; @@ -36,14 +43,15 @@ public abstract class AbstractUnitOfWork implements UnitOfW this.parent = parent; } - public UnitOfWork addNestedUnitOfWork(UnitOfWork uow) { + @Override + public void addNestedUnitOfWork(UnitOfWork uow) { synchronized (nested) { nested.add((AbstractUnitOfWork) uow); } - return this; } - public UnitOfWork begin() { + @Override + public UnitOfWork begin() { // log.record(txn::start) return this; } @@ -56,20 +64,49 @@ public abstract class AbstractUnitOfWork implements UnitOfW } } - public Set cacheLookup(String key) { - Set r = getCache().get(key); - if (r != null) { - return r; - } else { - if (parent != null) { - return parent.cacheLookup(key); + @Override + public Optional>> cacheLookupByFacet(Set facets) { + Optional>> result = null; + Collection emits = cacheIndex.parseText(String.join(" ", facets.stream() + .map(facet -> facet.toString()).collect(Collectors.toList()))); + for (Emit emit : emits) { + // NOTE: rethink. should this match *all* facets? how do I know which emit keyword is the primary key? + String key = emit.getKeyword(); + result = cacheLookup(key); } - } - return null; + return result; } - public Map> getCache() { - return cache; + @Override + public Optional>> cacheLookupByStatement(String[] statementKeys) { + Optional>> result = null; + String key = String.join(",", statementKeys); + return cacheLookup(key); + } + + @Override + public Optional>> cacheLookup(String key) { + Optional>> result = Optional.of(cache.get(key)); + + if (result.isPresent()) { + return result; + } else { + // Be sure to check all enclosing UnitOfWork caches as well, we may be nested. + if (parent != null) { + return parent.cacheLookup(key); + } + } + return Optional.empty(); + } + + @Override + public void cacheUpdate(Either> value, String[] statementKeys, Set facets) { + String key = String.join(",", statementKeys); + cache.put(key, value); + Trie.TrieBuilder builder = cacheIndex.builder(); + facets.forEach(facet -> { + builder.addKeyword(facet.toString()); + }); } private Iterator> getChildNodes() { @@ -108,18 +145,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW // Merge UOW cache into parent's cache. if (parent != null) { - Map> parentCache = parent.getCache(); - for (String key : cache.keySet()) { - if (parentCache.containsKey(key)) { - // merge the sets - Set ps = parentCache.get(key); - ps.addAll( - cache.get(key)); //TODO(gburd): review this, likely not correct in all cases as-is. - } else { - // add the missing set - parentCache.put(key, cache.get(key)); - } - } + parent.assumeCache(cache, cacheIndex); } // Apply all post-commit functions for @@ -155,6 +181,37 @@ public abstract class AbstractUnitOfWork implements UnitOfW // cache.invalidateSince(txn::start time) } + private void assumeCache(Map>> childCache, Trie childCacheIndex) { + for (String key : childCache.keySet()) { + if (cache.containsKey(key)) { + Either> value = cache.get(key); + if (value.isLeft()) { + Object obj = value.getLeft(); + // merge objects + Either> childValue = childCache.get(key); + if (childValue.isLeft()) { + Object childObj = childValue.getLeft(); + } else { + Set childSet = childValue.getRight(); + } + } else { + // merge the sets + Set set = value.getRight(); + Either> childValue = childCache.get(key); + if (childValue.isLeft()) { + Object childObj = childValue.getLeft(); + set.add(childObj); + } else { + Set childSet = childValue.getRight(); + set.addAll(childSet); + } + } + } else { + cache.put(key, childCache.get(key)); + } + } + } + public String describeConflicts() { return "it's complex..."; } diff --git a/src/main/java/net/helenus/core/UnitOfWork.java b/src/main/java/net/helenus/core/UnitOfWork.java index 6bc630a..da799fc 100644 --- a/src/main/java/net/helenus/core/UnitOfWork.java +++ b/src/main/java/net/helenus/core/UnitOfWork.java @@ -15,10 +15,13 @@ */ package net.helenus.core; -import java.util.Map; +import net.helenus.core.cache.EntityIdentifyingFacet; +import net.helenus.support.Either; + +import java.util.Optional; import java.util.Set; -public interface UnitOfWork extends AutoCloseable { +public interface UnitOfWork extends AutoCloseable { /** * Marks the beginning of a transactional section of work. Will write a record to the shared @@ -26,17 +29,17 @@ public interface UnitOfWork extends AutoCloseable { * * @return the handle used to commit or abort the work. */ - UnitOfWork begin(); + UnitOfWork begin(); - UnitOfWork addNestedUnitOfWork(UnitOfWork uow); + void addNestedUnitOfWork(UnitOfWork uow); /** * Checks to see if the work performed between calling begin and now can be committed or not. * * @return a function from which to chain work that only happens when commit is successful - * @throws E when the work overlaps with other concurrent writers. + * @throws X when the work overlaps with other concurrent writers. */ - PostCommitFunction commit() throws E; + PostCommitFunction commit() throws X; /** * Explicitly abort the work within this unit of work. Any nested aborted unit of work will @@ -48,8 +51,9 @@ public interface UnitOfWork extends AutoCloseable { boolean hasCommitted(); - //Either> cacheLookup(String key); - Set cacheLookup(String key); + Optional>> cacheLookup(String key); + Optional>> cacheLookupByFacet(Set facets); + Optional>> cacheLookupByStatement(String[] statementKeys); + void cacheUpdate(Either> pojo, String[] statementKeys, Set facets); - Map> getCache(); } diff --git a/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java b/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java index b4a7cf9..62b3849 100644 --- a/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java +++ b/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java @@ -2,9 +2,27 @@ package net.helenus.core.cache; import net.helenus.mapping.HelenusProperty; +import java.util.Set; + public class EntityIdentifyingFacet extends Facet { public EntityIdentifyingFacet(HelenusProperty prop) {} public EntityIdentifyingFacet(HelenusProperty[]... props) {} + + public boolean isFullyBound() { + return false; + } + + public HelenusProperty getProperty() { + return null; + } + + public Set getUnboundEntityProperties() { + return null; + } + + public void setValueForProperty(HelenusProperty prop, Object value) { + } + } diff --git a/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java b/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java index b78daf1..9a5bc8c 100644 --- a/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java @@ -22,9 +22,7 @@ import java.util.Map; import net.helenus.core.*; import net.helenus.mapping.HelenusProperty; -public abstract class AbstractFilterStreamOperation< - E, O extends AbstractFilterStreamOperation> - extends AbstractStreamOperation { +public abstract class AbstractFilterStreamOperation> extends AbstractStreamOperation { protected Map> filters = null; protected List> ifFilters = null; diff --git a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java index 349469a..e4b9302 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java @@ -21,164 +21,109 @@ import com.datastax.driver.core.ResultSet; import com.google.common.base.Function; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import java.util.HashSet; -import java.util.Map; +import net.helenus.core.AbstractSessionOperations; +import net.helenus.core.UnitOfWork; +import net.helenus.core.cache.EntityIdentifyingFacet; + import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.TimeoutException; -import net.helenus.core.AbstractSessionOperations; -import net.helenus.core.Filter; -import net.helenus.core.Helenus; -import net.helenus.core.UnitOfWork; -import net.helenus.core.cache.EntityIdentifyingFacet; -import net.helenus.mapping.HelenusEntity; -import net.helenus.mapping.HelenusProperty; -import net.helenus.mapping.value.BeanColumnValueProvider; -import net.helenus.support.Either; - -import javax.swing.text.html.parser.Entity; - public abstract class AbstractOptionalOperation> - extends AbstractStatementOperation { + extends AbstractStatementOperation { - public AbstractOptionalOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } - - public abstract Optional transform(ResultSet resultSet); - - public PreparedOptionalOperation prepare() { - return new PreparedOptionalOperation(prepareStatement(), this); - } - - public ListenableFuture> prepareAsync() { - final O _this = (O) this; - return Futures.transform( - prepareStatementAsync(), - new Function>() { - @Override - public PreparedOptionalOperation apply(PreparedStatement preparedStatement) { - return new PreparedOptionalOperation(preparedStatement, _this); - } - }); - } - - public Optional sync() throws TimeoutException { - final Timer.Context context = requestLatency.time(); - try { - ResultSet resultSet = this.execute(sessionOps, null, traceContext, queryExecutionTimeout, queryTimeoutUnits, showValues, false); - return transform(resultSet); - } finally { - context.stop(); + public AbstractOptionalOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); } - } - public Optional sync(UnitOfWork uow) throws TimeoutException { - if (uow == null) return sync(); + public abstract Optional transform(ResultSet resultSet); - final Timer.Context context = requestLatency.time(); - try { + public PreparedOptionalOperation prepare() { + return new PreparedOptionalOperation(prepareStatement(), this); + } - Optional result = null; - String stmtKey = null; - if (enableCache) { - Set facets = getIdentifyingFacets(); - if (!facets.isEmpty()) { - for (EntityIdentifyingFacet facet : facets) { - //TODO(gburd): what about select ResultSet, Tuple... etc.? - Optional, E>> optionalCachedResult = uow.cacheLookup(facet.hashCode()); - if (optionalCachedResult.isPresent()) { - uowCacheHits.mark(); - logger.info("UnitOfWork({}) cache hit for facet: {} with key: {}", uow.hashCode(), facet.toString(), facet.hashCode()); - Either, E> eitherCachedResult = optionalCachedResult.get(); - if (eitherCachedResult.isRight()) { - E cachedResult = eitherCachedResult.getRight(); - result = Optional.of(cachedResult); - } - break; - } - } - } else { - // The operation didn't provide enough information to uniquely identify the entity object - // using one of the facets, but that doesn't mean a filtering query won't return a proper - // result. Look in the cache to see if this statement has been executed before. - stmtKey = getStatementCacheKey(); - Optional, E>> optionalCachedResult = uow.cacheLookup(stmtKey.hashCode()); - if (optionalCachedResult.isPresent()) { - Either, E> eitherCachedResult = optionalCachedResult.get(); - if (eitherCachedResult.isLeft()) { - Set cachedResult = eitherCachedResult.getLeft(); - // Ensure that this non-indexed selection uniquely identified an Entity. - if (!(cachedResult.isEmpty() || cachedResult.size() > 1)) { - uowCacheHits.mark(); - logger.info("UnitOfWork({}) cache hit for stmt {} {}", uow.hashCode(), stmtKey, - stmtKey.hashCode()); - result = cachedResult.stream().findFirst(); - } - } - } - } - - if (result == null) { - ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits, showValues, true); - result = transform(resultSet); - - if (enableCache && result.isPresent()) { - // If we executed a query that didn't depend on an we have a stmtKey for the filters, add that to the cache. - if (stmtKey != null) { - Set set = new HashSet(1); - set.add(result.get()); - uow.getCache().put(stmtKey.hashCode(), set); - } - // Now insert this entity into the cache for each facet for this entity that we can fully bind. - E entity = result.get(); - Map facetMap = Helenus.entity(result.get().getClass()).getIdentityFacets(); - facetMap.forEach((facetName, facet) -> { - EntityIdentifyingFacet boundFacet = null; - if (!facet.isFullyBound()) { - boundFacet = new EntityIdentifyingFacet(facet); - for (HelenusProperty prop : facet.getUnboundEntityProperties()) { - Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(entity, -1, prop); - if (value == null) { break; } - boundFacet.setValueForProperty(prop, value); + public ListenableFuture> prepareAsync() { + final O _this = (O) this; + return Futures.transform( + prepareStatementAsync(), + new Function>() { + @Override + public PreparedOptionalOperation apply(PreparedStatement preparedStatement) { + return new PreparedOptionalOperation(preparedStatement, _this); } - } - if (boundFacet != null && boundFacet.isFullyBound()) { - uow.getCache().put(boundFacet.hashCode(), Either) - } - }); - Set set = new HashSet(1); - set.add(result.get()); - uow.getCache().put(key, set); - } else { - uow.getCache().put(key, new HashSet(0)); - } - } - } - - return result; - } finally { - context.stop(); + }); } - } - public CompletableFuture> async() { - return CompletableFuture.>supplyAsync(() -> { + public Optional sync() throws TimeoutException { + final Timer.Context context = requestLatency.time(); try { - return sync(); - } catch (TimeoutException ex) { throw new CompletionException(ex); } - }); - } + ResultSet resultSet = this.execute(sessionOps, null, traceContext, queryExecutionTimeout, queryTimeoutUnits, + showValues, false); + return transform(resultSet); + } finally { + context.stop(); + } + } - public CompletableFuture> async(UnitOfWork uow) { - if (uow == null) return async(); - return CompletableFuture.>supplyAsync(() -> { - try { + public Optional sync(UnitOfWork uow) throws TimeoutException { + if (uow == null) return sync(); - } catch (TimeoutException ex) { throw new CompletionException(ex); } - }); - } + + final Timer.Context context = requestLatency.time(); + try { + + Optional result = Optional.empty(); + String[] statementKeys = null; + + if (enableCache) { + Set facets = getFacets(); + statementKeys = getQueryKeys(); + result = Optional.of(checkCache(uow, facets, statementKeys)); + } + + if (!result.isPresent()) { + // Formulate the query and execute it against the Cassandra cluster. + ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits, + showValues, true); + + // Transform the query result set into the desired shape. + result = transform(resultSet); + } + + // If we have a result and we're caching then we need to put it into the cache for future requests to find. + if (enableCache && result.isPresent()) { + updateCache(uow, result.get(), statementKeys); + } + + return result; + } finally { + context.stop(); + } + } + + public CompletableFuture> async() { + return CompletableFuture.>supplyAsync(() -> { + try { + return sync(); + } + catch (TimeoutException ex) { + throw new CompletionException(ex); + } + }); + } + + public CompletableFuture> async(UnitOfWork uow) { + if (uow == null) + return async(); + return CompletableFuture.>supplyAsync(() -> { + try { + return sync(); + } + catch (TimeoutException ex) { + throw new CompletionException(ex); + } + }); + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java index bba8f9b..115ee51 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java @@ -28,283 +28,357 @@ import com.datastax.driver.core.policies.RetryPolicy; import com.datastax.driver.core.querybuilder.BuiltStatement; import com.google.common.util.concurrent.ListenableFuture; import net.helenus.core.AbstractSessionOperations; +import net.helenus.core.Helenus; +import net.helenus.core.UnitOfWork; +import net.helenus.core.cache.EntityIdentifyingFacet; +import net.helenus.mapping.HelenusProperty; +import net.helenus.mapping.value.BeanColumnValueProvider; +import net.helenus.support.Either; import net.helenus.support.HelenusException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; public abstract class AbstractStatementOperation> - extends Operation { + extends Operation { - final Logger logger = LoggerFactory.getLogger(getClass()); - - public abstract Statement buildStatement(boolean cached); - - protected boolean enableCache = true; - protected boolean showValues = true; - protected TraceContext traceContext; - private ConsistencyLevel consistencyLevel; - private ConsistencyLevel serialConsistencyLevel; - private RetryPolicy retryPolicy; - private boolean idempotent = false; - private boolean enableTracing = false; - private long[] defaultTimestamp = null; - private int[] fetchSize = null; - long queryExecutionTimeout = 10; - TimeUnit queryTimeoutUnits = TimeUnit.SECONDS; - - public AbstractStatementOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - this.consistencyLevel = sessionOperations.getDefaultConsistencyLevel(); - this.idempotent = sessionOperations.getDefaultQueryIdempotency(); - } - - public O ignoreCache(boolean enabled) { - enableCache = enabled; - return (O) this; - } - - public O ignoreCache() { - enableCache = true; - return (O) this; - } - - public O showValues(boolean enabled) { - this.showValues = enabled; - return (O) this; - } - - public O defaultTimestamp(long timestamp) { - this.defaultTimestamp = new long[1]; - this.defaultTimestamp[0] = timestamp; - return (O) this; - } - - public O retryPolicy(RetryPolicy retryPolicy) { - this.retryPolicy = retryPolicy; - return (O) this; - } - - public O defaultRetryPolicy() { - this.retryPolicy = DefaultRetryPolicy.INSTANCE; - return (O) this; - } - - public O idempotent() { - this.idempotent = true; - return (O) this; - } - - public O isIdempotent(boolean idempotent) { - this.idempotent = idempotent; - return (O) this; - } - - public O downgradingConsistencyRetryPolicy() { - this.retryPolicy = DowngradingConsistencyRetryPolicy.INSTANCE; - return (O) this; - } - - public O fallthroughRetryPolicy() { - this.retryPolicy = FallthroughRetryPolicy.INSTANCE; - return (O) this; - } - - public O consistency(ConsistencyLevel level) { - this.consistencyLevel = level; - return (O) this; - } - - public O consistencyAny() { - this.consistencyLevel = ConsistencyLevel.ANY; - return (O) this; - } - - public O consistencyOne() { - this.consistencyLevel = ConsistencyLevel.ONE; - return (O) this; - } - - public O consistencyQuorum() { - this.consistencyLevel = ConsistencyLevel.QUORUM; - return (O) this; - } - - public O consistencyAll() { - this.consistencyLevel = ConsistencyLevel.ALL; - return (O) this; - } - - public O consistencyLocalOne() { - this.consistencyLevel = ConsistencyLevel.LOCAL_ONE; - return (O) this; - } - - public O consistencyLocalQuorum() { - this.consistencyLevel = ConsistencyLevel.LOCAL_QUORUM; - return (O) this; - } - - public O consistencyEachQuorum() { - this.consistencyLevel = ConsistencyLevel.EACH_QUORUM; - return (O) this; - } - - public O serialConsistency(ConsistencyLevel level) { - this.serialConsistencyLevel = level; - return (O) this; - } - - public O serialConsistencyAny() { - this.serialConsistencyLevel = ConsistencyLevel.ANY; - return (O) this; - } - - public O serialConsistencyOne() { - this.serialConsistencyLevel = ConsistencyLevel.ONE; - return (O) this; - } - - public O serialConsistencyQuorum() { - this.serialConsistencyLevel = ConsistencyLevel.QUORUM; - return (O) this; - } - - public O serialConsistencyAll() { - this.serialConsistencyLevel = ConsistencyLevel.ALL; - return (O) this; - } - - public O serialConsistencyLocal() { - this.serialConsistencyLevel = ConsistencyLevel.LOCAL_SERIAL; - return (O) this; - } - - public O serialConsistencyLocalQuorum() { - this.serialConsistencyLevel = ConsistencyLevel.LOCAL_QUORUM; - return (O) this; - } - - public O disableTracing() { - this.enableTracing = false; - return (O) this; - } - - public O enableTracing() { - this.enableTracing = true; - return (O) this; - } - - public O tracing(boolean enable) { - this.enableTracing = enable; - return (O) this; - } - - public O fetchSize(int fetchSize) { - this.fetchSize = new int[1]; - this.fetchSize[0] = fetchSize; - return (O) this; - } - - public O queryTimeoutMs(long ms) { - this.queryExecutionTimeout = ms; - this.queryTimeoutUnits = TimeUnit.MILLISECONDS; - return (O) this; - } - - public O queryTimeout(long timeout, TimeUnit units) { - this.queryExecutionTimeout = timeout; - this.queryTimeoutUnits = units; - return (O) this; - } - - public Statement options(Statement statement) { - - if (defaultTimestamp != null) { - statement.setDefaultTimestamp(defaultTimestamp[0]); + final Logger logger = LoggerFactory.getLogger(getClass()); + protected boolean enableCache = true; + protected boolean showValues = true; + protected TraceContext traceContext; + long queryExecutionTimeout = 10; + TimeUnit queryTimeoutUnits = TimeUnit.SECONDS; + private ConsistencyLevel consistencyLevel; + private ConsistencyLevel serialConsistencyLevel; + private RetryPolicy retryPolicy; + private boolean idempotent = false; + private boolean enableTracing = false; + private long[] defaultTimestamp = null; + private int[] fetchSize = null; + public AbstractStatementOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + this.consistencyLevel = sessionOperations.getDefaultConsistencyLevel(); + this.idempotent = sessionOperations.getDefaultQueryIdempotency(); } - if (consistencyLevel != null) { - statement.setConsistencyLevel(consistencyLevel); + public abstract Statement buildStatement(boolean cached); + + public O ignoreCache(boolean enabled) { + enableCache = enabled; + return (O) this; } - if (serialConsistencyLevel != null) { - statement.setSerialConsistencyLevel(serialConsistencyLevel); + public O ignoreCache() { + enableCache = true; + return (O) this; } - if (retryPolicy != null) { - statement.setRetryPolicy(retryPolicy); + public O showValues(boolean enabled) { + this.showValues = enabled; + return (O) this; } - if (enableTracing) { - statement.enableTracing(); - } else { - statement.disableTracing(); + public O defaultTimestamp(long timestamp) { + this.defaultTimestamp = new long[1]; + this.defaultTimestamp[0] = timestamp; + return (O) this; } - if (fetchSize != null) { - statement.setFetchSize(fetchSize[0]); + public O retryPolicy(RetryPolicy retryPolicy) { + this.retryPolicy = retryPolicy; + return (O) this; } - if (idempotent) { - statement.setIdempotent(true); + public O defaultRetryPolicy() { + this.retryPolicy = DefaultRetryPolicy.INSTANCE; + return (O) this; } - return statement; - } - - public O zipkinContext(TraceContext traceContext) { - if (traceContext != null) { - Tracer tracer = this.sessionOps.getZipkinTracer(); - if (tracer != null) { - this.traceContext = traceContext; - } + public O idempotent() { + this.idempotent = true; + return (O) this; } - return (O) this; - } - - public Statement statement() { - return buildStatement(false); - } - - public String cql() { - Statement statement = buildStatement(false); - if (statement == null) return ""; - if (statement instanceof BuiltStatement) { - BuiltStatement buildStatement = (BuiltStatement) statement; - return buildStatement.setForceNoValues(true).getQueryString(); - } else { - return statement.toString(); - } - } - - public PreparedStatement prepareStatement() { - - Statement statement = buildStatement(true); - - if (statement instanceof RegularStatement) { - - RegularStatement regularStatement = (RegularStatement) statement; - - return sessionOps.prepare(regularStatement); + public O isIdempotent(boolean idempotent) { + this.idempotent = idempotent; + return (O) this; } - throw new HelenusException("only RegularStatements can be prepared"); - } - - public ListenableFuture prepareStatementAsync() { - - Statement statement = buildStatement(true); - - if (statement instanceof RegularStatement) { - - RegularStatement regularStatement = (RegularStatement) statement; - - return sessionOps.prepareAsync(regularStatement); + public O downgradingConsistencyRetryPolicy() { + this.retryPolicy = DowngradingConsistencyRetryPolicy.INSTANCE; + return (O) this; + } + + public O fallthroughRetryPolicy() { + this.retryPolicy = FallthroughRetryPolicy.INSTANCE; + return (O) this; + } + + public O consistency(ConsistencyLevel level) { + this.consistencyLevel = level; + return (O) this; + } + + public O consistencyAny() { + this.consistencyLevel = ConsistencyLevel.ANY; + return (O) this; + } + + public O consistencyOne() { + this.consistencyLevel = ConsistencyLevel.ONE; + return (O) this; + } + + public O consistencyQuorum() { + this.consistencyLevel = ConsistencyLevel.QUORUM; + return (O) this; + } + + public O consistencyAll() { + this.consistencyLevel = ConsistencyLevel.ALL; + return (O) this; + } + + public O consistencyLocalOne() { + this.consistencyLevel = ConsistencyLevel.LOCAL_ONE; + return (O) this; + } + + public O consistencyLocalQuorum() { + this.consistencyLevel = ConsistencyLevel.LOCAL_QUORUM; + return (O) this; + } + + public O consistencyEachQuorum() { + this.consistencyLevel = ConsistencyLevel.EACH_QUORUM; + return (O) this; + } + + public O serialConsistency(ConsistencyLevel level) { + this.serialConsistencyLevel = level; + return (O) this; + } + + public O serialConsistencyAny() { + this.serialConsistencyLevel = ConsistencyLevel.ANY; + return (O) this; + } + + public O serialConsistencyOne() { + this.serialConsistencyLevel = ConsistencyLevel.ONE; + return (O) this; + } + + public O serialConsistencyQuorum() { + this.serialConsistencyLevel = ConsistencyLevel.QUORUM; + return (O) this; + } + + public O serialConsistencyAll() { + this.serialConsistencyLevel = ConsistencyLevel.ALL; + return (O) this; + } + + public O serialConsistencyLocal() { + this.serialConsistencyLevel = ConsistencyLevel.LOCAL_SERIAL; + return (O) this; + } + + public O serialConsistencyLocalQuorum() { + this.serialConsistencyLevel = ConsistencyLevel.LOCAL_QUORUM; + return (O) this; + } + + public O disableTracing() { + this.enableTracing = false; + return (O) this; + } + + public O enableTracing() { + this.enableTracing = true; + return (O) this; + } + + public O tracing(boolean enable) { + this.enableTracing = enable; + return (O) this; + } + + public O fetchSize(int fetchSize) { + this.fetchSize = new int[1]; + this.fetchSize[0] = fetchSize; + return (O) this; + } + + public O queryTimeoutMs(long ms) { + this.queryExecutionTimeout = ms; + this.queryTimeoutUnits = TimeUnit.MILLISECONDS; + return (O) this; + } + + public O queryTimeout(long timeout, TimeUnit units) { + this.queryExecutionTimeout = timeout; + this.queryTimeoutUnits = units; + return (O) this; + } + + public Statement options(Statement statement) { + + if (defaultTimestamp != null) { + statement.setDefaultTimestamp(defaultTimestamp[0]); + } + + if (consistencyLevel != null) { + statement.setConsistencyLevel(consistencyLevel); + } + + if (serialConsistencyLevel != null) { + statement.setSerialConsistencyLevel(serialConsistencyLevel); + } + + if (retryPolicy != null) { + statement.setRetryPolicy(retryPolicy); + } + + if (enableTracing) { + statement.enableTracing(); + } else { + statement.disableTracing(); + } + + if (fetchSize != null) { + statement.setFetchSize(fetchSize[0]); + } + + if (idempotent) { + statement.setIdempotent(true); + } + + return statement; + } + + public O zipkinContext(TraceContext traceContext) { + if (traceContext != null) { + Tracer tracer = this.sessionOps.getZipkinTracer(); + if (tracer != null) { + this.traceContext = traceContext; + } + } + + return (O) this; + } + + public Statement statement() { + return buildStatement(false); + } + + public String cql() { + Statement statement = buildStatement(false); + if (statement == null) + return ""; + if (statement instanceof BuiltStatement) { + BuiltStatement buildStatement = (BuiltStatement) statement; + return buildStatement.setForceNoValues(true).getQueryString(); + } else { + return statement.toString(); + } + } + + public PreparedStatement prepareStatement() { + + Statement statement = buildStatement(true); + + if (statement instanceof RegularStatement) { + + RegularStatement regularStatement = (RegularStatement) statement; + + return sessionOps.prepare(regularStatement); + } + + throw new HelenusException("only RegularStatements can be prepared"); + } + + public ListenableFuture prepareStatementAsync() { + + Statement statement = buildStatement(true); + + if (statement instanceof RegularStatement) { + + RegularStatement regularStatement = (RegularStatement) statement; + + return sessionOps.prepareAsync(regularStatement); + } + + throw new HelenusException("only RegularStatements can be prepared"); + } + + protected E checkCache(UnitOfWork uow, Set facets, String[] statementKeys) { + E result = null; + + if (!facets.isEmpty()) { + //TODO(gburd): what about select ResultSet, Tuple... etc.? + Optional>> optionalCachedResult = uow.cacheLookupByFacet(facets); + if (optionalCachedResult.isPresent()) { + Either> eitherCachedResult = optionalCachedResult.get(); + if (eitherCachedResult.isLeft()) { + uowCacheHits.mark(); + logger.info("UnitOfWork({}) cache hit using facets", uow.hashCode()); + result = (E) eitherCachedResult.getLeft(); + } + } + } else { + // Then check to see if this query happens to uniquely identify a single object in the + // cache. + Optional>> optionalCachedResult = uow.cacheLookupByStatement(statementKeys); + if (optionalCachedResult.isPresent()) { + Either> eitherCachedResult = optionalCachedResult.get(); + // Statements always store Set as the value in the cache. + if (eitherCachedResult.isRight()) { + Set cachedResult = eitherCachedResult.getRight(); + if (cachedResult.size() == 1) { + Optional maybeResult = cachedResult.stream().findFirst(); + if (maybeResult.isPresent()) { + uowCacheHits.mark(); + logger.info("UnitOfWork({}) cache hit for stmt", uow.hashCode()); + } else { + result = null; + } + } + } + } + } + if (result == null) { + uowCacheMiss.mark(); + logger.info("UnitOfWork({}) cache miss", uow.hashCode()); + } + return result; + } + + protected void updateCache(UnitOfWork uow, E pojo, String[] statementKeys) { + + // Insert this entity into the cache for each facet for this entity that we can fully bind. + Map facetMap = Helenus.entity(pojo.getClass()).getIdentifyingFacets(); + facetMap.forEach((facetName, facet) -> { + if (!facet.isFullyBound()) { + HelenusProperty prop = facet.getProperty(); + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop); + facet.setValueForProperty(prop, value); + } + }); + + // Cache the value (pojo), the statement key, and the fully bound facets. + if (statementKeys != null) { + uow.cacheUpdate(Either.left(pojo), statementKeys, + facetMap.values() + .stream() + .filter(facet -> facet.isFullyBound()) + .collect(Collectors.toSet())); + } } - throw new HelenusException("only RegularStatements can be prepared"); - } } diff --git a/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java b/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java index 17fcfa4..2c253ba 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java @@ -21,13 +21,15 @@ import com.datastax.driver.core.ResultSet; import com.google.common.base.Function; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; +import net.helenus.core.AbstractSessionOperations; +import net.helenus.core.UnitOfWork; +import net.helenus.core.cache.EntityIdentifyingFacet; + import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.TimeoutException; import java.util.stream.Stream; -import net.helenus.core.AbstractSessionOperations; -import net.helenus.core.UnitOfWork; public abstract class AbstractStreamOperation> extends AbstractStatementOperation { @@ -64,33 +66,35 @@ public abstract class AbstractStreamOperation sync(UnitOfWork uow) throws TimeoutException { - if (uow == null) return sync(); + public Stream sync(UnitOfWork uow) throws TimeoutException { + if (uow == null) + return sync(); final Timer.Context context = requestLatency.time(); try { - Stream result = null; - String key = getStatementCacheKey(); - if (enableCache && key != null) { - Set cachedResult = (Set) uow.cacheLookup(key); - if (cachedResult != null) { - //TODO(gburd): what about select ResultSet, Tuple... etc.? - uowCacheHits.mark(); - logger.info("UOW({}) cache hit, {}", uow.hashCode()); - result = cachedResult.stream(); - } else { - uowCacheMiss.mark(); - } - } + Stream result = null; + E cachedResult = null; + String[] statementKeys = null; - if (result == null) { - ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits, showValues, true); - result = transform(resultSet); - - if (key != null) { - uow.getCache().put(key, (Set) result); + if (enableCache) { + Set facets = getFacets(); + statementKeys = getQueryKeys(); + cachedResult = checkCache(uow, facets, statementKeys); + if (cachedResult != null) { + result = Stream.of(cachedResult); + } + } + + if (result == null) { + ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits, + showValues, true); + result = transform(resultSet); + } + + // If we have a result and we're caching then we need to put it into the cache for future requests to find. + if (enableCache && cachedResult != null) { + updateCache(uow, cachedResult, statementKeys); } - } return result; } finally { @@ -106,7 +110,7 @@ public abstract class AbstractStreamOperation> async(UnitOfWork uow) { + public CompletableFuture> async(UnitOfWork uow) { if (uow == null) return async(); return CompletableFuture.>supplyAsync(() -> { try { diff --git a/src/main/java/net/helenus/core/operation/BoundStreamOperation.java b/src/main/java/net/helenus/core/operation/BoundStreamOperation.java index 7a3cf2c..1c7e03c 100644 --- a/src/main/java/net/helenus/core/operation/BoundStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/BoundStreamOperation.java @@ -18,6 +18,9 @@ package net.helenus.core.operation; import com.datastax.driver.core.BoundStatement; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Statement; +import net.helenus.core.cache.EntityIdentifyingFacet; + +import java.util.Set; import java.util.stream.Stream; public final class BoundStreamOperation @@ -34,10 +37,13 @@ public final class BoundStreamOperation } @Override - public String getStatementCacheKey() { - return delegate.getStatementCacheKey(); + public String[] getQueryKeys() { + return delegate.getQueryKeys(); } + @Override + public Set getFacets() { return delegate.getFacets(); } + @Override public Stream transform(ResultSet resultSet) { return delegate.transform(resultSet); diff --git a/src/main/java/net/helenus/core/operation/InsertOperation.java b/src/main/java/net/helenus/core/operation/InsertOperation.java index 61b883c..30bf94c 100644 --- a/src/main/java/net/helenus/core/operation/InsertOperation.java +++ b/src/main/java/net/helenus/core/operation/InsertOperation.java @@ -240,7 +240,7 @@ public final class InsertOperation extends AbstractOperation keys = new ArrayList<>(values.size()); values.forEach( t -> { @@ -248,13 +248,13 @@ public final class InsertOperation extends AbstractOperation extends AbstractOperation iface = entity.getMappingInterface(); if (resultType == iface) { - String key = getStatementCacheKey(); - if (key != null) { - Set set = new HashSet(1); - set.add(result); - uow.getCache().put(key, set); - } + updateCache(uow, result, getQueryKeys()); } return result; } diff --git a/src/main/java/net/helenus/core/operation/Operation.java b/src/main/java/net/helenus/core/operation/Operation.java index 4099068..4fe5efc 100644 --- a/src/main/java/net/helenus/core/operation/Operation.java +++ b/src/main/java/net/helenus/core/operation/Operation.java @@ -16,6 +16,7 @@ import java.util.concurrent.TimeoutException; import net.helenus.core.AbstractSessionOperations; import net.helenus.core.UnitOfWork; +import net.helenus.core.cache.EntityIdentifyingFacet; import net.helenus.support.HelenusException; public abstract class Operation { @@ -75,7 +76,12 @@ public abstract class Operation { return null; } - public Set getIdentifyingFacets() { + public String[] getQueryKeys() { + return null; + } + + public Set getFacets() { return null; } + } diff --git a/src/main/java/net/helenus/core/operation/SelectFirstOperation.java b/src/main/java/net/helenus/core/operation/SelectFirstOperation.java index d5cf01e..523dbbd 100644 --- a/src/main/java/net/helenus/core/operation/SelectFirstOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectFirstOperation.java @@ -17,7 +17,10 @@ package net.helenus.core.operation; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.BuiltStatement; +import net.helenus.core.cache.EntityIdentifyingFacet; + import java.util.Optional; +import java.util.Set; import java.util.function.Function; public final class SelectFirstOperation @@ -38,8 +41,8 @@ public final class SelectFirstOperation } @Override - public String getStatementCacheKey() { - return delegate.getStatementCacheKey(); + public String[] getQueryKeys() { + return delegate.getQueryKeys(); } @Override @@ -47,6 +50,9 @@ public final class SelectFirstOperation return delegate.buildStatement(cached); } + @Override + public Set getFacets() { return delegate.getFacets(); } + @Override public Optional transform(ResultSet resultSet) { return delegate.transform(resultSet).findFirst(); diff --git a/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java b/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java index 8ef4f60..95f18e8 100644 --- a/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java @@ -17,7 +17,10 @@ package net.helenus.core.operation; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.BuiltStatement; +import net.helenus.core.cache.EntityIdentifyingFacet; + import java.util.Optional; +import java.util.Set; import java.util.function.Function; public final class SelectFirstTransformingOperation @@ -36,10 +39,13 @@ public final class SelectFirstTransformingOperation } @Override - public String getStatementCacheKey() { - return delegate.getStatementCacheKey(); + public String[] getQueryKeys() { + return delegate.getQueryKeys(); } + @Override + public Set getFacets() { return delegate.getFacets(); } + @Override public BuiltStatement buildStatement(boolean cached) { return delegate.buildStatement(cached); diff --git a/src/main/java/net/helenus/core/operation/SelectOperation.java b/src/main/java/net/helenus/core/operation/SelectOperation.java index dcb916c..73a4553 100644 --- a/src/main/java/net/helenus/core/operation/SelectOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectOperation.java @@ -15,6 +15,7 @@ */ package net.helenus.core.operation; +import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.Ordering; @@ -22,11 +23,13 @@ import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Select; import com.datastax.driver.core.querybuilder.Select.Selection; import com.datastax.driver.core.querybuilder.Select.Where; -import com.google.common.base.Joiner; + import java.util.*; import java.util.function.Function; import java.util.stream.Stream; import java.util.stream.StreamSupport; + +import com.google.common.collect.Iterables; import net.helenus.core.*; import net.helenus.core.cache.EntityIdentifyingFacet; import net.helenus.core.reflect.HelenusPropertyNode; @@ -194,28 +197,24 @@ public final class SelectOperation extends AbstractFilterStreamOperation getIdentityFacets() { + public Set getFacets() { HelenusEntity entity = props.get(0).getEntity(); final Set facets = new HashSet<>(filters.size()); // Check to see if this select statement has enough information to build one or // more identifying facets. entity - .getIdentityFacets() + .getIdentifyingFacets() .forEach( (facetName, facet) -> { - EntityIdentifyingFacet boundFacet = null; - if (!facet.isFullyBound()) { - boundFacet = new EntityIdentifyingFacet(facet); - for (HelenusProperty prop : facet.getUnboundEntityProperties()) { - Filter filter = filters.get(facet.getProperty()); - if (filter == null) { - break; + if (facet.isFullyBound()) { + facets.add(facet); + } else { + HelenusProperty prop = facet.getProperty(); + Filter filter = filters.get(prop); + if (filter != null) { + facet.setValueForProperty(prop, filter.toString()); + facets.add(facet); } - boundFacet.setValueForProperty(prop, filter.toString()); - } - } - if (boundFacet != null && boundFacet.isFullyBound()) { - facets.add(boundFacet); } }); return facets; @@ -245,7 +244,6 @@ public final class SelectOperation extends AbstractFilterStreamOperation extends AbstractFilterStreamOperation } @Override - public String getStatementCacheKey() { - return delegate.getStatementCacheKey(); + public String[] getQueryKeys() { + return delegate.getQueryKeys(); } + @Override + public Set getFacets() { return delegate.getFacets(); } + @Override public BuiltStatement buildStatement(boolean cached) { return delegate.buildStatement(cached); diff --git a/src/main/java/net/helenus/core/operation/UpdateOperation.java b/src/main/java/net/helenus/core/operation/UpdateOperation.java index cf84b47..f4aa3c7 100644 --- a/src/main/java/net/helenus/core/operation/UpdateOperation.java +++ b/src/main/java/net/helenus/core/operation/UpdateOperation.java @@ -584,13 +584,9 @@ public final class UpdateOperation extends AbstractFilterOperation set = new HashSet(1); - set.add(result); - uow.getCache().put(key, set); - } + updateCache(uow, result, getQueryKeys()); } return result; } diff --git a/src/main/java/net/helenus/mapping/HelenusEntity.java b/src/main/java/net/helenus/mapping/HelenusEntity.java index fa84c7b..681d8d1 100644 --- a/src/main/java/net/helenus/mapping/HelenusEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusEntity.java @@ -33,5 +33,5 @@ public interface HelenusEntity { HelenusProperty getProperty(String name); - Map getIdentityFacets(); + Map getIdentifyingFacets(); } diff --git a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java index ceb9722..feeec77 100644 --- a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java @@ -124,9 +124,6 @@ public final class HelenusMappingEntity implements HelenusEntity { if (primaryProperties != null) { primaryFacet = new EntityIdentifyingFacet( - keyspace, - table, - schemaVersion, primaryProperties.toArray(new HelenusProperty[props.size()])); allFacetsBuilder.put("*", primaryFacet); primaryProperties = null; @@ -134,7 +131,7 @@ public final class HelenusMappingEntity implements HelenusEntity { Optional optionalIndexName = prop.getIndexName(); if (optionalIndexName.isPresent()) { EntityIdentifyingFacet facet = - new EntityIdentifyingFacet(keyspace, table, schemaVersion, prop); + new EntityIdentifyingFacet(prop); ancillaryFacetsBuilder.put(prop.getPropertyName(), facet); } } @@ -174,6 +171,11 @@ public final class HelenusMappingEntity implements HelenusEntity { return props.get(name); } + @Override + public Map getIdentifyingFacets() { + return allIdentityFacets; + } + @Override public IdentityName getName() { return name; From 75f32eb542fa8a8b6df641ad8733920e79c5bb8f Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Thu, 19 Oct 2017 13:08:58 -0400 Subject: [PATCH 7/9] more progress. --- NOTES | 31 + .../net/helenus/core/AbstractUnitOfWork.java | 141 ++-- .../net/helenus/core/SessionInitializer.java | 2 +- .../java/net/helenus/core/UnitOfWork.java | 15 +- .../helenus/core/annotation/Cacheable.java | 15 + .../net/helenus/core/cache/BoundFacet.java | 38 ++ .../core/cache/EntityIdentifyingFacet.java | 66 +- .../AbstractFilterStreamOperation.java | 4 +- .../core/operation/AbstractOperation.java | 46 +- .../operation/AbstractOptionalOperation.java | 188 +++--- .../operation/AbstractStatementOperation.java | 635 +++++++++--------- .../operation/AbstractStreamOperation.java | 87 ++- .../core/operation/BoundStreamOperation.java | 7 +- .../core/operation/InsertOperation.java | 11 +- .../net/helenus/core/operation/Operation.java | 48 +- .../core/operation/SelectFirstOperation.java | 24 +- .../SelectFirstTransformingOperation.java | 7 +- .../core/operation/SelectOperation.java | 52 +- .../SelectTransformingOperation.java | 14 +- .../core/operation/UpdateOperation.java | 2 +- .../net/helenus/core/reflect/Drafted.java | 15 + .../helenus/core/reflect/DslExportable.java | 8 +- .../core/reflect/DslInvocationHandler.java | 4 +- .../core/reflect/MapperInvocationHandler.java | 7 +- .../helenus/mapping/HelenusMappingEntity.java | 7 +- .../value/BeanColumnValueProvider.java | 3 +- .../mapping/value/ColumnValueProvider.java | 6 +- .../mapping/value/RowColumnValueProvider.java | 48 +- .../value/TupleColumnValueProvider.java | 3 +- .../mapping/value/UDTColumnValueProvider.java | 3 +- .../mapping/value/ValueProviderMap.java | 18 +- .../core/collection/CollectionTest.java | 1 - .../integration/core/counter/CounterTest.java | 3 +- .../core/hierarchy/HierarchyTest.java | 1 - .../core/index/SecondaryIndexTest.java | 3 +- .../core/simple/SimpleUserTest.java | 1 - .../core/tuple/InnerTupleTest.java | 3 +- .../integration/core/tuple/TupleTest.java | 3 +- .../core/tuplecollection/TupleKeyMapTest.java | 1 - .../core/tuplecollection/TupleListTest.java | 1 - .../core/tuplecollection/TupleMapTest.java | 1 - .../core/tuplecollection/TupleSetTest.java | 1 - .../tuplecollection/TupleValueMapTest.java | 1 - .../core/udtcollection/UDTKeyMapTest.java | 1 - .../core/udtcollection/UDTListTest.java | 1 - .../core/udtcollection/UDTMapTest.java | 1 - .../core/udtcollection/UDTSetTest.java | 1 - .../core/udtcollection/UDTValueMapTest.java | 1 - .../core/unitofwork/UnitOfWorkTest.java | 37 + .../usertype/InnerUserDefinedTypeTest.java | 1 - .../core/usertype/UserDefinedTypeTest.java | 1 - .../core/views/MaterializedViewTest.java | 17 +- 52 files changed, 995 insertions(+), 641 deletions(-) create mode 100644 src/main/java/net/helenus/core/cache/BoundFacet.java diff --git a/NOTES b/NOTES index 038b1e9..8a76512 100644 --- a/NOTES +++ b/NOTES @@ -320,3 +320,34 @@ begin: } }; } +---------------------------------- + if ("ttl".equals(methodName) && method.getParameterCount() == 1 && method.getReturnType() == int.class) { + Getter getter = (Getter) args[0]; + if (getter == null) { + return false; + } + HelenusProperty prop = MappingUtil.resolveMappingProperty(getter).getProperty(); + String getterName = prop.getPropertyName(); + String ttlKeyForProperty = prop.getColumnName().toCql() + "_ttl"; + if (src.containsKey(ttlKeyForProperty)) { + return src.get(ttlKeyForProperty); + } else { + return 0; + } + } + + if ("written".equals(methodName) && method.getParameterCount() == 1 && method.getReturnType() == int.class) { + Getter getter = (Getter) args[0]; + if (getter == null) { + return false; + } + HelenusProperty prop = MappingUtil.resolveMappingProperty(getter).getProperty(); + String getterName = prop.getPropertyName(); + String ttlKeyForProperty = prop.getColumnName().toCql() + "_ttl"; + if (src.containsKey(ttlKeyForProperty)) { + return src.get(ttlKeyForProperty); + } else { + return 0; + } + } + diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index 3d505dd..9533ee1 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -17,22 +17,24 @@ package net.helenus.core; import com.diffplug.common.base.Errors; import com.google.common.collect.TreeTraverser; -import net.helenus.core.cache.EntityIdentifyingFacet; +import java.util.*; +import java.util.stream.Collectors; +import net.helenus.core.cache.BoundFacet; import net.helenus.support.Either; import org.ahocorasick.trie.Emit; import org.ahocorasick.trie.Trie; -import java.util.*; -import java.util.stream.Collectors; - /** Encapsulates the concept of a "transaction" as a unit-of-work. */ -public abstract class AbstractUnitOfWork implements UnitOfWork, AutoCloseable { +public abstract class AbstractUnitOfWork + implements UnitOfWork, AutoCloseable { private final List> nested = new ArrayList<>(); private final HelenusSession session; private final AbstractUnitOfWork parent; private List postCommit = new ArrayList(); - private final Map>> cache = new HashMap>>(); - private Trie cacheIndex = Trie.builder().ignoreOverlaps().onlyWholeWordsWhiteSpaceSeparated().build(); + private final Map>> cache = + new HashMap>>(); + private Trie cacheIndex = + Trie.builder().ignoreOverlaps().onlyWholeWordsWhiteSpaceSeparated().build(); private boolean aborted = false; private boolean committed = false; @@ -65,48 +67,64 @@ public abstract class AbstractUnitOfWork implements UnitOfW } @Override - public Optional>> cacheLookupByFacet(Set facets) { - Optional>> result = null; - Collection emits = cacheIndex.parseText(String.join(" ", facets.stream() - .map(facet -> facet.toString()).collect(Collectors.toList()))); - for (Emit emit : emits) { - // NOTE: rethink. should this match *all* facets? how do I know which emit keyword is the primary key? - String key = emit.getKeyword(); - result = cacheLookup(key); + public Optional>> cacheLookupByFacet(Set facets) { + Optional>> result = Optional.empty(); + Collection emits = + cacheIndex.parseText( + String.join( + " ", facets.stream().map(facet -> facet.toString()).collect(Collectors.toList()))); + for (Emit emit : emits) { + // NOTE: rethink. should this match *all* facets? how do I know which emit keyword is the primary key? + String key = emit.getKeyword(); + result = cacheLookup(key); + if (result.isPresent()) { + return result; } - return result; + } + if (!result.isPresent()) { + // Be sure to check all enclosing UnitOfWork caches as well, we may be nested. + if (parent != null) { + return parent.cacheLookupByFacet(facets); + } + } + return result; } @Override public Optional>> cacheLookupByStatement(String[] statementKeys) { - Optional>> result = null; - String key = String.join(",", statementKeys); - return cacheLookup(key); + String key = String.join(",", statementKeys); + return cacheLookup(key); } @Override public Optional>> cacheLookup(String key) { - Optional>> result = Optional.of(cache.get(key)); + Optional>> result = + (cache.containsKey(key)) ? Optional.of(cache.get(key)) : Optional.empty(); - if (result.isPresent()) { - return result; - } else { - // Be sure to check all enclosing UnitOfWork caches as well, we may be nested. - if (parent != null) { - return parent.cacheLookup(key); - } + if (!result.isPresent()) { + // Be sure to check all enclosing UnitOfWork caches as well, we may be nested. + if (parent != null) { + return parent.cacheLookup(key); } - return Optional.empty(); + } + return result; } @Override - public void cacheUpdate(Either> value, String[] statementKeys, Set facets) { - String key = String.join(",", statementKeys); - cache.put(key, value); - Trie.TrieBuilder builder = cacheIndex.builder(); - facets.forEach(facet -> { + public void cacheUpdate( + Either> value, String[] statementKeys, Map facetMap) { + String key = "CQL::" + String.join(",", statementKeys); + cache.put(key, value); + Trie.TrieBuilder builder = + cacheIndex.builder().ignoreOverlaps().onlyWholeWordsWhiteSpaceSeparated(); + facetMap.forEach( + (facetName, facet) -> { builder.addKeyword(facet.toString()); - }); + if (facetName.equals("*")) { + cache.put(facet.toString(), value); + } + }); + cacheIndex = builder.build(); } private Iterator> getChildNodes() { @@ -145,7 +163,7 @@ public abstract class AbstractUnitOfWork implements UnitOfW // Merge UOW cache into parent's cache. if (parent != null) { - parent.assumeCache(cache, cacheIndex); + parent.assumeCache(cache, cacheIndex); } // Apply all post-commit functions for @@ -181,35 +199,36 @@ public abstract class AbstractUnitOfWork implements UnitOfW // cache.invalidateSince(txn::start time) } - private void assumeCache(Map>> childCache, Trie childCacheIndex) { - for (String key : childCache.keySet()) { - if (cache.containsKey(key)) { - Either> value = cache.get(key); - if (value.isLeft()) { - Object obj = value.getLeft(); - // merge objects - Either> childValue = childCache.get(key); - if (childValue.isLeft()) { - Object childObj = childValue.getLeft(); - } else { - Set childSet = childValue.getRight(); - } - } else { - // merge the sets - Set set = value.getRight(); - Either> childValue = childCache.get(key); - if (childValue.isLeft()) { - Object childObj = childValue.getLeft(); - set.add(childObj); - } else { - Set childSet = childValue.getRight(); - set.addAll(childSet); - } - } + private void assumeCache( + Map>> childCache, Trie childCacheIndex) { + for (String key : childCache.keySet()) { + if (cache.containsKey(key)) { + Either> value = cache.get(key); + if (value.isLeft()) { + Object obj = value.getLeft(); + // merge objects + Either> childValue = childCache.get(key); + if (childValue.isLeft()) { + Object childObj = childValue.getLeft(); } else { - cache.put(key, childCache.get(key)); + Set childSet = childValue.getRight(); } + } else { + // merge the sets + Set set = value.getRight(); + Either> childValue = childCache.get(key); + if (childValue.isLeft()) { + Object childObj = childValue.getLeft(); + set.add(childObj); + } else { + Set childSet = childValue.getRight(); + set.addAll(childSet); + } + } + } else { + cache.put(key, childCache.get(key)); } + } } public String describeConflicts() { diff --git a/src/main/java/net/helenus/core/SessionInitializer.java b/src/main/java/net/helenus/core/SessionInitializer.java index f6ecfd6..4a8d2f9 100644 --- a/src/main/java/net/helenus/core/SessionInitializer.java +++ b/src/main/java/net/helenus/core/SessionInitializer.java @@ -277,7 +277,7 @@ public final class SessionInitializer extends AbstractSessionOperations { } DslExportable dsl = (DslExportable) Helenus.dsl(iface); - dsl.setCassandraMetadataForHelenusSesion(session.getCluster().getMetadata()); + dsl.setCassandraMetadataForHelenusSession(session.getCluster().getMetadata()); sessionRepository.add(dsl); }); diff --git a/src/main/java/net/helenus/core/UnitOfWork.java b/src/main/java/net/helenus/core/UnitOfWork.java index da799fc..9ff1312 100644 --- a/src/main/java/net/helenus/core/UnitOfWork.java +++ b/src/main/java/net/helenus/core/UnitOfWork.java @@ -15,11 +15,11 @@ */ package net.helenus.core; -import net.helenus.core.cache.EntityIdentifyingFacet; -import net.helenus.support.Either; - +import java.util.Map; import java.util.Optional; import java.util.Set; +import net.helenus.core.cache.BoundFacet; +import net.helenus.support.Either; public interface UnitOfWork extends AutoCloseable { @@ -52,8 +52,11 @@ public interface UnitOfWork extends AutoCloseable { boolean hasCommitted(); Optional>> cacheLookup(String key); - Optional>> cacheLookupByFacet(Set facets); - Optional>> cacheLookupByStatement(String[] statementKeys); - void cacheUpdate(Either> pojo, String[] statementKeys, Set facets); + Optional>> cacheLookupByFacet(Set facets); + + Optional>> cacheLookupByStatement(String[] statementKeys); + + void cacheUpdate( + Either> pojo, String[] statementKeys, Map facets); } diff --git a/src/main/java/net/helenus/core/annotation/Cacheable.java b/src/main/java/net/helenus/core/annotation/Cacheable.java index 2160563..935a214 100644 --- a/src/main/java/net/helenus/core/annotation/Cacheable.java +++ b/src/main/java/net/helenus/core/annotation/Cacheable.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2015 The Helenus Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package net.helenus.core.annotation; import java.lang.annotation.ElementType; diff --git a/src/main/java/net/helenus/core/cache/BoundFacet.java b/src/main/java/net/helenus/core/cache/BoundFacet.java new file mode 100644 index 0000000..20c1de0 --- /dev/null +++ b/src/main/java/net/helenus/core/cache/BoundFacet.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2015 The Helenus Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.helenus.core.cache; + +import java.util.Map; +import java.util.stream.Collectors; +import net.helenus.mapping.HelenusProperty; + +public class BoundFacet { + private final Map properties; + + BoundFacet(Map properties) { + this.properties = properties; + } + + public String toString() { + return String.join( + ";", + properties + .keySet() + .stream() + .map(key -> properties.get(key).toString()) + .collect(Collectors.toSet())); + } +} diff --git a/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java b/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java index 62b3849..f8aa5b2 100644 --- a/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java +++ b/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java @@ -1,28 +1,72 @@ +/* + * Copyright (C) 2015 The Helenus Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package net.helenus.core.cache; -import net.helenus.mapping.HelenusProperty; - +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; import java.util.Set; +import net.helenus.mapping.HelenusProperty; public class EntityIdentifyingFacet extends Facet { - public EntityIdentifyingFacet(HelenusProperty prop) {} + private final Set properties; - public EntityIdentifyingFacet(HelenusProperty[]... props) {} + public EntityIdentifyingFacet(HelenusProperty prop) { + properties = new HashSet(); + properties.add(prop); + } + + public EntityIdentifyingFacet(Set props) { + properties = props; + } public boolean isFullyBound() { - return false; + return false; } - public HelenusProperty getProperty() { - return null; + public Set getProperties() { + return properties; } - public Set getUnboundEntityProperties() { - return null; + public Binder binder() { + return new Binder(properties); } - public void setValueForProperty(HelenusProperty prop, Object value) { - } + public static class Binder { + private final Set properties = new HashSet(); + private Map boundProperties = new HashMap(); + + Binder(Set properties) { + this.properties.addAll(properties); + } + + public Binder setValueForProperty(HelenusProperty prop, Object value) { + properties.remove(prop); + boundProperties.put(prop, value); + return this; + } + + public boolean isFullyBound() { + return properties.isEmpty(); + } + + public BoundFacet bind() { + return new BoundFacet(boundProperties); + } + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java b/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java index 9a5bc8c..b78daf1 100644 --- a/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java @@ -22,7 +22,9 @@ import java.util.Map; import net.helenus.core.*; import net.helenus.mapping.HelenusProperty; -public abstract class AbstractFilterStreamOperation> extends AbstractStreamOperation { +public abstract class AbstractFilterStreamOperation< + E, O extends AbstractFilterStreamOperation> + extends AbstractStreamOperation { protected Map> filters = null; protected List> ifFilters = null; diff --git a/src/main/java/net/helenus/core/operation/AbstractOperation.java b/src/main/java/net/helenus/core/operation/AbstractOperation.java index 7990c5a..a612696 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOperation.java @@ -17,13 +17,9 @@ package net.helenus.core.operation; import com.codahale.metrics.Timer; import com.datastax.driver.core.ResultSet; - -import java.sql.Time; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.TimeoutException; - -import com.diffplug.common.base.Errors; import net.helenus.core.AbstractSessionOperations; import net.helenus.core.UnitOfWork; @@ -47,7 +43,15 @@ public abstract class AbstractOperation> public E sync() throws TimeoutException { final Timer.Context context = requestLatency.time(); try { - ResultSet resultSet = this.execute(sessionOps, null, traceContext, queryExecutionTimeout, queryTimeoutUnits, showValues, false); + ResultSet resultSet = + this.execute( + sessionOps, + null, + traceContext, + queryExecutionTimeout, + queryTimeoutUnits, + showValues, + false); return transform(resultSet); } finally { context.stop(); @@ -59,7 +63,15 @@ public abstract class AbstractOperation> final Timer.Context context = requestLatency.time(); try { - ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits, showValues, true); + ResultSet resultSet = + execute( + sessionOps, + uow, + traceContext, + queryExecutionTimeout, + queryTimeoutUnits, + showValues, + true); E result = transform(resultSet); return result; } finally { @@ -68,19 +80,25 @@ public abstract class AbstractOperation> } public CompletableFuture async() { - return CompletableFuture.supplyAsync(() -> { - try { + return CompletableFuture.supplyAsync( + () -> { + try { return sync(); - } catch (TimeoutException ex) { throw new CompletionException(ex); } - }); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } + }); } public CompletableFuture async(UnitOfWork uow) { if (uow == null) return async(); - return CompletableFuture.supplyAsync(() -> { - try { + return CompletableFuture.supplyAsync( + () -> { + try { return sync(); - } catch (TimeoutException ex) { throw new CompletionException(ex); } - }); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } + }); } } diff --git a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java index e4b9302..dfe94c9 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java @@ -21,109 +21,125 @@ import com.datastax.driver.core.ResultSet; import com.google.common.base.Function; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import net.helenus.core.AbstractSessionOperations; -import net.helenus.core.UnitOfWork; -import net.helenus.core.cache.EntityIdentifyingFacet; - import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.TimeoutException; +import net.helenus.core.AbstractSessionOperations; +import net.helenus.core.UnitOfWork; +import net.helenus.core.cache.BoundFacet; public abstract class AbstractOptionalOperation> - extends AbstractStatementOperation { + extends AbstractStatementOperation { - public AbstractOptionalOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); + public AbstractOptionalOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } + + public abstract Optional transform(ResultSet resultSet); + + public PreparedOptionalOperation prepare() { + return new PreparedOptionalOperation(prepareStatement(), this); + } + + public ListenableFuture> prepareAsync() { + final O _this = (O) this; + return Futures.transform( + prepareStatementAsync(), + new Function>() { + @Override + public PreparedOptionalOperation apply(PreparedStatement preparedStatement) { + return new PreparedOptionalOperation(preparedStatement, _this); + } + }); + } + + public Optional sync() throws TimeoutException { + final Timer.Context context = requestLatency.time(); + try { + ResultSet resultSet = + this.execute( + sessionOps, + null, + traceContext, + queryExecutionTimeout, + queryTimeoutUnits, + showValues, + false); + return transform(resultSet); + } finally { + context.stop(); } + } - public abstract Optional transform(ResultSet resultSet); + public Optional sync(UnitOfWork uow) throws TimeoutException { + if (uow == null) return sync(); - public PreparedOptionalOperation prepare() { - return new PreparedOptionalOperation(prepareStatement(), this); - } + final Timer.Context context = requestLatency.time(); + try { - public ListenableFuture> prepareAsync() { - final O _this = (O) this; - return Futures.transform( - prepareStatementAsync(), - new Function>() { - @Override - public PreparedOptionalOperation apply(PreparedStatement preparedStatement) { - return new PreparedOptionalOperation(preparedStatement, _this); - } - }); - } + Optional result = Optional.empty(); + E cacheResult = null; + String[] statementKeys = null; - public Optional sync() throws TimeoutException { - final Timer.Context context = requestLatency.time(); - try { - ResultSet resultSet = this.execute(sessionOps, null, traceContext, queryExecutionTimeout, queryTimeoutUnits, - showValues, false); - return transform(resultSet); - } finally { - context.stop(); + if (enableCache) { + Set facets = bindFacetValues(); + statementKeys = getQueryKeys(); + cacheResult = checkCache(uow, facets, statementKeys); + if (cacheResult != null) { + result = Optional.of(cacheResult); } - } + } - public Optional sync(UnitOfWork uow) throws TimeoutException { - if (uow == null) + if (!result.isPresent()) { + // Formulate the query and execute it against the Cassandra cluster. + ResultSet resultSet = + execute( + sessionOps, + uow, + traceContext, + queryExecutionTimeout, + queryTimeoutUnits, + showValues, + true); + + // Transform the query result set into the desired shape. + result = transform(resultSet); + } + + // If we have a result, it wasn't from cache, and we're caching things then we need to put this result + // into the cache for future requests to find. + if (enableCache && cacheResult == null && result.isPresent()) { + updateCache(uow, result.get(), getIdentifyingFacets(), statementKeys); + } + + return result; + } finally { + context.stop(); + } + } + + public CompletableFuture> async() { + return CompletableFuture.>supplyAsync( + () -> { + try { return sync(); - - final Timer.Context context = requestLatency.time(); - try { - - Optional result = Optional.empty(); - String[] statementKeys = null; - - if (enableCache) { - Set facets = getFacets(); - statementKeys = getQueryKeys(); - result = Optional.of(checkCache(uow, facets, statementKeys)); - } - - if (!result.isPresent()) { - // Formulate the query and execute it against the Cassandra cluster. - ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits, - showValues, true); - - // Transform the query result set into the desired shape. - result = transform(resultSet); - } - - // If we have a result and we're caching then we need to put it into the cache for future requests to find. - if (enableCache && result.isPresent()) { - updateCache(uow, result.get(), statementKeys); - } - - return result; - } finally { - context.stop(); - } - } - - public CompletableFuture> async() { - return CompletableFuture.>supplyAsync(() -> { - try { - return sync(); - } - catch (TimeoutException ex) { - throw new CompletionException(ex); - } + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } }); - } + } - public CompletableFuture> async(UnitOfWork uow) { - if (uow == null) - return async(); - return CompletableFuture.>supplyAsync(() -> { - try { - return sync(); - } - catch (TimeoutException ex) { - throw new CompletionException(ex); - } + public CompletableFuture> async(UnitOfWork uow) { + if (uow == null) return async(); + return CompletableFuture.>supplyAsync( + () -> { + try { + return sync(); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } }); - } + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java index 115ee51..9a73cf2 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java @@ -27,358 +27,377 @@ import com.datastax.driver.core.policies.FallthroughRetryPolicy; import com.datastax.driver.core.policies.RetryPolicy; import com.datastax.driver.core.querybuilder.BuiltStatement; import com.google.common.util.concurrent.ListenableFuture; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.TimeUnit; import net.helenus.core.AbstractSessionOperations; -import net.helenus.core.Helenus; import net.helenus.core.UnitOfWork; +import net.helenus.core.cache.BoundFacet; import net.helenus.core.cache.EntityIdentifyingFacet; -import net.helenus.mapping.HelenusProperty; +import net.helenus.core.reflect.MapExportable; import net.helenus.mapping.value.BeanColumnValueProvider; import net.helenus.support.Either; import net.helenus.support.HelenusException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - public abstract class AbstractStatementOperation> - extends Operation { + extends Operation { - final Logger logger = LoggerFactory.getLogger(getClass()); - protected boolean enableCache = true; - protected boolean showValues = true; - protected TraceContext traceContext; - long queryExecutionTimeout = 10; - TimeUnit queryTimeoutUnits = TimeUnit.SECONDS; - private ConsistencyLevel consistencyLevel; - private ConsistencyLevel serialConsistencyLevel; - private RetryPolicy retryPolicy; - private boolean idempotent = false; - private boolean enableTracing = false; - private long[] defaultTimestamp = null; - private int[] fetchSize = null; - public AbstractStatementOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - this.consistencyLevel = sessionOperations.getDefaultConsistencyLevel(); - this.idempotent = sessionOperations.getDefaultQueryIdempotency(); + final Logger logger = LoggerFactory.getLogger(getClass()); + protected boolean enableCache = true; + protected boolean showValues = true; + protected TraceContext traceContext; + long queryExecutionTimeout = 10; + TimeUnit queryTimeoutUnits = TimeUnit.SECONDS; + private ConsistencyLevel consistencyLevel; + private ConsistencyLevel serialConsistencyLevel; + private RetryPolicy retryPolicy; + private boolean idempotent = false; + private boolean enableTracing = false; + private long[] defaultTimestamp = null; + private int[] fetchSize = null; + + public AbstractStatementOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + this.consistencyLevel = sessionOperations.getDefaultConsistencyLevel(); + this.idempotent = sessionOperations.getDefaultQueryIdempotency(); + } + + public abstract Statement buildStatement(boolean cached); + + public O ignoreCache(boolean enabled) { + enableCache = enabled; + return (O) this; + } + + public O ignoreCache() { + enableCache = true; + return (O) this; + } + + public O showValues(boolean enabled) { + this.showValues = enabled; + return (O) this; + } + + public O defaultTimestamp(long timestamp) { + this.defaultTimestamp = new long[1]; + this.defaultTimestamp[0] = timestamp; + return (O) this; + } + + public O retryPolicy(RetryPolicy retryPolicy) { + this.retryPolicy = retryPolicy; + return (O) this; + } + + public O defaultRetryPolicy() { + this.retryPolicy = DefaultRetryPolicy.INSTANCE; + return (O) this; + } + + public O idempotent() { + this.idempotent = true; + return (O) this; + } + + public O isIdempotent(boolean idempotent) { + this.idempotent = idempotent; + return (O) this; + } + + public O downgradingConsistencyRetryPolicy() { + this.retryPolicy = DowngradingConsistencyRetryPolicy.INSTANCE; + return (O) this; + } + + public O fallthroughRetryPolicy() { + this.retryPolicy = FallthroughRetryPolicy.INSTANCE; + return (O) this; + } + + public O consistency(ConsistencyLevel level) { + this.consistencyLevel = level; + return (O) this; + } + + public O consistencyAny() { + this.consistencyLevel = ConsistencyLevel.ANY; + return (O) this; + } + + public O consistencyOne() { + this.consistencyLevel = ConsistencyLevel.ONE; + return (O) this; + } + + public O consistencyQuorum() { + this.consistencyLevel = ConsistencyLevel.QUORUM; + return (O) this; + } + + public O consistencyAll() { + this.consistencyLevel = ConsistencyLevel.ALL; + return (O) this; + } + + public O consistencyLocalOne() { + this.consistencyLevel = ConsistencyLevel.LOCAL_ONE; + return (O) this; + } + + public O consistencyLocalQuorum() { + this.consistencyLevel = ConsistencyLevel.LOCAL_QUORUM; + return (O) this; + } + + public O consistencyEachQuorum() { + this.consistencyLevel = ConsistencyLevel.EACH_QUORUM; + return (O) this; + } + + public O serialConsistency(ConsistencyLevel level) { + this.serialConsistencyLevel = level; + return (O) this; + } + + public O serialConsistencyAny() { + this.serialConsistencyLevel = ConsistencyLevel.ANY; + return (O) this; + } + + public O serialConsistencyOne() { + this.serialConsistencyLevel = ConsistencyLevel.ONE; + return (O) this; + } + + public O serialConsistencyQuorum() { + this.serialConsistencyLevel = ConsistencyLevel.QUORUM; + return (O) this; + } + + public O serialConsistencyAll() { + this.serialConsistencyLevel = ConsistencyLevel.ALL; + return (O) this; + } + + public O serialConsistencyLocal() { + this.serialConsistencyLevel = ConsistencyLevel.LOCAL_SERIAL; + return (O) this; + } + + public O serialConsistencyLocalQuorum() { + this.serialConsistencyLevel = ConsistencyLevel.LOCAL_QUORUM; + return (O) this; + } + + public O disableTracing() { + this.enableTracing = false; + return (O) this; + } + + public O enableTracing() { + this.enableTracing = true; + return (O) this; + } + + public O tracing(boolean enable) { + this.enableTracing = enable; + return (O) this; + } + + public O fetchSize(int fetchSize) { + this.fetchSize = new int[1]; + this.fetchSize[0] = fetchSize; + return (O) this; + } + + public O queryTimeoutMs(long ms) { + this.queryExecutionTimeout = ms; + this.queryTimeoutUnits = TimeUnit.MILLISECONDS; + return (O) this; + } + + public O queryTimeout(long timeout, TimeUnit units) { + this.queryExecutionTimeout = timeout; + this.queryTimeoutUnits = units; + return (O) this; + } + + public Statement options(Statement statement) { + + if (defaultTimestamp != null) { + statement.setDefaultTimestamp(defaultTimestamp[0]); } - public abstract Statement buildStatement(boolean cached); - - public O ignoreCache(boolean enabled) { - enableCache = enabled; - return (O) this; + if (consistencyLevel != null) { + statement.setConsistencyLevel(consistencyLevel); } - public O ignoreCache() { - enableCache = true; - return (O) this; + if (serialConsistencyLevel != null) { + statement.setSerialConsistencyLevel(serialConsistencyLevel); } - public O showValues(boolean enabled) { - this.showValues = enabled; - return (O) this; + if (retryPolicy != null) { + statement.setRetryPolicy(retryPolicy); } - public O defaultTimestamp(long timestamp) { - this.defaultTimestamp = new long[1]; - this.defaultTimestamp[0] = timestamp; - return (O) this; + if (enableTracing) { + statement.enableTracing(); + } else { + statement.disableTracing(); } - public O retryPolicy(RetryPolicy retryPolicy) { - this.retryPolicy = retryPolicy; - return (O) this; + if (fetchSize != null) { + statement.setFetchSize(fetchSize[0]); } - public O defaultRetryPolicy() { - this.retryPolicy = DefaultRetryPolicy.INSTANCE; - return (O) this; + if (idempotent) { + statement.setIdempotent(true); } - public O idempotent() { - this.idempotent = true; - return (O) this; + return statement; + } + + public O zipkinContext(TraceContext traceContext) { + if (traceContext != null) { + Tracer tracer = this.sessionOps.getZipkinTracer(); + if (tracer != null) { + this.traceContext = traceContext; + } } - public O isIdempotent(boolean idempotent) { - this.idempotent = idempotent; - return (O) this; + return (O) this; + } + + public Statement statement() { + return buildStatement(false); + } + + public String cql() { + Statement statement = buildStatement(false); + if (statement == null) return ""; + if (statement instanceof BuiltStatement) { + BuiltStatement buildStatement = (BuiltStatement) statement; + return buildStatement.setForceNoValues(true).getQueryString(); + } else { + return statement.toString(); + } + } + + public PreparedStatement prepareStatement() { + + Statement statement = buildStatement(true); + + if (statement instanceof RegularStatement) { + + RegularStatement regularStatement = (RegularStatement) statement; + + return sessionOps.prepare(regularStatement); } - public O downgradingConsistencyRetryPolicy() { - this.retryPolicy = DowngradingConsistencyRetryPolicy.INSTANCE; - return (O) this; + throw new HelenusException("only RegularStatements can be prepared"); + } + + public ListenableFuture prepareStatementAsync() { + + Statement statement = buildStatement(true); + + if (statement instanceof RegularStatement) { + + RegularStatement regularStatement = (RegularStatement) statement; + + return sessionOps.prepareAsync(regularStatement); } - public O fallthroughRetryPolicy() { - this.retryPolicy = FallthroughRetryPolicy.INSTANCE; - return (O) this; - } + throw new HelenusException("only RegularStatements can be prepared"); + } - public O consistency(ConsistencyLevel level) { - this.consistencyLevel = level; - return (O) this; - } + protected E checkCache(UnitOfWork uow, Set facets, String[] statementKeys) { + E result = null; + Optional>> optionalCachedResult = Optional.empty(); - public O consistencyAny() { - this.consistencyLevel = ConsistencyLevel.ANY; - return (O) this; - } - - public O consistencyOne() { - this.consistencyLevel = ConsistencyLevel.ONE; - return (O) this; - } - - public O consistencyQuorum() { - this.consistencyLevel = ConsistencyLevel.QUORUM; - return (O) this; - } - - public O consistencyAll() { - this.consistencyLevel = ConsistencyLevel.ALL; - return (O) this; - } - - public O consistencyLocalOne() { - this.consistencyLevel = ConsistencyLevel.LOCAL_ONE; - return (O) this; - } - - public O consistencyLocalQuorum() { - this.consistencyLevel = ConsistencyLevel.LOCAL_QUORUM; - return (O) this; - } - - public O consistencyEachQuorum() { - this.consistencyLevel = ConsistencyLevel.EACH_QUORUM; - return (O) this; - } - - public O serialConsistency(ConsistencyLevel level) { - this.serialConsistencyLevel = level; - return (O) this; - } - - public O serialConsistencyAny() { - this.serialConsistencyLevel = ConsistencyLevel.ANY; - return (O) this; - } - - public O serialConsistencyOne() { - this.serialConsistencyLevel = ConsistencyLevel.ONE; - return (O) this; - } - - public O serialConsistencyQuorum() { - this.serialConsistencyLevel = ConsistencyLevel.QUORUM; - return (O) this; - } - - public O serialConsistencyAll() { - this.serialConsistencyLevel = ConsistencyLevel.ALL; - return (O) this; - } - - public O serialConsistencyLocal() { - this.serialConsistencyLevel = ConsistencyLevel.LOCAL_SERIAL; - return (O) this; - } - - public O serialConsistencyLocalQuorum() { - this.serialConsistencyLevel = ConsistencyLevel.LOCAL_QUORUM; - return (O) this; - } - - public O disableTracing() { - this.enableTracing = false; - return (O) this; - } - - public O enableTracing() { - this.enableTracing = true; - return (O) this; - } - - public O tracing(boolean enable) { - this.enableTracing = enable; - return (O) this; - } - - public O fetchSize(int fetchSize) { - this.fetchSize = new int[1]; - this.fetchSize[0] = fetchSize; - return (O) this; - } - - public O queryTimeoutMs(long ms) { - this.queryExecutionTimeout = ms; - this.queryTimeoutUnits = TimeUnit.MILLISECONDS; - return (O) this; - } - - public O queryTimeout(long timeout, TimeUnit units) { - this.queryExecutionTimeout = timeout; - this.queryTimeoutUnits = units; - return (O) this; - } - - public Statement options(Statement statement) { - - if (defaultTimestamp != null) { - statement.setDefaultTimestamp(defaultTimestamp[0]); + if (!facets.isEmpty()) { + //TODO(gburd): what about select ResultSet, Tuple... etc.? + optionalCachedResult = uow.cacheLookupByFacet(facets); + if (optionalCachedResult.isPresent()) { + Either> eitherCachedResult = optionalCachedResult.get(); + if (eitherCachedResult.isLeft()) { + uowCacheHits.mark(); + logger.info("UnitOfWork({}) cache hit using facets", uow.hashCode()); + result = (E) eitherCachedResult.getLeft(); } - - if (consistencyLevel != null) { - statement.setConsistencyLevel(consistencyLevel); - } - - if (serialConsistencyLevel != null) { - statement.setSerialConsistencyLevel(serialConsistencyLevel); - } - - if (retryPolicy != null) { - statement.setRetryPolicy(retryPolicy); - } - - if (enableTracing) { - statement.enableTracing(); - } else { - statement.disableTracing(); - } - - if (fetchSize != null) { - statement.setFetchSize(fetchSize[0]); - } - - if (idempotent) { - statement.setIdempotent(true); - } - - return statement; + } } - public O zipkinContext(TraceContext traceContext) { - if (traceContext != null) { - Tracer tracer = this.sessionOps.getZipkinTracer(); - if (tracer != null) { - this.traceContext = traceContext; + if (result == null && statementKeys != null) { + // Then check to see if this query happens to uniquely identify a single object in thecache. + optionalCachedResult = uow.cacheLookupByStatement(statementKeys); + if (optionalCachedResult.isPresent()) { + Either> eitherCachedResult = optionalCachedResult.get(); + // Statements always store Set as the value in the cache. + if (eitherCachedResult.isRight()) { + Set cachedResult = eitherCachedResult.getRight(); + if (cachedResult.size() == 1) { + Optional maybeResult = cachedResult.stream().findFirst(); + if (maybeResult.isPresent()) { + uowCacheHits.mark(); + logger.info("UnitOfWork({}) cache hit for stmt", uow.hashCode()); + } else { + result = null; } + } } - - return (O) this; + } } - public Statement statement() { - return buildStatement(false); + if (result == null) { + uowCacheMiss.mark(); + logger.info("UnitOfWork({}) cache miss", uow.hashCode()); } - public String cql() { - Statement statement = buildStatement(false); - if (statement == null) - return ""; - if (statement instanceof BuiltStatement) { - BuiltStatement buildStatement = (BuiltStatement) statement; - return buildStatement.setForceNoValues(true).getQueryString(); - } else { - return statement.toString(); - } - } + return result; + } - public PreparedStatement prepareStatement() { + protected void updateCache( + UnitOfWork uow, + E pojo, + Map facetMap, + String[] statementKeys) { - Statement statement = buildStatement(true); - - if (statement instanceof RegularStatement) { - - RegularStatement regularStatement = (RegularStatement) statement; - - return sessionOps.prepare(regularStatement); - } - - throw new HelenusException("only RegularStatements can be prepared"); - } - - public ListenableFuture prepareStatementAsync() { - - Statement statement = buildStatement(true); - - if (statement instanceof RegularStatement) { - - RegularStatement regularStatement = (RegularStatement) statement; - - return sessionOps.prepareAsync(regularStatement); - } - - throw new HelenusException("only RegularStatements can be prepared"); - } - - protected E checkCache(UnitOfWork uow, Set facets, String[] statementKeys) { - E result = null; - - if (!facets.isEmpty()) { - //TODO(gburd): what about select ResultSet, Tuple... etc.? - Optional>> optionalCachedResult = uow.cacheLookupByFacet(facets); - if (optionalCachedResult.isPresent()) { - Either> eitherCachedResult = optionalCachedResult.get(); - if (eitherCachedResult.isLeft()) { - uowCacheHits.mark(); - logger.info("UnitOfWork({}) cache hit using facets", uow.hashCode()); - result = (E) eitherCachedResult.getLeft(); - } - } - } else { - // Then check to see if this query happens to uniquely identify a single object in the - // cache. - Optional>> optionalCachedResult = uow.cacheLookupByStatement(statementKeys); - if (optionalCachedResult.isPresent()) { - Either> eitherCachedResult = optionalCachedResult.get(); - // Statements always store Set as the value in the cache. - if (eitherCachedResult.isRight()) { - Set cachedResult = eitherCachedResult.getRight(); - if (cachedResult.size() == 1) { - Optional maybeResult = cachedResult.stream().findFirst(); - if (maybeResult.isPresent()) { - uowCacheHits.mark(); - logger.info("UnitOfWork({}) cache hit for stmt", uow.hashCode()); - } else { - result = null; - } - } - } - } - } - if (result == null) { - uowCacheMiss.mark(); - logger.info("UnitOfWork({}) cache miss", uow.hashCode()); - } - return result; - } - - protected void updateCache(UnitOfWork uow, E pojo, String[] statementKeys) { - - // Insert this entity into the cache for each facet for this entity that we can fully bind. - Map facetMap = Helenus.entity(pojo.getClass()).getIdentifyingFacets(); - facetMap.forEach((facetName, facet) -> { - if (!facet.isFullyBound()) { - HelenusProperty prop = facet.getProperty(); - Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop); - facet.setValueForProperty(prop, value); - } + // Insert this entity into the cache for each facet for this entity that we can fully bind. + Map boundFacets = new HashMap(); + Map valueMap = + pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; + facetMap.forEach( + (facetName, facet) -> { + if (!facet.isFullyBound()) { + EntityIdentifyingFacet.Binder binder = facet.binder(); + facet + .getProperties() + .forEach( + prop -> { + if (valueMap == null) { + Object value = + BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false); + binder.setValueForProperty( + prop, prop.getColumnName().toCql() + "==" + value.toString()); + } else { + binder.setValueForProperty( + prop, + prop.getColumnName().toCql() + + "==" + + valueMap.get(prop.getPropertyName()).toString()); + } + }); + boundFacets.put(facetName, binder.bind()); + } }); - // Cache the value (pojo), the statement key, and the fully bound facets. - if (statementKeys != null) { - uow.cacheUpdate(Either.left(pojo), statementKeys, - facetMap.values() - .stream() - .filter(facet -> facet.isFullyBound()) - .collect(Collectors.toSet())); - } - } - + // Cache the value (pojo), the statement key, and the fully bound facets. + uow.cacheUpdate(Either.left(pojo), statementKeys, boundFacets); + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java b/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java index 2c253ba..e588bda 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java @@ -21,15 +21,14 @@ import com.datastax.driver.core.ResultSet; import com.google.common.base.Function; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import net.helenus.core.AbstractSessionOperations; -import net.helenus.core.UnitOfWork; -import net.helenus.core.cache.EntityIdentifyingFacet; - import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.TimeoutException; import java.util.stream.Stream; +import net.helenus.core.AbstractSessionOperations; +import net.helenus.core.UnitOfWork; +import net.helenus.core.cache.BoundFacet; public abstract class AbstractStreamOperation> extends AbstractStatementOperation { @@ -59,7 +58,15 @@ public abstract class AbstractStreamOperation sync() throws TimeoutException { final Timer.Context context = requestLatency.time(); try { - ResultSet resultSet = this.execute(sessionOps, null, traceContext, queryExecutionTimeout, queryTimeoutUnits, showValues, false); + ResultSet resultSet = + this.execute( + sessionOps, + null, + traceContext, + queryExecutionTimeout, + queryTimeoutUnits, + showValues, + false); return transform(resultSet); } finally { context.stop(); @@ -67,34 +74,40 @@ public abstract class AbstractStreamOperation sync(UnitOfWork uow) throws TimeoutException { - if (uow == null) - return sync(); + if (uow == null) return sync(); final Timer.Context context = requestLatency.time(); try { - Stream result = null; - E cachedResult = null; - String[] statementKeys = null; + Stream result = null; + E cachedResult = null; + String[] statementKeys = null; - if (enableCache) { - Set facets = getFacets(); - statementKeys = getQueryKeys(); - cachedResult = checkCache(uow, facets, statementKeys); - if (cachedResult != null) { - result = Stream.of(cachedResult); - } + if (enableCache) { + Set facets = bindFacetValues(); + statementKeys = getQueryKeys(); + cachedResult = checkCache(uow, facets, statementKeys); + if (cachedResult != null) { + result = Stream.of(cachedResult); } + } - if (result == null) { - ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits, - showValues, true); - result = transform(resultSet); - } + if (result == null) { + ResultSet resultSet = + execute( + sessionOps, + uow, + traceContext, + queryExecutionTimeout, + queryTimeoutUnits, + showValues, + true); + result = transform(resultSet); + } - // If we have a result and we're caching then we need to put it into the cache for future requests to find. - if (enableCache && cachedResult != null) { - updateCache(uow, cachedResult, statementKeys); - } + // If we have a result and we're caching then we need to put it into the cache for future requests to find. + if (enableCache && cachedResult != null) { + updateCache(uow, cachedResult, getIdentifyingFacets(), statementKeys); + } return result; } finally { @@ -103,19 +116,25 @@ public abstract class AbstractStreamOperation> async() { - return CompletableFuture.>supplyAsync(() -> { - try { + return CompletableFuture.>supplyAsync( + () -> { + try { return sync(); - } catch (TimeoutException ex) { throw new CompletionException(ex); } - }); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } + }); } public CompletableFuture> async(UnitOfWork uow) { if (uow == null) return async(); - return CompletableFuture.>supplyAsync(() -> { - try { + return CompletableFuture.>supplyAsync( + () -> { + try { return sync(); - } catch (TimeoutException ex) { throw new CompletionException(ex); } - }); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } + }); } } diff --git a/src/main/java/net/helenus/core/operation/BoundStreamOperation.java b/src/main/java/net/helenus/core/operation/BoundStreamOperation.java index 1c7e03c..d89128d 100644 --- a/src/main/java/net/helenus/core/operation/BoundStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/BoundStreamOperation.java @@ -18,10 +18,9 @@ package net.helenus.core.operation; import com.datastax.driver.core.BoundStatement; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Statement; -import net.helenus.core.cache.EntityIdentifyingFacet; - import java.util.Set; import java.util.stream.Stream; +import net.helenus.core.cache.BoundFacet; public final class BoundStreamOperation extends AbstractStreamOperation> { @@ -42,7 +41,9 @@ public final class BoundStreamOperation } @Override - public Set getFacets() { return delegate.getFacets(); } + public Set bindFacetValues() { + return delegate.bindFacetValues(); + } @Override public Stream transform(ResultSet resultSet) { diff --git a/src/main/java/net/helenus/core/operation/InsertOperation.java b/src/main/java/net/helenus/core/operation/InsertOperation.java index 30bf94c..18c7e6a 100644 --- a/src/main/java/net/helenus/core/operation/InsertOperation.java +++ b/src/main/java/net/helenus/core/operation/InsertOperation.java @@ -19,7 +19,6 @@ import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.Insert; import com.datastax.driver.core.querybuilder.QueryBuilder; -import com.google.common.base.Joiner; import java.util.*; import java.util.concurrent.TimeoutException; import java.util.function.Function; @@ -28,6 +27,7 @@ import net.helenus.core.Getter; import net.helenus.core.Helenus; import net.helenus.core.UnitOfWork; import net.helenus.core.reflect.DefaultPrimitiveTypes; +import net.helenus.core.reflect.Drafted; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusProperty; @@ -170,6 +170,7 @@ public final class InsertOperation extends AbstractOperation iface = entity.getMappingInterface(); if (resultType == iface) { if (values.size() > 0) { + boolean immutable = iface.isAssignableFrom(Drafted.class); Collection properties = entity.getOrderedProperties(); Map backingMap = new HashMap(properties.size()); @@ -190,7 +191,8 @@ public final class InsertOperation extends AbstractOperation propType = prop.getJavaType(); @@ -248,7 +250,8 @@ public final class InsertOperation extends AbstractOperation extends AbstractOperation iface = entity.getMappingInterface(); if (resultType == iface) { - updateCache(uow, result, getQueryKeys()); + updateCache(uow, result, entity.getIdentifyingFacets(), getQueryKeys()); } return result; } diff --git a/src/main/java/net/helenus/core/operation/Operation.java b/src/main/java/net/helenus/core/operation/Operation.java index 4fe5efc..3f07ec2 100644 --- a/src/main/java/net/helenus/core/operation/Operation.java +++ b/src/main/java/net/helenus/core/operation/Operation.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2015 The Helenus Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package net.helenus.core.operation; import brave.Span; @@ -9,15 +24,14 @@ import com.codahale.metrics.Timer; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.ResultSetFuture; import com.datastax.driver.core.Statement; +import java.util.Map; import java.util.Set; -import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; - import net.helenus.core.AbstractSessionOperations; import net.helenus.core.UnitOfWork; +import net.helenus.core.cache.BoundFacet; import net.helenus.core.cache.EntityIdentifyingFacet; -import net.helenus.support.HelenusException; public abstract class Operation { @@ -41,7 +55,8 @@ public abstract class Operation { long timeout, TimeUnit units, boolean showValues, - boolean cached) throws TimeoutException { + boolean cached) + throws TimeoutException { // Start recording in a Zipkin sub-span our execution time to perform this operation. Tracer tracer = session.getZipkinTracer(); @@ -52,14 +67,14 @@ public abstract class Operation { try { - if (span != null) { - span.name("cassandra"); - span.start(); - } + if (span != null) { + span.name("cassandra"); + span.start(); + } - Statement statement = options(buildStatement(cached)); - ResultSetFuture futureResultSet = session.executeAsync(statement, showValues); - return futureResultSet.getUninterruptibly(timeout, units); + Statement statement = options(buildStatement(cached)); + ResultSetFuture futureResultSet = session.executeAsync(statement, showValues); + return futureResultSet.getUninterruptibly(timeout, units); } finally { if (span != null) { @@ -77,11 +92,14 @@ public abstract class Operation { } public String[] getQueryKeys() { - return null; - } - - public Set getFacets() { return null; } + public Map getIdentifyingFacets() { + return null; + } + + public Set bindFacetValues() { + return null; + } } diff --git a/src/main/java/net/helenus/core/operation/SelectFirstOperation.java b/src/main/java/net/helenus/core/operation/SelectFirstOperation.java index 523dbbd..74970ff 100644 --- a/src/main/java/net/helenus/core/operation/SelectFirstOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectFirstOperation.java @@ -17,11 +17,12 @@ package net.helenus.core.operation; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.BuiltStatement; -import net.helenus.core.cache.EntityIdentifyingFacet; - +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.function.Function; +import net.helenus.core.cache.BoundFacet; +import net.helenus.core.cache.EntityIdentifyingFacet; public final class SelectFirstOperation extends AbstractFilterOptionalOperation> { @@ -40,18 +41,25 @@ public final class SelectFirstOperation return new SelectFirstTransformingOperation(delegate, fn); } - @Override - public String[] getQueryKeys() { - return delegate.getQueryKeys(); - } - @Override public BuiltStatement buildStatement(boolean cached) { return delegate.buildStatement(cached); } @Override - public Set getFacets() { return delegate.getFacets(); } + public String[] getQueryKeys() { + return delegate.getQueryKeys(); + } + + @Override + public Map getIdentifyingFacets() { + return delegate.getIdentifyingFacets(); + } + + @Override + public Set bindFacetValues() { + return delegate.bindFacetValues(); + } @Override public Optional transform(ResultSet resultSet) { diff --git a/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java b/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java index 95f18e8..4ecf46d 100644 --- a/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java @@ -17,11 +17,10 @@ package net.helenus.core.operation; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.BuiltStatement; -import net.helenus.core.cache.EntityIdentifyingFacet; - import java.util.Optional; import java.util.Set; import java.util.function.Function; +import net.helenus.core.cache.BoundFacet; public final class SelectFirstTransformingOperation extends AbstractFilterOptionalOperation> { @@ -44,7 +43,9 @@ public final class SelectFirstTransformingOperation } @Override - public Set getFacets() { return delegate.getFacets(); } + public Set bindFacetValues() { + return delegate.bindFacetValues(); + } @Override public BuiltStatement buildStatement(boolean cached) { diff --git a/src/main/java/net/helenus/core/operation/SelectOperation.java b/src/main/java/net/helenus/core/operation/SelectOperation.java index 73a4553..7435d0f 100644 --- a/src/main/java/net/helenus/core/operation/SelectOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectOperation.java @@ -23,18 +23,16 @@ import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Select; import com.datastax.driver.core.querybuilder.Select.Selection; import com.datastax.driver.core.querybuilder.Select.Where; - +import com.google.common.collect.Iterables; import java.util.*; import java.util.function.Function; import java.util.stream.Stream; import java.util.stream.StreamSupport; - -import com.google.common.collect.Iterables; import net.helenus.core.*; +import net.helenus.core.cache.BoundFacet; import net.helenus.core.cache.EntityIdentifyingFacet; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; -import net.helenus.mapping.HelenusProperty; import net.helenus.mapping.MappingUtil; import net.helenus.mapping.OrderingDirection; import net.helenus.mapping.value.ColumnValueProvider; @@ -197,27 +195,48 @@ public final class SelectOperation extends AbstractFilterStreamOperation getFacets() { + public String[] getQueryKeys() { + int i = 0; + String[] keys = new String[filters.size()]; HelenusEntity entity = props.get(0).getEntity(); - final Set facets = new HashSet<>(filters.size()); + String entityName = entity.getName().toCql(); + for (Filter filter : filters.values()) { + keys[i++] = entityName + '.' + filter.toString(); + } + return keys; + } + + @Override + public Map getIdentifyingFacets() { + HelenusEntity entity = props.get(0).getEntity(); + return entity.getIdentifyingFacets(); + } + + @Override + public Set bindFacetValues() { + HelenusEntity entity = props.get(0).getEntity(); + Set boundFacets = new HashSet(); // Check to see if this select statement has enough information to build one or // more identifying facets. entity .getIdentifyingFacets() .forEach( (facetName, facet) -> { - if (facet.isFullyBound()) { - facets.add(facet); - } else { - HelenusProperty prop = facet.getProperty(); - Filter filter = filters.get(prop); - if (filter != null) { - facet.setValueForProperty(prop, filter.toString()); - facets.add(facet); - } + EntityIdentifyingFacet.Binder binder = facet.binder(); + facet + .getProperties() + .forEach( + prop -> { + Filter filter = filters.get(prop); + if (filter != null) { + binder.setValueForProperty(prop, filter.toString()); + } + }); + if (binder.isFullyBound()) { + boundFacets.add(binder.bind()); } }); - return facets; + return boundFacets; } @Override @@ -262,7 +281,6 @@ public final class SelectOperation extends AbstractFilterStreamOperation extends AbstractFilterStreamOperation> { @@ -44,7 +45,14 @@ public final class SelectTransformingOperation } @Override - public Set getFacets() { return delegate.getFacets(); } + public Set bindFacetValues() { + return delegate.bindFacetValues(); + } + + @Override + public Map getIdentifyingFacets() { + return delegate.getIdentifyingFacets(); + } @Override public BuiltStatement buildStatement(boolean cached) { diff --git a/src/main/java/net/helenus/core/operation/UpdateOperation.java b/src/main/java/net/helenus/core/operation/UpdateOperation.java index f4aa3c7..a86d0d7 100644 --- a/src/main/java/net/helenus/core/operation/UpdateOperation.java +++ b/src/main/java/net/helenus/core/operation/UpdateOperation.java @@ -586,7 +586,7 @@ public final class UpdateOperation extends AbstractFilterOperation implements InvocationHandler { this.classLoader = classLoader; } - public void setCassandraMetadataForHelenusSesion(Metadata metadata) { + public void setCassandraMetadataForHelenusSession(Metadata metadata) { if (metadata != null) { this.metadata = metadata; entity = init(metadata); @@ -130,7 +130,7 @@ public class DslInvocationHandler implements InvocationHandler { && args.length == 1 && args[0] instanceof Metadata) { if (metadata == null) { - this.setCassandraMetadataForHelenusSesion((Metadata) args[0]); + this.setCassandraMetadataForHelenusSession((Metadata) args[0]); } return null; } diff --git a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java index 4845c11..105c2fc 100644 --- a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java +++ b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java @@ -75,7 +75,12 @@ public class MapperInvocationHandler implements InvocationHandler, Serializab return false; } if (Proxy.isProxyClass(otherObj.getClass())) { - return this == Proxy.getInvocationHandler(otherObj); + if (this == Proxy.getInvocationHandler(otherObj)) { + return true; + } + } + if (otherObj instanceof MapExportable && src.equals(((MapExportable) otherObj).toMap())) { + return true; } return false; } diff --git a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java index feeec77..f510a34 100644 --- a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java @@ -123,16 +123,15 @@ public final class HelenusMappingEntity implements HelenusEntity { default: if (primaryProperties != null) { primaryFacet = - new EntityIdentifyingFacet( - primaryProperties.toArray(new HelenusProperty[props.size()])); + new EntityIdentifyingFacet(new HashSet(primaryProperties)); allFacetsBuilder.put("*", primaryFacet); primaryProperties = null; } Optional optionalIndexName = prop.getIndexName(); if (optionalIndexName.isPresent()) { - EntityIdentifyingFacet facet = - new EntityIdentifyingFacet(prop); + EntityIdentifyingFacet facet = new EntityIdentifyingFacet(prop); ancillaryFacetsBuilder.put(prop.getPropertyName(), facet); + allFacetsBuilder.put(prop.getPropertyName(), facet); } } } diff --git a/src/main/java/net/helenus/mapping/value/BeanColumnValueProvider.java b/src/main/java/net/helenus/mapping/value/BeanColumnValueProvider.java index a87fd15..9c1c44d 100644 --- a/src/main/java/net/helenus/mapping/value/BeanColumnValueProvider.java +++ b/src/main/java/net/helenus/mapping/value/BeanColumnValueProvider.java @@ -25,7 +25,8 @@ public enum BeanColumnValueProvider implements ColumnValueProvider { INSTANCE; @Override - public V getColumnValue(Object bean, int columnIndexUnused, HelenusProperty property) { + public V getColumnValue( + Object bean, int columnIndexUnused, HelenusProperty property, boolean immutable) { Method getter = property.getGetterMethod(); diff --git a/src/main/java/net/helenus/mapping/value/ColumnValueProvider.java b/src/main/java/net/helenus/mapping/value/ColumnValueProvider.java index ece28a8..45c604b 100644 --- a/src/main/java/net/helenus/mapping/value/ColumnValueProvider.java +++ b/src/main/java/net/helenus/mapping/value/ColumnValueProvider.java @@ -22,7 +22,11 @@ import net.helenus.mapping.HelenusProperty; public interface ColumnValueProvider { - V getColumnValue(Object source, int columnIndex, HelenusProperty property); + V getColumnValue(Object source, int columnIndex, HelenusProperty property, boolean immutable); + + default V getColumnValue(Object source, int columnIndex, HelenusProperty property) { + return getColumnValue(source, columnIndex, property, false); + } default TypeCodec codecFor(DataType type) { return CodecRegistry.DEFAULT_INSTANCE.codecFor(type); diff --git a/src/main/java/net/helenus/mapping/value/RowColumnValueProvider.java b/src/main/java/net/helenus/mapping/value/RowColumnValueProvider.java index 305ec38..65d5e82 100644 --- a/src/main/java/net/helenus/mapping/value/RowColumnValueProvider.java +++ b/src/main/java/net/helenus/mapping/value/RowColumnValueProvider.java @@ -16,9 +16,14 @@ package net.helenus.mapping.value; import com.datastax.driver.core.*; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import java.nio.ByteBuffer; import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.function.Function; import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; @@ -32,15 +37,16 @@ public final class RowColumnValueProvider implements ColumnValueProvider { } @Override - public V getColumnValue(Object sourceObj, int columnIndex, HelenusProperty property) { + public V getColumnValue( + Object sourceObj, int columnIndex, HelenusProperty property, boolean immutable) { Row source = (Row) sourceObj; Object value = null; if (columnIndex != -1) { - value = readValueByIndex(source, columnIndex); + value = readValueByIndex(source, columnIndex, immutable); } else { - value = readValueByName(source, property.getColumnName().getName()); + value = readValueByName(source, property.getColumnName().getName(), immutable); } if (value != null) { @@ -55,7 +61,7 @@ public final class RowColumnValueProvider implements ColumnValueProvider { return (V) value; } - private Object readValueByIndex(Row source, int columnIndex) { + private Object readValueByIndex(Row source, int columnIndex, boolean immutable) { if (source.isNull(columnIndex)) { return null; @@ -71,14 +77,18 @@ public final class RowColumnValueProvider implements ColumnValueProvider { switch (columnType.getName()) { case SET: - return source.getSet(columnIndex, codecFor(typeArguments.get(0)).getJavaType()); + Set set = source.getSet(columnIndex, codecFor(typeArguments.get(0)).getJavaType()); + return immutable ? ImmutableSet.copyOf(set) : set; case MAP: - return source.getMap( - columnIndex, - codecFor(typeArguments.get(0)).getJavaType(), - codecFor(typeArguments.get(1)).getJavaType()); + Map map = + source.getMap( + columnIndex, + codecFor(typeArguments.get(0)).getJavaType(), + codecFor(typeArguments.get(1)).getJavaType()); + return immutable ? ImmutableMap.copyOf(map) : map; case LIST: - return source.getList(columnIndex, codecFor(typeArguments.get(0)).getJavaType()); + List list = source.getList(columnIndex, codecFor(typeArguments.get(0)).getJavaType()); + return immutable ? ImmutableList.copyOf(list) : list; } } @@ -88,7 +98,7 @@ public final class RowColumnValueProvider implements ColumnValueProvider { return value; } - private Object readValueByName(Row source, String columnName) { + private Object readValueByName(Row source, String columnName, boolean immutable) { if (source.isNull(columnName)) { return null; @@ -104,14 +114,18 @@ public final class RowColumnValueProvider implements ColumnValueProvider { switch (columnType.getName()) { case SET: - return source.getSet(columnName, codecFor(typeArguments.get(0)).getJavaType()); + Set set = source.getSet(columnName, codecFor(typeArguments.get(0)).getJavaType()); + return immutable ? ImmutableSet.copyOf(set) : set; case MAP: - return source.getMap( - columnName, - codecFor(typeArguments.get(0)).getJavaType(), - codecFor(typeArguments.get(1)).getJavaType()); + Map map = + source.getMap( + columnName, + codecFor(typeArguments.get(0)).getJavaType(), + codecFor(typeArguments.get(1)).getJavaType()); + return immutable ? ImmutableMap.copyOf(map) : map; case LIST: - return source.getList(columnName, codecFor(typeArguments.get(0)).getJavaType()); + List list = source.getList(columnName, codecFor(typeArguments.get(0)).getJavaType()); + return immutable ? ImmutableList.copyOf(list) : list; } } diff --git a/src/main/java/net/helenus/mapping/value/TupleColumnValueProvider.java b/src/main/java/net/helenus/mapping/value/TupleColumnValueProvider.java index c6e8e2e..569598c 100644 --- a/src/main/java/net/helenus/mapping/value/TupleColumnValueProvider.java +++ b/src/main/java/net/helenus/mapping/value/TupleColumnValueProvider.java @@ -34,7 +34,8 @@ public final class TupleColumnValueProvider implements ColumnValueProvider { } @Override - public V getColumnValue(Object sourceObj, int columnIndexUnused, HelenusProperty property) { + public V getColumnValue( + Object sourceObj, int columnIndexUnused, HelenusProperty property, boolean immutable) { int columnIndex = property.getOrdinal(); diff --git a/src/main/java/net/helenus/mapping/value/UDTColumnValueProvider.java b/src/main/java/net/helenus/mapping/value/UDTColumnValueProvider.java index 5b617b0..d6f0c5a 100644 --- a/src/main/java/net/helenus/mapping/value/UDTColumnValueProvider.java +++ b/src/main/java/net/helenus/mapping/value/UDTColumnValueProvider.java @@ -35,7 +35,8 @@ public final class UDTColumnValueProvider implements ColumnValueProvider { @Override @SuppressWarnings("unchecked") - public V getColumnValue(Object sourceObj, int columnIndexUnused, HelenusProperty property) { + public V getColumnValue( + Object sourceObj, int columnIndexUnused, HelenusProperty property, boolean immutable) { UDTValue source = (UDTValue) sourceObj; diff --git a/src/main/java/net/helenus/mapping/value/ValueProviderMap.java b/src/main/java/net/helenus/mapping/value/ValueProviderMap.java index bd04eb2..4a0cad2 100644 --- a/src/main/java/net/helenus/mapping/value/ValueProviderMap.java +++ b/src/main/java/net/helenus/mapping/value/ValueProviderMap.java @@ -19,6 +19,7 @@ import java.util.Collection; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import net.helenus.core.reflect.Drafted; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusProperty; import net.helenus.support.HelenusMappingException; @@ -28,11 +29,13 @@ public final class ValueProviderMap implements Map { private final Object source; private final ColumnValueProvider valueProvider; private final HelenusEntity entity; + private final boolean immutable; public ValueProviderMap(Object source, ColumnValueProvider valueProvider, HelenusEntity entity) { this.source = source; this.valueProvider = valueProvider; this.entity = entity; + this.immutable = entity.getMappingInterface().isAssignableFrom(Drafted.class); } @Override @@ -41,7 +44,7 @@ public final class ValueProviderMap implements Map { String name = (String) key; HelenusProperty prop = entity.getProperty(name); if (prop != null) { - return valueProvider.getColumnValue(source, -1, prop); + return valueProvider.getColumnValue(source, -1, prop, immutable); } } return null; @@ -126,4 +129,17 @@ public final class ValueProviderMap implements Map { public String toString() { return source.toString(); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || (!o.getClass().isAssignableFrom(Map.class) && getClass() != o.getClass())) + return false; + + Map that = (Map) o; + if (this.size() != that.size()) return false; + for (String key : this.keySet()) if (!this.get(key).equals(that.get(key))) return false; + + return true; + } } diff --git a/src/test/java/net/helenus/test/integration/core/collection/CollectionTest.java b/src/test/java/net/helenus/test/integration/core/collection/CollectionTest.java index 2c1cb1f..bd1ac60 100644 --- a/src/test/java/net/helenus/test/integration/core/collection/CollectionTest.java +++ b/src/test/java/net/helenus/test/integration/core/collection/CollectionTest.java @@ -27,7 +27,6 @@ import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.TimeoutException; - import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; diff --git a/src/test/java/net/helenus/test/integration/core/counter/CounterTest.java b/src/test/java/net/helenus/test/integration/core/counter/CounterTest.java index c2cbfe0..b1c8c0f 100644 --- a/src/test/java/net/helenus/test/integration/core/counter/CounterTest.java +++ b/src/test/java/net/helenus/test/integration/core/counter/CounterTest.java @@ -17,6 +17,7 @@ package net.helenus.test.integration.core.counter; import static net.helenus.core.Query.eq; +import java.util.concurrent.TimeoutException; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; @@ -24,8 +25,6 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import java.util.concurrent.TimeoutException; - public class CounterTest extends AbstractEmbeddedCassandraTest { static Page page; diff --git a/src/test/java/net/helenus/test/integration/core/hierarchy/HierarchyTest.java b/src/test/java/net/helenus/test/integration/core/hierarchy/HierarchyTest.java index ef7fcdc..f5073bf 100644 --- a/src/test/java/net/helenus/test/integration/core/hierarchy/HierarchyTest.java +++ b/src/test/java/net/helenus/test/integration/core/hierarchy/HierarchyTest.java @@ -5,7 +5,6 @@ import static net.helenus.core.Query.eq; import java.util.Optional; import java.util.Random; import java.util.concurrent.TimeoutException; - import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; diff --git a/src/test/java/net/helenus/test/integration/core/index/SecondaryIndexTest.java b/src/test/java/net/helenus/test/integration/core/index/SecondaryIndexTest.java index 299523c..5882d8f 100644 --- a/src/test/java/net/helenus/test/integration/core/index/SecondaryIndexTest.java +++ b/src/test/java/net/helenus/test/integration/core/index/SecondaryIndexTest.java @@ -15,6 +15,7 @@ */ package net.helenus.test.integration.core.index; +import java.util.concurrent.TimeoutException; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.Query; @@ -23,8 +24,6 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import java.util.concurrent.TimeoutException; - public class SecondaryIndexTest extends AbstractEmbeddedCassandraTest { Book book; diff --git a/src/test/java/net/helenus/test/integration/core/simple/SimpleUserTest.java b/src/test/java/net/helenus/test/integration/core/simple/SimpleUserTest.java index 77f4252..0a94e2b 100644 --- a/src/test/java/net/helenus/test/integration/core/simple/SimpleUserTest.java +++ b/src/test/java/net/helenus/test/integration/core/simple/SimpleUserTest.java @@ -20,7 +20,6 @@ import static net.helenus.core.Query.eq; import com.datastax.driver.core.ResultSet; import java.util.*; import java.util.concurrent.TimeoutException; - import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.Operator; diff --git a/src/test/java/net/helenus/test/integration/core/tuple/InnerTupleTest.java b/src/test/java/net/helenus/test/integration/core/tuple/InnerTupleTest.java index d10f1be..500689b 100644 --- a/src/test/java/net/helenus/test/integration/core/tuple/InnerTupleTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuple/InnerTupleTest.java @@ -15,6 +15,7 @@ */ package net.helenus.test.integration.core.tuple; +import java.util.concurrent.TimeoutException; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.Query; @@ -23,8 +24,6 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import java.util.concurrent.TimeoutException; - public class InnerTupleTest extends AbstractEmbeddedCassandraTest { static PhotoAlbum photoAlbum; diff --git a/src/test/java/net/helenus/test/integration/core/tuple/TupleTest.java b/src/test/java/net/helenus/test/integration/core/tuple/TupleTest.java index b97b7a3..5fbe1b7 100644 --- a/src/test/java/net/helenus/test/integration/core/tuple/TupleTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuple/TupleTest.java @@ -20,6 +20,7 @@ import static net.helenus.core.Query.eq; import com.datastax.driver.core.DataType; import com.datastax.driver.core.TupleType; import com.datastax.driver.core.TupleValue; +import java.util.concurrent.TimeoutException; import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; @@ -27,8 +28,6 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import java.util.concurrent.TimeoutException; - public class TupleTest extends AbstractEmbeddedCassandraTest { static Album album; diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleKeyMapTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleKeyMapTest.java index d70ecf7..b5501e3 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleKeyMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleKeyMapTest.java @@ -18,7 +18,6 @@ package net.helenus.test.integration.core.tuplecollection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeoutException; - import net.helenus.core.Query; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleListTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleListTest.java index 96a5792..c09685d 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleListTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleListTest.java @@ -18,7 +18,6 @@ package net.helenus.test.integration.core.tuplecollection; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeoutException; - import net.helenus.core.Query; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleMapTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleMapTest.java index 2d72de9..ef95e1f 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleMapTest.java @@ -18,7 +18,6 @@ package net.helenus.test.integration.core.tuplecollection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeoutException; - import net.helenus.core.Query; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleSetTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleSetTest.java index 03345e4..24c1da5 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleSetTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleSetTest.java @@ -18,7 +18,6 @@ package net.helenus.test.integration.core.tuplecollection; import java.util.HashSet; import java.util.Set; import java.util.concurrent.TimeoutException; - import net.helenus.core.Query; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleValueMapTest.java b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleValueMapTest.java index e3fcd8c..c0de2a3 100644 --- a/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleValueMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/tuplecollection/TupleValueMapTest.java @@ -18,7 +18,6 @@ package net.helenus.test.integration.core.tuplecollection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeoutException; - import net.helenus.core.Query; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTKeyMapTest.java b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTKeyMapTest.java index fb84def..c6d55e3 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTKeyMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTKeyMapTest.java @@ -21,7 +21,6 @@ import static net.helenus.core.Query.get; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeoutException; - import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTListTest.java b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTListTest.java index 6c1cda2..378d559 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTListTest.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTListTest.java @@ -18,7 +18,6 @@ package net.helenus.test.integration.core.udtcollection; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeoutException; - import net.helenus.core.Query; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTMapTest.java b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTMapTest.java index 572f2a1..b563202 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTMapTest.java @@ -18,7 +18,6 @@ package net.helenus.test.integration.core.udtcollection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeoutException; - import net.helenus.core.Query; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTSetTest.java b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTSetTest.java index d96185b..7a23687 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTSetTest.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTSetTest.java @@ -18,7 +18,6 @@ package net.helenus.test.integration.core.udtcollection; import java.util.HashSet; import java.util.Set; import java.util.concurrent.TimeoutException; - import net.helenus.core.Query; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTValueMapTest.java b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTValueMapTest.java index 2bb5121..e1b50f0 100644 --- a/src/test/java/net/helenus/test/integration/core/udtcollection/UDTValueMapTest.java +++ b/src/test/java/net/helenus/test/integration/core/udtcollection/UDTValueMapTest.java @@ -21,7 +21,6 @@ import static net.helenus.core.Query.get; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeoutException; - import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java b/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java index 4e45fff..bf217c2 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java @@ -25,6 +25,7 @@ import net.helenus.core.HelenusSession; import net.helenus.core.UnitOfWork; import net.helenus.core.annotation.Cacheable; import net.helenus.mapping.annotation.Column; +import net.helenus.mapping.annotation.Index; import net.helenus.mapping.annotation.PartitionKey; import net.helenus.mapping.annotation.Table; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; @@ -39,6 +40,7 @@ interface Widget { UUID id(); @Column + @Index String name(); } @@ -141,6 +143,41 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest { }); } } + + @Test + public void testSelectViaIndexAfterSelect() throws Exception { + Widget w1, w2; + UUID key = UUIDs.timeBased(); + + try (UnitOfWork uow = session.begin()) { + // This should inserted Widget, but not cache it. + session + .insert(widget) + .value(widget::id, key) + .value(widget::name, RandomString.make(20)) + .sync(); + + // This should read from the database and return a Widget. + w1 = + session.select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null); + + // This should read from the cache and get the same instance of a Widget. + w2 = + session + .select(widget) + .where(widget::name, eq(w1.name())) + .single() + .sync(uow) + .orElse(null); + + uow.commit() + .andThen( + () -> { + Assert.assertEquals(w1, w2); + }); + } + } + /* @Test public void testSelectAfterInsertProperlyCachesEntity() throws Exception { diff --git a/src/test/java/net/helenus/test/integration/core/usertype/InnerUserDefinedTypeTest.java b/src/test/java/net/helenus/test/integration/core/usertype/InnerUserDefinedTypeTest.java index d0ebe47..bb0a287 100644 --- a/src/test/java/net/helenus/test/integration/core/usertype/InnerUserDefinedTypeTest.java +++ b/src/test/java/net/helenus/test/integration/core/usertype/InnerUserDefinedTypeTest.java @@ -19,7 +19,6 @@ import com.google.common.collect.Sets; import java.util.Set; import java.util.UUID; import java.util.concurrent.TimeoutException; - import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.Query; diff --git a/src/test/java/net/helenus/test/integration/core/usertype/UserDefinedTypeTest.java b/src/test/java/net/helenus/test/integration/core/usertype/UserDefinedTypeTest.java index d36a600..b5e5ef9 100644 --- a/src/test/java/net/helenus/test/integration/core/usertype/UserDefinedTypeTest.java +++ b/src/test/java/net/helenus/test/integration/core/usertype/UserDefinedTypeTest.java @@ -19,7 +19,6 @@ import com.datastax.driver.core.UDTValue; import com.datastax.driver.core.UserType; import java.util.Set; import java.util.concurrent.TimeoutException; - import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.core.Query; diff --git a/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java b/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java index 2cfb0c2..09f56c4 100644 --- a/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java +++ b/src/test/java/net/helenus/test/integration/core/views/MaterializedViewTest.java @@ -21,7 +21,6 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.TimeoutException; - import net.helenus.core.Helenus; import net.helenus.core.HelenusSession; import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest; @@ -60,15 +59,15 @@ public class MaterializedViewTest extends AbstractEmbeddedCassandraTest { try { session - .insert(cyclist) - .value(cyclist::cid, UUID.randomUUID()) - .value(cyclist::age, 18) - .value(cyclist::birthday, dateFromString("1997-02-08")) - .value(cyclist::country, "Netherlands") - .value(cyclist::name, "Pascal EENKHOORN") - .sync(); + .insert(cyclist) + .value(cyclist::cid, UUID.randomUUID()) + .value(cyclist::age, 18) + .value(cyclist::birthday, dateFromString("1997-02-08")) + .value(cyclist::country, "Netherlands") + .value(cyclist::name, "Pascal EENKHOORN") + .sync(); + } catch (TimeoutException e) { } - catch (TimeoutException e) {} } @Test From 6e687a7e90292abbc5f8978b7dc4c24de9a08374 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Fri, 20 Oct 2017 08:22:35 -0400 Subject: [PATCH 8/9] Formatting --- .../datastax/driver/core/DefaultMetadata.java | 24 +- .../core/querybuilder/IsNotNullClause.java | 43 +- .../core/schemabuilder/CreateCustomIndex.java | 255 ++-- .../schemabuilder/CreateMaterializedView.java | 83 +- .../core/schemabuilder/CreateSasiIndex.java | 21 +- .../core/schemabuilder/CreateTable.java | 24 +- .../schemabuilder/DropMaterializedView.java | 77 +- .../config/DefaultHelenusSettings.java | 33 +- .../helenus/config/GetterMethodDetector.java | 37 +- .../net/helenus/config/HelenusSettings.java | 9 +- .../core/AbstractAuditedEntityDraft.java | 47 +- .../net/helenus/core/AbstractEntityDraft.java | 243 ++-- .../core/AbstractSessionOperations.java | 161 +-- .../net/helenus/core/AbstractUnitOfWork.java | 408 ++++--- src/main/java/net/helenus/core/AutoDdl.java | 5 +- .../java/net/helenus/core/CommitThunk.java | 2 +- .../core/ConflictingUnitOfWorkException.java | 8 +- .../net/helenus/core/DslInstantiator.java | 10 +- src/main/java/net/helenus/core/Filter.java | 127 +- src/main/java/net/helenus/core/Getter.java | 2 +- src/main/java/net/helenus/core/Helenus.java | 244 ++-- .../java/net/helenus/core/HelenusSession.java | 1074 ++++++++--------- .../net/helenus/core/HelenusValidator.java | 33 +- .../net/helenus/core/MapperInstantiator.java | 2 +- src/main/java/net/helenus/core/Mappers.java | 304 ++--- src/main/java/net/helenus/core/Operator.java | 44 +- src/main/java/net/helenus/core/Ordered.java | 48 +- .../net/helenus/core/PostCommitFunction.java | 38 +- src/main/java/net/helenus/core/Postulate.java | 111 +- .../helenus/core/PropertyValueValidator.java | 2 +- src/main/java/net/helenus/core/Query.java | 107 +- .../java/net/helenus/core/SchemaUtil.java | 766 ++++++------ .../net/helenus/core/SessionInitializer.java | 749 ++++++------ .../net/helenus/core/SessionRepository.java | 29 +- .../core/SessionRepositoryBuilder.java | 156 +-- .../net/helenus/core/TableOperations.java | 131 +- .../java/net/helenus/core/UnitOfWork.java | 58 +- .../java/net/helenus/core/UnitOfWorkImpl.java | 8 +- .../net/helenus/core/UserTypeOperations.java | 78 +- .../helenus/core/annotation/Cacheable.java | 3 +- .../net/helenus/core/annotation/Retry.java | 5 +- .../net/helenus/core/aspect/RetryAspect.java | 112 +- .../net/helenus/core/cache/BoundFacet.java | 24 +- .../core/cache/EntityIdentifyingFacet.java | 71 +- .../java/net/helenus/core/cache/Facet.java | 35 +- .../operation/AbstractFilterOperation.java | 110 +- .../AbstractFilterOptionalOperation.java | 113 +- .../AbstractFilterStreamOperation.java | 113 +- .../core/operation/AbstractOperation.java | 129 +- .../operation/AbstractOptionalOperation.java | 193 ++- .../operation/AbstractStatementOperation.java | 727 ++++++----- .../operation/AbstractStreamOperation.java | 187 ++- .../core/operation/BoundOperation.java | 30 +- .../operation/BoundOptionalOperation.java | 37 +- .../core/operation/BoundStreamOperation.java | 58 +- .../core/operation/CountOperation.java | 78 +- .../core/operation/DeleteOperation.java | 144 ++- .../core/operation/InsertOperation.java | 389 +++--- .../net/helenus/core/operation/Operation.java | 122 +- .../core/operation/PreparedOperation.java | 34 +- .../operation/PreparedOptionalOperation.java | 35 +- .../operation/PreparedStreamOperation.java | 35 +- .../core/operation/SelectFirstOperation.java | 71 +- .../SelectFirstTransformingOperation.java | 61 +- .../core/operation/SelectOperation.java | 462 ++++--- .../SelectTransformingOperation.java | 69 +- .../core/operation/UpdateOperation.java | 844 +++++++------ .../core/reflect/DefaultPrimitiveTypes.java | 53 +- .../net/helenus/core/reflect/Drafted.java | 4 +- .../helenus/core/reflect/DslExportable.java | 13 +- .../core/reflect/DslInvocationHandler.java | 252 ++-- .../core/reflect/HelenusNamedProperty.java | 122 +- .../core/reflect/HelenusPropertyNode.java | 135 ++- .../net/helenus/core/reflect/ListDsl.java | 255 ++-- .../java/net/helenus/core/reflect/MapDsl.java | 145 +-- .../helenus/core/reflect/MapExportable.java | 4 +- .../core/reflect/MapperInvocationHandler.java | 166 +-- .../reflect/ReflectionDslInstantiator.java | 27 +- .../core/reflect/ReflectionInstantiator.java | 17 +- .../reflect/ReflectionMapperInstantiator.java | 18 +- .../java/net/helenus/core/reflect/SetDsl.java | 157 +-- .../helenus/mapping/ColumnInformation.java | 153 ++- .../java/net/helenus/mapping/ColumnType.java | 5 +- .../net/helenus/mapping/HelenusEntity.java | 15 +- .../helenus/mapping/HelenusEntityType.java | 5 +- .../helenus/mapping/HelenusMappingEntity.java | 469 ++++--- .../mapping/HelenusMappingProperty.java | 266 ++-- .../net/helenus/mapping/HelenusProperty.java | 30 +- .../net/helenus/mapping/IdentityName.java | 58 +- .../java/net/helenus/mapping/MappingUtil.java | 346 +++--- .../helenus/mapping/OrderingDirection.java | 34 +- .../TypeAndOrdinalColumnComparator.java | 17 +- .../mapping/annotation/ClusteringColumn.java | 127 +- .../helenus/mapping/annotation/Column.java | 68 +- .../mapping/annotation/Constraints.java | 380 +++--- .../mapping/annotation/CoveringIndex.java | 68 +- .../net/helenus/mapping/annotation/Index.java | 66 +- .../mapping/annotation/InheritedTable.java | 6 +- .../mapping/annotation/MaterializedView.java | 45 +- .../mapping/annotation/PartitionKey.java | 77 +- .../mapping/annotation/StaticColumn.java | 55 +- .../net/helenus/mapping/annotation/Table.java | 42 +- .../helenus/mapping/annotation/Transient.java | 8 +- .../net/helenus/mapping/annotation/Tuple.java | 16 +- .../net/helenus/mapping/annotation/Types.java | 823 +++++++------ .../net/helenus/mapping/annotation/UDT.java | 31 +- .../convert/AbstractEntityValueWriter.java | 57 +- .../ByteArrayToByteBufferConverter.java | 16 +- .../ByteBufferToByteArrayConverter.java | 16 +- .../CamelCaseToUnderscoreConverter.java | 19 +- .../convert/DateToTimeuuidConverter.java | 13 +- .../convert/EnumToStringConverter.java | 10 +- .../mapping/convert/ProxyValueReader.java | 33 +- .../convert/StringToEnumConverter.java | 16 +- .../convert/TimeuuidToDateConverter.java | 11 +- .../mapping/convert/TupleValueWriter.java | 55 +- .../mapping/convert/TypedConverter.java | 64 +- .../mapping/convert/UDTValueWriter.java | 55 +- .../tuple/EntityToTupleValueConverter.java | 14 +- .../tuple/MapToTupleKeyMapConverter.java | 21 +- .../convert/tuple/MapToTupleMapConverter.java | 30 +- .../tuple/MapToTupleValueMapConverter.java | 21 +- .../convert/tuple/SetToTupleSetConverter.java | 20 +- .../tuple/TupleKeyMapToMapConverter.java | 20 +- .../tuple/TupleListToListConverter.java | 20 +- .../convert/tuple/TupleMapToMapConverter.java | 27 +- .../convert/tuple/TupleSetToSetConverter.java | 20 +- .../tuple/TupleValueMapToMapConverter.java | 20 +- .../tuple/TupleValueToEntityConverter.java | 13 +- .../udt/EntityToUDTValueConverter.java | 8 +- .../convert/udt/ListToUDTListConverter.java | 20 +- .../convert/udt/MapToUDTKeyMapConverter.java | 20 +- .../convert/udt/MapToUDTMapConverter.java | 30 +- .../udt/MapToUDTValueMapConverter.java | 21 +- .../convert/udt/SetToUDTSetConverter.java | 20 +- .../convert/udt/UDTKeyMapToMapConverter.java | 20 +- .../convert/udt/UDTListToListConverter.java | 20 +- .../convert/udt/UDTMapToMapConverter.java | 27 +- .../convert/udt/UDTSetToSetConverter.java | 20 +- .../udt/UDTValueMapToMapConverter.java | 20 +- .../udt/UDTValueToEntityConverter.java | 13 +- .../javatype/AbstractCollectionJavaType.java | 6 +- .../mapping/javatype/AbstractJavaType.java | 159 +-- .../mapping/javatype/ByteArrayJavaType.java | 64 +- .../mapping/javatype/ByteBufferJavaType.java | 38 +- .../mapping/javatype/DateJavaType.java | 74 +- .../mapping/javatype/EnumJavaType.java | 50 +- .../mapping/javatype/ListJavaType.java | 156 +-- .../mapping/javatype/LongJavaType.java | 44 +- .../helenus/mapping/javatype/MapJavaType.java | 449 ++++--- .../mapping/javatype/MappingJavaTypes.java | 298 ++--- .../helenus/mapping/javatype/SetJavaType.java | 156 +-- .../mapping/javatype/SimpleJavaTypes.java | 63 +- .../mapping/javatype/StringJavaType.java | 42 +- .../mapping/javatype/TupleValueJavaType.java | 158 ++- .../mapping/javatype/UDTValueJavaType.java | 119 +- .../mapping/javatype/UUIDJavaType.java | 36 +- .../type/AbstractCollectionDataType.java | 12 +- .../mapping/type/AbstractDataType.java | 49 +- .../net/helenus/mapping/type/DTDataType.java | 257 ++-- .../type/ListToTupleListConverter.java | 21 +- .../mapping/type/OptionalColumnMetadata.java | 4 +- .../net/helenus/mapping/type/UDTDataType.java | 132 +- .../mapping/type/UDTKeyMapDataType.java | 132 +- .../helenus/mapping/type/UDTListDataType.java | 124 +- .../helenus/mapping/type/UDTMapDataType.java | 173 ++- .../helenus/mapping/type/UDTSetDataType.java | 121 +- .../mapping/type/UDTValueMapDataType.java | 133 +- .../mapping/validator/AlphabetValidator.java | 45 +- .../mapping/validator/EmailValidator.java | 34 +- .../mapping/validator/LengthValidator.java | 27 +- .../mapping/validator/LowerCaseValidator.java | 53 +- .../mapping/validator/MaxLengthValidator.java | 30 +- .../mapping/validator/MinLengthValidator.java | 30 +- .../mapping/validator/NotEmptyValidator.java | 31 +- .../mapping/validator/NotNullValidator.java | 14 +- .../mapping/validator/NumberValidator.java | 40 +- .../mapping/validator/PatternValidator.java | 29 +- .../mapping/validator/SizeConstraint.java | 52 +- .../mapping/validator/UpperCaseValidator.java | 53 +- .../value/BeanColumnValueProvider.java | 38 +- .../mapping/value/ColumnValuePreparer.java | 9 +- .../mapping/value/ColumnValueProvider.java | 15 +- .../mapping/value/RowColumnValueProvider.java | 162 ++- .../value/StatementColumnValuePreparer.java | 43 +- .../value/TupleColumnValuePreparer.java | 54 +- .../value/TupleColumnValueProvider.java | 55 +- .../mapping/value/UDTColumnValuePreparer.java | 52 +- .../mapping/value/UDTColumnValueProvider.java | 57 +- .../mapping/value/ValueProviderMap.java | 195 ++- .../java/net/helenus/support/CqlUtil.java | 21 +- .../helenus/support/DslPropertyException.java | 18 +- src/main/java/net/helenus/support/Either.java | 96 +- .../java/net/helenus/support/EitherCase.java | 3 +- src/main/java/net/helenus/support/Fun.java | 324 +++-- .../net/helenus/support/HelenusException.java | 20 +- .../support/HelenusMappingException.java | 20 +- .../java/net/helenus/support/Immutables.java | 689 ++++++----- .../java/net/helenus/support/Mutable.java | 20 +- .../java/net/helenus/support/PackageUtil.java | 206 ++-- .../java/net/helenus/support/Requires.java | 17 +- .../java/net/helenus/support/Timeuuid.java | 89 +- .../net/helenus/support/Transformers.java | 96 +- .../java/net/helenus/support/UuidBuilder.java | 104 +- .../core/unitofwork/UnitOfWorkTest.java | 11 +- 205 files changed, 10518 insertions(+), 10704 deletions(-) diff --git a/src/main/java/com/datastax/driver/core/DefaultMetadata.java b/src/main/java/com/datastax/driver/core/DefaultMetadata.java index 57566ab..4ca45d0 100644 --- a/src/main/java/com/datastax/driver/core/DefaultMetadata.java +++ b/src/main/java/com/datastax/driver/core/DefaultMetadata.java @@ -5,19 +5,19 @@ import java.util.List; public class DefaultMetadata extends Metadata { - public DefaultMetadata() { - super(null); - } + public DefaultMetadata() { + super(null); + } - private DefaultMetadata(Cluster.Manager cluster) { - super(cluster); - } + private DefaultMetadata(Cluster.Manager cluster) { + super(cluster); + } - public TupleType newTupleType(DataType... types) { - return newTupleType(Arrays.asList(types)); - } + public TupleType newTupleType(DataType... types) { + return newTupleType(Arrays.asList(types)); + } - public TupleType newTupleType(List types) { - return new TupleType(types, ProtocolVersion.NEWEST_SUPPORTED, CodecRegistry.DEFAULT_INSTANCE); - } + public TupleType newTupleType(List types) { + return new TupleType(types, ProtocolVersion.NEWEST_SUPPORTED, CodecRegistry.DEFAULT_INSTANCE); + } } diff --git a/src/main/java/com/datastax/driver/core/querybuilder/IsNotNullClause.java b/src/main/java/com/datastax/driver/core/querybuilder/IsNotNullClause.java index 9ff2596..991de7c 100644 --- a/src/main/java/com/datastax/driver/core/querybuilder/IsNotNullClause.java +++ b/src/main/java/com/datastax/driver/core/querybuilder/IsNotNullClause.java @@ -15,34 +15,35 @@ */ package com.datastax.driver.core.querybuilder; -import com.datastax.driver.core.CodecRegistry; import java.util.List; +import com.datastax.driver.core.CodecRegistry; + public class IsNotNullClause extends Clause { - final String name; + final String name; - public IsNotNullClause(String name) { - this.name = name; - } + public IsNotNullClause(String name) { + this.name = name; + } - @Override - String name() { - return name; - } + @Override + String name() { + return name; + } - @Override - Object firstValue() { - return null; - } + @Override + Object firstValue() { + return null; + } - @Override - void appendTo(StringBuilder sb, List variables, CodecRegistry codecRegistry) { - Utils.appendName(name, sb).append(" IS NOT NULL"); - } + @Override + void appendTo(StringBuilder sb, List variables, CodecRegistry codecRegistry) { + Utils.appendName(name, sb).append(" IS NOT NULL"); + } - @Override - boolean containsBindMarker() { - return false; - } + @Override + boolean containsBindMarker() { + return false; + } } diff --git a/src/main/java/com/datastax/driver/core/schemabuilder/CreateCustomIndex.java b/src/main/java/com/datastax/driver/core/schemabuilder/CreateCustomIndex.java index 54e247a..be5b7b6 100644 --- a/src/main/java/com/datastax/driver/core/schemabuilder/CreateCustomIndex.java +++ b/src/main/java/com/datastax/driver/core/schemabuilder/CreateCustomIndex.java @@ -1,157 +1,148 @@ package com.datastax.driver.core.schemabuilder; -import static com.datastax.driver.core.schemabuilder.SchemaStatement.STATEMENT_START; -import static com.datastax.driver.core.schemabuilder.SchemaStatement.validateNotEmpty; -import static com.datastax.driver.core.schemabuilder.SchemaStatement.validateNotKeyWord; +import static com.datastax.driver.core.schemabuilder.SchemaStatement.*; import com.google.common.base.Optional; public class CreateCustomIndex extends CreateIndex { - private String indexName; - private boolean ifNotExists = false; - private Optional keyspaceName = Optional.absent(); - private String tableName; - private String columnName; - private boolean keys; + private String indexName; + private boolean ifNotExists = false; + private Optional keyspaceName = Optional.absent(); + private String tableName; + private String columnName; + private boolean keys; - CreateCustomIndex(String indexName) { - super(indexName); - validateNotEmpty(indexName, "Index name"); - validateNotKeyWord( - indexName, - String.format( - "The index name '%s' is not allowed because it is a reserved keyword", indexName)); - this.indexName = indexName; - } + CreateCustomIndex(String indexName) { + super(indexName); + validateNotEmpty(indexName, "Index name"); + validateNotKeyWord(indexName, + String.format("The index name '%s' is not allowed because it is a reserved keyword", indexName)); + this.indexName = indexName; + } - /** - * Add the 'IF NOT EXISTS' condition to this CREATE INDEX statement. - * - * @return this CREATE INDEX statement. - */ - public CreateIndex ifNotExists() { - this.ifNotExists = true; - return this; - } + /** + * Add the 'IF NOT EXISTS' condition to this CREATE INDEX statement. + * + * @return this CREATE INDEX statement. + */ + public CreateIndex ifNotExists() { + this.ifNotExists = true; + return this; + } - /** - * Specify the keyspace and table to create the index on. - * - * @param keyspaceName the keyspace name. - * @param tableName the table name. - * @return a {@link CreateIndex.CreateIndexOn} that will allow the specification of the column. - */ - public CreateIndex.CreateIndexOn onTable(String keyspaceName, String tableName) { - validateNotEmpty(keyspaceName, "Keyspace name"); - validateNotEmpty(tableName, "Table name"); - validateNotKeyWord( - keyspaceName, - String.format( - "The keyspace name '%s' is not allowed because it is a reserved keyword", - keyspaceName)); - validateNotKeyWord( - tableName, - String.format( - "The table name '%s' is not allowed because it is a reserved keyword", tableName)); - this.keyspaceName = Optional.fromNullable(keyspaceName); - this.tableName = tableName; - return new CreateCustomIndex.CreateIndexOn(); - } + /** + * Specify the keyspace and table to create the index on. + * + * @param keyspaceName + * the keyspace name. + * @param tableName + * the table name. + * @return a {@link CreateIndex.CreateIndexOn} that will allow the specification + * of the column. + */ + public CreateIndex.CreateIndexOn onTable(String keyspaceName, String tableName) { + validateNotEmpty(keyspaceName, "Keyspace name"); + validateNotEmpty(tableName, "Table name"); + validateNotKeyWord(keyspaceName, + String.format("The keyspace name '%s' is not allowed because it is a reserved keyword", keyspaceName)); + validateNotKeyWord(tableName, + String.format("The table name '%s' is not allowed because it is a reserved keyword", tableName)); + this.keyspaceName = Optional.fromNullable(keyspaceName); + this.tableName = tableName; + return new CreateCustomIndex.CreateIndexOn(); + } - /** - * Specify the table to create the index on. - * - * @param tableName the table name. - * @return a {@link CreateIndex.CreateIndexOn} that will allow the specification of the column. - */ - public CreateIndex.CreateIndexOn onTable(String tableName) { - validateNotEmpty(tableName, "Table name"); - validateNotKeyWord( - tableName, - String.format( - "The table name '%s' is not allowed because it is a reserved keyword", tableName)); - this.tableName = tableName; - return new CreateCustomIndex.CreateIndexOn(); - } + /** + * Specify the table to create the index on. + * + * @param tableName + * the table name. + * @return a {@link CreateIndex.CreateIndexOn} that will allow the specification + * of the column. + */ + public CreateIndex.CreateIndexOn onTable(String tableName) { + validateNotEmpty(tableName, "Table name"); + validateNotKeyWord(tableName, + String.format("The table name '%s' is not allowed because it is a reserved keyword", tableName)); + this.tableName = tableName; + return new CreateCustomIndex.CreateIndexOn(); + } - public class CreateIndexOn extends CreateIndex.CreateIndexOn { - /** - * Specify the column to create the index on. - * - * @param columnName the column name. - * @return the final CREATE INDEX statement. - */ - public SchemaStatement andColumn(String columnName) { - validateNotEmpty(columnName, "Column name"); - validateNotKeyWord( - columnName, - String.format( - "The column name '%s' is not allowed because it is a reserved keyword", columnName)); - CreateCustomIndex.this.columnName = columnName; - return SchemaStatement.fromQueryString(buildInternal()); - } + public class CreateIndexOn extends CreateIndex.CreateIndexOn { + /** + * Specify the column to create the index on. + * + * @param columnName + * the column name. + * @return the final CREATE INDEX statement. + */ + public SchemaStatement andColumn(String columnName) { + validateNotEmpty(columnName, "Column name"); + validateNotKeyWord(columnName, + String.format("The column name '%s' is not allowed because it is a reserved keyword", columnName)); + CreateCustomIndex.this.columnName = columnName; + return SchemaStatement.fromQueryString(buildInternal()); + } - /** - * Create an index on the keys of the given map column. - * - * @param columnName the column name. - * @return the final CREATE INDEX statement. - */ - public SchemaStatement andKeysOfColumn(String columnName) { - validateNotEmpty(columnName, "Column name"); - validateNotKeyWord( - columnName, - String.format( - "The column name '%s' is not allowed because it is a reserved keyword", columnName)); - CreateCustomIndex.this.columnName = columnName; - CreateCustomIndex.this.keys = true; - return SchemaStatement.fromQueryString(buildInternal()); - } - } + /** + * Create an index on the keys of the given map column. + * + * @param columnName + * the column name. + * @return the final CREATE INDEX statement. + */ + public SchemaStatement andKeysOfColumn(String columnName) { + validateNotEmpty(columnName, "Column name"); + validateNotKeyWord(columnName, + String.format("The column name '%s' is not allowed because it is a reserved keyword", columnName)); + CreateCustomIndex.this.columnName = columnName; + CreateCustomIndex.this.keys = true; + return SchemaStatement.fromQueryString(buildInternal()); + } + } - String getCustomClassName() { - return ""; - } + String getCustomClassName() { + return ""; + } - String getOptions() { - return ""; - } + String getOptions() { + return ""; + } - @Override - public String buildInternal() { - StringBuilder createStatement = - new StringBuilder(STATEMENT_START).append("CREATE CUSTOM INDEX "); + @Override + public String buildInternal() { + StringBuilder createStatement = new StringBuilder(STATEMENT_START).append("CREATE CUSTOM INDEX "); - if (ifNotExists) { - createStatement.append("IF NOT EXISTS "); - } + if (ifNotExists) { + createStatement.append("IF NOT EXISTS "); + } - createStatement.append(indexName).append(" ON "); + createStatement.append(indexName).append(" ON "); - if (keyspaceName.isPresent()) { - createStatement.append(keyspaceName.get()).append("."); - } - createStatement.append(tableName); + if (keyspaceName.isPresent()) { + createStatement.append(keyspaceName.get()).append("."); + } + createStatement.append(tableName); - createStatement.append("("); - if (keys) { - createStatement.append("KEYS("); - } + createStatement.append("("); + if (keys) { + createStatement.append("KEYS("); + } - createStatement.append(columnName); + createStatement.append(columnName); - if (keys) { - createStatement.append(")"); - } - createStatement.append(")"); + if (keys) { + createStatement.append(")"); + } + createStatement.append(")"); - createStatement.append(" USING '"); - createStatement.append(getCustomClassName()); - createStatement.append("' WITH OPTIONS = {"); - createStatement.append(getOptions()); - createStatement.append(" }"); + createStatement.append(" USING '"); + createStatement.append(getCustomClassName()); + createStatement.append("' WITH OPTIONS = {"); + createStatement.append(getOptions()); + createStatement.append(" }"); - return createStatement.toString(); - } + return createStatement.toString(); + } } diff --git a/src/main/java/com/datastax/driver/core/schemabuilder/CreateMaterializedView.java b/src/main/java/com/datastax/driver/core/schemabuilder/CreateMaterializedView.java index d6ba093..867cbc6 100644 --- a/src/main/java/com/datastax/driver/core/schemabuilder/CreateMaterializedView.java +++ b/src/main/java/com/datastax/driver/core/schemabuilder/CreateMaterializedView.java @@ -5,53 +5,48 @@ import com.datastax.driver.core.querybuilder.Select; public class CreateMaterializedView extends Create { - private String viewName; - private Select.Where selection; - private String primaryKey; - private String clustering; + private String viewName; + private Select.Where selection; + private String primaryKey; + private String clustering; - public CreateMaterializedView( - String keyspaceName, - String viewName, - Select.Where selection, - String primaryKey, - String clustering) { - super(keyspaceName, viewName); - this.viewName = viewName; - this.selection = selection; - this.primaryKey = primaryKey; - this.clustering = clustering; - } + public CreateMaterializedView(String keyspaceName, String viewName, Select.Where selection, String primaryKey, + String clustering) { + super(keyspaceName, viewName); + this.viewName = viewName; + this.selection = selection; + this.primaryKey = primaryKey; + this.clustering = clustering; + } - public String getQueryString(CodecRegistry codecRegistry) { - return buildInternal(); - } + public String getQueryString(CodecRegistry codecRegistry) { + return buildInternal(); + } - public String buildInternal() { - StringBuilder createStatement = - new StringBuilder(STATEMENT_START).append("CREATE MATERIALIZED VIEW"); - if (ifNotExists) { - createStatement.append(" IF NOT EXISTS"); - } - createStatement.append(" "); - if (keyspaceName.isPresent()) { - createStatement.append(keyspaceName.get()).append("."); - } - createStatement.append(viewName); - createStatement.append(" AS "); - createStatement.append(selection.getQueryString()); - createStatement.setLength(createStatement.length() - 1); - createStatement.append(" "); - createStatement.append(primaryKey); - if (clustering != null) { - createStatement.append(" ").append(clustering); - } - createStatement.append(";"); + public String buildInternal() { + StringBuilder createStatement = new StringBuilder(STATEMENT_START).append("CREATE MATERIALIZED VIEW"); + if (ifNotExists) { + createStatement.append(" IF NOT EXISTS"); + } + createStatement.append(" "); + if (keyspaceName.isPresent()) { + createStatement.append(keyspaceName.get()).append("."); + } + createStatement.append(viewName); + createStatement.append(" AS "); + createStatement.append(selection.getQueryString()); + createStatement.setLength(createStatement.length() - 1); + createStatement.append(" "); + createStatement.append(primaryKey); + if (clustering != null) { + createStatement.append(" ").append(clustering); + } + createStatement.append(";"); - return createStatement.toString(); - } + return createStatement.toString(); + } - public String toString() { - return buildInternal(); - } + public String toString() { + return buildInternal(); + } } diff --git a/src/main/java/com/datastax/driver/core/schemabuilder/CreateSasiIndex.java b/src/main/java/com/datastax/driver/core/schemabuilder/CreateSasiIndex.java index 7a82590..6487b32 100644 --- a/src/main/java/com/datastax/driver/core/schemabuilder/CreateSasiIndex.java +++ b/src/main/java/com/datastax/driver/core/schemabuilder/CreateSasiIndex.java @@ -2,17 +2,16 @@ package com.datastax.driver.core.schemabuilder; public class CreateSasiIndex extends CreateCustomIndex { - public CreateSasiIndex(String indexName) { - super(indexName); - } + public CreateSasiIndex(String indexName) { + super(indexName); + } - String getCustomClassName() { - return "org.apache.cassandra.index.sasi.SASIIndex"; - } + String getCustomClassName() { + return "org.apache.cassandra.index.sasi.SASIIndex"; + } - String getOptions() { - return "'analyzer_class': " - + "'org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer', " - + "'case_sensitive': 'false'"; - } + String getOptions() { + return "'analyzer_class': " + "'org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer', " + + "'case_sensitive': 'false'"; + } } diff --git a/src/main/java/com/datastax/driver/core/schemabuilder/CreateTable.java b/src/main/java/com/datastax/driver/core/schemabuilder/CreateTable.java index 7efce6f..cab8549 100644 --- a/src/main/java/com/datastax/driver/core/schemabuilder/CreateTable.java +++ b/src/main/java/com/datastax/driver/core/schemabuilder/CreateTable.java @@ -20,19 +20,19 @@ import com.datastax.driver.core.CodecRegistry; /** A built CREATE TABLE statement. */ public class CreateTable extends Create { - public CreateTable(String keyspaceName, String tableName) { - super(keyspaceName, tableName); - } + public CreateTable(String keyspaceName, String tableName) { + super(keyspaceName, tableName); + } - public CreateTable(String tableName) { - super(tableName); - } + public CreateTable(String tableName) { + super(tableName); + } - public String getQueryString(CodecRegistry codecRegistry) { - return buildInternal(); - } + public String getQueryString(CodecRegistry codecRegistry) { + return buildInternal(); + } - public String toString() { - return buildInternal(); - } + public String toString() { + return buildInternal(); + } } diff --git a/src/main/java/com/datastax/driver/core/schemabuilder/DropMaterializedView.java b/src/main/java/com/datastax/driver/core/schemabuilder/DropMaterializedView.java index 7eca05d..02b622a 100644 --- a/src/main/java/com/datastax/driver/core/schemabuilder/DropMaterializedView.java +++ b/src/main/java/com/datastax/driver/core/schemabuilder/DropMaterializedView.java @@ -4,50 +4,47 @@ import com.google.common.base.Optional; public class DropMaterializedView extends Drop { - enum DroppedItem { - TABLE, - TYPE, - INDEX, - MATERIALIZED_VIEW - } + enum DroppedItem { + TABLE, TYPE, INDEX, MATERIALIZED_VIEW + } - private Optional keyspaceName = Optional.absent(); - private String itemName; - private boolean ifExists = true; - private final String itemType = "MATERIALIZED VIEW"; + private Optional keyspaceName = Optional.absent(); + private String itemName; + private boolean ifExists = true; + private final String itemType = "MATERIALIZED VIEW"; - public DropMaterializedView(String keyspaceName, String viewName) { - this(keyspaceName, viewName, DroppedItem.MATERIALIZED_VIEW); - } + public DropMaterializedView(String keyspaceName, String viewName) { + this(keyspaceName, viewName, DroppedItem.MATERIALIZED_VIEW); + } - private DropMaterializedView(String keyspaceName, String viewName, DroppedItem itemType) { - super(keyspaceName, viewName, Drop.DroppedItem.TABLE); - validateNotEmpty(keyspaceName, "Keyspace name"); - this.keyspaceName = Optional.fromNullable(keyspaceName); - this.itemName = viewName; - } + private DropMaterializedView(String keyspaceName, String viewName, DroppedItem itemType) { + super(keyspaceName, viewName, Drop.DroppedItem.TABLE); + validateNotEmpty(keyspaceName, "Keyspace name"); + this.keyspaceName = Optional.fromNullable(keyspaceName); + this.itemName = viewName; + } - /** - * Add the 'IF EXISTS' condition to this DROP statement. - * - * @return this statement. - */ - public Drop ifExists() { - this.ifExists = true; - return this; - } + /** + * Add the 'IF EXISTS' condition to this DROP statement. + * + * @return this statement. + */ + public Drop ifExists() { + this.ifExists = true; + return this; + } - @Override - public String buildInternal() { - StringBuilder dropStatement = new StringBuilder("DROP " + itemType + " "); - if (ifExists) { - dropStatement.append("IF EXISTS "); - } - if (keyspaceName.isPresent()) { - dropStatement.append(keyspaceName.get()).append("."); - } + @Override + public String buildInternal() { + StringBuilder dropStatement = new StringBuilder("DROP " + itemType + " "); + if (ifExists) { + dropStatement.append("IF EXISTS "); + } + if (keyspaceName.isPresent()) { + dropStatement.append(keyspaceName.get()).append("."); + } - dropStatement.append(itemName); - return dropStatement.toString(); - } + dropStatement.append(itemName); + return dropStatement.toString(); + } } diff --git a/src/main/java/net/helenus/config/DefaultHelenusSettings.java b/src/main/java/net/helenus/config/DefaultHelenusSettings.java index 500fed5..a8daa1c 100644 --- a/src/main/java/net/helenus/config/DefaultHelenusSettings.java +++ b/src/main/java/net/helenus/config/DefaultHelenusSettings.java @@ -17,6 +17,7 @@ package net.helenus.config; import java.lang.reflect.Method; import java.util.function.Function; + import net.helenus.core.DslInstantiator; import net.helenus.core.MapperInstantiator; import net.helenus.core.reflect.ReflectionDslInstantiator; @@ -25,23 +26,23 @@ import net.helenus.mapping.convert.CamelCaseToUnderscoreConverter; public class DefaultHelenusSettings implements HelenusSettings { - @Override - public Function getPropertyToColumnConverter() { - return CamelCaseToUnderscoreConverter.INSTANCE; - } + @Override + public Function getPropertyToColumnConverter() { + return CamelCaseToUnderscoreConverter.INSTANCE; + } - @Override - public Function getGetterMethodDetector() { - return GetterMethodDetector.INSTANCE; - } + @Override + public Function getGetterMethodDetector() { + return GetterMethodDetector.INSTANCE; + } - @Override - public DslInstantiator getDslInstantiator() { - return ReflectionDslInstantiator.INSTANCE; - } + @Override + public DslInstantiator getDslInstantiator() { + return ReflectionDslInstantiator.INSTANCE; + } - @Override - public MapperInstantiator getMapperInstantiator() { - return ReflectionMapperInstantiator.INSTANCE; - } + @Override + public MapperInstantiator getMapperInstantiator() { + return ReflectionMapperInstantiator.INSTANCE; + } } diff --git a/src/main/java/net/helenus/config/GetterMethodDetector.java b/src/main/java/net/helenus/config/GetterMethodDetector.java index 60a9ec0..a4535f5 100644 --- a/src/main/java/net/helenus/config/GetterMethodDetector.java +++ b/src/main/java/net/helenus/config/GetterMethodDetector.java @@ -18,31 +18,32 @@ package net.helenus.config; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.function.Function; + import net.helenus.mapping.annotation.Transient; public enum GetterMethodDetector implements Function { - INSTANCE; + INSTANCE; - @Override - public Boolean apply(Method method) { + @Override + public Boolean apply(Method method) { - if (method == null) { - throw new IllegalArgumentException("empty parameter"); - } + if (method == null) { + throw new IllegalArgumentException("empty parameter"); + } - if (method.getParameterCount() != 0 || method.getReturnType() == void.class) { - return false; - } + if (method.getParameterCount() != 0 || method.getReturnType() == void.class) { + return false; + } - if (Modifier.isStatic(method.getModifiers())) { - return false; - } + if (Modifier.isStatic(method.getModifiers())) { + return false; + } - // Methods marked "Transient" are not mapped, skip them. - if (method.getDeclaredAnnotation(Transient.class) != null) { - return false; - } + // Methods marked "Transient" are not mapped, skip them. + if (method.getDeclaredAnnotation(Transient.class) != null) { + return false; + } - return true; - } + return true; + } } diff --git a/src/main/java/net/helenus/config/HelenusSettings.java b/src/main/java/net/helenus/config/HelenusSettings.java index c8ffee2..27d1431 100644 --- a/src/main/java/net/helenus/config/HelenusSettings.java +++ b/src/main/java/net/helenus/config/HelenusSettings.java @@ -17,16 +17,17 @@ package net.helenus.config; import java.lang.reflect.Method; import java.util.function.Function; + import net.helenus.core.DslInstantiator; import net.helenus.core.MapperInstantiator; public interface HelenusSettings { - Function getPropertyToColumnConverter(); + Function getPropertyToColumnConverter(); - Function getGetterMethodDetector(); + Function getGetterMethodDetector(); - DslInstantiator getDslInstantiator(); + DslInstantiator getDslInstantiator(); - MapperInstantiator getMapperInstantiator(); + MapperInstantiator getMapperInstantiator(); } diff --git a/src/main/java/net/helenus/core/AbstractAuditedEntityDraft.java b/src/main/java/net/helenus/core/AbstractAuditedEntityDraft.java index a9a09e2..f2b16ff 100644 --- a/src/main/java/net/helenus/core/AbstractAuditedEntityDraft.java +++ b/src/main/java/net/helenus/core/AbstractAuditedEntityDraft.java @@ -3,36 +3,37 @@ package net.helenus.core; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.Date; + import net.helenus.core.reflect.MapExportable; public abstract class AbstractAuditedEntityDraft extends AbstractEntityDraft { - public AbstractAuditedEntityDraft(MapExportable entity) { - super(entity); + public AbstractAuditedEntityDraft(MapExportable entity) { + super(entity); - Date in = new Date(); - LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault()); - Date now = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant()); + Date in = new Date(); + LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault()); + Date now = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant()); - String who = getCurrentAuditor(); + String who = getCurrentAuditor(); - if (entity == null) { - if (who != null) { - set("createdBy", who); - } - set("createdAt", now); - } - if (who != null) { - set("modifiedBy", who); - } - set("modifiedAt", now); - } + if (entity == null) { + if (who != null) { + set("createdBy", who); + } + set("createdAt", now); + } + if (who != null) { + set("modifiedBy", who); + } + set("modifiedAt", now); + } - protected String getCurrentAuditor() { - return null; - } + protected String getCurrentAuditor() { + return null; + } - public Date createdAt() { - return (Date) get("createdAt", Date.class); - } + public Date createdAt() { + return (Date) get("createdAt", Date.class); + } } diff --git a/src/main/java/net/helenus/core/AbstractEntityDraft.java b/src/main/java/net/helenus/core/AbstractEntityDraft.java index fbccb3b..6c9bf9f 100644 --- a/src/main/java/net/helenus/core/AbstractEntityDraft.java +++ b/src/main/java/net/helenus/core/AbstractEntityDraft.java @@ -1,7 +1,12 @@ package net.helenus.core; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + import com.google.common.primitives.Primitives; -import java.util.*; + import net.helenus.core.reflect.DefaultPrimitiveTypes; import net.helenus.core.reflect.Drafted; import net.helenus.core.reflect.MapExportable; @@ -9,151 +14,151 @@ import net.helenus.mapping.MappingUtil; public abstract class AbstractEntityDraft implements Drafted { - private final Map backingMap = new HashMap(); - private final MapExportable entity; - private final Map entityMap; + private final Map backingMap = new HashMap(); + private final MapExportable entity; + private final Map entityMap; - public AbstractEntityDraft(MapExportable entity) { - this.entity = entity; - this.entityMap = entity != null ? entity.toMap() : new HashMap(); - } + public AbstractEntityDraft(MapExportable entity) { + this.entity = entity; + this.entityMap = entity != null ? entity.toMap() : new HashMap(); + } - public abstract Class getEntityClass(); + public abstract Class getEntityClass(); - public E build() { - return Helenus.map(getEntityClass(), toMap()); - } + public E build() { + return Helenus.map(getEntityClass(), toMap()); + } - @SuppressWarnings("unchecked") - protected T get(Getter getter, Class returnType) { - return (T) get(this.methodNameFor(getter), returnType); - } + @SuppressWarnings("unchecked") + protected T get(Getter getter, Class returnType) { + return (T) get(this.methodNameFor(getter), returnType); + } - @SuppressWarnings("unchecked") - protected T get(String key, Class returnType) { - T value = (T) backingMap.get(key); + @SuppressWarnings("unchecked") + protected T get(String key, Class returnType) { + T value = (T) backingMap.get(key); - if (value == null) { - value = (T) entityMap.get(key); - if (value == null) { + 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(); - } - } - } + return (T) type.getDefaultValue(); + } + } + } - return value; - } + return value; + } - protected Object set(Getter getter, Object value) { - return set(this.methodNameFor(getter), value); - } + protected Object set(Getter getter, Object value) { + return set(this.methodNameFor(getter), value); + } - protected Object set(String key, Object value) { - if (key == null || value == null) { - return null; - } + protected Object set(String key, Object value) { + if (key == null || value == null) { + return null; + } - backingMap.put(key, value); - return value; - } + backingMap.put(key, value); + return value; + } - @SuppressWarnings("unchecked") - protected T mutate(Getter getter, T value) { - return (T) mutate(this.methodNameFor(getter), value); - } + @SuppressWarnings("unchecked") + protected T mutate(Getter getter, T value) { + return (T) mutate(this.methodNameFor(getter), value); + } - protected Object mutate(String key, Object value) { - Objects.requireNonNull(key); + protected Object mutate(String key, Object value) { + Objects.requireNonNull(key); - if (value == null) { - return null; - } + if (value == null) { + return null; + } - if (entity != null) { - Map map = entity.toMap(); + if (entity != null) { + Map map = entity.toMap(); - if (map.containsKey(key) && !value.equals(map.get(key))) { - backingMap.put(key, value); - return value; - } + if (map.containsKey(key) && !value.equals(map.get(key))) { + backingMap.put(key, value); + return value; + } - return map.get(key); - } else { - backingMap.put(key, value); + return map.get(key); + } else { + backingMap.put(key, value); - return null; - } - } + return null; + } + } - private String methodNameFor(Getter getter) { - return MappingUtil.resolveMappingProperty(getter).getProperty().getPropertyName(); - } + private String methodNameFor(Getter getter) { + return MappingUtil.resolveMappingProperty(getter).getProperty().getPropertyName(); + } - public Object unset(Getter getter) { - return unset(methodNameFor(getter)); - } + public Object unset(Getter getter) { + return unset(methodNameFor(getter)); + } - public Object unset(String key) { - if (key != null) { - Object value = backingMap.get(key); - backingMap.put(key, null); - return value; - } - return null; - } + public Object unset(String key) { + if (key != null) { + Object value = backingMap.get(key); + backingMap.put(key, null); + return value; + } + return null; + } - public boolean reset(Getter getter, T desiredValue) { - return this.reset(this.methodNameFor(getter), desiredValue); - } + public boolean reset(Getter getter, T desiredValue) { + return this.reset(this.methodNameFor(getter), desiredValue); + } - public boolean reset(String key, T desiredValue) { - if (key != null && desiredValue != null) { - @SuppressWarnings("unchecked") - T currentValue = (T) backingMap.get(key); - if (currentValue == null || !currentValue.equals(desiredValue)) { - set(key, desiredValue); - return true; - } - } - return false; - } + public boolean reset(String key, T desiredValue) { + if (key != null && desiredValue != null) { + @SuppressWarnings("unchecked") + T currentValue = (T) backingMap.get(key); + if (currentValue == null || !currentValue.equals(desiredValue)) { + set(key, desiredValue); + return true; + } + } + return false; + } - @Override - public Map toMap() { - return toMap(entityMap); - } + @Override + public Map toMap() { + return toMap(entityMap); + } - public Map toMap(Map entityMap) { - Map combined; - if (entityMap != null && entityMap.size() > 0) { - combined = new HashMap(entityMap.size()); - for (String key : entityMap.keySet()) { - combined.put(key, entityMap.get(key)); - } - } else { - combined = new HashMap(backingMap.size()); - } - for (String key : mutated()) { - combined.put(key, backingMap.get(key)); - } - return combined; - } + public Map toMap(Map entityMap) { + Map combined; + if (entityMap != null && entityMap.size() > 0) { + combined = new HashMap(entityMap.size()); + for (String key : entityMap.keySet()) { + combined.put(key, entityMap.get(key)); + } + } else { + combined = new HashMap(backingMap.size()); + } + for (String key : mutated()) { + combined.put(key, backingMap.get(key)); + } + return combined; + } - @Override - public Set mutated() { - return backingMap.keySet(); - } + @Override + public Set mutated() { + return backingMap.keySet(); + } - @Override - public String toString() { - return backingMap.toString(); - } + @Override + public String toString() { + return backingMap.toString(); + } } diff --git a/src/main/java/net/helenus/core/AbstractSessionOperations.java b/src/main/java/net/helenus/core/AbstractSessionOperations.java index 5721051..8039650 100644 --- a/src/main/java/net/helenus/core/AbstractSessionOperations.java +++ b/src/main/java/net/helenus/core/AbstractSessionOperations.java @@ -15,112 +15,115 @@ */ package net.helenus.core; -import brave.Tracer; +import java.io.PrintStream; +import java.util.concurrent.Executor; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.codahale.metrics.MetricRegistry; import com.datastax.driver.core.*; import com.datastax.driver.core.querybuilder.BuiltStatement; import com.google.common.util.concurrent.ListenableFuture; -import java.io.PrintStream; -import java.util.concurrent.Executor; + +import brave.Tracer; import net.helenus.mapping.value.ColumnValuePreparer; import net.helenus.mapping.value.ColumnValueProvider; import net.helenus.support.HelenusException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public abstract class AbstractSessionOperations { - final Logger logger = LoggerFactory.getLogger(getClass()); + final Logger logger = LoggerFactory.getLogger(getClass()); - public abstract Session currentSession(); + public abstract Session currentSession(); - public abstract String usingKeyspace(); + public abstract String usingKeyspace(); - public abstract boolean isShowCql(); + public abstract boolean isShowCql(); - public abstract PrintStream getPrintStream(); + public abstract PrintStream getPrintStream(); - public abstract Executor getExecutor(); + public abstract Executor getExecutor(); - public abstract SessionRepository getSessionRepository(); + public abstract SessionRepository getSessionRepository(); - public abstract ColumnValueProvider getValueProvider(); + public abstract ColumnValueProvider getValueProvider(); - public abstract ColumnValuePreparer getValuePreparer(); + public abstract ColumnValuePreparer getValuePreparer(); - public abstract ConsistencyLevel getDefaultConsistencyLevel(); + public abstract ConsistencyLevel getDefaultConsistencyLevel(); - public abstract boolean getDefaultQueryIdempotency(); + public abstract boolean getDefaultQueryIdempotency(); - public PreparedStatement prepare(RegularStatement statement) { - try { - log(statement, false); - return currentSession().prepare(statement); - } catch (RuntimeException e) { - throw translateException(e); - } - } + public PreparedStatement prepare(RegularStatement statement) { + try { + log(statement, false); + return currentSession().prepare(statement); + } catch (RuntimeException e) { + throw translateException(e); + } + } - public ListenableFuture prepareAsync(RegularStatement statement) { - try { - log(statement, false); - return currentSession().prepareAsync(statement); - } catch (RuntimeException e) { - throw translateException(e); - } - } + public ListenableFuture prepareAsync(RegularStatement statement) { + try { + log(statement, false); + return currentSession().prepareAsync(statement); + } catch (RuntimeException e) { + throw translateException(e); + } + } - public ResultSet execute(Statement statement, boolean showValues) { - return executeAsync(statement, showValues).getUninterruptibly(); - } + public ResultSet execute(Statement statement, boolean showValues) { + return executeAsync(statement, showValues).getUninterruptibly(); + } - public ResultSetFuture executeAsync(Statement statement, boolean showValues) { - try { - log(statement, showValues); - return currentSession().executeAsync(statement); - } catch (RuntimeException e) { - throw translateException(e); - } - } + public ResultSetFuture executeAsync(Statement statement, boolean showValues) { + try { + log(statement, showValues); + return currentSession().executeAsync(statement); + } catch (RuntimeException e) { + throw translateException(e); + } + } - void log(Statement statement, boolean showValues) { - if (logger.isInfoEnabled()) { - logger.info("Execute statement " + statement); - } - if (isShowCql()) { - if (statement instanceof BuiltStatement) { - BuiltStatement builtStatement = (BuiltStatement) statement; - if (showValues) { - RegularStatement regularStatement = builtStatement.setForceNoValues(true); - printCql(regularStatement.getQueryString()); - } else { - printCql(builtStatement.getQueryString()); - } - } else if (statement instanceof RegularStatement) { - RegularStatement regularStatement = (RegularStatement) statement; - printCql(regularStatement.getQueryString()); - } else { - printCql(statement.toString()); - } - } - } + void log(Statement statement, boolean showValues) { + if (logger.isInfoEnabled()) { + logger.info("Execute statement " + statement); + } + if (isShowCql()) { + if (statement instanceof BuiltStatement) { + BuiltStatement builtStatement = (BuiltStatement) statement; + if (showValues) { + RegularStatement regularStatement = builtStatement.setForceNoValues(true); + printCql(regularStatement.getQueryString()); + } else { + printCql(builtStatement.getQueryString()); + } + } else if (statement instanceof RegularStatement) { + RegularStatement regularStatement = (RegularStatement) statement; + printCql(regularStatement.getQueryString()); + } else { + printCql(statement.toString()); + } + } + } - public Tracer getZipkinTracer() { - return null; - } + public Tracer getZipkinTracer() { + return null; + } - public MetricRegistry getMetricRegistry() { - return null; - } + public MetricRegistry getMetricRegistry() { + return null; + } - RuntimeException translateException(RuntimeException e) { - if (e instanceof HelenusException) { - return e; - } - throw new HelenusException(e); - } + RuntimeException translateException(RuntimeException e) { + if (e instanceof HelenusException) { + return e; + } + throw new HelenusException(e); + } - void printCql(String cql) { - getPrintStream().println(cql); - } + void printCql(String cql) { + getPrintStream().println(cql); + } } diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index 9533ee1..b689ab2 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -15,239 +15,237 @@ */ package net.helenus.core; -import com.diffplug.common.base.Errors; -import com.google.common.collect.TreeTraverser; import java.util.*; import java.util.stream.Collectors; -import net.helenus.core.cache.BoundFacet; -import net.helenus.support.Either; + import org.ahocorasick.trie.Emit; import org.ahocorasick.trie.Trie; +import com.diffplug.common.base.Errors; +import com.google.common.collect.TreeTraverser; + +import net.helenus.core.cache.BoundFacet; +import net.helenus.core.cache.Facet; +import net.helenus.support.Either; + /** Encapsulates the concept of a "transaction" as a unit-of-work. */ -public abstract class AbstractUnitOfWork - implements UnitOfWork, AutoCloseable { - private final List> nested = new ArrayList<>(); - private final HelenusSession session; - private final AbstractUnitOfWork parent; - private List postCommit = new ArrayList(); - private final Map>> cache = - new HashMap>>(); - private Trie cacheIndex = - Trie.builder().ignoreOverlaps().onlyWholeWordsWhiteSpaceSeparated().build(); - private boolean aborted = false; - private boolean committed = false; +public abstract class AbstractUnitOfWork implements UnitOfWork, AutoCloseable { + private final List> nested = new ArrayList<>(); + private final HelenusSession session; + private final AbstractUnitOfWork parent; + private List postCommit = new ArrayList(); + private final Map>> cache = new HashMap>>(); + private Trie cacheIndex = Trie.builder().ignoreOverlaps().build(); + private boolean aborted = false; + private boolean committed = false; - protected AbstractUnitOfWork(HelenusSession session, AbstractUnitOfWork parent) { - Objects.requireNonNull(session, "containing session cannot be null"); + protected AbstractUnitOfWork(HelenusSession session, AbstractUnitOfWork parent) { + Objects.requireNonNull(session, "containing session cannot be null"); - this.session = session; - this.parent = parent; - } + this.session = session; + this.parent = parent; + } - @Override - public void addNestedUnitOfWork(UnitOfWork uow) { - synchronized (nested) { - nested.add((AbstractUnitOfWork) uow); - } - } + @Override + public void addNestedUnitOfWork(UnitOfWork uow) { + synchronized (nested) { + nested.add((AbstractUnitOfWork) uow); + } + } - @Override - public UnitOfWork begin() { - // log.record(txn::start) - return this; - } + @Override + public UnitOfWork begin() { + // log.record(txn::start) + return this; + } - private void applyPostCommitFunctions() { - if (!postCommit.isEmpty()) { - for (CommitThunk f : postCommit) { - f.apply(); - } - } - } + private void applyPostCommitFunctions() { + if (!postCommit.isEmpty()) { + for (CommitThunk f : postCommit) { + f.apply(); + } + } + } - @Override - public Optional>> cacheLookupByFacet(Set facets) { - Optional>> result = Optional.empty(); - Collection emits = - cacheIndex.parseText( - String.join( - " ", facets.stream().map(facet -> facet.toString()).collect(Collectors.toList()))); - for (Emit emit : emits) { - // NOTE: rethink. should this match *all* facets? how do I know which emit keyword is the primary key? - String key = emit.getKeyword(); - result = cacheLookup(key); - if (result.isPresent()) { - return result; - } - } - if (!result.isPresent()) { - // Be sure to check all enclosing UnitOfWork caches as well, we may be nested. - if (parent != null) { - return parent.cacheLookupByFacet(facets); - } - } - return result; - } + @Override + public Optional>> cacheLookupByFacet(Set facets) { + Optional>> result = Optional.empty(); + Collection emits = cacheIndex.parseText( + String.join(" ", facets.stream().map(facet -> facet.toString()).collect(Collectors.toList()))); + for (Emit emit : emits) { + // NOTE: rethink. should this match *all* facets? how do I know which emit + // keyword is the primary key? + String key = emit.getKeyword(); + result = cacheLookup(key); + if (result.isPresent()) { + return result; + } + } + if (!result.isPresent()) { + // Be sure to check all enclosing UnitOfWork caches as well, we may be nested. + if (parent != null) { + return parent.cacheLookupByFacet(facets); + } + } + return result; + } - @Override - public Optional>> cacheLookupByStatement(String[] statementKeys) { - String key = String.join(",", statementKeys); - return cacheLookup(key); - } + @Override + public Optional>> cacheLookupByStatement(String[] statementKeys) { + String key = String.join(",", statementKeys); + return cacheLookup(key); + } - @Override - public Optional>> cacheLookup(String key) { - Optional>> result = - (cache.containsKey(key)) ? Optional.of(cache.get(key)) : Optional.empty(); + @Override + public Optional>> cacheLookup(String key) { + Optional>> result = (cache.containsKey(key)) + ? Optional.of(cache.get(key)) + : Optional.empty(); - if (!result.isPresent()) { - // Be sure to check all enclosing UnitOfWork caches as well, we may be nested. - if (parent != null) { - return parent.cacheLookup(key); - } - } - return result; - } + if (!result.isPresent()) { + // Be sure to check all enclosing UnitOfWork caches as well, we may be nested. + if (parent != null) { + return parent.cacheLookup(key); + } + } + return result; + } - @Override - public void cacheUpdate( - Either> value, String[] statementKeys, Map facetMap) { - String key = "CQL::" + String.join(",", statementKeys); - cache.put(key, value); - Trie.TrieBuilder builder = - cacheIndex.builder().ignoreOverlaps().onlyWholeWordsWhiteSpaceSeparated(); - facetMap.forEach( - (facetName, facet) -> { - builder.addKeyword(facet.toString()); - if (facetName.equals("*")) { - cache.put(facet.toString(), value); - } - }); - cacheIndex = builder.build(); - } + @Override + public void cacheUpdate(Either> value, String[] statementKeys, + Map facetMap) { + String key = "CQL::" + String.join(",", statementKeys); + cache.put(key, value); + Trie.TrieBuilder builder = cacheIndex.builder().ignoreOverlaps(); + facetMap.forEach((facetName, facet) -> { + builder.addKeyword(facet.toString()); + if (facetName.equals("*")) { + cache.put(facet.toString(), value); + } + }); + cacheIndex = builder.build(); + } - private Iterator> getChildNodes() { - return nested.iterator(); - } + private Iterator> getChildNodes() { + return nested.iterator(); + } - /** - * Checks to see if the work performed between calling begin and now can be committed or not. - * - * @return a function from which to chain work that only happens when commit is successful - * @throws E when the work overlaps with other concurrent writers. - */ - public PostCommitFunction commit() throws E { - // All nested UnitOfWork should be committed (not aborted) before calls to commit, check. - boolean canCommit = true; - TreeTraverser> traverser = - TreeTraverser.using(node -> node::getChildNodes); - for (AbstractUnitOfWork uow : traverser.postOrderTraversal(this)) { - if (this != uow) { - canCommit &= (!uow.aborted && uow.committed); - } - } + /** + * Checks to see if the work performed between calling begin and now can be + * committed or not. + * + * @return a function from which to chain work that only happens when commit is + * successful + * @throws E + * when the work overlaps with other concurrent writers. + */ + public PostCommitFunction commit() throws E { + // All nested UnitOfWork should be committed (not aborted) before calls to + // commit, check. + boolean canCommit = true; + TreeTraverser> traverser = TreeTraverser.using(node -> node::getChildNodes); + for (AbstractUnitOfWork uow : traverser.postOrderTraversal(this)) { + if (this != uow) { + canCommit &= (!uow.aborted && uow.committed); + } + } - // log.record(txn::provisionalCommit) - // examine log for conflicts in read-set and write-set between begin and provisional commit - // if (conflict) { throw new ConflictingUnitOfWorkException(this) } - // else return function so as to enable commit.andThen(() -> { do something iff commit was successful; }) + // log.record(txn::provisionalCommit) + // examine log for conflicts in read-set and write-set between begin and + // provisional commit + // if (conflict) { throw new ConflictingUnitOfWorkException(this) } + // else return function so as to enable commit.andThen(() -> { do something iff + // commit was successful; }) - if (canCommit) { - committed = true; - aborted = false; + if (canCommit) { + committed = true; + aborted = false; - // TODO(gburd): union this cache with parent's (if there is a parent) or with the session cache for all cacheable entities we currently hold + // TODO(gburd): union this cache with parent's (if there is a parent) or with + // the session cache for all cacheable entities we currently hold - nested.forEach((uow) -> Errors.rethrow().wrap(uow::commit)); + nested.forEach((uow) -> Errors.rethrow().wrap(uow::commit)); - // Merge UOW cache into parent's cache. - if (parent != null) { - parent.assumeCache(cache, cacheIndex); - } + // Merge UOW cache into parent's cache. + if (parent != null) { + parent.assumeCache(cache, cacheIndex); + } - // Apply all post-commit functions for - if (parent == null) { - traverser - .postOrderTraversal(this) - .forEach( - uow -> { - uow.applyPostCommitFunctions(); - }); - return new PostCommitFunction(this, null); - } - } - // else { - // Constructor ctor = clazz.getConstructor(conflictExceptionClass); - // T object = ctor.newInstance(new Object[] { String message }); - // } - return new PostCommitFunction(this, postCommit); - } + // Apply all post-commit functions for + if (parent == null) { + traverser.postOrderTraversal(this).forEach(uow -> { + uow.applyPostCommitFunctions(); + }); + return new PostCommitFunction(this, null); + } + } + // else { + // Constructor ctor = clazz.getConstructor(conflictExceptionClass); + // T object = ctor.newInstance(new Object[] { String message }); + // } + return new PostCommitFunction(this, postCommit); + } - /* Explicitly discard the work and mark it as as such in the log. */ - public void abort() { - TreeTraverser> traverser = - TreeTraverser.using(node -> node::getChildNodes); - traverser - .postOrderTraversal(this) - .forEach( - uow -> { - uow.committed = false; - uow.aborted = true; - }); - // log.record(txn::abort) - // cache.invalidateSince(txn::start time) - } + /* Explicitly discard the work and mark it as as such in the log. */ + public void abort() { + TreeTraverser> traverser = TreeTraverser.using(node -> node::getChildNodes); + traverser.postOrderTraversal(this).forEach(uow -> { + uow.committed = false; + uow.aborted = true; + }); + // log.record(txn::abort) + // cache.invalidateSince(txn::start time) + } - private void assumeCache( - Map>> childCache, Trie childCacheIndex) { - for (String key : childCache.keySet()) { - if (cache.containsKey(key)) { - Either> value = cache.get(key); - if (value.isLeft()) { - Object obj = value.getLeft(); - // merge objects - Either> childValue = childCache.get(key); - if (childValue.isLeft()) { - Object childObj = childValue.getLeft(); - } else { - Set childSet = childValue.getRight(); - } - } else { - // merge the sets - Set set = value.getRight(); - Either> childValue = childCache.get(key); - if (childValue.isLeft()) { - Object childObj = childValue.getLeft(); - set.add(childObj); - } else { - Set childSet = childValue.getRight(); - set.addAll(childSet); - } - } - } else { - cache.put(key, childCache.get(key)); - } - } - } + private void assumeCache(Map>> childCache, Trie childCacheIndex) { + for (String key : childCache.keySet()) { + if (cache.containsKey(key)) { + Either> value = cache.get(key); + if (value.isLeft()) { + Object obj = value.getLeft(); + // merge objects + Either> childValue = childCache.get(key); + if (childValue.isLeft()) { + Object childObj = childValue.getLeft(); + } else { + Set childSet = childValue.getRight(); + } + } else { + // merge the sets + Set set = value.getRight(); + Either> childValue = childCache.get(key); + if (childValue.isLeft()) { + Object childObj = childValue.getLeft(); + set.add(childObj); + } else { + Set childSet = childValue.getRight(); + set.addAll(childSet); + } + } + } else { + cache.put(key, childCache.get(key)); + } + } + } - public String describeConflicts() { - return "it's complex..."; - } + public String describeConflicts() { + return "it's complex..."; + } - @Override - public void close() throws E { - // Closing a AbstractUnitOfWork will abort iff we've not already aborted or committed this unit of work. - if (aborted == false && committed == false) { - abort(); - } - } + @Override + public void close() throws E { + // Closing a AbstractUnitOfWork will abort iff we've not already aborted or + // committed this unit of work. + if (aborted == false && committed == false) { + abort(); + } + } - public boolean hasAborted() { - return aborted; - } + public boolean hasAborted() { + return aborted; + } - public boolean hasCommitted() { - return committed; - } + public boolean hasCommitted() { + return committed; + } } diff --git a/src/main/java/net/helenus/core/AutoDdl.java b/src/main/java/net/helenus/core/AutoDdl.java index c1e2626..d578cfd 100644 --- a/src/main/java/net/helenus/core/AutoDdl.java +++ b/src/main/java/net/helenus/core/AutoDdl.java @@ -16,8 +16,5 @@ package net.helenus.core; public enum AutoDdl { - VALIDATE, - UPDATE, - CREATE, - CREATE_DROP; + VALIDATE, UPDATE, CREATE, CREATE_DROP; } diff --git a/src/main/java/net/helenus/core/CommitThunk.java b/src/main/java/net/helenus/core/CommitThunk.java index 1ad9e05..11b1e30 100644 --- a/src/main/java/net/helenus/core/CommitThunk.java +++ b/src/main/java/net/helenus/core/CommitThunk.java @@ -2,5 +2,5 @@ package net.helenus.core; @FunctionalInterface public interface CommitThunk { - void apply(); + void apply(); } diff --git a/src/main/java/net/helenus/core/ConflictingUnitOfWorkException.java b/src/main/java/net/helenus/core/ConflictingUnitOfWorkException.java index f91e75f..a20aad4 100644 --- a/src/main/java/net/helenus/core/ConflictingUnitOfWorkException.java +++ b/src/main/java/net/helenus/core/ConflictingUnitOfWorkException.java @@ -2,9 +2,9 @@ package net.helenus.core; public class ConflictingUnitOfWorkException extends Exception { - final UnitOfWork uow; + final UnitOfWork uow; - ConflictingUnitOfWorkException(UnitOfWork uow) { - this.uow = uow; - } + ConflictingUnitOfWorkException(UnitOfWork uow) { + this.uow = uow; + } } diff --git a/src/main/java/net/helenus/core/DslInstantiator.java b/src/main/java/net/helenus/core/DslInstantiator.java index d05914c..29b96de 100644 --- a/src/main/java/net/helenus/core/DslInstantiator.java +++ b/src/main/java/net/helenus/core/DslInstantiator.java @@ -15,15 +15,13 @@ */ package net.helenus.core; -import com.datastax.driver.core.Metadata; import java.util.Optional; + +import com.datastax.driver.core.Metadata; + import net.helenus.core.reflect.HelenusPropertyNode; public interface DslInstantiator { - E instantiate( - Class iface, - ClassLoader classLoader, - Optional parent, - Metadata metadata); + E instantiate(Class iface, ClassLoader classLoader, Optional parent, Metadata metadata); } diff --git a/src/main/java/net/helenus/core/Filter.java b/src/main/java/net/helenus/core/Filter.java index 0958c93..3d6762f 100644 --- a/src/main/java/net/helenus/core/Filter.java +++ b/src/main/java/net/helenus/core/Filter.java @@ -15,97 +15,98 @@ */ package net.helenus.core; -import com.datastax.driver.core.querybuilder.Clause; import java.util.Objects; + +import com.datastax.driver.core.querybuilder.Clause; + import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.MappingUtil; import net.helenus.mapping.value.ColumnValuePreparer; public final class Filter { - private final HelenusPropertyNode node; - private final Postulate postulate; + private final HelenusPropertyNode node; + private final Postulate postulate; - private Filter(HelenusPropertyNode node, Postulate postulate) { - this.node = node; - this.postulate = postulate; - } + private Filter(HelenusPropertyNode node, Postulate postulate) { + this.node = node; + this.postulate = postulate; + } - public HelenusPropertyNode getNode() { - return node; - } + public HelenusPropertyNode getNode() { + return node; + } - public Clause getClause(ColumnValuePreparer valuePreparer) { - return postulate.getClause(node, valuePreparer); - } + public Clause getClause(ColumnValuePreparer valuePreparer) { + return postulate.getClause(node, valuePreparer); + } - public static Filter equal(Getter getter, V val) { - return create(getter, Operator.EQ, val); - } + public static Filter equal(Getter getter, V val) { + return create(getter, Operator.EQ, val); + } - public static Filter in(Getter getter, V... vals) { - Objects.requireNonNull(getter, "empty getter"); - Objects.requireNonNull(vals, "empty values"); + public static Filter in(Getter getter, V... vals) { + Objects.requireNonNull(getter, "empty getter"); + Objects.requireNonNull(vals, "empty values"); - if (vals.length == 0) { - throw new IllegalArgumentException("values array is empty"); - } + if (vals.length == 0) { + throw new IllegalArgumentException("values array is empty"); + } - for (int i = 0; i != vals.length; ++i) { - Objects.requireNonNull(vals[i], "value[" + i + "] is empty"); - } + for (int i = 0; i != vals.length; ++i) { + Objects.requireNonNull(vals[i], "value[" + i + "] is empty"); + } - HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); + HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); - Postulate postulate = Postulate.of(Operator.IN, vals); + Postulate postulate = Postulate.of(Operator.IN, vals); - return new Filter(node, postulate); - } + return new Filter(node, postulate); + } - public static Filter greaterThan(Getter getter, V val) { - return create(getter, Operator.GT, val); - } + public static Filter greaterThan(Getter getter, V val) { + return create(getter, Operator.GT, val); + } - public static Filter lessThan(Getter getter, V val) { - return create(getter, Operator.LT, val); - } + public static Filter lessThan(Getter getter, V val) { + return create(getter, Operator.LT, val); + } - public static Filter greaterThanOrEqual(Getter getter, V val) { - return create(getter, Operator.GTE, val); - } + public static Filter greaterThanOrEqual(Getter getter, V val) { + return create(getter, Operator.GTE, val); + } - public static Filter lessThanOrEqual(Getter getter, V val) { - return create(getter, Operator.LTE, val); - } + public static Filter lessThanOrEqual(Getter getter, V val) { + return create(getter, Operator.LTE, val); + } - public static Filter create(Getter getter, Postulate postulate) { - Objects.requireNonNull(getter, "empty getter"); - Objects.requireNonNull(postulate, "empty operator"); + public static Filter create(Getter getter, Postulate postulate) { + Objects.requireNonNull(getter, "empty getter"); + Objects.requireNonNull(postulate, "empty operator"); - HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); + HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); - return new Filter(node, postulate); - } + return new Filter(node, postulate); + } - public static Filter create(Getter getter, Operator op, V val) { - Objects.requireNonNull(getter, "empty getter"); - Objects.requireNonNull(op, "empty op"); - Objects.requireNonNull(val, "empty value"); + public static Filter create(Getter getter, Operator op, V val) { + Objects.requireNonNull(getter, "empty getter"); + Objects.requireNonNull(op, "empty op"); + Objects.requireNonNull(val, "empty value"); - if (op == Operator.IN) { - throw new IllegalArgumentException( - "invalid usage of the 'in' operator, use Filter.in() static method"); - } + if (op == Operator.IN) { + throw new IllegalArgumentException("invalid usage of the 'in' operator, use Filter.in() static method"); + } - HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); + HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); - Postulate postulate = Postulate.of(op, val); + Postulate postulate = Postulate.of(op, val); - return new Filter(node, postulate); - } + return new Filter(node, postulate); + } - @Override - public String toString() { - return node.getColumnName() + postulate.toString(); - } + @Override + public String toString() { + return node.getColumnName() + postulate.toString(); + } } diff --git a/src/main/java/net/helenus/core/Getter.java b/src/main/java/net/helenus/core/Getter.java index 7b7d5dd..2cf9c39 100644 --- a/src/main/java/net/helenus/core/Getter.java +++ b/src/main/java/net/helenus/core/Getter.java @@ -17,5 +17,5 @@ package net.helenus.core; public interface Getter { - V get(); + V get(); } diff --git a/src/main/java/net/helenus/core/Helenus.java b/src/main/java/net/helenus/core/Helenus.java index c0d9bc6..7ea1c3e 100644 --- a/src/main/java/net/helenus/core/Helenus.java +++ b/src/main/java/net/helenus/core/Helenus.java @@ -15,12 +15,17 @@ */ package net.helenus.core; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + import com.datastax.driver.core.Cluster; import com.datastax.driver.core.Metadata; import com.datastax.driver.core.Session; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; + import net.helenus.config.DefaultHelenusSettings; import net.helenus.config.HelenusSettings; import net.helenus.core.reflect.DslExportable; @@ -30,164 +35,159 @@ import net.helenus.support.HelenusMappingException; public final class Helenus { - private static volatile HelenusSettings settings = new DefaultHelenusSettings(); - private static final ConcurrentMap, Object> dslCache = - new ConcurrentHashMap, Object>(); - private static final ConcurrentMap, Metadata> metadataForEntity = - new ConcurrentHashMap, Metadata>(); - private static final Set sessions = new HashSet(); - private static volatile HelenusSession singleton; + private static volatile HelenusSettings settings = new DefaultHelenusSettings(); + private static final ConcurrentMap, Object> dslCache = new ConcurrentHashMap, Object>(); + private static final ConcurrentMap, Metadata> metadataForEntity = new ConcurrentHashMap, Metadata>(); + private static final Set sessions = new HashSet(); + private static volatile HelenusSession singleton; - private Helenus() {} + private Helenus() { + } - protected static void setSession(HelenusSession session) { - sessions.add(session); - singleton = session; - } + protected static void setSession(HelenusSession session) { + sessions.add(session); + singleton = session; + } - public static HelenusSession session() { - return singleton; - } + public static HelenusSession session() { + return singleton; + } - public static void shutdown() { - sessions.forEach( - (session) -> { - session.close(); - sessions.remove(session); - }); - dslCache.clear(); - } + public static void shutdown() { + sessions.forEach((session) -> { + session.close(); + sessions.remove(session); + }); + dslCache.clear(); + } - public static HelenusSettings settings() { - return settings; - } + public static HelenusSettings settings() { + return settings; + } - public static HelenusSettings settings(HelenusSettings overrideSettings) { - HelenusSettings old = settings; - settings = overrideSettings; - return old; - } + public static HelenusSettings settings(HelenusSettings overrideSettings) { + HelenusSettings old = settings; + settings = overrideSettings; + return old; + } - public static SessionInitializer connect(Cluster cluster) { - Session session = cluster.connect(); - return new SessionInitializer(session); - } + public static SessionInitializer connect(Cluster cluster) { + Session session = cluster.connect(); + return new SessionInitializer(session); + } - public static SessionInitializer connect(Cluster cluster, String keyspace) { - Session session = cluster.connect(keyspace); - return new SessionInitializer(session); - } + public static SessionInitializer connect(Cluster cluster, String keyspace) { + Session session = cluster.connect(keyspace); + return new SessionInitializer(session); + } - public static SessionInitializer init(Session session) { + public static SessionInitializer init(Session session) { - if (session == null) { - throw new IllegalArgumentException("empty session"); - } + if (session == null) { + throw new IllegalArgumentException("empty session"); + } - return new SessionInitializer(session); - } + return new SessionInitializer(session); + } - public static void clearDslCache() { - dslCache.clear(); - } + public static void clearDslCache() { + dslCache.clear(); + } - public static E dsl(Class iface) { - return dsl(iface, null); - } + public static E dsl(Class iface) { + return dsl(iface, null); + } - public static E dsl(Class iface, Metadata metadata) { - return dsl(iface, iface.getClassLoader(), Optional.empty(), metadata); - } + public static E dsl(Class iface, Metadata metadata) { + return dsl(iface, iface.getClassLoader(), Optional.empty(), metadata); + } - public static E dsl(Class iface, ClassLoader classLoader, Metadata metadata) { - return dsl(iface, classLoader, Optional.empty(), metadata); - } + public static E dsl(Class iface, ClassLoader classLoader, Metadata metadata) { + return dsl(iface, classLoader, Optional.empty(), metadata); + } - public static E dsl( - Class iface, - ClassLoader classLoader, - Optional parent, - Metadata metadata) { + public static E dsl(Class iface, ClassLoader classLoader, Optional parent, + Metadata metadata) { - Object instance = null; + Object instance = null; - if (!parent.isPresent()) { - instance = dslCache.get(iface); - } + if (!parent.isPresent()) { + instance = dslCache.get(iface); + } - if (instance == null) { + if (instance == null) { - instance = settings.getDslInstantiator().instantiate(iface, classLoader, parent, metadata); + instance = settings.getDslInstantiator().instantiate(iface, classLoader, parent, metadata); - if (!parent.isPresent()) { + if (!parent.isPresent()) { - Object c = dslCache.putIfAbsent(iface, instance); - if (c != null) { - instance = c; - } - } - } + Object c = dslCache.putIfAbsent(iface, instance); + if (c != null) { + instance = c; + } + } + } - return (E) instance; - } + return (E) instance; + } - public static E map(Class iface, Map src) { - return map(iface, src, iface.getClassLoader()); - } + public static E map(Class iface, Map src) { + return map(iface, src, iface.getClassLoader()); + } - public static E map(Class iface, Map src, ClassLoader classLoader) { - return settings.getMapperInstantiator().instantiate(iface, src, classLoader); - } + public static E map(Class iface, Map src, ClassLoader classLoader) { + return settings.getMapperInstantiator().instantiate(iface, src, classLoader); + } - public static HelenusEntity entity(Class iface) { - Metadata metadata = metadataForEntity.get(iface); - if (metadata == null) { - HelenusSession session = session(); - if (session != null) { - metadata = session.getMetadata(); - } - } - return entity(iface, metadata); - } + public static HelenusEntity entity(Class iface) { + Metadata metadata = metadataForEntity.get(iface); + if (metadata == null) { + HelenusSession session = session(); + if (session != null) { + metadata = session.getMetadata(); + } + } + return entity(iface, metadata); + } - public static HelenusEntity entity(Class iface, Metadata metadata) { + public static HelenusEntity entity(Class iface, Metadata metadata) { - Object dsl = dsl(iface, metadata); + Object dsl = dsl(iface, metadata); - DslExportable e = (DslExportable) dsl; + DslExportable e = (DslExportable) dsl; - return e.getHelenusMappingEntity(); - } + return e.getHelenusMappingEntity(); + } - public static HelenusEntity resolve(Object ifaceOrDsl) { - return resolve(ifaceOrDsl, metadataForEntity.get(ifaceOrDsl)); - } + public static HelenusEntity resolve(Object ifaceOrDsl) { + return resolve(ifaceOrDsl, metadataForEntity.get(ifaceOrDsl)); + } - public static HelenusEntity resolve(Object ifaceOrDsl, Metadata metadata) { + public static HelenusEntity resolve(Object ifaceOrDsl, Metadata metadata) { - if (ifaceOrDsl == null) { - throw new HelenusMappingException("ifaceOrDsl is null"); - } + if (ifaceOrDsl == null) { + throw new HelenusMappingException("ifaceOrDsl is null"); + } - if (ifaceOrDsl instanceof DslExportable) { + if (ifaceOrDsl instanceof DslExportable) { - DslExportable e = (DslExportable) ifaceOrDsl; + DslExportable e = (DslExportable) ifaceOrDsl; - return e.getHelenusMappingEntity(); - } + return e.getHelenusMappingEntity(); + } - if (ifaceOrDsl instanceof Class) { + if (ifaceOrDsl instanceof Class) { - Class iface = (Class) ifaceOrDsl; + Class iface = (Class) ifaceOrDsl; - if (!iface.isInterface()) { - throw new HelenusMappingException("class is not an interface " + iface); - } + if (!iface.isInterface()) { + throw new HelenusMappingException("class is not an interface " + iface); + } - metadataForEntity.putIfAbsent(iface, metadata); - return entity(iface, metadata); - } + metadataForEntity.putIfAbsent(iface, metadata); + return entity(iface, metadata); + } - throw new HelenusMappingException("unknown dsl object or mapping interface " + ifaceOrDsl); - } + throw new HelenusMappingException("unknown dsl object or mapping interface " + ifaceOrDsl); + } } diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index 601a773..4776bbb 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -17,9 +17,6 @@ package net.helenus.core; import static net.helenus.core.Query.eq; -import brave.Tracer; -import com.codahale.metrics.MetricRegistry; -import com.datastax.driver.core.*; import java.io.Closeable; import java.io.PrintStream; import java.lang.reflect.Constructor; @@ -30,6 +27,11 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.Executor; import java.util.function.Function; + +import com.codahale.metrics.MetricRegistry; +import com.datastax.driver.core.*; + +import brave.Tracer; import net.helenus.core.operation.*; import net.helenus.core.reflect.Drafted; import net.helenus.core.reflect.HelenusPropertyNode; @@ -46,577 +48,501 @@ import net.helenus.support.HelenusMappingException; public final class HelenusSession extends AbstractSessionOperations implements Closeable { - private final int MAX_CACHE_SIZE = 10000; - private final int MAX_CACHE_EXPIRE_SECONDS = 600; - - private final Session session; - private final CodecRegistry registry; - private volatile String usingKeyspace; - private volatile boolean showCql; - private final ConsistencyLevel defaultConsistencyLevel; - private final boolean defaultQueryIdempotency; - private final MetricRegistry metricRegistry; - private final Tracer zipkinTracer; - private final PrintStream printStream; - private final Class unitOfWorkClass; - private final SessionRepository sessionRepository; - private final Executor executor; - private final boolean dropSchemaOnClose; - - private final RowColumnValueProvider valueProvider; - private final StatementColumnValuePreparer valuePreparer; - private final Metadata metadata; - - HelenusSession( - Session session, - String usingKeyspace, - CodecRegistry registry, - boolean showCql, - PrintStream printStream, - SessionRepositoryBuilder sessionRepositoryBuilder, - Executor executor, - boolean dropSchemaOnClose, - ConsistencyLevel consistencyLevel, - boolean defaultQueryIdempotency, - Class unitOfWorkClass, - MetricRegistry metricRegistry, - Tracer tracer) { - this.session = session; - this.registry = registry == null ? CodecRegistry.DEFAULT_INSTANCE : registry; - this.usingKeyspace = - Objects.requireNonNull( - usingKeyspace, "keyspace needs to be selected before creating session"); - this.showCql = showCql; - this.printStream = printStream; - this.sessionRepository = sessionRepositoryBuilder.build(); - this.executor = executor; - this.dropSchemaOnClose = dropSchemaOnClose; - this.defaultConsistencyLevel = consistencyLevel; - this.defaultQueryIdempotency = defaultQueryIdempotency; - this.unitOfWorkClass = unitOfWorkClass; - this.metricRegistry = metricRegistry; - this.zipkinTracer = tracer; - - this.valueProvider = new RowColumnValueProvider(this.sessionRepository); - this.valuePreparer = new StatementColumnValuePreparer(this.sessionRepository); - this.metadata = session.getCluster().getMetadata(); - } - - @Override - public Session currentSession() { - return session; - } - - @Override - public String usingKeyspace() { - return usingKeyspace; - } - - public HelenusSession useKeyspace(String keyspace) { - session.execute(SchemaUtil.use(keyspace, false)); - this.usingKeyspace = keyspace; - return this; - } - - @Override - public boolean isShowCql() { - return showCql; - } - - @Override - public PrintStream getPrintStream() { - return printStream; - } - - public HelenusSession showCql() { - this.showCql = true; - return this; - } - - public HelenusSession showCql(boolean showCql) { - this.showCql = showCql; - return this; - } - - @Override - public Executor getExecutor() { - return executor; - } - - @Override - public SessionRepository getSessionRepository() { - return sessionRepository; - } - - @Override - public ColumnValueProvider getValueProvider() { - return valueProvider; - } - - @Override - public ColumnValuePreparer getValuePreparer() { - return valuePreparer; - } - - @Override - public Tracer getZipkinTracer() { - return zipkinTracer; - } - - @Override - public MetricRegistry getMetricRegistry() { - return metricRegistry; - } - - @Override - public ConsistencyLevel getDefaultConsistencyLevel() { - return defaultConsistencyLevel; - } - - @Override - public boolean getDefaultQueryIdempotency() { - return defaultQueryIdempotency; - } - - public Metadata getMetadata() { - return metadata; - } - - public synchronized UnitOfWork begin() { - return begin(null); - } - - public synchronized UnitOfWork begin(UnitOfWork parent) { - try { - Class clazz = unitOfWorkClass; - Constructor ctor = - clazz.getConstructor(HelenusSession.class, UnitOfWork.class); - UnitOfWork uow = ctor.newInstance(this, parent); - if (parent != null) { - parent.addNestedUnitOfWork(uow); - } - return uow.begin(); - } catch (NoSuchMethodException - | InvocationTargetException - | InstantiationException - | IllegalAccessException e) { - throw new HelenusException( - String.format( - "Unable to instantiate {} as a UnitOfWork.", unitOfWorkClass.getSimpleName()), - e); - } - } - - public SelectOperation select(E pojo) { - Objects.requireNonNull( - pojo, "supplied object must be a dsl for a registered entity but cannot be null"); - ColumnValueProvider valueProvider = getValueProvider(); - HelenusEntity entity = Helenus.resolve(pojo); - Class entityClass = entity.getMappingInterface(); - - return new SelectOperation( - this, - entity, - (r) -> { - Map map = new ValueProviderMap(r, valueProvider, entity); - return (E) Helenus.map(entityClass, map); - }); - } - - public SelectOperation select(Class entityClass) { - Objects.requireNonNull(entityClass, "entityClass is empty"); - ColumnValueProvider valueProvider = getValueProvider(); - HelenusEntity entity = Helenus.entity(entityClass); - - return new SelectOperation( - this, - entity, - (r) -> { - Map map = new ValueProviderMap(r, valueProvider, entity); - return (E) Helenus.map(entityClass, map); - }); - } - - public SelectOperation select() { - return new SelectOperation(this); - } - - public SelectOperation selectAll(Class entityClass) { - Objects.requireNonNull(entityClass, "entityClass is empty"); - return new SelectOperation(this, Helenus.entity(entityClass)); - } - - public SelectOperation selectAll(E pojo) { - Objects.requireNonNull( - pojo, "supplied object must be a dsl for a registered entity but cannot be null"); - HelenusEntity entity = Helenus.resolve(pojo); - return new SelectOperation(this, entity); - } - - public SelectOperation selectAll(Class entityClass, Function rowMapper) { - Objects.requireNonNull(entityClass, "entityClass is empty"); - Objects.requireNonNull(rowMapper, "rowMapper is empty"); - return new SelectOperation(this, Helenus.entity(entityClass), rowMapper); - } - - public SelectOperation> select(Getter getter1) { - Objects.requireNonNull(getter1, "field 1 is empty"); - - HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); - return new SelectOperation>( - this, new Mappers.Mapper1(getValueProvider(), p1), p1); - } - - public SelectOperation> select(Getter getter1, Getter getter2) { - Objects.requireNonNull(getter1, "field 1 is empty"); - Objects.requireNonNull(getter2, "field 2 is empty"); - - HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); - HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); - return new SelectOperation>( - this, new Mappers.Mapper2(getValueProvider(), p1, p2), p1, p2); - } - - public SelectOperation> select( - Getter getter1, Getter getter2, Getter getter3) { - Objects.requireNonNull(getter1, "field 1 is empty"); - Objects.requireNonNull(getter2, "field 2 is empty"); - Objects.requireNonNull(getter3, "field 3 is empty"); - - HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); - HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); - HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); - return new SelectOperation>( - this, new Mappers.Mapper3(getValueProvider(), p1, p2, p3), p1, p2, p3); - } - - public SelectOperation> select( - Getter getter1, Getter getter2, Getter getter3, Getter getter4) { - Objects.requireNonNull(getter1, "field 1 is empty"); - Objects.requireNonNull(getter2, "field 2 is empty"); - Objects.requireNonNull(getter3, "field 3 is empty"); - Objects.requireNonNull(getter4, "field 4 is empty"); - - HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); - HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); - HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); - HelenusPropertyNode p4 = MappingUtil.resolveMappingProperty(getter4); - return new SelectOperation>( - this, - new Mappers.Mapper4(getValueProvider(), p1, p2, p3, p4), - p1, - p2, - p3, - p4); - } - - public SelectOperation> select( - Getter getter1, - Getter getter2, - Getter getter3, - Getter getter4, - Getter getter5) { - Objects.requireNonNull(getter1, "field 1 is empty"); - Objects.requireNonNull(getter2, "field 2 is empty"); - Objects.requireNonNull(getter3, "field 3 is empty"); - Objects.requireNonNull(getter4, "field 4 is empty"); - Objects.requireNonNull(getter5, "field 5 is empty"); - - HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); - HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); - HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); - HelenusPropertyNode p4 = MappingUtil.resolveMappingProperty(getter4); - HelenusPropertyNode p5 = MappingUtil.resolveMappingProperty(getter5); - return new SelectOperation>( - this, - new Mappers.Mapper5(getValueProvider(), p1, p2, p3, p4, p5), - p1, - p2, - p3, - p4, - p5); - } - - public SelectOperation> select( - Getter getter1, - Getter getter2, - Getter getter3, - Getter getter4, - Getter getter5, - Getter getter6) { - Objects.requireNonNull(getter1, "field 1 is empty"); - Objects.requireNonNull(getter2, "field 2 is empty"); - Objects.requireNonNull(getter3, "field 3 is empty"); - Objects.requireNonNull(getter4, "field 4 is empty"); - Objects.requireNonNull(getter5, "field 5 is empty"); - Objects.requireNonNull(getter6, "field 6 is empty"); - - HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); - HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); - HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); - HelenusPropertyNode p4 = MappingUtil.resolveMappingProperty(getter4); - HelenusPropertyNode p5 = MappingUtil.resolveMappingProperty(getter5); - HelenusPropertyNode p6 = MappingUtil.resolveMappingProperty(getter6); - return new SelectOperation>( - this, - new Mappers.Mapper6(getValueProvider(), p1, p2, p3, p4, p5, p6), - p1, - p2, - p3, - p4, - p5, - p6); - } - - public - SelectOperation> select( - Getter getter1, - Getter getter2, - Getter getter3, - Getter getter4, - Getter getter5, - Getter getter6, - Getter getter7) { - Objects.requireNonNull(getter1, "field 1 is empty"); - Objects.requireNonNull(getter2, "field 2 is empty"); - Objects.requireNonNull(getter3, "field 3 is empty"); - Objects.requireNonNull(getter4, "field 4 is empty"); - Objects.requireNonNull(getter5, "field 5 is empty"); - Objects.requireNonNull(getter6, "field 6 is empty"); - Objects.requireNonNull(getter7, "field 7 is empty"); - - HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); - HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); - HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); - HelenusPropertyNode p4 = MappingUtil.resolveMappingProperty(getter4); - HelenusPropertyNode p5 = MappingUtil.resolveMappingProperty(getter5); - HelenusPropertyNode p6 = MappingUtil.resolveMappingProperty(getter6); - HelenusPropertyNode p7 = MappingUtil.resolveMappingProperty(getter7); - return new SelectOperation>( - this, - new Mappers.Mapper7( - getValueProvider(), p1, p2, p3, p4, p5, p6, p7), - p1, - p2, - p3, - p4, - p5, - p6, - p7); - } - - public CountOperation count() { - return new CountOperation(this); - } - - public CountOperation count(Object dsl) { - Objects.requireNonNull(dsl, "dsl is empty"); - return new CountOperation(this, Helenus.resolve(dsl)); - } - - public UpdateOperation update() { - return new UpdateOperation(this); - } - - 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"); - } - AbstractEntityDraft draft = (AbstractEntityDraft) drafted; - UpdateOperation update = new UpdateOperation(this, draft); - Map map = draft.toMap(); - Set mutatedProperties = draft.mutated(); - HelenusEntity entity = Helenus.entity(draft.getEntityClass()); - - // Add all the mutated values contained in the draft. - entity - .getOrderedProperties() - .forEach( - property -> { - switch (property.getColumnType()) { - case PARTITION_KEY: - case CLUSTERING_COLUMN: - break; - default: - String propertyName = property.getPropertyName(); - if (mutatedProperties.contains(propertyName)) { - Object value = map.get(propertyName); - Getter getter = - new Getter() { - @Override - public Object get() { - throw new DslPropertyException( - new HelenusPropertyNode(property, Optional.empty())); - } - }; - update.set(getter, value); - } - } - }); - - // Add the partition and clustering keys if they were in the draft (normally the case). - entity - .getOrderedProperties() - .forEach( - property -> { - switch (property.getColumnType()) { - case PARTITION_KEY: - case CLUSTERING_COLUMN: - String propertyName = property.getPropertyName(); - Object value = map.get(propertyName); - Getter getter = - new Getter() { - @Override - public Object get() { - throw new DslPropertyException( - new HelenusPropertyNode(property, Optional.empty())); - } - }; - update.where(getter, eq(value)); - } - }); - - return update; - } - - public UpdateOperation update(Getter getter, V v) { - Objects.requireNonNull(getter, "field is empty"); - Objects.requireNonNull(v, "value is empty"); - - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(getter); - - return new UpdateOperation(this, p, v); - } - - public InsertOperation insert() { - return new InsertOperation(this, true); - } - - public InsertOperation insert(Class resultType) { - return new InsertOperation(this, resultType, true); - } - - public InsertOperation insert(T pojo) { - Objects.requireNonNull( - pojo, - "supplied object must be either an instance of the entity class or a dsl for it, but cannot be null"); - HelenusEntity entity = null; - try { - entity = Helenus.resolve(pojo); - } catch (HelenusMappingException e) { - } - if (entity != null) { - return new InsertOperation(this, entity.getMappingInterface(), true); - } else { - return this.insert(pojo, null); - } - } - - public InsertOperation insert(Drafted draft) { - return insert(draft.build(), draft.mutated()); - } - - private InsertOperation insert(T pojo, Set mutations) { - Objects.requireNonNull(pojo, "pojo is empty"); - - Class iface = MappingUtil.getMappingInterface(pojo); - HelenusEntity entity = Helenus.entity(iface); - - return new InsertOperation(this, entity, pojo, mutations, true); - } - - public InsertOperation upsert() { - return new InsertOperation(this, false); - } - - public InsertOperation upsert(Class resultType) { - return new InsertOperation(this, resultType, false); - } - - public InsertOperation upsert(Drafted draft) { - return this.upsert((T) draft.build(), draft.mutated()); - } - - public InsertOperation upsert(T pojo) { - Objects.requireNonNull( - pojo, - "supplied object must be either an instance of the entity class or a dsl for it, but cannot be null"); - HelenusEntity entity = null; - try { - entity = Helenus.resolve(pojo); - } catch (HelenusMappingException e) { - } - if (entity != null) { - return new InsertOperation(this, entity.getMappingInterface(), false); - } else { - return this.upsert(pojo, null); - } - } - - private InsertOperation upsert(T pojo, Set mutations) { - Objects.requireNonNull(pojo, "pojo is empty"); - - Class iface = MappingUtil.getMappingInterface(pojo); - HelenusEntity entity = Helenus.entity(iface); - - return new InsertOperation(this, entity, pojo, mutations, false); - } - - public DeleteOperation delete() { - return new DeleteOperation(this); - } - - public DeleteOperation delete(Object dsl) { - Objects.requireNonNull(dsl, "dsl is empty"); - return new DeleteOperation(this, Helenus.resolve(dsl)); - } - - public Session getSession() { - return session; - } - - public E dsl(Class iface) { - return Helenus.dsl(iface, getMetadata()); - } - - public void close() { - - if (session.isClosed()) { - return; - } - - if (dropSchemaOnClose) { - dropSchema(); - } - - session.close(); - } - - public CloseFuture closeAsync() { - - if (!session.isClosed() && dropSchemaOnClose) { - dropSchema(); - } - - return session.closeAsync(); - } - - private void dropSchema() { - - sessionRepository.entities().forEach(e -> dropEntity(e)); - } - - private void dropEntity(HelenusEntity entity) { + private final int MAX_CACHE_SIZE = 10000; + private final int MAX_CACHE_EXPIRE_SECONDS = 600; + + private final Session session; + private final CodecRegistry registry; + private volatile String usingKeyspace; + private volatile boolean showCql; + private final ConsistencyLevel defaultConsistencyLevel; + private final boolean defaultQueryIdempotency; + private final MetricRegistry metricRegistry; + private final Tracer zipkinTracer; + private final PrintStream printStream; + private final Class unitOfWorkClass; + private final SessionRepository sessionRepository; + private final Executor executor; + private final boolean dropSchemaOnClose; + + private final RowColumnValueProvider valueProvider; + private final StatementColumnValuePreparer valuePreparer; + private final Metadata metadata; + + HelenusSession(Session session, String usingKeyspace, CodecRegistry registry, boolean showCql, + PrintStream printStream, SessionRepositoryBuilder sessionRepositoryBuilder, Executor executor, + boolean dropSchemaOnClose, ConsistencyLevel consistencyLevel, boolean defaultQueryIdempotency, + Class unitOfWorkClass, MetricRegistry metricRegistry, Tracer tracer) { + this.session = session; + this.registry = registry == null ? CodecRegistry.DEFAULT_INSTANCE : registry; + this.usingKeyspace = Objects.requireNonNull(usingKeyspace, + "keyspace needs to be selected before creating session"); + this.showCql = showCql; + this.printStream = printStream; + this.sessionRepository = sessionRepositoryBuilder.build(); + this.executor = executor; + this.dropSchemaOnClose = dropSchemaOnClose; + this.defaultConsistencyLevel = consistencyLevel; + this.defaultQueryIdempotency = defaultQueryIdempotency; + this.unitOfWorkClass = unitOfWorkClass; + this.metricRegistry = metricRegistry; + this.zipkinTracer = tracer; + + this.valueProvider = new RowColumnValueProvider(this.sessionRepository); + this.valuePreparer = new StatementColumnValuePreparer(this.sessionRepository); + this.metadata = session.getCluster().getMetadata(); + } + + @Override + public Session currentSession() { + return session; + } + + @Override + public String usingKeyspace() { + return usingKeyspace; + } + + public HelenusSession useKeyspace(String keyspace) { + session.execute(SchemaUtil.use(keyspace, false)); + this.usingKeyspace = keyspace; + return this; + } + + @Override + public boolean isShowCql() { + return showCql; + } + + @Override + public PrintStream getPrintStream() { + return printStream; + } + + public HelenusSession showCql() { + this.showCql = true; + return this; + } + + public HelenusSession showCql(boolean showCql) { + this.showCql = showCql; + return this; + } + + @Override + public Executor getExecutor() { + return executor; + } + + @Override + public SessionRepository getSessionRepository() { + return sessionRepository; + } + + @Override + public ColumnValueProvider getValueProvider() { + return valueProvider; + } + + @Override + public ColumnValuePreparer getValuePreparer() { + return valuePreparer; + } + + @Override + public Tracer getZipkinTracer() { + return zipkinTracer; + } + + @Override + public MetricRegistry getMetricRegistry() { + return metricRegistry; + } + + @Override + public ConsistencyLevel getDefaultConsistencyLevel() { + return defaultConsistencyLevel; + } + + @Override + public boolean getDefaultQueryIdempotency() { + return defaultQueryIdempotency; + } + + public Metadata getMetadata() { + return metadata; + } + + public synchronized UnitOfWork begin() { + return begin(null); + } + + public synchronized UnitOfWork begin(UnitOfWork parent) { + try { + Class clazz = unitOfWorkClass; + Constructor ctor = clazz.getConstructor(HelenusSession.class, UnitOfWork.class); + UnitOfWork uow = ctor.newInstance(this, parent); + if (parent != null) { + parent.addNestedUnitOfWork(uow); + } + return uow.begin(); + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException + | IllegalAccessException e) { + throw new HelenusException( + String.format("Unable to instantiate {} as a UnitOfWork.", unitOfWorkClass.getSimpleName()), e); + } + } + + public SelectOperation select(E pojo) { + Objects.requireNonNull(pojo, "supplied object must be a dsl for a registered entity but cannot be null"); + ColumnValueProvider valueProvider = getValueProvider(); + HelenusEntity entity = Helenus.resolve(pojo); + Class entityClass = entity.getMappingInterface(); + + return new SelectOperation(this, entity, (r) -> { + Map map = new ValueProviderMap(r, valueProvider, entity); + return (E) Helenus.map(entityClass, map); + }); + } + + public SelectOperation select(Class entityClass) { + Objects.requireNonNull(entityClass, "entityClass is empty"); + ColumnValueProvider valueProvider = getValueProvider(); + HelenusEntity entity = Helenus.entity(entityClass); + + return new SelectOperation(this, entity, (r) -> { + Map map = new ValueProviderMap(r, valueProvider, entity); + return (E) Helenus.map(entityClass, map); + }); + } + + public SelectOperation select() { + return new SelectOperation(this); + } + + public SelectOperation selectAll(Class entityClass) { + Objects.requireNonNull(entityClass, "entityClass is empty"); + return new SelectOperation(this, Helenus.entity(entityClass)); + } + + public SelectOperation selectAll(E pojo) { + Objects.requireNonNull(pojo, "supplied object must be a dsl for a registered entity but cannot be null"); + HelenusEntity entity = Helenus.resolve(pojo); + return new SelectOperation(this, entity); + } + + public SelectOperation selectAll(Class entityClass, Function rowMapper) { + Objects.requireNonNull(entityClass, "entityClass is empty"); + Objects.requireNonNull(rowMapper, "rowMapper is empty"); + return new SelectOperation(this, Helenus.entity(entityClass), rowMapper); + } + + public SelectOperation> select(Getter getter1) { + Objects.requireNonNull(getter1, "field 1 is empty"); + + HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); + return new SelectOperation>(this, new Mappers.Mapper1(getValueProvider(), p1), p1); + } + + public SelectOperation> select(Getter getter1, Getter getter2) { + Objects.requireNonNull(getter1, "field 1 is empty"); + Objects.requireNonNull(getter2, "field 2 is empty"); + + HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); + HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); + return new SelectOperation>(this, new Mappers.Mapper2(getValueProvider(), p1, p2), + p1, p2); + } + + public SelectOperation> select(Getter getter1, Getter getter2, + Getter getter3) { + Objects.requireNonNull(getter1, "field 1 is empty"); + Objects.requireNonNull(getter2, "field 2 is empty"); + Objects.requireNonNull(getter3, "field 3 is empty"); + + HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); + HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); + HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); + return new SelectOperation>(this, + new Mappers.Mapper3(getValueProvider(), p1, p2, p3), p1, p2, p3); + } + + public SelectOperation> select(Getter getter1, Getter getter2, + Getter getter3, Getter getter4) { + Objects.requireNonNull(getter1, "field 1 is empty"); + Objects.requireNonNull(getter2, "field 2 is empty"); + Objects.requireNonNull(getter3, "field 3 is empty"); + Objects.requireNonNull(getter4, "field 4 is empty"); + + HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); + HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); + HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); + HelenusPropertyNode p4 = MappingUtil.resolveMappingProperty(getter4); + return new SelectOperation>(this, + new Mappers.Mapper4(getValueProvider(), p1, p2, p3, p4), p1, p2, p3, p4); + } + + public SelectOperation> select(Getter getter1, + Getter getter2, Getter getter3, Getter getter4, Getter getter5) { + Objects.requireNonNull(getter1, "field 1 is empty"); + Objects.requireNonNull(getter2, "field 2 is empty"); + Objects.requireNonNull(getter3, "field 3 is empty"); + Objects.requireNonNull(getter4, "field 4 is empty"); + Objects.requireNonNull(getter5, "field 5 is empty"); + + HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); + HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); + HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); + HelenusPropertyNode p4 = MappingUtil.resolveMappingProperty(getter4); + HelenusPropertyNode p5 = MappingUtil.resolveMappingProperty(getter5); + return new SelectOperation>(this, + new Mappers.Mapper5(getValueProvider(), p1, p2, p3, p4, p5), p1, p2, p3, p4, p5); + } + + public SelectOperation> select(Getter getter1, + Getter getter2, Getter getter3, Getter getter4, Getter getter5, Getter getter6) { + Objects.requireNonNull(getter1, "field 1 is empty"); + Objects.requireNonNull(getter2, "field 2 is empty"); + Objects.requireNonNull(getter3, "field 3 is empty"); + Objects.requireNonNull(getter4, "field 4 is empty"); + Objects.requireNonNull(getter5, "field 5 is empty"); + Objects.requireNonNull(getter6, "field 6 is empty"); + + HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); + HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); + HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); + HelenusPropertyNode p4 = MappingUtil.resolveMappingProperty(getter4); + HelenusPropertyNode p5 = MappingUtil.resolveMappingProperty(getter5); + HelenusPropertyNode p6 = MappingUtil.resolveMappingProperty(getter6); + return new SelectOperation>(this, + new Mappers.Mapper6(getValueProvider(), p1, p2, p3, p4, p5, p6), p1, p2, p3, p4, + p5, p6); + } + + public SelectOperation> select( + Getter getter1, Getter getter2, Getter getter3, Getter getter4, Getter getter5, + Getter getter6, Getter getter7) { + Objects.requireNonNull(getter1, "field 1 is empty"); + Objects.requireNonNull(getter2, "field 2 is empty"); + Objects.requireNonNull(getter3, "field 3 is empty"); + Objects.requireNonNull(getter4, "field 4 is empty"); + Objects.requireNonNull(getter5, "field 5 is empty"); + Objects.requireNonNull(getter6, "field 6 is empty"); + Objects.requireNonNull(getter7, "field 7 is empty"); + + HelenusPropertyNode p1 = MappingUtil.resolveMappingProperty(getter1); + HelenusPropertyNode p2 = MappingUtil.resolveMappingProperty(getter2); + HelenusPropertyNode p3 = MappingUtil.resolveMappingProperty(getter3); + HelenusPropertyNode p4 = MappingUtil.resolveMappingProperty(getter4); + HelenusPropertyNode p5 = MappingUtil.resolveMappingProperty(getter5); + HelenusPropertyNode p6 = MappingUtil.resolveMappingProperty(getter6); + HelenusPropertyNode p7 = MappingUtil.resolveMappingProperty(getter7); + return new SelectOperation>(this, + new Mappers.Mapper7(getValueProvider(), p1, p2, p3, p4, p5, p6, p7), p1, p2, + p3, p4, p5, p6, p7); + } + + public CountOperation count() { + return new CountOperation(this); + } + + public CountOperation count(Object dsl) { + Objects.requireNonNull(dsl, "dsl is empty"); + return new CountOperation(this, Helenus.resolve(dsl)); + } + + public UpdateOperation update() { + return new UpdateOperation(this); + } + + 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"); + } + AbstractEntityDraft draft = (AbstractEntityDraft) drafted; + UpdateOperation update = new UpdateOperation(this, draft); + Map map = draft.toMap(); + Set mutatedProperties = draft.mutated(); + HelenusEntity entity = Helenus.entity(draft.getEntityClass()); + + // Add all the mutated values contained in the draft. + entity.getOrderedProperties().forEach(property -> { + switch (property.getColumnType()) { + case PARTITION_KEY : + case CLUSTERING_COLUMN : + break; + default : + String propertyName = property.getPropertyName(); + if (mutatedProperties.contains(propertyName)) { + Object value = map.get(propertyName); + Getter getter = new Getter() { + @Override + public Object get() { + throw new DslPropertyException(new HelenusPropertyNode(property, Optional.empty())); + } + }; + update.set(getter, value); + } + } + }); + + // Add the partition and clustering keys if they were in the draft (normally the + // case). + entity.getOrderedProperties().forEach(property -> { + switch (property.getColumnType()) { + case PARTITION_KEY : + case CLUSTERING_COLUMN : + String propertyName = property.getPropertyName(); + Object value = map.get(propertyName); + Getter getter = new Getter() { + @Override + public Object get() { + throw new DslPropertyException(new HelenusPropertyNode(property, Optional.empty())); + } + }; + update.where(getter, eq(value)); + } + }); + + return update; + } + + public UpdateOperation update(Getter getter, V v) { + Objects.requireNonNull(getter, "field is empty"); + Objects.requireNonNull(v, "value is empty"); + + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(getter); + + return new UpdateOperation(this, p, v); + } + + public InsertOperation insert() { + return new InsertOperation(this, true); + } + + public InsertOperation insert(Class resultType) { + return new InsertOperation(this, resultType, true); + } + + public InsertOperation insert(T pojo) { + Objects.requireNonNull(pojo, + "supplied object must be either an instance of the entity class or a dsl for it, but cannot be null"); + HelenusEntity entity = null; + try { + entity = Helenus.resolve(pojo); + } catch (HelenusMappingException e) { + } + if (entity != null) { + return new InsertOperation(this, entity.getMappingInterface(), true); + } else { + return this.insert(pojo, null); + } + } + + public InsertOperation insert(Drafted draft) { + return insert(draft.build(), draft.mutated()); + } + + private InsertOperation insert(T pojo, Set mutations) { + Objects.requireNonNull(pojo, "pojo is empty"); + + Class iface = MappingUtil.getMappingInterface(pojo); + HelenusEntity entity = Helenus.entity(iface); + + return new InsertOperation(this, entity, pojo, mutations, true); + } + + public InsertOperation upsert() { + return new InsertOperation(this, false); + } + + public InsertOperation upsert(Class resultType) { + return new InsertOperation(this, resultType, false); + } + + public InsertOperation upsert(Drafted draft) { + return this.upsert((T) draft.build(), draft.mutated()); + } + + public InsertOperation upsert(T pojo) { + Objects.requireNonNull(pojo, + "supplied object must be either an instance of the entity class or a dsl for it, but cannot be null"); + HelenusEntity entity = null; + try { + entity = Helenus.resolve(pojo); + } catch (HelenusMappingException e) { + } + if (entity != null) { + return new InsertOperation(this, entity.getMappingInterface(), false); + } else { + return this.upsert(pojo, null); + } + } + + private InsertOperation upsert(T pojo, Set mutations) { + Objects.requireNonNull(pojo, "pojo is empty"); + + Class iface = MappingUtil.getMappingInterface(pojo); + HelenusEntity entity = Helenus.entity(iface); + + return new InsertOperation(this, entity, pojo, mutations, false); + } + + public DeleteOperation delete() { + return new DeleteOperation(this); + } + + public DeleteOperation delete(Object dsl) { + Objects.requireNonNull(dsl, "dsl is empty"); + return new DeleteOperation(this, Helenus.resolve(dsl)); + } + + public Session getSession() { + return session; + } + + public E dsl(Class iface) { + return Helenus.dsl(iface, getMetadata()); + } + + public void close() { + + if (session.isClosed()) { + return; + } + + if (dropSchemaOnClose) { + dropSchema(); + } + + session.close(); + } + + public CloseFuture closeAsync() { + + if (!session.isClosed() && dropSchemaOnClose) { + dropSchema(); + } + + return session.closeAsync(); + } + + private void dropSchema() { + + sessionRepository.entities().forEach(e -> dropEntity(e)); + } + + private void dropEntity(HelenusEntity entity) { - switch (entity.getType()) { - case TABLE: - execute(SchemaUtil.dropTable(entity), true); - break; + switch (entity.getType()) { + case TABLE : + execute(SchemaUtil.dropTable(entity), true); + break; - case UDT: - execute(SchemaUtil.dropUserType(entity), true); - break; - } - } + case UDT : + execute(SchemaUtil.dropUserType(entity), true); + break; + } + } } diff --git a/src/main/java/net/helenus/core/HelenusValidator.java b/src/main/java/net/helenus/core/HelenusValidator.java index b0087f4..1e75544 100644 --- a/src/main/java/net/helenus/core/HelenusValidator.java +++ b/src/main/java/net/helenus/core/HelenusValidator.java @@ -16,32 +16,33 @@ package net.helenus.core; import java.lang.annotation.Annotation; + import javax.validation.ConstraintValidator; + import net.helenus.mapping.HelenusProperty; import net.helenus.support.HelenusException; import net.helenus.support.HelenusMappingException; public enum HelenusValidator implements PropertyValueValidator { - INSTANCE; + INSTANCE; - public void validate(HelenusProperty prop, Object value) { + public void validate(HelenusProperty prop, Object value) { - for (ConstraintValidator validator : prop.getValidators()) { + for (ConstraintValidator validator : prop.getValidators()) { - ConstraintValidator typeless = (ConstraintValidator) validator; + ConstraintValidator typeless = (ConstraintValidator) validator; - boolean valid = false; + boolean valid = false; - try { - valid = typeless.isValid(value, null); - } catch (ClassCastException e) { - throw new HelenusMappingException( - "validator was used for wrong type '" + value + "' in " + prop, e); - } + try { + valid = typeless.isValid(value, null); + } catch (ClassCastException e) { + throw new HelenusMappingException("validator was used for wrong type '" + value + "' in " + prop, e); + } - if (!valid) { - throw new HelenusException("wrong value '" + value + "' for " + prop); - } - } - } + if (!valid) { + throw new HelenusException("wrong value '" + value + "' for " + prop); + } + } + } } diff --git a/src/main/java/net/helenus/core/MapperInstantiator.java b/src/main/java/net/helenus/core/MapperInstantiator.java index 70d4082..c16b4a1 100644 --- a/src/main/java/net/helenus/core/MapperInstantiator.java +++ b/src/main/java/net/helenus/core/MapperInstantiator.java @@ -19,5 +19,5 @@ import java.util.Map; public interface MapperInstantiator { - E instantiate(Class iface, Map src, ClassLoader classLoader); + E instantiate(Class iface, Map src, ClassLoader classLoader); } diff --git a/src/main/java/net/helenus/core/Mappers.java b/src/main/java/net/helenus/core/Mappers.java index 4dc26b1..d774d7f 100644 --- a/src/main/java/net/helenus/core/Mappers.java +++ b/src/main/java/net/helenus/core/Mappers.java @@ -15,8 +15,10 @@ */ package net.helenus.core; -import com.datastax.driver.core.Row; import java.util.function.Function; + +import com.datastax.driver.core.Row; + import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusProperty; import net.helenus.mapping.value.ColumnValueProvider; @@ -24,203 +26,161 @@ import net.helenus.support.Fun; public final class Mappers { - private Mappers() {} + private Mappers() { + } - public static final class Mapper1 implements Function> { + public static final class Mapper1 implements Function> { - private final ColumnValueProvider provider; - private final HelenusProperty p1; + private final ColumnValueProvider provider; + private final HelenusProperty p1; - public Mapper1(ColumnValueProvider provider, HelenusPropertyNode p1) { - this.provider = provider; - this.p1 = p1.getProperty(); - } + public Mapper1(ColumnValueProvider provider, HelenusPropertyNode p1) { + this.provider = provider; + this.p1 = p1.getProperty(); + } - @Override - public Fun.Tuple1 apply(Row row) { - return new Fun.Tuple1(provider.getColumnValue(row, 0, p1)); - } - } + @Override + public Fun.Tuple1 apply(Row row) { + return new Fun.Tuple1(provider.getColumnValue(row, 0, p1)); + } + } - public static final class Mapper2 implements Function> { + public static final class Mapper2 implements Function> { - private final ColumnValueProvider provider; - private final HelenusProperty p1; - private final HelenusProperty p2; + private final ColumnValueProvider provider; + private final HelenusProperty p1; + private final HelenusProperty p2; - public Mapper2(ColumnValueProvider provider, HelenusPropertyNode p1, HelenusPropertyNode p2) { - this.provider = provider; - this.p1 = p1.getProperty(); - this.p2 = p2.getProperty(); - } + public Mapper2(ColumnValueProvider provider, HelenusPropertyNode p1, HelenusPropertyNode p2) { + this.provider = provider; + this.p1 = p1.getProperty(); + this.p2 = p2.getProperty(); + } - @Override - public Fun.Tuple2 apply(Row row) { - return new Fun.Tuple2( - provider.getColumnValue(row, 0, p1), provider.getColumnValue(row, 1, p2)); - } - } + @Override + public Fun.Tuple2 apply(Row row) { + return new Fun.Tuple2(provider.getColumnValue(row, 0, p1), provider.getColumnValue(row, 1, p2)); + } + } - public static final class Mapper3 implements Function> { + public static final class Mapper3 implements Function> { - private final ColumnValueProvider provider; - private final HelenusProperty p1; - private final HelenusProperty p2; - private final HelenusProperty p3; + private final ColumnValueProvider provider; + private final HelenusProperty p1; + private final HelenusProperty p2; + private final HelenusProperty p3; - public Mapper3( - ColumnValueProvider provider, - HelenusPropertyNode p1, - HelenusPropertyNode p2, - HelenusPropertyNode p3) { - this.provider = provider; - this.p1 = p1.getProperty(); - this.p2 = p2.getProperty(); - this.p3 = p3.getProperty(); - } + public Mapper3(ColumnValueProvider provider, HelenusPropertyNode p1, HelenusPropertyNode p2, + HelenusPropertyNode p3) { + this.provider = provider; + this.p1 = p1.getProperty(); + this.p2 = p2.getProperty(); + this.p3 = p3.getProperty(); + } - @Override - public Fun.Tuple3 apply(Row row) { - return new Fun.Tuple3( - provider.getColumnValue(row, 0, p1), - provider.getColumnValue(row, 1, p2), - provider.getColumnValue(row, 2, p3)); - } - } + @Override + public Fun.Tuple3 apply(Row row) { + return new Fun.Tuple3(provider.getColumnValue(row, 0, p1), provider.getColumnValue(row, 1, p2), + provider.getColumnValue(row, 2, p3)); + } + } - public static final class Mapper4 implements Function> { + public static final class Mapper4 implements Function> { - private final ColumnValueProvider provider; - private final HelenusProperty p1; - private final HelenusProperty p2; - private final HelenusProperty p3; - private final HelenusProperty p4; + private final ColumnValueProvider provider; + private final HelenusProperty p1; + private final HelenusProperty p2; + private final HelenusProperty p3; + private final HelenusProperty p4; - public Mapper4( - ColumnValueProvider provider, - HelenusPropertyNode p1, - HelenusPropertyNode p2, - HelenusPropertyNode p3, - HelenusPropertyNode p4) { - this.provider = provider; - this.p1 = p1.getProperty(); - this.p2 = p2.getProperty(); - this.p3 = p3.getProperty(); - this.p4 = p4.getProperty(); - } + public Mapper4(ColumnValueProvider provider, HelenusPropertyNode p1, HelenusPropertyNode p2, + HelenusPropertyNode p3, HelenusPropertyNode p4) { + this.provider = provider; + this.p1 = p1.getProperty(); + this.p2 = p2.getProperty(); + this.p3 = p3.getProperty(); + this.p4 = p4.getProperty(); + } - @Override - public Fun.Tuple4 apply(Row row) { - return new Fun.Tuple4( - provider.getColumnValue(row, 0, p1), - provider.getColumnValue(row, 1, p2), - provider.getColumnValue(row, 2, p3), - provider.getColumnValue(row, 3, p4)); - } - } + @Override + public Fun.Tuple4 apply(Row row) { + return new Fun.Tuple4(provider.getColumnValue(row, 0, p1), provider.getColumnValue(row, 1, p2), + provider.getColumnValue(row, 2, p3), provider.getColumnValue(row, 3, p4)); + } + } - public static final class Mapper5 - implements Function> { + public static final class Mapper5 implements Function> { - private final ColumnValueProvider provider; - private final HelenusProperty p1, p2, p3, p4, p5; + private final ColumnValueProvider provider; + private final HelenusProperty p1, p2, p3, p4, p5; - public Mapper5( - ColumnValueProvider provider, - HelenusPropertyNode p1, - HelenusPropertyNode p2, - HelenusPropertyNode p3, - HelenusPropertyNode p4, - HelenusPropertyNode p5) { - this.provider = provider; - this.p1 = p1.getProperty(); - this.p2 = p2.getProperty(); - this.p3 = p3.getProperty(); - this.p4 = p4.getProperty(); - this.p5 = p5.getProperty(); - } + public Mapper5(ColumnValueProvider provider, HelenusPropertyNode p1, HelenusPropertyNode p2, + HelenusPropertyNode p3, HelenusPropertyNode p4, HelenusPropertyNode p5) { + this.provider = provider; + this.p1 = p1.getProperty(); + this.p2 = p2.getProperty(); + this.p3 = p3.getProperty(); + this.p4 = p4.getProperty(); + this.p5 = p5.getProperty(); + } - @Override - public Fun.Tuple5 apply(Row row) { - return new Fun.Tuple5( - provider.getColumnValue(row, 0, p1), - provider.getColumnValue(row, 1, p2), - provider.getColumnValue(row, 2, p3), - provider.getColumnValue(row, 3, p4), - provider.getColumnValue(row, 4, p5)); - } - } + @Override + public Fun.Tuple5 apply(Row row) { + return new Fun.Tuple5(provider.getColumnValue(row, 0, p1), + provider.getColumnValue(row, 1, p2), provider.getColumnValue(row, 2, p3), + provider.getColumnValue(row, 3, p4), provider.getColumnValue(row, 4, p5)); + } + } - public static final class Mapper6 - implements Function> { + public static final class Mapper6 implements Function> { - private final ColumnValueProvider provider; - private final HelenusProperty p1, p2, p3, p4, p5, p6; + private final ColumnValueProvider provider; + private final HelenusProperty p1, p2, p3, p4, p5, p6; - public Mapper6( - ColumnValueProvider provider, - HelenusPropertyNode p1, - HelenusPropertyNode p2, - HelenusPropertyNode p3, - HelenusPropertyNode p4, - HelenusPropertyNode p5, - HelenusPropertyNode p6) { - this.provider = provider; - this.p1 = p1.getProperty(); - this.p2 = p2.getProperty(); - this.p3 = p3.getProperty(); - this.p4 = p4.getProperty(); - this.p5 = p5.getProperty(); - this.p6 = p6.getProperty(); - } + public Mapper6(ColumnValueProvider provider, HelenusPropertyNode p1, HelenusPropertyNode p2, + HelenusPropertyNode p3, HelenusPropertyNode p4, HelenusPropertyNode p5, HelenusPropertyNode p6) { + this.provider = provider; + this.p1 = p1.getProperty(); + this.p2 = p2.getProperty(); + this.p3 = p3.getProperty(); + this.p4 = p4.getProperty(); + this.p5 = p5.getProperty(); + this.p6 = p6.getProperty(); + } - @Override - public Fun.Tuple6 apply(Row row) { - return new Fun.Tuple6( - provider.getColumnValue(row, 0, p1), - provider.getColumnValue(row, 1, p2), - provider.getColumnValue(row, 2, p3), - provider.getColumnValue(row, 3, p4), - provider.getColumnValue(row, 4, p5), - provider.getColumnValue(row, 5, p6)); - } - } + @Override + public Fun.Tuple6 apply(Row row) { + return new Fun.Tuple6(provider.getColumnValue(row, 0, p1), + provider.getColumnValue(row, 1, p2), provider.getColumnValue(row, 2, p3), + provider.getColumnValue(row, 3, p4), provider.getColumnValue(row, 4, p5), + provider.getColumnValue(row, 5, p6)); + } + } - public static final class Mapper7 - implements Function> { + public static final class Mapper7 implements Function> { - private final ColumnValueProvider provider; - private final HelenusProperty p1, p2, p3, p4, p5, p6, p7; + private final ColumnValueProvider provider; + private final HelenusProperty p1, p2, p3, p4, p5, p6, p7; - public Mapper7( - ColumnValueProvider provider, - HelenusPropertyNode p1, - HelenusPropertyNode p2, - HelenusPropertyNode p3, - HelenusPropertyNode p4, - HelenusPropertyNode p5, - HelenusPropertyNode p6, - HelenusPropertyNode p7) { - this.provider = provider; - this.p1 = p1.getProperty(); - this.p2 = p2.getProperty(); - this.p3 = p3.getProperty(); - this.p4 = p4.getProperty(); - this.p5 = p5.getProperty(); - this.p6 = p6.getProperty(); - this.p7 = p7.getProperty(); - } + public Mapper7(ColumnValueProvider provider, HelenusPropertyNode p1, HelenusPropertyNode p2, + HelenusPropertyNode p3, HelenusPropertyNode p4, HelenusPropertyNode p5, HelenusPropertyNode p6, + HelenusPropertyNode p7) { + this.provider = provider; + this.p1 = p1.getProperty(); + this.p2 = p2.getProperty(); + this.p3 = p3.getProperty(); + this.p4 = p4.getProperty(); + this.p5 = p5.getProperty(); + this.p6 = p6.getProperty(); + this.p7 = p7.getProperty(); + } - @Override - public Fun.Tuple7 apply(Row row) { - return new Fun.Tuple7( - provider.getColumnValue(row, 0, p1), - provider.getColumnValue(row, 1, p2), - provider.getColumnValue(row, 2, p3), - provider.getColumnValue(row, 3, p4), - provider.getColumnValue(row, 4, p5), - provider.getColumnValue(row, 5, p6), - provider.getColumnValue(row, 6, p7)); - } - } + @Override + public Fun.Tuple7 apply(Row row) { + return new Fun.Tuple7(provider.getColumnValue(row, 0, p1), + provider.getColumnValue(row, 1, p2), provider.getColumnValue(row, 2, p3), + provider.getColumnValue(row, 3, p4), provider.getColumnValue(row, 4, p5), + provider.getColumnValue(row, 5, p6), provider.getColumnValue(row, 6, p7)); + } + } } diff --git a/src/main/java/net/helenus/core/Operator.java b/src/main/java/net/helenus/core/Operator.java index bdff51c..ed49748 100644 --- a/src/main/java/net/helenus/core/Operator.java +++ b/src/main/java/net/helenus/core/Operator.java @@ -19,37 +19,37 @@ import java.util.HashMap; import java.util.Map; public enum Operator { - EQ("=="), + EQ("=="), - IN("in"), + IN("in"), - GT(">"), + GT(">"), - LT("<"), + LT("<"), - GTE(">="), + GTE(">="), - LTE("<="); + LTE("<="); - private final String name; + private final String name; - private static final Map indexByName = new HashMap(); + private static final Map indexByName = new HashMap(); - static { - for (Operator fo : Operator.values()) { - indexByName.put(fo.getName(), fo); - } - } + static { + for (Operator fo : Operator.values()) { + indexByName.put(fo.getName(), fo); + } + } - private Operator(String name) { - this.name = name; - } + private Operator(String name) { + this.name = name; + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public static Operator findByOperator(String name) { - return indexByName.get(name); - } + public static Operator findByOperator(String name) { + return indexByName.get(name); + } } diff --git a/src/main/java/net/helenus/core/Ordered.java b/src/main/java/net/helenus/core/Ordered.java index ac426aa..e86b293 100644 --- a/src/main/java/net/helenus/core/Ordered.java +++ b/src/main/java/net/helenus/core/Ordered.java @@ -1,8 +1,10 @@ package net.helenus.core; +import java.util.Objects; + import com.datastax.driver.core.querybuilder.Ordering; import com.datastax.driver.core.querybuilder.QueryBuilder; -import java.util.Objects; + import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.ColumnType; import net.helenus.mapping.MappingUtil; @@ -11,34 +13,34 @@ import net.helenus.support.HelenusMappingException; public final class Ordered { - private final Getter getter; - private final OrderingDirection direction; + private final Getter getter; + private final OrderingDirection direction; - public Ordered(Getter getter, OrderingDirection direction) { - this.getter = getter; - this.direction = direction; - } + public Ordered(Getter getter, OrderingDirection direction) { + this.getter = getter; + this.direction = direction; + } - public Ordering getOrdering() { + public Ordering getOrdering() { - Objects.requireNonNull(getter, "property is null"); - Objects.requireNonNull(direction, "direction is null"); + Objects.requireNonNull(getter, "property is null"); + Objects.requireNonNull(direction, "direction is null"); - HelenusPropertyNode propNode = MappingUtil.resolveMappingProperty(getter); + HelenusPropertyNode propNode = MappingUtil.resolveMappingProperty(getter); - if (propNode.getProperty().getColumnType() != ColumnType.CLUSTERING_COLUMN) { - throw new HelenusMappingException( - "property must be a clustering column " + propNode.getProperty().getPropertyName()); - } + if (propNode.getProperty().getColumnType() != ColumnType.CLUSTERING_COLUMN) { + throw new HelenusMappingException( + "property must be a clustering column " + propNode.getProperty().getPropertyName()); + } - switch (direction) { - case ASC: - return QueryBuilder.asc(propNode.getColumnName()); + switch (direction) { + case ASC : + return QueryBuilder.asc(propNode.getColumnName()); - case DESC: - return QueryBuilder.desc(propNode.getColumnName()); - } + case DESC : + return QueryBuilder.desc(propNode.getColumnName()); + } - throw new HelenusMappingException("invalid direction " + direction); - } + throw new HelenusMappingException("invalid direction " + direction); + } } diff --git a/src/main/java/net/helenus/core/PostCommitFunction.java b/src/main/java/net/helenus/core/PostCommitFunction.java index 3ba2b8b..a859608 100644 --- a/src/main/java/net/helenus/core/PostCommitFunction.java +++ b/src/main/java/net/helenus/core/PostCommitFunction.java @@ -1,29 +1,29 @@ package net.helenus.core; -import java.util.*; +import java.util.List; import java.util.Objects; public class PostCommitFunction implements java.util.function.Function { - private final UnitOfWork uow; - private final List postCommit; + private final UnitOfWork uow; + private final List postCommit; - PostCommitFunction(UnitOfWork uow, List postCommit) { - this.uow = uow; - this.postCommit = postCommit; - } + PostCommitFunction(UnitOfWork uow, List postCommit) { + this.uow = uow; + this.postCommit = postCommit; + } - public void andThen(CommitThunk after) { - Objects.requireNonNull(after); - if (postCommit == null) { - after.apply(); - } else { - postCommit.add(after); - } - } + public void andThen(CommitThunk after) { + Objects.requireNonNull(after); + if (postCommit == null) { + after.apply(); + } else { + postCommit.add(after); + } + } - @Override - public R apply(T t) { - return null; - } + @Override + public R apply(T t) { + return null; + } } diff --git a/src/main/java/net/helenus/core/Postulate.java b/src/main/java/net/helenus/core/Postulate.java index e0c8cf6..a31d0a8 100644 --- a/src/main/java/net/helenus/core/Postulate.java +++ b/src/main/java/net/helenus/core/Postulate.java @@ -17,80 +17,81 @@ package net.helenus.core; import com.datastax.driver.core.querybuilder.Clause; import com.datastax.driver.core.querybuilder.QueryBuilder; + import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.value.ColumnValuePreparer; import net.helenus.support.HelenusMappingException; public final class Postulate { - private final Operator operator; - private final V[] values; + private final Operator operator; + private final V[] values; - protected Postulate(Operator op, V[] values) { - this.operator = op; - this.values = values; - } + protected Postulate(Operator op, V[] values) { + this.operator = op; + this.values = values; + } - public static Postulate of(Operator op, V... values) { - return new Postulate(op, values); - } + public static Postulate of(Operator op, V... values) { + return new Postulate(op, values); + } - public Clause getClause(HelenusPropertyNode node, ColumnValuePreparer valuePreparer) { + public Clause getClause(HelenusPropertyNode node, ColumnValuePreparer valuePreparer) { - switch (operator) { - case EQ: - return QueryBuilder.eq( - node.getColumnName(), valuePreparer.prepareColumnValue(values[0], node.getProperty())); + switch (operator) { + case EQ : + return QueryBuilder.eq(node.getColumnName(), + valuePreparer.prepareColumnValue(values[0], node.getProperty())); - case IN: - Object[] preparedValues = new Object[values.length]; - for (int i = 0; i != values.length; ++i) { - preparedValues[i] = valuePreparer.prepareColumnValue(values[i], node.getProperty()); - } - return QueryBuilder.in(node.getColumnName(), preparedValues); + case IN : + Object[] preparedValues = new Object[values.length]; + for (int i = 0; i != values.length; ++i) { + preparedValues[i] = valuePreparer.prepareColumnValue(values[i], node.getProperty()); + } + return QueryBuilder.in(node.getColumnName(), preparedValues); - case LT: - return QueryBuilder.lt( - node.getColumnName(), valuePreparer.prepareColumnValue(values[0], node.getProperty())); + case LT : + return QueryBuilder.lt(node.getColumnName(), + valuePreparer.prepareColumnValue(values[0], node.getProperty())); - case LTE: - return QueryBuilder.lte( - node.getColumnName(), valuePreparer.prepareColumnValue(values[0], node.getProperty())); + case LTE : + return QueryBuilder.lte(node.getColumnName(), + valuePreparer.prepareColumnValue(values[0], node.getProperty())); - case GT: - return QueryBuilder.gt( - node.getColumnName(), valuePreparer.prepareColumnValue(values[0], node.getProperty())); + case GT : + return QueryBuilder.gt(node.getColumnName(), + valuePreparer.prepareColumnValue(values[0], node.getProperty())); - case GTE: - return QueryBuilder.gte( - node.getColumnName(), valuePreparer.prepareColumnValue(values[0], node.getProperty())); + case GTE : + return QueryBuilder.gte(node.getColumnName(), + valuePreparer.prepareColumnValue(values[0], node.getProperty())); - default: - throw new HelenusMappingException("unknown filter operation " + operator); - } - } + default : + throw new HelenusMappingException("unknown filter operation " + operator); + } + } - @Override - public String toString() { + @Override + public String toString() { - if (operator == Operator.IN) { + if (operator == Operator.IN) { - if (values == null) { - return "in()"; - } + if (values == null) { + return "in()"; + } - int len = values.length; - StringBuilder b = new StringBuilder(); - b.append("in("); - for (int i = 0; i != len; i++) { - if (b.length() > 3) { - b.append(", "); - } - b.append(String.valueOf(values[i])); - } - return b.append(')').toString(); - } + int len = values.length; + StringBuilder b = new StringBuilder(); + b.append("in("); + for (int i = 0; i != len; i++) { + if (b.length() > 3) { + b.append(", "); + } + b.append(String.valueOf(values[i])); + } + return b.append(')').toString(); + } - return operator.getName() + values[0]; - } + return operator.getName() + values[0]; + } } diff --git a/src/main/java/net/helenus/core/PropertyValueValidator.java b/src/main/java/net/helenus/core/PropertyValueValidator.java index 276418b..ca4aafb 100644 --- a/src/main/java/net/helenus/core/PropertyValueValidator.java +++ b/src/main/java/net/helenus/core/PropertyValueValidator.java @@ -19,5 +19,5 @@ import net.helenus.mapping.HelenusProperty; public interface PropertyValueValidator { - void validate(HelenusProperty prop, Object value); + void validate(HelenusProperty prop, Object value); } diff --git a/src/main/java/net/helenus/core/Query.java b/src/main/java/net/helenus/core/Query.java index b18fccb..7418876 100644 --- a/src/main/java/net/helenus/core/Query.java +++ b/src/main/java/net/helenus/core/Query.java @@ -15,80 +15,83 @@ */ package net.helenus.core; -import com.datastax.driver.core.querybuilder.BindMarker; -import com.datastax.driver.core.querybuilder.QueryBuilder; import java.util.List; import java.util.Map; import java.util.Objects; + +import com.datastax.driver.core.querybuilder.BindMarker; +import com.datastax.driver.core.querybuilder.QueryBuilder; + import net.helenus.mapping.OrderingDirection; /** Sugar methods for the queries */ public final class Query { - private Query() {} + private Query() { + } - public static BindMarker marker() { - return QueryBuilder.bindMarker(); - } + public static BindMarker marker() { + return QueryBuilder.bindMarker(); + } - public static BindMarker marker(String name) { - return QueryBuilder.bindMarker(name); - } + public static BindMarker marker(String name) { + return QueryBuilder.bindMarker(name); + } - public static Ordered asc(Getter getter) { - return new Ordered(getter, OrderingDirection.ASC); - } + public static Ordered asc(Getter getter) { + return new Ordered(getter, OrderingDirection.ASC); + } - public static Ordered desc(Getter getter) { - return new Ordered(getter, OrderingDirection.DESC); - } + public static Ordered desc(Getter getter) { + return new Ordered(getter, OrderingDirection.DESC); + } - public static Postulate eq(V val) { - return Postulate.of(Operator.EQ, val); - } + public static Postulate eq(V val) { + return Postulate.of(Operator.EQ, val); + } - public static Postulate lt(V val) { - return Postulate.of(Operator.LT, val); - } + public static Postulate lt(V val) { + return Postulate.of(Operator.LT, val); + } - public static Postulate lte(V val) { - return Postulate.of(Operator.LTE, val); - } + public static Postulate lte(V val) { + return Postulate.of(Operator.LTE, val); + } - public static Postulate gt(V val) { - return Postulate.of(Operator.GT, val); - } + public static Postulate gt(V val) { + return Postulate.of(Operator.GT, val); + } - public static Postulate gte(V val) { - return Postulate.of(Operator.GTE, val); - } + public static Postulate gte(V val) { + return Postulate.of(Operator.GTE, val); + } - public static Postulate in(V[] vals) { - return new Postulate(Operator.IN, vals); - } + public static Postulate in(V[] vals) { + return new Postulate(Operator.IN, vals); + } - public static Getter getIdx(Getter> listGetter, int index) { - Objects.requireNonNull(listGetter, "listGetter is null"); + public static Getter getIdx(Getter> listGetter, int index) { + Objects.requireNonNull(listGetter, "listGetter is null"); - return new Getter() { + return new Getter() { - @Override - public V get() { - return listGetter.get().get(index); - } - }; - } + @Override + public V get() { + return listGetter.get().get(index); + } + }; + } - public static Getter get(Getter> mapGetter, K k) { - Objects.requireNonNull(mapGetter, "mapGetter is null"); - Objects.requireNonNull(k, "key is null"); + public static Getter get(Getter> mapGetter, K k) { + Objects.requireNonNull(mapGetter, "mapGetter is null"); + Objects.requireNonNull(k, "key is null"); - return new Getter() { + return new Getter() { - @Override - public V get() { - return mapGetter.get().get(k); - } - }; - } + @Override + public V get() { + return mapGetter.get().get(k); + } + }; + } } diff --git a/src/main/java/net/helenus/core/SchemaUtil.java b/src/main/java/net/helenus/core/SchemaUtil.java index 02fb929..8e421c0 100644 --- a/src/main/java/net/helenus/core/SchemaUtil.java +++ b/src/main/java/net/helenus/core/SchemaUtil.java @@ -15,15 +15,16 @@ */ package net.helenus.core; +import java.util.*; +import java.util.stream.Collectors; + import com.datastax.driver.core.*; -import com.datastax.driver.core.IndexMetadata; import com.datastax.driver.core.querybuilder.IsNotNullClause; import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Select; import com.datastax.driver.core.schemabuilder.*; import com.datastax.driver.core.schemabuilder.Create.Options; -import java.util.*; -import java.util.stream.Collectors; + import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.*; import net.helenus.mapping.ColumnType; @@ -34,416 +35,375 @@ import net.helenus.support.HelenusMappingException; public final class SchemaUtil { - private SchemaUtil() {} + private SchemaUtil() { + } - public static RegularStatement use(String keyspace, boolean forceQuote) { - if (forceQuote) { - return new SimpleStatement("USE" + CqlUtil.forceQuote(keyspace)); - } else { - return new SimpleStatement("USE " + keyspace); - } - } + public static RegularStatement use(String keyspace, boolean forceQuote) { + if (forceQuote) { + return new SimpleStatement("USE" + CqlUtil.forceQuote(keyspace)); + } else { + return new SimpleStatement("USE " + keyspace); + } + } - public static SchemaStatement createUserType(HelenusEntity entity) { + public static SchemaStatement createUserType(HelenusEntity entity) { - if (entity.getType() != HelenusEntityType.UDT) { - throw new HelenusMappingException("expected UDT entity " + entity); - } + if (entity.getType() != HelenusEntityType.UDT) { + throw new HelenusMappingException("expected UDT entity " + entity); + } - CreateType create = SchemaBuilder.createType(entity.getName().toCql()); + CreateType create = SchemaBuilder.createType(entity.getName().toCql()); - for (HelenusProperty prop : entity.getOrderedProperties()) { + for (HelenusProperty prop : entity.getOrderedProperties()) { - ColumnType columnType = prop.getColumnType(); + ColumnType columnType = prop.getColumnType(); - if (columnType == ColumnType.PARTITION_KEY || columnType == ColumnType.CLUSTERING_COLUMN) { - throw new HelenusMappingException( - "primary key columns are not supported in UserDefinedType for " - + prop.getPropertyName() - + " in entity " - + entity); - } + if (columnType == ColumnType.PARTITION_KEY || columnType == ColumnType.CLUSTERING_COLUMN) { + throw new HelenusMappingException("primary key columns are not supported in UserDefinedType for " + + prop.getPropertyName() + " in entity " + entity); + } - try { - prop.getDataType().addColumn(create, prop.getColumnName()); - } catch (IllegalArgumentException e) { - throw new HelenusMappingException( - "invalid column name '" - + prop.getColumnName() - + "' in entity '" - + entity.getName().getName() - + "'", - e); - } - } - - return create; - } - - public static List alterUserType( - UserType userType, HelenusEntity entity, boolean dropUnusedColumns) { - - if (entity.getType() != HelenusEntityType.UDT) { - throw new HelenusMappingException("expected UDT entity " + entity); - } - - List result = new ArrayList(); - - /** - * TODO: In future replace SchemaBuilder.alterTable by SchemaBuilder.alterType when it will - * exist - */ - Alter alter = SchemaBuilder.alterTable(entity.getName().toCql()); - - final Set visitedColumns = - dropUnusedColumns ? new HashSet() : Collections.emptySet(); - - for (HelenusProperty prop : entity.getOrderedProperties()) { - - String columnName = prop.getColumnName().getName(); - - if (dropUnusedColumns) { - visitedColumns.add(columnName); - } - - ColumnType columnType = prop.getColumnType(); - - if (columnType == ColumnType.PARTITION_KEY || columnType == ColumnType.CLUSTERING_COLUMN) { - continue; - } - - DataType dataType = userType.getFieldType(columnName); - SchemaStatement stmt = - prop.getDataType() - .alterColumn(alter, prop.getColumnName(), optional(columnName, dataType)); - - if (stmt != null) { - result.add(stmt); - } - } - - if (dropUnusedColumns) { - for (String field : userType.getFieldNames()) { - if (!visitedColumns.contains(field)) { - - result.add(alter.dropColumn(field)); - } - } - } - - return result; - } - - public static SchemaStatement dropUserType(HelenusEntity entity) { - - if (entity.getType() != HelenusEntityType.UDT) { - throw new HelenusMappingException("expected UDT entity " + entity); - } - - return SchemaBuilder.dropType(entity.getName().toCql()).ifExists(); - } - - public static SchemaStatement dropUserType(UserType type) { - - return SchemaBuilder.dropType(type.getTypeName()).ifExists(); - } - - public static SchemaStatement createMaterializedView( - String keyspace, String viewName, HelenusEntity entity) { - if (entity.getType() != HelenusEntityType.VIEW) { - throw new HelenusMappingException("expected view entity " + entity); - } - - if (entity == null) { - throw new HelenusMappingException("no entity or table to select data"); - } - - List props = new ArrayList(); - entity - .getOrderedProperties() - .stream() - .map(p -> new HelenusPropertyNode(p, Optional.empty())) - .forEach(p -> props.add(p)); - - Select.Selection selection = QueryBuilder.select(); - - for (HelenusPropertyNode prop : props) { - String columnName = prop.getColumnName(); - selection = selection.column(columnName); - } - Class iface = entity.getMappingInterface(); - String tableName = Helenus.entity(iface.getInterfaces()[0]).getName().toCql(); - Select.Where where = selection.from(tableName).where(); - List p = new ArrayList(props.size()); - List c = new ArrayList(props.size()); - List o = new ArrayList(props.size()); + try { + prop.getDataType().addColumn(create, prop.getColumnName()); + } catch (IllegalArgumentException e) { + throw new HelenusMappingException("invalid column name '" + prop.getColumnName() + "' in entity '" + + entity.getName().getName() + "'", e); + } + } - for (HelenusPropertyNode prop : props) { - String columnName = prop.getColumnName(); - switch (prop.getProperty().getColumnType()) { - case PARTITION_KEY: - p.add(columnName); - where = where.and(new IsNotNullClause(columnName)); - break; + return create; + } - case CLUSTERING_COLUMN: - c.add(columnName); - where = where.and(new IsNotNullClause(columnName)); + public static List alterUserType(UserType userType, HelenusEntity entity, + boolean dropUnusedColumns) { - ClusteringColumn clusteringColumn = - prop.getProperty().getGetterMethod().getAnnotation(ClusteringColumn.class); - if (clusteringColumn != null && clusteringColumn.ordering() != null) { - o.add(columnName + " " + clusteringColumn.ordering().cql()); - } - break; - default: - break; - } - } - - String primaryKey = - "PRIMARY KEY (" - + ((p.size() > 1) ? "(" + String.join(", ", p) + ")" : p.get(0)) - + ((c.size() > 0) - ? ", " + ((c.size() > 1) ? "(" + String.join(", ", c) + ")" : c.get(0)) - : "") - + ")"; - - String clustering = ""; - if (o.size() > 0) { - clustering = "WITH CLUSTERING ORDER BY (" + String.join(", ", o) + ")"; - } - return new CreateMaterializedView(keyspace, viewName, where, primaryKey, clustering) - .ifNotExists(); - } + if (entity.getType() != HelenusEntityType.UDT) { + throw new HelenusMappingException("expected UDT entity " + entity); + } - public static SchemaStatement dropMaterializedView( - String keyspace, String viewName, HelenusEntity entity) { - return new DropMaterializedView(keyspace, viewName); - } - - public static SchemaStatement createTable(HelenusEntity entity) { - - if (entity.getType() != HelenusEntityType.TABLE) { - throw new HelenusMappingException("expected table entity " + entity); - } - - // NOTE: There is a bug in the normal path of createTable where the - // "cache" is set too early and never unset preventing more than - // one column on a table. - // SchemaBuilder.createTable(entity.getName().toCql()); - CreateTable create = new CreateTable(entity.getName().toCql()); - - create.ifNotExists(); - - List clusteringColumns = new ArrayList(); - - for (HelenusProperty prop : entity.getOrderedProperties()) { - - ColumnType columnType = prop.getColumnType(); - - if (columnType == ColumnType.CLUSTERING_COLUMN) { - clusteringColumns.add(prop); - } - - prop.getDataType().addColumn(create, prop.getColumnName()); - } - - if (!clusteringColumns.isEmpty()) { - Options options = create.withOptions(); - clusteringColumns.forEach( - p -> options.clusteringOrder(p.getColumnName().toCql(), mapDirection(p.getOrdering()))); - } - - return create; - } - - public static List alterTable( - TableMetadata tmd, HelenusEntity entity, boolean dropUnusedColumns) { - - if (entity.getType() != HelenusEntityType.TABLE) { - throw new HelenusMappingException("expected table entity " + entity); - } - - List result = new ArrayList(); - - Alter alter = SchemaBuilder.alterTable(entity.getName().toCql()); - - final Set visitedColumns = - dropUnusedColumns ? new HashSet() : Collections.emptySet(); - - for (HelenusProperty prop : entity.getOrderedProperties()) { - - String columnName = prop.getColumnName().getName(); - - if (dropUnusedColumns) { - visitedColumns.add(columnName); - } - - ColumnType columnType = prop.getColumnType(); - - if (columnType == ColumnType.PARTITION_KEY || columnType == ColumnType.CLUSTERING_COLUMN) { - continue; - } - - ColumnMetadata columnMetadata = tmd.getColumn(columnName); - SchemaStatement stmt = - prop.getDataType().alterColumn(alter, prop.getColumnName(), optional(columnMetadata)); - - if (stmt != null) { - result.add(stmt); - } - } - - if (dropUnusedColumns) { - for (ColumnMetadata cm : tmd.getColumns()) { - if (!visitedColumns.contains(cm.getName())) { - - result.add(alter.dropColumn(cm.getName())); - } - } - } - - return result; - } - - public static SchemaStatement dropTable(HelenusEntity entity) { - - if (entity.getType() != HelenusEntityType.TABLE) { - throw new HelenusMappingException("expected table entity " + entity); - } - - return SchemaBuilder.dropTable(entity.getName().toCql()).ifExists(); - } - - public static SchemaStatement createIndex(HelenusProperty prop) { - if (prop.caseSensitiveIndex()) { - return SchemaBuilder.createIndex(prop.getIndexName().get().toCql()) - .ifNotExists() - .onTable(prop.getEntity().getName().toCql()) - .andColumn(prop.getColumnName().toCql()); - } else { - return new CreateSasiIndex(prop.getIndexName().get().toCql()) - .ifNotExists() - .onTable(prop.getEntity().getName().toCql()) - .andColumn(prop.getColumnName().toCql()); - } - } - - public static List createIndexes(HelenusEntity entity) { - - return entity - .getOrderedProperties() - .stream() - .filter(p -> p.getIndexName().isPresent()) - .map(p -> SchemaUtil.createIndex(p)) - .collect(Collectors.toList()); - } - - public static List alterIndexes( - TableMetadata tmd, HelenusEntity entity, boolean dropUnusedIndexes) { - - List list = new ArrayList(); - - final Set visitedColumns = - dropUnusedIndexes ? new HashSet() : Collections.emptySet(); - - entity - .getOrderedProperties() - .stream() - .filter(p -> p.getIndexName().isPresent()) - .forEach( - p -> { - String columnName = p.getColumnName().getName(); - - if (dropUnusedIndexes) { - visitedColumns.add(columnName); - } - - ColumnMetadata cm = tmd.getColumn(columnName); - - if (cm != null) { - IndexMetadata im = tmd.getIndex(columnName); - if (im == null) { - list.add(createIndex(p)); - } - } else { - list.add(createIndex(p)); - } - }); - - if (dropUnusedIndexes) { - - tmd.getColumns() - .stream() - .filter(c -> tmd.getIndex(c.getName()) != null && !visitedColumns.contains(c.getName())) - .forEach( - c -> { - list.add(SchemaBuilder.dropIndex(tmd.getIndex(c.getName()).getName()).ifExists()); - }); - } - - return list; - } - - public static SchemaStatement dropIndex(HelenusProperty prop) { - return SchemaBuilder.dropIndex(prop.getIndexName().get().toCql()).ifExists(); - } - - private static SchemaBuilder.Direction mapDirection(OrderingDirection o) { - switch (o) { - case ASC: - return SchemaBuilder.Direction.ASC; - case DESC: - return SchemaBuilder.Direction.DESC; - } - throw new HelenusMappingException("unknown ordering " + o); - } - - public static void throwNoMapping(HelenusProperty prop) { - - throw new HelenusMappingException( - "only primitive types and Set,List,Map collections and UserDefinedTypes are allowed, unknown type for property '" - + prop.getPropertyName() - + "' type is '" - + prop.getJavaType() - + "' in the entity " - + prop.getEntity()); - } - - private static OptionalColumnMetadata optional(final ColumnMetadata columnMetadata) { - if (columnMetadata != null) { - return new OptionalColumnMetadata() { - - @Override - public String getName() { - return columnMetadata.getName(); - } - - @Override - public DataType getType() { - return columnMetadata.getType(); - } - }; - } - return null; - } - - private static OptionalColumnMetadata optional(final String name, final DataType dataType) { - if (dataType != null) { - return new OptionalColumnMetadata() { - - @Override - public String getName() { - return name; - } - - @Override - public DataType getType() { - return dataType; - } - }; - } - return null; - } + List result = new ArrayList(); + + /** + * TODO: In future replace SchemaBuilder.alterTable by SchemaBuilder.alterType + * when it will exist + */ + Alter alter = SchemaBuilder.alterTable(entity.getName().toCql()); + + final Set visitedColumns = dropUnusedColumns ? new HashSet() : Collections.emptySet(); + + for (HelenusProperty prop : entity.getOrderedProperties()) { + + String columnName = prop.getColumnName().getName(); + + if (dropUnusedColumns) { + visitedColumns.add(columnName); + } + + ColumnType columnType = prop.getColumnType(); + + if (columnType == ColumnType.PARTITION_KEY || columnType == ColumnType.CLUSTERING_COLUMN) { + continue; + } + + DataType dataType = userType.getFieldType(columnName); + SchemaStatement stmt = prop.getDataType().alterColumn(alter, prop.getColumnName(), + optional(columnName, dataType)); + + if (stmt != null) { + result.add(stmt); + } + } + + if (dropUnusedColumns) { + for (String field : userType.getFieldNames()) { + if (!visitedColumns.contains(field)) { + + result.add(alter.dropColumn(field)); + } + } + } + + return result; + } + + public static SchemaStatement dropUserType(HelenusEntity entity) { + + if (entity.getType() != HelenusEntityType.UDT) { + throw new HelenusMappingException("expected UDT entity " + entity); + } + + return SchemaBuilder.dropType(entity.getName().toCql()).ifExists(); + } + + public static SchemaStatement dropUserType(UserType type) { + + return SchemaBuilder.dropType(type.getTypeName()).ifExists(); + } + + public static SchemaStatement createMaterializedView(String keyspace, String viewName, HelenusEntity entity) { + if (entity.getType() != HelenusEntityType.VIEW) { + throw new HelenusMappingException("expected view entity " + entity); + } + + if (entity == null) { + throw new HelenusMappingException("no entity or table to select data"); + } + + List props = new ArrayList(); + entity.getOrderedProperties().stream().map(p -> new HelenusPropertyNode(p, Optional.empty())) + .forEach(p -> props.add(p)); + + Select.Selection selection = QueryBuilder.select(); + + for (HelenusPropertyNode prop : props) { + String columnName = prop.getColumnName(); + selection = selection.column(columnName); + } + Class iface = entity.getMappingInterface(); + String tableName = Helenus.entity(iface.getInterfaces()[0]).getName().toCql(); + Select.Where where = selection.from(tableName).where(); + List p = new ArrayList(props.size()); + List c = new ArrayList(props.size()); + List o = new ArrayList(props.size()); + + for (HelenusPropertyNode prop : props) { + String columnName = prop.getColumnName(); + switch (prop.getProperty().getColumnType()) { + case PARTITION_KEY : + p.add(columnName); + where = where.and(new IsNotNullClause(columnName)); + break; + + case CLUSTERING_COLUMN : + c.add(columnName); + where = where.and(new IsNotNullClause(columnName)); + + ClusteringColumn clusteringColumn = prop.getProperty().getGetterMethod() + .getAnnotation(ClusteringColumn.class); + if (clusteringColumn != null && clusteringColumn.ordering() != null) { + o.add(columnName + " " + clusteringColumn.ordering().cql()); + } + break; + default : + break; + } + } + + String primaryKey = "PRIMARY KEY (" + ((p.size() > 1) ? "(" + String.join(", ", p) + ")" : p.get(0)) + + ((c.size() > 0) ? ", " + ((c.size() > 1) ? "(" + String.join(", ", c) + ")" : c.get(0)) : "") + ")"; + + String clustering = ""; + if (o.size() > 0) { + clustering = "WITH CLUSTERING ORDER BY (" + String.join(", ", o) + ")"; + } + return new CreateMaterializedView(keyspace, viewName, where, primaryKey, clustering).ifNotExists(); + } + + public static SchemaStatement dropMaterializedView(String keyspace, String viewName, HelenusEntity entity) { + return new DropMaterializedView(keyspace, viewName); + } + + public static SchemaStatement createTable(HelenusEntity entity) { + + if (entity.getType() != HelenusEntityType.TABLE) { + throw new HelenusMappingException("expected table entity " + entity); + } + + // NOTE: There is a bug in the normal path of createTable where the + // "cache" is set too early and never unset preventing more than + // one column on a table. + // SchemaBuilder.createTable(entity.getName().toCql()); + CreateTable create = new CreateTable(entity.getName().toCql()); + + create.ifNotExists(); + + List clusteringColumns = new ArrayList(); + + for (HelenusProperty prop : entity.getOrderedProperties()) { + + ColumnType columnType = prop.getColumnType(); + + if (columnType == ColumnType.CLUSTERING_COLUMN) { + clusteringColumns.add(prop); + } + + prop.getDataType().addColumn(create, prop.getColumnName()); + } + + if (!clusteringColumns.isEmpty()) { + Options options = create.withOptions(); + clusteringColumns + .forEach(p -> options.clusteringOrder(p.getColumnName().toCql(), mapDirection(p.getOrdering()))); + } + + return create; + } + + public static List alterTable(TableMetadata tmd, HelenusEntity entity, boolean dropUnusedColumns) { + + if (entity.getType() != HelenusEntityType.TABLE) { + throw new HelenusMappingException("expected table entity " + entity); + } + + List result = new ArrayList(); + + Alter alter = SchemaBuilder.alterTable(entity.getName().toCql()); + + final Set visitedColumns = dropUnusedColumns ? new HashSet() : Collections.emptySet(); + + for (HelenusProperty prop : entity.getOrderedProperties()) { + + String columnName = prop.getColumnName().getName(); + + if (dropUnusedColumns) { + visitedColumns.add(columnName); + } + + ColumnType columnType = prop.getColumnType(); + + if (columnType == ColumnType.PARTITION_KEY || columnType == ColumnType.CLUSTERING_COLUMN) { + continue; + } + + ColumnMetadata columnMetadata = tmd.getColumn(columnName); + SchemaStatement stmt = prop.getDataType().alterColumn(alter, prop.getColumnName(), + optional(columnMetadata)); + + if (stmt != null) { + result.add(stmt); + } + } + + if (dropUnusedColumns) { + for (ColumnMetadata cm : tmd.getColumns()) { + if (!visitedColumns.contains(cm.getName())) { + + result.add(alter.dropColumn(cm.getName())); + } + } + } + + return result; + } + + public static SchemaStatement dropTable(HelenusEntity entity) { + + if (entity.getType() != HelenusEntityType.TABLE) { + throw new HelenusMappingException("expected table entity " + entity); + } + + return SchemaBuilder.dropTable(entity.getName().toCql()).ifExists(); + } + + public static SchemaStatement createIndex(HelenusProperty prop) { + if (prop.caseSensitiveIndex()) { + return SchemaBuilder.createIndex(prop.getIndexName().get().toCql()).ifNotExists() + .onTable(prop.getEntity().getName().toCql()).andColumn(prop.getColumnName().toCql()); + } else { + return new CreateSasiIndex(prop.getIndexName().get().toCql()).ifNotExists() + .onTable(prop.getEntity().getName().toCql()).andColumn(prop.getColumnName().toCql()); + } + } + + public static List createIndexes(HelenusEntity entity) { + + return entity.getOrderedProperties().stream().filter(p -> p.getIndexName().isPresent()) + .map(p -> SchemaUtil.createIndex(p)).collect(Collectors.toList()); + } + + public static List alterIndexes(TableMetadata tmd, HelenusEntity entity, + boolean dropUnusedIndexes) { + + List list = new ArrayList(); + + final Set visitedColumns = dropUnusedIndexes ? new HashSet() : Collections.emptySet(); + + entity.getOrderedProperties().stream().filter(p -> p.getIndexName().isPresent()).forEach(p -> { + String columnName = p.getColumnName().getName(); + + if (dropUnusedIndexes) { + visitedColumns.add(columnName); + } + + ColumnMetadata cm = tmd.getColumn(columnName); + + if (cm != null) { + IndexMetadata im = tmd.getIndex(columnName); + if (im == null) { + list.add(createIndex(p)); + } + } else { + list.add(createIndex(p)); + } + }); + + if (dropUnusedIndexes) { + + tmd.getColumns().stream() + .filter(c -> tmd.getIndex(c.getName()) != null && !visitedColumns.contains(c.getName())) + .forEach(c -> { + list.add(SchemaBuilder.dropIndex(tmd.getIndex(c.getName()).getName()).ifExists()); + }); + } + + return list; + } + + public static SchemaStatement dropIndex(HelenusProperty prop) { + return SchemaBuilder.dropIndex(prop.getIndexName().get().toCql()).ifExists(); + } + + private static SchemaBuilder.Direction mapDirection(OrderingDirection o) { + switch (o) { + case ASC : + return SchemaBuilder.Direction.ASC; + case DESC : + return SchemaBuilder.Direction.DESC; + } + throw new HelenusMappingException("unknown ordering " + o); + } + + public static void throwNoMapping(HelenusProperty prop) { + + throw new HelenusMappingException( + "only primitive types and Set,List,Map collections and UserDefinedTypes are allowed, unknown type for property '" + + prop.getPropertyName() + "' type is '" + prop.getJavaType() + "' in the entity " + + prop.getEntity()); + } + + private static OptionalColumnMetadata optional(final ColumnMetadata columnMetadata) { + if (columnMetadata != null) { + return new OptionalColumnMetadata() { + + @Override + public String getName() { + return columnMetadata.getName(); + } + + @Override + public DataType getType() { + return columnMetadata.getType(); + } + }; + } + return null; + } + + private static OptionalColumnMetadata optional(final String name, final DataType dataType) { + if (dataType != null) { + return new OptionalColumnMetadata() { + + @Override + public String getName() { + return name; + } + + @Override + public DataType getType() { + return dataType; + } + }; + } + return null; + } } diff --git a/src/main/java/net/helenus/core/SessionInitializer.java b/src/main/java/net/helenus/core/SessionInitializer.java index 4a8d2f9..046daa4 100644 --- a/src/main/java/net/helenus/core/SessionInitializer.java +++ b/src/main/java/net/helenus/core/SessionInitializer.java @@ -15,16 +15,18 @@ */ package net.helenus.core; -import brave.Tracer; -import com.codahale.metrics.MetricRegistry; -import com.datastax.driver.core.*; -import com.google.common.util.concurrent.MoreExecutors; import java.io.IOException; import java.io.PrintStream; import java.util.*; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.function.Consumer; + +import com.codahale.metrics.MetricRegistry; +import com.datastax.driver.core.*; +import com.google.common.util.concurrent.MoreExecutors; + +import brave.Tracer; import net.helenus.core.reflect.DslExportable; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusEntityType; @@ -37,399 +39,348 @@ import net.helenus.support.PackageUtil; public final class SessionInitializer extends AbstractSessionOperations { - private final Session session; - private CodecRegistry registry; - private String usingKeyspace; - private boolean showCql = false; - private ConsistencyLevel consistencyLevel; - private boolean idempotent = true; - private MetricRegistry metricRegistry = new MetricRegistry(); - private Tracer zipkinTracer; - private PrintStream printStream = System.out; - private Executor executor = MoreExecutors.directExecutor(); - private Class unitOfWorkClass = UnitOfWorkImpl.class; - - private SessionRepositoryBuilder sessionRepository; - - private boolean dropUnusedColumns = false; - private boolean dropUnusedIndexes = false; - - private KeyspaceMetadata keyspaceMetadata; - - private final List>> initList = new ArrayList>>(); - private AutoDdl autoDdl = AutoDdl.UPDATE; - - SessionInitializer(Session session) { - this.session = Objects.requireNonNull(session, "empty session"); - this.usingKeyspace = session.getLoggedKeyspace(); // can be null - this.sessionRepository = new SessionRepositoryBuilder(session); - } - - @Override - public Session currentSession() { - return session; - } - - @Override - public String usingKeyspace() { - return usingKeyspace; - } - - @Override - public Executor getExecutor() { - return executor; - } - - @Override - public SessionRepository getSessionRepository() { - throw new HelenusException("not expected to call"); - } - - @Override - public ColumnValueProvider getValueProvider() { - throw new HelenusException("not expected to call"); - } - - @Override - public ColumnValuePreparer getValuePreparer() { - throw new HelenusException("not expected to call"); - } - - public SessionInitializer showCql() { - this.showCql = true; - return this; - } - - public SessionInitializer showCql(boolean enabled) { - this.showCql = enabled; - return this; - } - - public SessionInitializer metricRegistry(MetricRegistry metricRegistry) { - this.metricRegistry = metricRegistry; - return this; - } - - public SessionInitializer zipkinTracer(Tracer tracer) { - this.zipkinTracer = tracer; - return this; - } - - public SessionInitializer setUnitOfWorkClass(Class e) { - this.unitOfWorkClass = e; - return this; - } - - public SessionInitializer consistencyLevel(ConsistencyLevel consistencyLevel) { - this.consistencyLevel = consistencyLevel; - return this; - } - - public ConsistencyLevel getDefaultConsistencyLevel() { - return consistencyLevel; - } - - public SessionInitializer idempotentQueryExecution(boolean idempotent) { - this.idempotent = idempotent; - return this; - } - - public boolean getDefaultQueryIdempotency() { - return idempotent; - } - - @Override - public PrintStream getPrintStream() { - return printStream; - } - - public SessionInitializer printTo(PrintStream out) { - this.printStream = out; - return this; - } - - public SessionInitializer withExecutor(Executor executor) { - Objects.requireNonNull(executor, "empty executor"); - this.executor = executor; - return this; - } - - public SessionInitializer withCachingExecutor() { - this.executor = Executors.newCachedThreadPool(); - return this; - } - - public SessionInitializer dropUnusedColumns(boolean enabled) { - this.dropUnusedColumns = enabled; - return this; - } - - public SessionInitializer dropUnusedIndexes(boolean enabled) { - this.dropUnusedIndexes = enabled; - return this; - } - - public SessionInitializer withCodecRegistry(CodecRegistry registry) { - this.registry = registry; - return this; - } - - @Override - public boolean isShowCql() { - return showCql; - } - - public SessionInitializer addPackage(String packageName) { - try { - PackageUtil.getClasses(packageName) - .stream() - .filter(c -> c.isInterface() && !c.isAnnotation()) - .forEach( - clazz -> { - initList.add(Either.right(clazz)); - }); - } catch (IOException | ClassNotFoundException e) { - throw new HelenusException("fail to add package " + packageName, e); - } - return this; - } - - public SessionInitializer add(Object... dsls) { - Objects.requireNonNull(dsls, "dsls is empty"); - int len = dsls.length; - for (int i = 0; i != len; ++i) { - Object obj = Objects.requireNonNull(dsls[i], "element " + i + " is empty"); - initList.add(Either.left(obj)); - } - return this; - } - - public SessionInitializer autoValidate() { - this.autoDdl = AutoDdl.VALIDATE; - return this; - } - - public SessionInitializer autoUpdate() { - this.autoDdl = AutoDdl.UPDATE; - return this; - } - - public SessionInitializer autoCreate() { - this.autoDdl = AutoDdl.CREATE; - return this; - } - - public SessionInitializer autoCreateDrop() { - this.autoDdl = AutoDdl.CREATE_DROP; - return this; - } - - public SessionInitializer auto(AutoDdl autoDdl) { - this.autoDdl = autoDdl; - return this; - } - - public SessionInitializer use(String keyspace) { - session.execute(SchemaUtil.use(keyspace, false)); - this.usingKeyspace = keyspace; - return this; - } - - public SessionInitializer use(String keyspace, boolean forceQuote) { - session.execute(SchemaUtil.use(keyspace, forceQuote)); - this.usingKeyspace = keyspace; - return this; - } - - public void singleton() { - Helenus.setSession(get()); - } - - public synchronized HelenusSession get() { - initialize(); - return new HelenusSession( - session, - usingKeyspace, - registry, - showCql, - printStream, - sessionRepository, - executor, - autoDdl == AutoDdl.CREATE_DROP, - consistencyLevel, - idempotent, - unitOfWorkClass, - metricRegistry, - zipkinTracer); - } - - private void initialize() { - - Objects.requireNonNull(usingKeyspace, "please define keyspace by 'use' operator"); - - initList.forEach( - (either) -> { - Class iface = null; - if (either.isLeft()) { - iface = MappingUtil.getMappingInterface(either.getLeft()); - } else { - iface = either.getRight(); - } - - DslExportable dsl = (DslExportable) Helenus.dsl(iface); - dsl.setCassandraMetadataForHelenusSession(session.getCluster().getMetadata()); - sessionRepository.add(dsl); - }); - - TableOperations tableOps = new TableOperations(this, dropUnusedColumns, dropUnusedIndexes); - UserTypeOperations userTypeOps = new UserTypeOperations(this, dropUnusedColumns); - - switch (autoDdl) { - case CREATE_DROP: - - // Drop view first, otherwise a `DROP TABLE ...` will fail as the type is still referenced - // by a view. - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.VIEW) - .forEach(e -> tableOps.dropView(e)); - - // Drop tables second, before DROP TYPE otherwise a `DROP TYPE ...` will fail as the type is - // still referenced by a table. - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.TABLE) - .forEach(e -> tableOps.dropTable(e)); - - eachUserTypeInReverseOrder(userTypeOps, e -> userTypeOps.dropUserType(e)); - - // FALLTHRU to CREATE case (read: the absence of a `break;` statement here is intentional!) - case CREATE: - eachUserTypeInOrder(userTypeOps, e -> userTypeOps.createUserType(e)); - - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.TABLE) - .forEach(e -> tableOps.createTable(e)); - - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.VIEW) - .forEach(e -> tableOps.createView(e)); - - break; - - case VALIDATE: - eachUserTypeInOrder(userTypeOps, e -> userTypeOps.validateUserType(getUserType(e), e)); - - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.TABLE) - .forEach(e -> tableOps.validateTable(getTableMetadata(e), e)); - - break; - - case UPDATE: - eachUserTypeInOrder(userTypeOps, e -> userTypeOps.updateUserType(getUserType(e), e)); - - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.VIEW) - .forEach(e -> tableOps.dropView(e)); - - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.TABLE) - .forEach(e -> tableOps.updateTable(getTableMetadata(e), e)); - - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.VIEW) - .forEach(e -> tableOps.createView(e)); - break; - } - - KeyspaceMetadata km = getKeyspaceMetadata(); - - for (UserType userType : km.getUserTypes()) { - sessionRepository.addUserType(userType.getTypeName(), userType); - } - } - - private void eachUserTypeInOrder( - UserTypeOperations userTypeOps, Consumer action) { - - Set processedSet = new HashSet(); - Set stack = new HashSet(); - - sessionRepository - .entities() - .stream() - .filter(e -> e.getType() == HelenusEntityType.UDT) - .forEach( - e -> { - stack.clear(); - eachUserTypeInRecursion(e, processedSet, stack, userTypeOps, action); - }); - } - - private void eachUserTypeInReverseOrder( - UserTypeOperations userTypeOps, Consumer action) { - ArrayDeque deque = new ArrayDeque<>(); - eachUserTypeInOrder(userTypeOps, e -> deque.addFirst(e)); - deque - .stream() - .forEach( - e -> { - action.accept(e); - }); - } - - private void eachUserTypeInRecursion( - HelenusEntity e, - Set processedSet, - Set stack, - UserTypeOperations userTypeOps, - Consumer action) { - - stack.add(e); - - Collection createBefore = sessionRepository.getUserTypeUses(e); - - for (HelenusEntity be : createBefore) { - if (!processedSet.contains(be) && !stack.contains(be)) { - eachUserTypeInRecursion(be, processedSet, stack, userTypeOps, action); - processedSet.add(be); - } - } - - if (!processedSet.contains(e)) { - action.accept(e); - processedSet.add(e); - } - } - - private KeyspaceMetadata getKeyspaceMetadata() { - if (keyspaceMetadata == null) { - keyspaceMetadata = - session.getCluster().getMetadata().getKeyspace(usingKeyspace.toLowerCase()); - } - return keyspaceMetadata; - } - - private TableMetadata getTableMetadata(HelenusEntity entity) { - return getKeyspaceMetadata().getTable(entity.getName().getName()); - } - - private UserType getUserType(HelenusEntity entity) { - return getKeyspaceMetadata().getUserType(entity.getName().getName()); - } + private final Session session; + private CodecRegistry registry; + private String usingKeyspace; + private boolean showCql = false; + private ConsistencyLevel consistencyLevel; + private boolean idempotent = true; + private MetricRegistry metricRegistry = new MetricRegistry(); + private Tracer zipkinTracer; + private PrintStream printStream = System.out; + private Executor executor = MoreExecutors.directExecutor(); + private Class unitOfWorkClass = UnitOfWorkImpl.class; + + private SessionRepositoryBuilder sessionRepository; + + private boolean dropUnusedColumns = false; + private boolean dropUnusedIndexes = false; + + private KeyspaceMetadata keyspaceMetadata; + + private final List>> initList = new ArrayList>>(); + private AutoDdl autoDdl = AutoDdl.UPDATE; + + SessionInitializer(Session session) { + this.session = Objects.requireNonNull(session, "empty session"); + this.usingKeyspace = session.getLoggedKeyspace(); // can be null + this.sessionRepository = new SessionRepositoryBuilder(session); + } + + @Override + public Session currentSession() { + return session; + } + + @Override + public String usingKeyspace() { + return usingKeyspace; + } + + @Override + public Executor getExecutor() { + return executor; + } + + @Override + public SessionRepository getSessionRepository() { + throw new HelenusException("not expected to call"); + } + + @Override + public ColumnValueProvider getValueProvider() { + throw new HelenusException("not expected to call"); + } + + @Override + public ColumnValuePreparer getValuePreparer() { + throw new HelenusException("not expected to call"); + } + + public SessionInitializer showCql() { + this.showCql = true; + return this; + } + + public SessionInitializer showCql(boolean enabled) { + this.showCql = enabled; + return this; + } + + public SessionInitializer metricRegistry(MetricRegistry metricRegistry) { + this.metricRegistry = metricRegistry; + return this; + } + + public SessionInitializer zipkinTracer(Tracer tracer) { + this.zipkinTracer = tracer; + return this; + } + + public SessionInitializer setUnitOfWorkClass(Class e) { + this.unitOfWorkClass = e; + return this; + } + + public SessionInitializer consistencyLevel(ConsistencyLevel consistencyLevel) { + this.consistencyLevel = consistencyLevel; + return this; + } + + public ConsistencyLevel getDefaultConsistencyLevel() { + return consistencyLevel; + } + + public SessionInitializer idempotentQueryExecution(boolean idempotent) { + this.idempotent = idempotent; + return this; + } + + public boolean getDefaultQueryIdempotency() { + return idempotent; + } + + @Override + public PrintStream getPrintStream() { + return printStream; + } + + public SessionInitializer printTo(PrintStream out) { + this.printStream = out; + return this; + } + + public SessionInitializer withExecutor(Executor executor) { + Objects.requireNonNull(executor, "empty executor"); + this.executor = executor; + return this; + } + + public SessionInitializer withCachingExecutor() { + this.executor = Executors.newCachedThreadPool(); + return this; + } + + public SessionInitializer dropUnusedColumns(boolean enabled) { + this.dropUnusedColumns = enabled; + return this; + } + + public SessionInitializer dropUnusedIndexes(boolean enabled) { + this.dropUnusedIndexes = enabled; + return this; + } + + public SessionInitializer withCodecRegistry(CodecRegistry registry) { + this.registry = registry; + return this; + } + + @Override + public boolean isShowCql() { + return showCql; + } + + public SessionInitializer addPackage(String packageName) { + try { + PackageUtil.getClasses(packageName).stream().filter(c -> c.isInterface() && !c.isAnnotation()) + .forEach(clazz -> { + initList.add(Either.right(clazz)); + }); + } catch (IOException | ClassNotFoundException e) { + throw new HelenusException("fail to add package " + packageName, e); + } + return this; + } + + public SessionInitializer add(Object... dsls) { + Objects.requireNonNull(dsls, "dsls is empty"); + int len = dsls.length; + for (int i = 0; i != len; ++i) { + Object obj = Objects.requireNonNull(dsls[i], "element " + i + " is empty"); + initList.add(Either.left(obj)); + } + return this; + } + + public SessionInitializer autoValidate() { + this.autoDdl = AutoDdl.VALIDATE; + return this; + } + + public SessionInitializer autoUpdate() { + this.autoDdl = AutoDdl.UPDATE; + return this; + } + + public SessionInitializer autoCreate() { + this.autoDdl = AutoDdl.CREATE; + return this; + } + + public SessionInitializer autoCreateDrop() { + this.autoDdl = AutoDdl.CREATE_DROP; + return this; + } + + public SessionInitializer auto(AutoDdl autoDdl) { + this.autoDdl = autoDdl; + return this; + } + + public SessionInitializer use(String keyspace) { + session.execute(SchemaUtil.use(keyspace, false)); + this.usingKeyspace = keyspace; + return this; + } + + public SessionInitializer use(String keyspace, boolean forceQuote) { + session.execute(SchemaUtil.use(keyspace, forceQuote)); + this.usingKeyspace = keyspace; + return this; + } + + public void singleton() { + Helenus.setSession(get()); + } + + public synchronized HelenusSession get() { + initialize(); + return new HelenusSession(session, usingKeyspace, registry, showCql, printStream, sessionRepository, executor, + autoDdl == AutoDdl.CREATE_DROP, consistencyLevel, idempotent, unitOfWorkClass, metricRegistry, + zipkinTracer); + } + + private void initialize() { + + Objects.requireNonNull(usingKeyspace, "please define keyspace by 'use' operator"); + + initList.forEach((either) -> { + Class iface = null; + if (either.isLeft()) { + iface = MappingUtil.getMappingInterface(either.getLeft()); + } else { + iface = either.getRight(); + } + + DslExportable dsl = (DslExportable) Helenus.dsl(iface); + dsl.setCassandraMetadataForHelenusSession(session.getCluster().getMetadata()); + sessionRepository.add(dsl); + }); + + TableOperations tableOps = new TableOperations(this, dropUnusedColumns, dropUnusedIndexes); + UserTypeOperations userTypeOps = new UserTypeOperations(this, dropUnusedColumns); + + switch (autoDdl) { + case CREATE_DROP : + + // Drop view first, otherwise a `DROP TABLE ...` will fail as the type is still + // referenced + // by a view. + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.VIEW) + .forEach(e -> tableOps.dropView(e)); + + // Drop tables second, before DROP TYPE otherwise a `DROP TYPE ...` will fail as + // the type is + // still referenced by a table. + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.TABLE) + .forEach(e -> tableOps.dropTable(e)); + + eachUserTypeInReverseOrder(userTypeOps, e -> userTypeOps.dropUserType(e)); + + // FALLTHRU to CREATE case (read: the absence of a `break;` statement here is + // intentional!) + case CREATE : + eachUserTypeInOrder(userTypeOps, e -> userTypeOps.createUserType(e)); + + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.TABLE) + .forEach(e -> tableOps.createTable(e)); + + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.VIEW) + .forEach(e -> tableOps.createView(e)); + + break; + + case VALIDATE : + eachUserTypeInOrder(userTypeOps, e -> userTypeOps.validateUserType(getUserType(e), e)); + + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.TABLE) + .forEach(e -> tableOps.validateTable(getTableMetadata(e), e)); + + break; + + case UPDATE : + eachUserTypeInOrder(userTypeOps, e -> userTypeOps.updateUserType(getUserType(e), e)); + + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.VIEW) + .forEach(e -> tableOps.dropView(e)); + + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.TABLE) + .forEach(e -> tableOps.updateTable(getTableMetadata(e), e)); + + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.VIEW) + .forEach(e -> tableOps.createView(e)); + break; + } + + KeyspaceMetadata km = getKeyspaceMetadata(); + + for (UserType userType : km.getUserTypes()) { + sessionRepository.addUserType(userType.getTypeName(), userType); + } + } + + private void eachUserTypeInOrder(UserTypeOperations userTypeOps, Consumer action) { + + Set processedSet = new HashSet(); + Set stack = new HashSet(); + + sessionRepository.entities().stream().filter(e -> e.getType() == HelenusEntityType.UDT).forEach(e -> { + stack.clear(); + eachUserTypeInRecursion(e, processedSet, stack, userTypeOps, action); + }); + } + + private void eachUserTypeInReverseOrder(UserTypeOperations userTypeOps, Consumer action) { + ArrayDeque deque = new ArrayDeque<>(); + eachUserTypeInOrder(userTypeOps, e -> deque.addFirst(e)); + deque.stream().forEach(e -> { + action.accept(e); + }); + } + + private void eachUserTypeInRecursion(HelenusEntity e, Set processedSet, Set stack, + UserTypeOperations userTypeOps, Consumer action) { + + stack.add(e); + + Collection createBefore = sessionRepository.getUserTypeUses(e); + + for (HelenusEntity be : createBefore) { + if (!processedSet.contains(be) && !stack.contains(be)) { + eachUserTypeInRecursion(be, processedSet, stack, userTypeOps, action); + processedSet.add(be); + } + } + + if (!processedSet.contains(e)) { + action.accept(e); + processedSet.add(e); + } + } + + private KeyspaceMetadata getKeyspaceMetadata() { + if (keyspaceMetadata == null) { + keyspaceMetadata = session.getCluster().getMetadata().getKeyspace(usingKeyspace.toLowerCase()); + } + return keyspaceMetadata; + } + + private TableMetadata getTableMetadata(HelenusEntity entity) { + return getKeyspaceMetadata().getTable(entity.getName().getName()); + } + + private UserType getUserType(HelenusEntity entity) { + return getKeyspaceMetadata().getUserType(entity.getName().getName()); + } } diff --git a/src/main/java/net/helenus/core/SessionRepository.java b/src/main/java/net/helenus/core/SessionRepository.java index 05d6f64..faf7774 100644 --- a/src/main/java/net/helenus/core/SessionRepository.java +++ b/src/main/java/net/helenus/core/SessionRepository.java @@ -15,30 +15,31 @@ */ package net.helenus.core; +import java.util.Collection; + import com.datastax.driver.core.UserType; import com.google.common.collect.ImmutableMap; -import java.util.Collection; + import net.helenus.mapping.HelenusEntity; public final class SessionRepository { - private final ImmutableMap userTypeMap; + private final ImmutableMap userTypeMap; - private final ImmutableMap, HelenusEntity> entityMap; + private final ImmutableMap, HelenusEntity> entityMap; - public SessionRepository(SessionRepositoryBuilder builder) { + public SessionRepository(SessionRepositoryBuilder builder) { - userTypeMap = ImmutableMap.builder().putAll(builder.getUserTypeMap()).build(); + userTypeMap = ImmutableMap.builder().putAll(builder.getUserTypeMap()).build(); - entityMap = - ImmutableMap., HelenusEntity>builder().putAll(builder.getEntityMap()).build(); - } + entityMap = ImmutableMap., HelenusEntity>builder().putAll(builder.getEntityMap()).build(); + } - public UserType findUserType(String name) { - return userTypeMap.get(name.toLowerCase()); - } + public UserType findUserType(String name) { + return userTypeMap.get(name.toLowerCase()); + } - public Collection entities() { - return entityMap.values(); - } + public Collection entities() { + return entityMap.values(); + } } diff --git a/src/main/java/net/helenus/core/SessionRepositoryBuilder.java b/src/main/java/net/helenus/core/SessionRepositoryBuilder.java index 413ec48..8ef0734 100644 --- a/src/main/java/net/helenus/core/SessionRepositoryBuilder.java +++ b/src/main/java/net/helenus/core/SessionRepositoryBuilder.java @@ -15,15 +15,17 @@ */ package net.helenus.core; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + import com.datastax.driver.core.Session; import com.datastax.driver.core.UDTValue; import com.datastax.driver.core.UserType; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; + import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusEntityType; import net.helenus.mapping.HelenusProperty; @@ -33,112 +35,110 @@ import net.helenus.support.HelenusMappingException; public final class SessionRepositoryBuilder { - private static final Optional OPTIONAL_UDT = - Optional.of(HelenusEntityType.UDT); + private static final Optional OPTIONAL_UDT = Optional.of(HelenusEntityType.UDT); - private final Map, HelenusEntity> entityMap = new HashMap, HelenusEntity>(); + private final Map, HelenusEntity> entityMap = new HashMap, HelenusEntity>(); - private final Map userTypeMap = new HashMap(); + private final Map userTypeMap = new HashMap(); - private final Multimap userTypeUsesMap = HashMultimap.create(); + private final Multimap userTypeUsesMap = HashMultimap.create(); - private final Session session; + private final Session session; - SessionRepositoryBuilder(Session session) { - this.session = session; - } + SessionRepositoryBuilder(Session session) { + this.session = session; + } - public SessionRepository build() { - return new SessionRepository(this); - } + public SessionRepository build() { + return new SessionRepository(this); + } - public Collection getUserTypeUses(HelenusEntity udtName) { - return userTypeUsesMap.get(udtName); - } + public Collection getUserTypeUses(HelenusEntity udtName) { + return userTypeUsesMap.get(udtName); + } - public Collection entities() { - return entityMap.values(); - } + public Collection entities() { + return entityMap.values(); + } - protected Map, HelenusEntity> getEntityMap() { - return entityMap; - } + protected Map, HelenusEntity> getEntityMap() { + return entityMap; + } - protected Map getUserTypeMap() { - return userTypeMap; - } + protected Map getUserTypeMap() { + return userTypeMap; + } - public void addUserType(String name, UserType userType) { - userTypeMap.putIfAbsent(name.toLowerCase(), userType); - } + public void addUserType(String name, UserType userType) { + userTypeMap.putIfAbsent(name.toLowerCase(), userType); + } - public HelenusEntity add(Object dsl) { - return add(dsl, Optional.empty()); - } + public HelenusEntity add(Object dsl) { + return add(dsl, Optional.empty()); + } - public void addEntity(HelenusEntity entity) { + public void addEntity(HelenusEntity entity) { - HelenusEntity concurrentEntity = entityMap.putIfAbsent(entity.getMappingInterface(), entity); + HelenusEntity concurrentEntity = entityMap.putIfAbsent(entity.getMappingInterface(), entity); - if (concurrentEntity == null) { - addUserDefinedTypes(entity.getOrderedProperties()); - } - } + if (concurrentEntity == null) { + addUserDefinedTypes(entity.getOrderedProperties()); + } + } - public HelenusEntity add(Object dsl, Optional type) { + public HelenusEntity add(Object dsl, Optional type) { - HelenusEntity helenusEntity = Helenus.resolve(dsl, session.getCluster().getMetadata()); + HelenusEntity helenusEntity = Helenus.resolve(dsl, session.getCluster().getMetadata()); - Class iface = helenusEntity.getMappingInterface(); + Class iface = helenusEntity.getMappingInterface(); - HelenusEntity entity = entityMap.get(iface); + HelenusEntity entity = entityMap.get(iface); - if (entity == null) { + if (entity == null) { - entity = helenusEntity; + entity = helenusEntity; - if (type.isPresent() && entity.getType() != type.get()) { - throw new HelenusMappingException( - "unexpected entity type " + entity.getType() + " for " + entity); - } + if (type.isPresent() && entity.getType() != type.get()) { + throw new HelenusMappingException("unexpected entity type " + entity.getType() + " for " + entity); + } - HelenusEntity concurrentEntity = entityMap.putIfAbsent(iface, entity); + HelenusEntity concurrentEntity = entityMap.putIfAbsent(iface, entity); - if (concurrentEntity == null) { - addUserDefinedTypes(entity.getOrderedProperties()); - } else { - entity = concurrentEntity; - } - } + if (concurrentEntity == null) { + addUserDefinedTypes(entity.getOrderedProperties()); + } else { + entity = concurrentEntity; + } + } - return entity; - } + return entity; + } - private void addUserDefinedTypes(Collection props) { + private void addUserDefinedTypes(Collection props) { - for (HelenusProperty prop : props) { + for (HelenusProperty prop : props) { - AbstractDataType type = prop.getDataType(); + AbstractDataType type = prop.getDataType(); - if (type instanceof DTDataType) { - continue; - } + if (type instanceof DTDataType) { + continue; + } - if (!UDTValue.class.isAssignableFrom(prop.getJavaType())) { + if (!UDTValue.class.isAssignableFrom(prop.getJavaType())) { - for (Class udtClass : type.getTypeArguments()) { + for (Class udtClass : type.getTypeArguments()) { - if (UDTValue.class.isAssignableFrom(udtClass)) { - continue; - } + if (UDTValue.class.isAssignableFrom(udtClass)) { + continue; + } - HelenusEntity addedUserType = add(udtClass, OPTIONAL_UDT); + HelenusEntity addedUserType = add(udtClass, OPTIONAL_UDT); - if (HelenusEntityType.UDT == prop.getEntity().getType()) { - userTypeUsesMap.put(prop.getEntity(), addedUserType); - } - } - } - } - } + if (HelenusEntityType.UDT == prop.getEntity().getType()) { + userTypeUsesMap.put(prop.getEntity(), addedUserType); + } + } + } + } + } } diff --git a/src/main/java/net/helenus/core/TableOperations.java b/src/main/java/net/helenus/core/TableOperations.java index 3c602d6..354851a 100644 --- a/src/main/java/net/helenus/core/TableOperations.java +++ b/src/main/java/net/helenus/core/TableOperations.java @@ -15,97 +15,88 @@ */ package net.helenus.core; +import java.util.List; + import com.datastax.driver.core.TableMetadata; import com.datastax.driver.core.schemabuilder.SchemaStatement; -import java.util.List; + import net.helenus.mapping.HelenusEntity; import net.helenus.support.HelenusException; public final class TableOperations { - private final AbstractSessionOperations sessionOps; - private final boolean dropUnusedColumns; - private final boolean dropUnusedIndexes; + private final AbstractSessionOperations sessionOps; + private final boolean dropUnusedColumns; + private final boolean dropUnusedIndexes; - public TableOperations( - AbstractSessionOperations sessionOps, boolean dropUnusedColumns, boolean dropUnusedIndexes) { - this.sessionOps = sessionOps; - this.dropUnusedColumns = dropUnusedColumns; - this.dropUnusedIndexes = dropUnusedIndexes; - } + public TableOperations(AbstractSessionOperations sessionOps, boolean dropUnusedColumns, boolean dropUnusedIndexes) { + this.sessionOps = sessionOps; + this.dropUnusedColumns = dropUnusedColumns; + this.dropUnusedIndexes = dropUnusedIndexes; + } - public void createTable(HelenusEntity entity) { - sessionOps.execute(SchemaUtil.createTable(entity), true); - executeBatch(SchemaUtil.createIndexes(entity)); - } + public void createTable(HelenusEntity entity) { + sessionOps.execute(SchemaUtil.createTable(entity), true); + executeBatch(SchemaUtil.createIndexes(entity)); + } - public void dropTable(HelenusEntity entity) { - sessionOps.execute(SchemaUtil.dropTable(entity), true); - } + public void dropTable(HelenusEntity entity) { + sessionOps.execute(SchemaUtil.dropTable(entity), true); + } - public void validateTable(TableMetadata tmd, HelenusEntity entity) { + public void validateTable(TableMetadata tmd, HelenusEntity entity) { - if (tmd == null) { - throw new HelenusException( - "table does not exists " - + entity.getName() - + "for entity " - + entity.getMappingInterface()); - } + if (tmd == null) { + throw new HelenusException( + "table does not exists " + entity.getName() + "for entity " + entity.getMappingInterface()); + } - List list = SchemaUtil.alterTable(tmd, entity, dropUnusedColumns); + List list = SchemaUtil.alterTable(tmd, entity, dropUnusedColumns); - list.addAll(SchemaUtil.alterIndexes(tmd, entity, dropUnusedIndexes)); + list.addAll(SchemaUtil.alterIndexes(tmd, entity, dropUnusedIndexes)); - if (!list.isEmpty()) { - throw new HelenusException( - "schema changed for entity " - + entity.getMappingInterface() - + ", apply this command: " - + list); - } - } + if (!list.isEmpty()) { + throw new HelenusException( + "schema changed for entity " + entity.getMappingInterface() + ", apply this command: " + list); + } + } - public void updateTable(TableMetadata tmd, HelenusEntity entity) { - if (tmd == null) { - createTable(entity); - return; - } + public void updateTable(TableMetadata tmd, HelenusEntity entity) { + if (tmd == null) { + createTable(entity); + return; + } - executeBatch(SchemaUtil.alterTable(tmd, entity, dropUnusedColumns)); - executeBatch(SchemaUtil.alterIndexes(tmd, entity, dropUnusedIndexes)); - } + executeBatch(SchemaUtil.alterTable(tmd, entity, dropUnusedColumns)); + executeBatch(SchemaUtil.alterIndexes(tmd, entity, dropUnusedIndexes)); + } - public void createView(HelenusEntity entity) { - sessionOps.execute( - SchemaUtil.createMaterializedView( - sessionOps.usingKeyspace(), entity.getName().toCql(), entity), - true); - // executeBatch(SchemaUtil.createIndexes(entity)); NOTE: Unfortunately C* 3.10 does not yet support 2i on materialized views. - } + public void createView(HelenusEntity entity) { + sessionOps.execute( + SchemaUtil.createMaterializedView(sessionOps.usingKeyspace(), entity.getName().toCql(), entity), true); + // executeBatch(SchemaUtil.createIndexes(entity)); NOTE: Unfortunately C* 3.10 + // does not yet support 2i on materialized views. + } - public void dropView(HelenusEntity entity) { - sessionOps.execute( - SchemaUtil.dropMaterializedView( - sessionOps.usingKeyspace(), entity.getName().toCql(), entity), - true); - } + public void dropView(HelenusEntity entity) { + sessionOps.execute( + SchemaUtil.dropMaterializedView(sessionOps.usingKeyspace(), entity.getName().toCql(), entity), true); + } - public void updateView(TableMetadata tmd, HelenusEntity entity) { - if (tmd == null) { - createTable(entity); - return; - } + public void updateView(TableMetadata tmd, HelenusEntity entity) { + if (tmd == null) { + createTable(entity); + return; + } - executeBatch(SchemaUtil.alterTable(tmd, entity, dropUnusedColumns)); - executeBatch(SchemaUtil.alterIndexes(tmd, entity, dropUnusedIndexes)); - } + executeBatch(SchemaUtil.alterTable(tmd, entity, dropUnusedColumns)); + executeBatch(SchemaUtil.alterIndexes(tmd, entity, dropUnusedIndexes)); + } - private void executeBatch(List list) { + private void executeBatch(List list) { - list.forEach( - s -> { - sessionOps.execute(s, true); - }); - } + list.forEach(s -> { + sessionOps.execute(s, true); + }); + } } diff --git a/src/main/java/net/helenus/core/UnitOfWork.java b/src/main/java/net/helenus/core/UnitOfWork.java index 9ff1312..36f1291 100644 --- a/src/main/java/net/helenus/core/UnitOfWork.java +++ b/src/main/java/net/helenus/core/UnitOfWork.java @@ -18,45 +18,49 @@ package net.helenus.core; import java.util.Map; import java.util.Optional; import java.util.Set; + import net.helenus.core.cache.BoundFacet; +import net.helenus.core.cache.Facet; import net.helenus.support.Either; public interface UnitOfWork extends AutoCloseable { - /** - * Marks the beginning of a transactional section of work. Will write a record to the shared - * write-ahead log. - * - * @return the handle used to commit or abort the work. - */ - UnitOfWork begin(); + /** + * Marks the beginning of a transactional section of work. Will write a record + * to the shared write-ahead log. + * + * @return the handle used to commit or abort the work. + */ + UnitOfWork begin(); - void addNestedUnitOfWork(UnitOfWork uow); + void addNestedUnitOfWork(UnitOfWork uow); - /** - * Checks to see if the work performed between calling begin and now can be committed or not. - * - * @return a function from which to chain work that only happens when commit is successful - * @throws X when the work overlaps with other concurrent writers. - */ - PostCommitFunction commit() throws X; + /** + * Checks to see if the work performed between calling begin and now can be + * committed or not. + * + * @return a function from which to chain work that only happens when commit is + * successful + * @throws X + * when the work overlaps with other concurrent writers. + */ + PostCommitFunction commit() throws X; - /** - * Explicitly abort the work within this unit of work. Any nested aborted unit of work will - * trigger the entire unit of work to commit. - */ - void abort(); + /** + * Explicitly abort the work within this unit of work. Any nested aborted unit + * of work will trigger the entire unit of work to commit. + */ + void abort(); - boolean hasAborted(); + boolean hasAborted(); - boolean hasCommitted(); + boolean hasCommitted(); - Optional>> cacheLookup(String key); + Optional>> cacheLookup(String key); - Optional>> cacheLookupByFacet(Set facets); + Optional>> cacheLookupByFacet(Set facets); - Optional>> cacheLookupByStatement(String[] statementKeys); + Optional>> cacheLookupByStatement(String[] statementKeys); - void cacheUpdate( - Either> pojo, String[] statementKeys, Map facets); + void cacheUpdate(Either> pojo, String[] statementKeys, Map facets); } diff --git a/src/main/java/net/helenus/core/UnitOfWorkImpl.java b/src/main/java/net/helenus/core/UnitOfWorkImpl.java index 52cae59..ce57ff9 100644 --- a/src/main/java/net/helenus/core/UnitOfWorkImpl.java +++ b/src/main/java/net/helenus/core/UnitOfWorkImpl.java @@ -19,8 +19,8 @@ import net.helenus.support.HelenusException; class UnitOfWorkImpl extends AbstractUnitOfWork { - @SuppressWarnings("unchecked") - public UnitOfWorkImpl(HelenusSession session, UnitOfWork parent) { - super(session, (AbstractUnitOfWork) parent); - } + @SuppressWarnings("unchecked") + public UnitOfWorkImpl(HelenusSession session, UnitOfWork parent) { + super(session, (AbstractUnitOfWork) parent); + } } diff --git a/src/main/java/net/helenus/core/UserTypeOperations.java b/src/main/java/net/helenus/core/UserTypeOperations.java index 2c18339..2b1ed32 100644 --- a/src/main/java/net/helenus/core/UserTypeOperations.java +++ b/src/main/java/net/helenus/core/UserTypeOperations.java @@ -15,65 +15,63 @@ */ package net.helenus.core; +import java.util.List; + import com.datastax.driver.core.UserType; import com.datastax.driver.core.schemabuilder.SchemaStatement; -import java.util.List; + import net.helenus.mapping.HelenusEntity; import net.helenus.support.HelenusException; public final class UserTypeOperations { - private final AbstractSessionOperations sessionOps; - private final boolean dropUnusedColumns; + private final AbstractSessionOperations sessionOps; + private final boolean dropUnusedColumns; - public UserTypeOperations(AbstractSessionOperations sessionOps, boolean dropUnusedColumns) { - this.sessionOps = sessionOps; - this.dropUnusedColumns = dropUnusedColumns; - } + public UserTypeOperations(AbstractSessionOperations sessionOps, boolean dropUnusedColumns) { + this.sessionOps = sessionOps; + this.dropUnusedColumns = dropUnusedColumns; + } - public void createUserType(HelenusEntity entity) { + public void createUserType(HelenusEntity entity) { - sessionOps.execute(SchemaUtil.createUserType(entity), true); - } + sessionOps.execute(SchemaUtil.createUserType(entity), true); + } - public void dropUserType(HelenusEntity entity) { + public void dropUserType(HelenusEntity entity) { - sessionOps.execute(SchemaUtil.dropUserType(entity), true); - } + sessionOps.execute(SchemaUtil.dropUserType(entity), true); + } - public void validateUserType(UserType userType, HelenusEntity entity) { + public void validateUserType(UserType userType, HelenusEntity entity) { - if (userType == null) { - throw new HelenusException( - "userType not exists " + entity.getName() + "for entity " + entity.getMappingInterface()); - } + if (userType == null) { + throw new HelenusException( + "userType not exists " + entity.getName() + "for entity " + entity.getMappingInterface()); + } - List list = SchemaUtil.alterUserType(userType, entity, dropUnusedColumns); + List list = SchemaUtil.alterUserType(userType, entity, dropUnusedColumns); - if (!list.isEmpty()) { - throw new HelenusException( - "schema changed for entity " - + entity.getMappingInterface() - + ", apply this command: " - + list); - } - } + if (!list.isEmpty()) { + throw new HelenusException( + "schema changed for entity " + entity.getMappingInterface() + ", apply this command: " + list); + } + } - public void updateUserType(UserType userType, HelenusEntity entity) { + public void updateUserType(UserType userType, HelenusEntity entity) { - if (userType == null) { - createUserType(entity); - return; - } + if (userType == null) { + createUserType(entity); + return; + } - executeBatch(SchemaUtil.alterUserType(userType, entity, dropUnusedColumns)); - } + executeBatch(SchemaUtil.alterUserType(userType, entity, dropUnusedColumns)); + } - private void executeBatch(List list) { + private void executeBatch(List list) { - list.forEach( - s -> { - sessionOps.execute(s, true); - }); - } + list.forEach(s -> { + sessionOps.execute(s, true); + }); + } } diff --git a/src/main/java/net/helenus/core/annotation/Cacheable.java b/src/main/java/net/helenus/core/annotation/Cacheable.java index 935a214..8202bdd 100644 --- a/src/main/java/net/helenus/core/annotation/Cacheable.java +++ b/src/main/java/net/helenus/core/annotation/Cacheable.java @@ -22,4 +22,5 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) -public @interface Cacheable {} +public @interface Cacheable { +} diff --git a/src/main/java/net/helenus/core/annotation/Retry.java b/src/main/java/net/helenus/core/annotation/Retry.java index 14631da..7db5b20 100644 --- a/src/main/java/net/helenus/core/annotation/Retry.java +++ b/src/main/java/net/helenus/core/annotation/Retry.java @@ -4,13 +4,14 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; + import net.helenus.core.ConflictingUnitOfWorkException; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Retry { - Class[] on() default ConflictingUnitOfWorkException.class; + Class[] on() default ConflictingUnitOfWorkException.class; - int times() default 3; + int times() default 3; } diff --git a/src/main/java/net/helenus/core/aspect/RetryAspect.java b/src/main/java/net/helenus/core/aspect/RetryAspect.java index e828f8b..587d087 100644 --- a/src/main/java/net/helenus/core/aspect/RetryAspect.java +++ b/src/main/java/net/helenus/core/aspect/RetryAspect.java @@ -2,7 +2,7 @@ package net.helenus.core.aspect; import java.lang.reflect.Method; import java.util.Arrays; -import net.helenus.core.annotation.Retry; + import org.apache.commons.lang3.exception.ExceptionUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; @@ -13,69 +13,71 @@ import org.slf4j.LoggerFactory; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.Assert; +import net.helenus.core.annotation.Retry; + @Aspect public class RetryAspect { - private static final Logger log = LoggerFactory.getLogger(RetryAspect.class); + private static final Logger log = LoggerFactory.getLogger(RetryAspect.class); - @Around("@annotation(net.helenus.core.annotations.Retry)") - public Object retry(ProceedingJoinPoint pjp) throws Throwable { - Retry retryAnnotation = getRetryAnnotation(pjp); - return (retryAnnotation != null) ? proceed(pjp, retryAnnotation) : proceed(pjp); - } + @Around("@annotation(net.helenus.core.annotations.Retry)") + public Object retry(ProceedingJoinPoint pjp) throws Throwable { + Retry retryAnnotation = getRetryAnnotation(pjp); + return (retryAnnotation != null) ? proceed(pjp, retryAnnotation) : proceed(pjp); + } - private Object proceed(ProceedingJoinPoint pjp) throws Throwable { - return pjp.proceed(); - } + private Object proceed(ProceedingJoinPoint pjp) throws Throwable { + return pjp.proceed(); + } - private Object proceed(ProceedingJoinPoint pjp, Retry retryAnnotation) throws Throwable { - int times = retryAnnotation.times(); - Class[] retryOn = retryAnnotation.on(); - Assert.isTrue(times > 0, "@Retry{times} should be greater than 0!"); - Assert.isTrue(retryOn.length > 0, "@Retry{on} should have at least one Throwable!"); - log.info("Proceed with {} retries on {}", times, Arrays.toString(retryOn)); - return tryProceeding(pjp, times, retryOn); - } + private Object proceed(ProceedingJoinPoint pjp, Retry retryAnnotation) throws Throwable { + int times = retryAnnotation.times(); + Class[] retryOn = retryAnnotation.on(); + Assert.isTrue(times > 0, "@Retry{times} should be greater than 0!"); + Assert.isTrue(retryOn.length > 0, "@Retry{on} should have at least one Throwable!"); + log.info("Proceed with {} retries on {}", times, Arrays.toString(retryOn)); + return tryProceeding(pjp, times, retryOn); + } - private Object tryProceeding( - ProceedingJoinPoint pjp, int times, Class[] retryOn) throws Throwable { - try { - return proceed(pjp); - } catch (Throwable throwable) { - if (isRetryThrowable(throwable, retryOn) && times-- > 0) { - log.info("Conflict detected, {} remaining retries on {}", times, Arrays.toString(retryOn)); - return tryProceeding(pjp, times, retryOn); - } - throw throwable; - } - } + private Object tryProceeding(ProceedingJoinPoint pjp, int times, Class[] retryOn) + throws Throwable { + try { + return proceed(pjp); + } catch (Throwable throwable) { + if (isRetryThrowable(throwable, retryOn) && times-- > 0) { + log.info("Conflict detected, {} remaining retries on {}", times, Arrays.toString(retryOn)); + return tryProceeding(pjp, times, retryOn); + } + throw throwable; + } + } - private boolean isRetryThrowable(Throwable throwable, Class[] retryOn) { - Throwable[] causes = ExceptionUtils.getThrowables(throwable); - for (Throwable cause : causes) { - for (Class retryThrowable : retryOn) { - if (retryThrowable.isAssignableFrom(cause.getClass())) { - return true; - } - } - } - return false; - } + private boolean isRetryThrowable(Throwable throwable, Class[] retryOn) { + Throwable[] causes = ExceptionUtils.getThrowables(throwable); + for (Throwable cause : causes) { + for (Class retryThrowable : retryOn) { + if (retryThrowable.isAssignableFrom(cause.getClass())) { + return true; + } + } + } + return false; + } - private Retry getRetryAnnotation(ProceedingJoinPoint pjp) throws NoSuchMethodException { - MethodSignature signature = (MethodSignature) pjp.getSignature(); - Method method = signature.getMethod(); - Retry retryAnnotation = AnnotationUtils.findAnnotation(method, Retry.class); + private Retry getRetryAnnotation(ProceedingJoinPoint pjp) throws NoSuchMethodException { + MethodSignature signature = (MethodSignature) pjp.getSignature(); + Method method = signature.getMethod(); + Retry retryAnnotation = AnnotationUtils.findAnnotation(method, Retry.class); - if (retryAnnotation != null) { - return retryAnnotation; - } + if (retryAnnotation != null) { + return retryAnnotation; + } - Class[] argClasses = new Class[pjp.getArgs().length]; - for (int i = 0; i < pjp.getArgs().length; i++) { - argClasses[i] = pjp.getArgs()[i].getClass(); - } - method = pjp.getTarget().getClass().getMethod(pjp.getSignature().getName(), argClasses); - return AnnotationUtils.findAnnotation(method, Retry.class); - } + Class[] argClasses = new Class[pjp.getArgs().length]; + for (int i = 0; i < pjp.getArgs().length; i++) { + argClasses[i] = pjp.getArgs()[i].getClass(); + } + method = pjp.getTarget().getClass().getMethod(pjp.getSignature().getName(), argClasses); + return AnnotationUtils.findAnnotation(method, Retry.class); + } } diff --git a/src/main/java/net/helenus/core/cache/BoundFacet.java b/src/main/java/net/helenus/core/cache/BoundFacet.java index 20c1de0..d6bc7d1 100644 --- a/src/main/java/net/helenus/core/cache/BoundFacet.java +++ b/src/main/java/net/helenus/core/cache/BoundFacet.java @@ -17,22 +17,18 @@ package net.helenus.core.cache; import java.util.Map; import java.util.stream.Collectors; + import net.helenus.mapping.HelenusProperty; -public class BoundFacet { - private final Map properties; +public class BoundFacet extends Facet { + private final Map properties; - BoundFacet(Map properties) { - this.properties = properties; - } + BoundFacet(Map properties) { + this.properties = properties; + } - public String toString() { - return String.join( - ";", - properties - .keySet() - .stream() - .map(key -> properties.get(key).toString()) - .collect(Collectors.toSet())); - } + public String toString() { + return String.join(";", + properties.keySet().stream().map(key -> properties.get(key).toString()).collect(Collectors.toSet())); + } } diff --git a/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java b/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java index f8aa5b2..fb28dc1 100644 --- a/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java +++ b/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java @@ -19,54 +19,55 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; + import net.helenus.mapping.HelenusProperty; public class EntityIdentifyingFacet extends Facet { - private final Set properties; + private final Set properties; - public EntityIdentifyingFacet(HelenusProperty prop) { - properties = new HashSet(); - properties.add(prop); - } + public EntityIdentifyingFacet(HelenusProperty prop) { + properties = new HashSet(); + properties.add(prop); + } - public EntityIdentifyingFacet(Set props) { - properties = props; - } + public EntityIdentifyingFacet(Set props) { + properties = props; + } - public boolean isFullyBound() { - return false; - } + public boolean isFullyBound() { + return false; + } - public Set getProperties() { - return properties; - } + public Set getProperties() { + return properties; + } - public Binder binder() { - return new Binder(properties); - } + public Binder binder() { + return new Binder(properties); + } - public static class Binder { + public static class Binder { - private final Set properties = new HashSet(); - private Map boundProperties = new HashMap(); + private final Set properties = new HashSet(); + private Map boundProperties = new HashMap(); - Binder(Set properties) { - this.properties.addAll(properties); - } + Binder(Set properties) { + this.properties.addAll(properties); + } - public Binder setValueForProperty(HelenusProperty prop, Object value) { - properties.remove(prop); - boundProperties.put(prop, value); - return this; - } + public Binder setValueForProperty(HelenusProperty prop, Object value) { + properties.remove(prop); + boundProperties.put(prop, value); + return this; + } - public boolean isFullyBound() { - return properties.isEmpty(); - } + public boolean isFullyBound() { + return properties.isEmpty(); + } - public BoundFacet bind() { - return new BoundFacet(boundProperties); - } - } + public BoundFacet bind() { + return new BoundFacet(boundProperties); + } + } } diff --git a/src/main/java/net/helenus/core/cache/Facet.java b/src/main/java/net/helenus/core/cache/Facet.java index 31fdb2c..fd5eaa2 100644 --- a/src/main/java/net/helenus/core/cache/Facet.java +++ b/src/main/java/net/helenus/core/cache/Facet.java @@ -1,20 +1,23 @@ package net.helenus.core.cache; -public class Facet {} +public class Facet { +} /* - -An Entity is identifiable via one or more Facets - -A Facet is is a set of Properties and bound Facets - -An Entity will have it's Keyspace, Table and Schema Version Facets bound. - -A property may also have a TTL or write time bound. - -The cache contains key->value mappings of merkel-hash -> Entity or Set -The only way a Set is put into the cache is with a key = hash([Entity's bound Facets, hash(filter clause from SELECT)]) - -REMEMBER to update the cache on build() for all impacted facets, delete existing keys and add new keys - - + * + * An Entity is identifiable via one or more Facets + * + * A Facet is is a set of Properties and bound Facets + * + * An Entity will have it's Keyspace, Table and Schema Version Facets bound. + * + * A property may also have a TTL or write time bound. + * + * The cache contains key->value mappings of merkel-hash -> Entity or + * Set The only way a Set is put into the cache is with a key = + * hash([Entity's bound Facets, hash(filter clause from SELECT)]) + * + * REMEMBER to update the cache on build() for all impacted facets, delete + * existing keys and add new keys + * + * */ diff --git a/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java b/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java index 75c8979..c7a4787 100644 --- a/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractFilterOperation.java @@ -17,92 +17,94 @@ package net.helenus.core.operation; import java.util.LinkedList; import java.util.List; + import net.helenus.core.*; public abstract class AbstractFilterOperation> - extends AbstractOperation { + extends + AbstractOperation { - protected List> filters = null; - protected List> ifFilters = null; + protected List> filters = null; + protected List> ifFilters = null; - public AbstractFilterOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } + public AbstractFilterOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } - public O where(Getter getter, Postulate postulate) { + public O where(Getter getter, Postulate postulate) { - addFilter(Filter.create(getter, postulate)); + addFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O where(Getter getter, Operator operator, V val) { + public O where(Getter getter, Operator operator, V val) { - addFilter(Filter.create(getter, operator, val)); + addFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O where(Filter filter) { + public O where(Filter filter) { - addFilter(filter); + addFilter(filter); - return (O) this; - } + return (O) this; + } - public O and(Getter getter, Postulate postulate) { + public O and(Getter getter, Postulate postulate) { - addFilter(Filter.create(getter, postulate)); + addFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O and(Getter getter, Operator operator, V val) { + public O and(Getter getter, Operator operator, V val) { - addFilter(Filter.create(getter, operator, val)); + addFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O and(Filter filter) { + public O and(Filter filter) { - addFilter(filter); + addFilter(filter); - return (O) this; - } + return (O) this; + } - public O onlyIf(Getter getter, Postulate postulate) { + public O onlyIf(Getter getter, Postulate postulate) { - addIfFilter(Filter.create(getter, postulate)); + addIfFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O onlyIf(Getter getter, Operator operator, V val) { + public O onlyIf(Getter getter, Operator operator, V val) { - addIfFilter(Filter.create(getter, operator, val)); + addIfFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O onlyIf(Filter filter) { + public O onlyIf(Filter filter) { - addIfFilter(filter); + addIfFilter(filter); - return (O) this; - } + return (O) this; + } - private void addFilter(Filter filter) { - if (filters == null) { - filters = new LinkedList>(); - } - filters.add(filter); - } + private void addFilter(Filter filter) { + if (filters == null) { + filters = new LinkedList>(); + } + filters.add(filter); + } - private void addIfFilter(Filter filter) { - if (ifFilters == null) { - ifFilters = new LinkedList>(); - } - ifFilters.add(filter); - } + private void addIfFilter(Filter filter) { + if (ifFilters == null) { + ifFilters = new LinkedList>(); + } + ifFilters.add(filter); + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractFilterOptionalOperation.java b/src/main/java/net/helenus/core/operation/AbstractFilterOptionalOperation.java index 6abfd81..83374aa 100644 --- a/src/main/java/net/helenus/core/operation/AbstractFilterOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractFilterOptionalOperation.java @@ -19,94 +19,95 @@ import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; + import net.helenus.core.*; import net.helenus.mapping.HelenusProperty; -public abstract class AbstractFilterOptionalOperation< - E, O extends AbstractFilterOptionalOperation> - extends AbstractOptionalOperation { +public abstract class AbstractFilterOptionalOperation> + extends + AbstractOptionalOperation { - protected Map> filters = null; - protected List> ifFilters = null; + protected Map> filters = null; + protected List> ifFilters = null; - public AbstractFilterOptionalOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } + public AbstractFilterOptionalOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } - public O where(Getter getter, Postulate postulate) { + public O where(Getter getter, Postulate postulate) { - addFilter(Filter.create(getter, postulate)); + addFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O where(Getter getter, Operator operator, V val) { + public O where(Getter getter, Operator operator, V val) { - addFilter(Filter.create(getter, operator, val)); + addFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O where(Filter filter) { + public O where(Filter filter) { - addFilter(filter); + addFilter(filter); - return (O) this; - } + return (O) this; + } - public O and(Getter getter, Postulate postulate) { + public O and(Getter getter, Postulate postulate) { - addFilter(Filter.create(getter, postulate)); + addFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O and(Getter getter, Operator operator, V val) { + public O and(Getter getter, Operator operator, V val) { - addFilter(Filter.create(getter, operator, val)); + addFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O and(Filter filter) { + public O and(Filter filter) { - addFilter(filter); + addFilter(filter); - return (O) this; - } + return (O) this; + } - public O onlyIf(Getter getter, Postulate postulate) { + public O onlyIf(Getter getter, Postulate postulate) { - addIfFilter(Filter.create(getter, postulate)); + addIfFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O onlyIf(Getter getter, Operator operator, V val) { + public O onlyIf(Getter getter, Operator operator, V val) { - addIfFilter(Filter.create(getter, operator, val)); + addIfFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O onlyIf(Filter filter) { + public O onlyIf(Filter filter) { - addIfFilter(filter); + addIfFilter(filter); - return (O) this; - } + return (O) this; + } - private void addFilter(Filter filter) { - if (filters == null) { - filters = new LinkedHashMap>(); - } - filters.put(filter.getNode().getProperty(), filter); - } + private void addFilter(Filter filter) { + if (filters == null) { + filters = new LinkedHashMap>(); + } + filters.put(filter.getNode().getProperty(), filter); + } - private void addIfFilter(Filter filter) { - if (ifFilters == null) { - ifFilters = new LinkedList>(); - } - ifFilters.add(filter); - } + private void addIfFilter(Filter filter) { + if (ifFilters == null) { + ifFilters = new LinkedList>(); + } + ifFilters.add(filter); + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java b/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java index b78daf1..519f421 100644 --- a/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractFilterStreamOperation.java @@ -19,94 +19,95 @@ import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; + import net.helenus.core.*; import net.helenus.mapping.HelenusProperty; -public abstract class AbstractFilterStreamOperation< - E, O extends AbstractFilterStreamOperation> - extends AbstractStreamOperation { +public abstract class AbstractFilterStreamOperation> + extends + AbstractStreamOperation { - protected Map> filters = null; - protected List> ifFilters = null; + protected Map> filters = null; + protected List> ifFilters = null; - public AbstractFilterStreamOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } + public AbstractFilterStreamOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } - public O where(Getter getter, Postulate postulate) { + public O where(Getter getter, Postulate postulate) { - addFilter(Filter.create(getter, postulate)); + addFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O where(Getter getter, Operator operator, V val) { + public O where(Getter getter, Operator operator, V val) { - addFilter(Filter.create(getter, operator, val)); + addFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O where(Filter filter) { + public O where(Filter filter) { - addFilter(filter); + addFilter(filter); - return (O) this; - } + return (O) this; + } - public O and(Getter getter, Postulate postulate) { + public O and(Getter getter, Postulate postulate) { - addFilter(Filter.create(getter, postulate)); + addFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O and(Getter getter, Operator operator, V val) { + public O and(Getter getter, Operator operator, V val) { - addFilter(Filter.create(getter, operator, val)); + addFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O and(Filter filter) { + public O and(Filter filter) { - addFilter(filter); + addFilter(filter); - return (O) this; - } + return (O) this; + } - public O onlyIf(Getter getter, Postulate postulate) { + public O onlyIf(Getter getter, Postulate postulate) { - addIfFilter(Filter.create(getter, postulate)); + addIfFilter(Filter.create(getter, postulate)); - return (O) this; - } + return (O) this; + } - public O onlyIf(Getter getter, Operator operator, V val) { + public O onlyIf(Getter getter, Operator operator, V val) { - addIfFilter(Filter.create(getter, operator, val)); + addIfFilter(Filter.create(getter, operator, val)); - return (O) this; - } + return (O) this; + } - public O onlyIf(Filter filter) { + public O onlyIf(Filter filter) { - addIfFilter(filter); + addIfFilter(filter); - return (O) this; - } + return (O) this; + } - private void addFilter(Filter filter) { - if (filters == null) { - filters = new LinkedHashMap>(); - } - filters.put(filter.getNode().getProperty(), filter); - } + private void addFilter(Filter filter) { + if (filters == null) { + filters = new LinkedHashMap>(); + } + filters.put(filter.getNode().getProperty(), filter); + } - private void addIfFilter(Filter filter) { - if (ifFilters == null) { - ifFilters = new LinkedList>(); - } - ifFilters.add(filter); - } + private void addIfFilter(Filter filter) { + if (ifFilters == null) { + ifFilters = new LinkedList>(); + } + ifFilters.add(filter); + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractOperation.java b/src/main/java/net/helenus/core/operation/AbstractOperation.java index a612696..aff7d77 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOperation.java @@ -15,90 +15,77 @@ */ package net.helenus.core.operation; -import com.codahale.metrics.Timer; -import com.datastax.driver.core.ResultSet; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.TimeoutException; + +import com.codahale.metrics.Timer; +import com.datastax.driver.core.ResultSet; + import net.helenus.core.AbstractSessionOperations; import net.helenus.core.UnitOfWork; -public abstract class AbstractOperation> - extends AbstractStatementOperation { +public abstract class AbstractOperation> extends AbstractStatementOperation { - public abstract E transform(ResultSet resultSet); + public AbstractOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } - public boolean cacheable() { - return false; - } + public abstract E transform(ResultSet resultSet); - public AbstractOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } + public boolean cacheable() { + return false; + } - public PreparedOperation prepare() { - return new PreparedOperation(prepareStatement(), this); - } + public PreparedOperation prepare() { + return new PreparedOperation(prepareStatement(), this); + } - public E sync() throws TimeoutException { - final Timer.Context context = requestLatency.time(); - try { - ResultSet resultSet = - this.execute( - sessionOps, - null, - traceContext, - queryExecutionTimeout, - queryTimeoutUnits, - showValues, - false); - return transform(resultSet); - } finally { - context.stop(); - } - } + public E sync() throws TimeoutException { + final Timer.Context context = requestLatency.time(); + try { + ResultSet resultSet = this.execute(sessionOps, null, traceContext, queryExecutionTimeout, queryTimeoutUnits, + showValues, false); + return transform(resultSet); + } finally { + context.stop(); + } + } - public E sync(UnitOfWork uow) throws TimeoutException { - if (uow == null) return sync(); + public E sync(UnitOfWork uow) throws TimeoutException { + if (uow == null) + return sync(); - final Timer.Context context = requestLatency.time(); - try { - ResultSet resultSet = - execute( - sessionOps, - uow, - traceContext, - queryExecutionTimeout, - queryTimeoutUnits, - showValues, - true); - E result = transform(resultSet); - return result; - } finally { - context.stop(); - } - } + final Timer.Context context = requestLatency.time(); + try { + ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits, + showValues, true); + E result = transform(resultSet); + return result; + } finally { + context.stop(); + } + } - public CompletableFuture async() { - return CompletableFuture.supplyAsync( - () -> { - try { - return sync(); - } catch (TimeoutException ex) { - throw new CompletionException(ex); - } - }); - } + public CompletableFuture async() { + return CompletableFuture.supplyAsync(() -> { + try { + return sync(); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } + }); + } - public CompletableFuture async(UnitOfWork uow) { - if (uow == null) return async(); - return CompletableFuture.supplyAsync( - () -> { - try { - return sync(); - } catch (TimeoutException ex) { - throw new CompletionException(ex); - } - }); - } + public CompletableFuture async(UnitOfWork uow) { + if (uow == null) + return async(); + return CompletableFuture.supplyAsync(() -> { + try { + return sync(); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } + }); + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java index dfe94c9..f644c2e 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java @@ -15,131 +15,120 @@ */ package net.helenus.core.operation; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.TimeoutException; + import com.codahale.metrics.Timer; import com.datastax.driver.core.PreparedStatement; import com.datastax.driver.core.ResultSet; import com.google.common.base.Function; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.concurrent.TimeoutException; + import net.helenus.core.AbstractSessionOperations; import net.helenus.core.UnitOfWork; -import net.helenus.core.cache.BoundFacet; +import net.helenus.core.cache.Facet; public abstract class AbstractOptionalOperation> - extends AbstractStatementOperation { + extends + AbstractStatementOperation { - public AbstractOptionalOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } + public AbstractOptionalOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } - public abstract Optional transform(ResultSet resultSet); + public abstract Optional transform(ResultSet resultSet); - public PreparedOptionalOperation prepare() { - return new PreparedOptionalOperation(prepareStatement(), this); - } + public PreparedOptionalOperation prepare() { + return new PreparedOptionalOperation(prepareStatement(), this); + } - public ListenableFuture> prepareAsync() { - final O _this = (O) this; - return Futures.transform( - prepareStatementAsync(), - new Function>() { - @Override - public PreparedOptionalOperation apply(PreparedStatement preparedStatement) { - return new PreparedOptionalOperation(preparedStatement, _this); - } - }); - } + public ListenableFuture> prepareAsync() { + final O _this = (O) this; + return Futures.transform(prepareStatementAsync(), + new Function>() { + @Override + public PreparedOptionalOperation apply(PreparedStatement preparedStatement) { + return new PreparedOptionalOperation(preparedStatement, _this); + } + }); + } - public Optional sync() throws TimeoutException { - final Timer.Context context = requestLatency.time(); - try { - ResultSet resultSet = - this.execute( - sessionOps, - null, - traceContext, - queryExecutionTimeout, - queryTimeoutUnits, - showValues, - false); - return transform(resultSet); - } finally { - context.stop(); - } - } + public Optional sync() throws TimeoutException { + final Timer.Context context = requestLatency.time(); + try { + ResultSet resultSet = this.execute(sessionOps, null, traceContext, queryExecutionTimeout, queryTimeoutUnits, + showValues, false); + return transform(resultSet); + } finally { + context.stop(); + } + } - public Optional sync(UnitOfWork uow) throws TimeoutException { - if (uow == null) return sync(); + public Optional sync(UnitOfWork uow) throws TimeoutException { + if (uow == null) + return sync(); - final Timer.Context context = requestLatency.time(); - try { + final Timer.Context context = requestLatency.time(); + try { - Optional result = Optional.empty(); - E cacheResult = null; - String[] statementKeys = null; + Optional result = Optional.empty(); + E cacheResult = null; + String[] statementKeys = null; - if (enableCache) { - Set facets = bindFacetValues(); - statementKeys = getQueryKeys(); - cacheResult = checkCache(uow, facets, statementKeys); - if (cacheResult != null) { - result = Optional.of(cacheResult); - } - } + if (enableCache) { + Set facets = bindFacetValues(); + statementKeys = getQueryKeys(); + cacheResult = checkCache(uow, facets, statementKeys); + if (cacheResult != null) { + result = Optional.of(cacheResult); + } + } - if (!result.isPresent()) { - // Formulate the query and execute it against the Cassandra cluster. - ResultSet resultSet = - execute( - sessionOps, - uow, - traceContext, - queryExecutionTimeout, - queryTimeoutUnits, - showValues, - true); + if (!result.isPresent()) { + // Formulate the query and execute it against the Cassandra cluster. + ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits, + showValues, true); - // Transform the query result set into the desired shape. - result = transform(resultSet); - } + // Transform the query result set into the desired shape. + result = transform(resultSet); + } - // If we have a result, it wasn't from cache, and we're caching things then we need to put this result - // into the cache for future requests to find. - if (enableCache && cacheResult == null && result.isPresent()) { - updateCache(uow, result.get(), getIdentifyingFacets(), statementKeys); - } + // If we have a result, it wasn't from cache, and we're caching things then we + // need to put this result + // into the cache for future requests to find. + if (enableCache && cacheResult == null && result.isPresent()) { + updateCache(uow, result.get(), getIdentifyingFacets(), statementKeys); + } - return result; - } finally { - context.stop(); - } - } + return result; + } finally { + context.stop(); + } + } - public CompletableFuture> async() { - return CompletableFuture.>supplyAsync( - () -> { - try { - return sync(); - } catch (TimeoutException ex) { - throw new CompletionException(ex); - } - }); - } + public CompletableFuture> async() { + return CompletableFuture.>supplyAsync(() -> { + try { + return sync(); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } + }); + } - public CompletableFuture> async(UnitOfWork uow) { - if (uow == null) return async(); - return CompletableFuture.>supplyAsync( - () -> { - try { - return sync(); - } catch (TimeoutException ex) { - throw new CompletionException(ex); - } - }); - } + public CompletableFuture> async(UnitOfWork uow) { + if (uow == null) + return async(); + return CompletableFuture.>supplyAsync(() -> { + try { + return sync(); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } + }); + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java index 9a73cf2..327ab8d 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java @@ -15,8 +15,15 @@ */ package net.helenus.core.operation; -import brave.Tracer; -import brave.propagation.TraceContext; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.datastax.driver.core.ConsistencyLevel; import com.datastax.driver.core.PreparedStatement; import com.datastax.driver.core.RegularStatement; @@ -27,377 +34,363 @@ import com.datastax.driver.core.policies.FallthroughRetryPolicy; import com.datastax.driver.core.policies.RetryPolicy; import com.datastax.driver.core.querybuilder.BuiltStatement; import com.google.common.util.concurrent.ListenableFuture; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.TimeUnit; + +import brave.Tracer; +import brave.propagation.TraceContext; import net.helenus.core.AbstractSessionOperations; import net.helenus.core.UnitOfWork; import net.helenus.core.cache.BoundFacet; import net.helenus.core.cache.EntityIdentifyingFacet; +import net.helenus.core.cache.Facet; import net.helenus.core.reflect.MapExportable; import net.helenus.mapping.value.BeanColumnValueProvider; import net.helenus.support.Either; import net.helenus.support.HelenusException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class AbstractStatementOperation> - extends Operation { - - final Logger logger = LoggerFactory.getLogger(getClass()); - protected boolean enableCache = true; - protected boolean showValues = true; - protected TraceContext traceContext; - long queryExecutionTimeout = 10; - TimeUnit queryTimeoutUnits = TimeUnit.SECONDS; - private ConsistencyLevel consistencyLevel; - private ConsistencyLevel serialConsistencyLevel; - private RetryPolicy retryPolicy; - private boolean idempotent = false; - private boolean enableTracing = false; - private long[] defaultTimestamp = null; - private int[] fetchSize = null; - - public AbstractStatementOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - this.consistencyLevel = sessionOperations.getDefaultConsistencyLevel(); - this.idempotent = sessionOperations.getDefaultQueryIdempotency(); - } - - public abstract Statement buildStatement(boolean cached); - - public O ignoreCache(boolean enabled) { - enableCache = enabled; - return (O) this; - } - - public O ignoreCache() { - enableCache = true; - return (O) this; - } - - public O showValues(boolean enabled) { - this.showValues = enabled; - return (O) this; - } - - public O defaultTimestamp(long timestamp) { - this.defaultTimestamp = new long[1]; - this.defaultTimestamp[0] = timestamp; - return (O) this; - } - - public O retryPolicy(RetryPolicy retryPolicy) { - this.retryPolicy = retryPolicy; - return (O) this; - } - - public O defaultRetryPolicy() { - this.retryPolicy = DefaultRetryPolicy.INSTANCE; - return (O) this; - } - - public O idempotent() { - this.idempotent = true; - return (O) this; - } - - public O isIdempotent(boolean idempotent) { - this.idempotent = idempotent; - return (O) this; - } - - public O downgradingConsistencyRetryPolicy() { - this.retryPolicy = DowngradingConsistencyRetryPolicy.INSTANCE; - return (O) this; - } - - public O fallthroughRetryPolicy() { - this.retryPolicy = FallthroughRetryPolicy.INSTANCE; - return (O) this; - } - - public O consistency(ConsistencyLevel level) { - this.consistencyLevel = level; - return (O) this; - } - - public O consistencyAny() { - this.consistencyLevel = ConsistencyLevel.ANY; - return (O) this; - } - - public O consistencyOne() { - this.consistencyLevel = ConsistencyLevel.ONE; - return (O) this; - } - - public O consistencyQuorum() { - this.consistencyLevel = ConsistencyLevel.QUORUM; - return (O) this; - } - - public O consistencyAll() { - this.consistencyLevel = ConsistencyLevel.ALL; - return (O) this; - } - - public O consistencyLocalOne() { - this.consistencyLevel = ConsistencyLevel.LOCAL_ONE; - return (O) this; - } - - public O consistencyLocalQuorum() { - this.consistencyLevel = ConsistencyLevel.LOCAL_QUORUM; - return (O) this; - } - - public O consistencyEachQuorum() { - this.consistencyLevel = ConsistencyLevel.EACH_QUORUM; - return (O) this; - } - - public O serialConsistency(ConsistencyLevel level) { - this.serialConsistencyLevel = level; - return (O) this; - } - - public O serialConsistencyAny() { - this.serialConsistencyLevel = ConsistencyLevel.ANY; - return (O) this; - } - - public O serialConsistencyOne() { - this.serialConsistencyLevel = ConsistencyLevel.ONE; - return (O) this; - } - - public O serialConsistencyQuorum() { - this.serialConsistencyLevel = ConsistencyLevel.QUORUM; - return (O) this; - } - - public O serialConsistencyAll() { - this.serialConsistencyLevel = ConsistencyLevel.ALL; - return (O) this; - } - - public O serialConsistencyLocal() { - this.serialConsistencyLevel = ConsistencyLevel.LOCAL_SERIAL; - return (O) this; - } - - public O serialConsistencyLocalQuorum() { - this.serialConsistencyLevel = ConsistencyLevel.LOCAL_QUORUM; - return (O) this; - } - - public O disableTracing() { - this.enableTracing = false; - return (O) this; - } - - public O enableTracing() { - this.enableTracing = true; - return (O) this; - } - - public O tracing(boolean enable) { - this.enableTracing = enable; - return (O) this; - } - - public O fetchSize(int fetchSize) { - this.fetchSize = new int[1]; - this.fetchSize[0] = fetchSize; - return (O) this; - } - - public O queryTimeoutMs(long ms) { - this.queryExecutionTimeout = ms; - this.queryTimeoutUnits = TimeUnit.MILLISECONDS; - return (O) this; - } - - public O queryTimeout(long timeout, TimeUnit units) { - this.queryExecutionTimeout = timeout; - this.queryTimeoutUnits = units; - return (O) this; - } - - public Statement options(Statement statement) { - - if (defaultTimestamp != null) { - statement.setDefaultTimestamp(defaultTimestamp[0]); - } - - if (consistencyLevel != null) { - statement.setConsistencyLevel(consistencyLevel); - } - - if (serialConsistencyLevel != null) { - statement.setSerialConsistencyLevel(serialConsistencyLevel); - } - - if (retryPolicy != null) { - statement.setRetryPolicy(retryPolicy); - } - - if (enableTracing) { - statement.enableTracing(); - } else { - statement.disableTracing(); - } - - if (fetchSize != null) { - statement.setFetchSize(fetchSize[0]); - } - - if (idempotent) { - statement.setIdempotent(true); - } - - return statement; - } - - public O zipkinContext(TraceContext traceContext) { - if (traceContext != null) { - Tracer tracer = this.sessionOps.getZipkinTracer(); - if (tracer != null) { - this.traceContext = traceContext; - } - } - - return (O) this; - } - - public Statement statement() { - return buildStatement(false); - } - - public String cql() { - Statement statement = buildStatement(false); - if (statement == null) return ""; - if (statement instanceof BuiltStatement) { - BuiltStatement buildStatement = (BuiltStatement) statement; - return buildStatement.setForceNoValues(true).getQueryString(); - } else { - return statement.toString(); - } - } - - public PreparedStatement prepareStatement() { - - Statement statement = buildStatement(true); - - if (statement instanceof RegularStatement) { - - RegularStatement regularStatement = (RegularStatement) statement; - - return sessionOps.prepare(regularStatement); - } - - throw new HelenusException("only RegularStatements can be prepared"); - } - - public ListenableFuture prepareStatementAsync() { - - Statement statement = buildStatement(true); - - if (statement instanceof RegularStatement) { - - RegularStatement regularStatement = (RegularStatement) statement; - - return sessionOps.prepareAsync(regularStatement); - } - - throw new HelenusException("only RegularStatements can be prepared"); - } - - protected E checkCache(UnitOfWork uow, Set facets, String[] statementKeys) { - E result = null; - Optional>> optionalCachedResult = Optional.empty(); - - if (!facets.isEmpty()) { - //TODO(gburd): what about select ResultSet, Tuple... etc.? - optionalCachedResult = uow.cacheLookupByFacet(facets); - if (optionalCachedResult.isPresent()) { - Either> eitherCachedResult = optionalCachedResult.get(); - if (eitherCachedResult.isLeft()) { - uowCacheHits.mark(); - logger.info("UnitOfWork({}) cache hit using facets", uow.hashCode()); - result = (E) eitherCachedResult.getLeft(); - } - } - } - - if (result == null && statementKeys != null) { - // Then check to see if this query happens to uniquely identify a single object in thecache. - optionalCachedResult = uow.cacheLookupByStatement(statementKeys); - if (optionalCachedResult.isPresent()) { - Either> eitherCachedResult = optionalCachedResult.get(); - // Statements always store Set as the value in the cache. - if (eitherCachedResult.isRight()) { - Set cachedResult = eitherCachedResult.getRight(); - if (cachedResult.size() == 1) { - Optional maybeResult = cachedResult.stream().findFirst(); - if (maybeResult.isPresent()) { - uowCacheHits.mark(); - logger.info("UnitOfWork({}) cache hit for stmt", uow.hashCode()); - } else { - result = null; - } - } - } - } - } - - if (result == null) { - uowCacheMiss.mark(); - logger.info("UnitOfWork({}) cache miss", uow.hashCode()); - } - - return result; - } - - protected void updateCache( - UnitOfWork uow, - E pojo, - Map facetMap, - String[] statementKeys) { - - // Insert this entity into the cache for each facet for this entity that we can fully bind. - Map boundFacets = new HashMap(); - Map valueMap = - pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; - facetMap.forEach( - (facetName, facet) -> { - if (!facet.isFullyBound()) { - EntityIdentifyingFacet.Binder binder = facet.binder(); - facet - .getProperties() - .forEach( - prop -> { - if (valueMap == null) { - Object value = - BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false); - binder.setValueForProperty( - prop, prop.getColumnName().toCql() + "==" + value.toString()); - } else { - binder.setValueForProperty( - prop, - prop.getColumnName().toCql() - + "==" - + valueMap.get(prop.getPropertyName()).toString()); - } - }); - boundFacets.put(facetName, binder.bind()); - } - }); - - // Cache the value (pojo), the statement key, and the fully bound facets. - uow.cacheUpdate(Either.left(pojo), statementKeys, boundFacets); - } + +public abstract class AbstractStatementOperation> extends Operation { + + final Logger logger = LoggerFactory.getLogger(getClass()); + protected boolean enableCache = true; + protected boolean showValues = true; + protected TraceContext traceContext; + long queryExecutionTimeout = 10; + TimeUnit queryTimeoutUnits = TimeUnit.SECONDS; + private ConsistencyLevel consistencyLevel; + private ConsistencyLevel serialConsistencyLevel; + private RetryPolicy retryPolicy; + private boolean idempotent = false; + private boolean enableTracing = false; + private long[] defaultTimestamp = null; + private int[] fetchSize = null; + + public AbstractStatementOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + this.consistencyLevel = sessionOperations.getDefaultConsistencyLevel(); + this.idempotent = sessionOperations.getDefaultQueryIdempotency(); + } + + public abstract Statement buildStatement(boolean cached); + + public O ignoreCache(boolean enabled) { + enableCache = enabled; + return (O) this; + } + + public O ignoreCache() { + enableCache = true; + return (O) this; + } + + public O showValues(boolean enabled) { + this.showValues = enabled; + return (O) this; + } + + public O defaultTimestamp(long timestamp) { + this.defaultTimestamp = new long[1]; + this.defaultTimestamp[0] = timestamp; + return (O) this; + } + + public O retryPolicy(RetryPolicy retryPolicy) { + this.retryPolicy = retryPolicy; + return (O) this; + } + + public O defaultRetryPolicy() { + this.retryPolicy = DefaultRetryPolicy.INSTANCE; + return (O) this; + } + + public O idempotent() { + this.idempotent = true; + return (O) this; + } + + public O isIdempotent(boolean idempotent) { + this.idempotent = idempotent; + return (O) this; + } + + public O downgradingConsistencyRetryPolicy() { + this.retryPolicy = DowngradingConsistencyRetryPolicy.INSTANCE; + return (O) this; + } + + public O fallthroughRetryPolicy() { + this.retryPolicy = FallthroughRetryPolicy.INSTANCE; + return (O) this; + } + + public O consistency(ConsistencyLevel level) { + this.consistencyLevel = level; + return (O) this; + } + + public O consistencyAny() { + this.consistencyLevel = ConsistencyLevel.ANY; + return (O) this; + } + + public O consistencyOne() { + this.consistencyLevel = ConsistencyLevel.ONE; + return (O) this; + } + + public O consistencyQuorum() { + this.consistencyLevel = ConsistencyLevel.QUORUM; + return (O) this; + } + + public O consistencyAll() { + this.consistencyLevel = ConsistencyLevel.ALL; + return (O) this; + } + + public O consistencyLocalOne() { + this.consistencyLevel = ConsistencyLevel.LOCAL_ONE; + return (O) this; + } + + public O consistencyLocalQuorum() { + this.consistencyLevel = ConsistencyLevel.LOCAL_QUORUM; + return (O) this; + } + + public O consistencyEachQuorum() { + this.consistencyLevel = ConsistencyLevel.EACH_QUORUM; + return (O) this; + } + + public O serialConsistency(ConsistencyLevel level) { + this.serialConsistencyLevel = level; + return (O) this; + } + + public O serialConsistencyAny() { + this.serialConsistencyLevel = ConsistencyLevel.ANY; + return (O) this; + } + + public O serialConsistencyOne() { + this.serialConsistencyLevel = ConsistencyLevel.ONE; + return (O) this; + } + + public O serialConsistencyQuorum() { + this.serialConsistencyLevel = ConsistencyLevel.QUORUM; + return (O) this; + } + + public O serialConsistencyAll() { + this.serialConsistencyLevel = ConsistencyLevel.ALL; + return (O) this; + } + + public O serialConsistencyLocal() { + this.serialConsistencyLevel = ConsistencyLevel.LOCAL_SERIAL; + return (O) this; + } + + public O serialConsistencyLocalQuorum() { + this.serialConsistencyLevel = ConsistencyLevel.LOCAL_QUORUM; + return (O) this; + } + + public O disableTracing() { + this.enableTracing = false; + return (O) this; + } + + public O enableTracing() { + this.enableTracing = true; + return (O) this; + } + + public O tracing(boolean enable) { + this.enableTracing = enable; + return (O) this; + } + + public O fetchSize(int fetchSize) { + this.fetchSize = new int[1]; + this.fetchSize[0] = fetchSize; + return (O) this; + } + + public O queryTimeoutMs(long ms) { + this.queryExecutionTimeout = ms; + this.queryTimeoutUnits = TimeUnit.MILLISECONDS; + return (O) this; + } + + public O queryTimeout(long timeout, TimeUnit units) { + this.queryExecutionTimeout = timeout; + this.queryTimeoutUnits = units; + return (O) this; + } + + public Statement options(Statement statement) { + + if (defaultTimestamp != null) { + statement.setDefaultTimestamp(defaultTimestamp[0]); + } + + if (consistencyLevel != null) { + statement.setConsistencyLevel(consistencyLevel); + } + + if (serialConsistencyLevel != null) { + statement.setSerialConsistencyLevel(serialConsistencyLevel); + } + + if (retryPolicy != null) { + statement.setRetryPolicy(retryPolicy); + } + + if (enableTracing) { + statement.enableTracing(); + } else { + statement.disableTracing(); + } + + if (fetchSize != null) { + statement.setFetchSize(fetchSize[0]); + } + + if (idempotent) { + statement.setIdempotent(true); + } + + return statement; + } + + public O zipkinContext(TraceContext traceContext) { + if (traceContext != null) { + Tracer tracer = this.sessionOps.getZipkinTracer(); + if (tracer != null) { + this.traceContext = traceContext; + } + } + + return (O) this; + } + + public Statement statement() { + return buildStatement(false); + } + + public String cql() { + Statement statement = buildStatement(false); + if (statement == null) + return ""; + if (statement instanceof BuiltStatement) { + BuiltStatement buildStatement = (BuiltStatement) statement; + return buildStatement.setForceNoValues(true).getQueryString(); + } else { + return statement.toString(); + } + } + + public PreparedStatement prepareStatement() { + + Statement statement = buildStatement(true); + + if (statement instanceof RegularStatement) { + + RegularStatement regularStatement = (RegularStatement) statement; + + return sessionOps.prepare(regularStatement); + } + + throw new HelenusException("only RegularStatements can be prepared"); + } + + public ListenableFuture prepareStatementAsync() { + + Statement statement = buildStatement(true); + + if (statement instanceof RegularStatement) { + + RegularStatement regularStatement = (RegularStatement) statement; + + return sessionOps.prepareAsync(regularStatement); + } + + throw new HelenusException("only RegularStatements can be prepared"); + } + + protected E checkCache(UnitOfWork uow, Set facets, String[] statementKeys) { + E result = null; + Optional>> optionalCachedResult = Optional.empty(); + + if (!facets.isEmpty()) { + // TODO(gburd): what about select ResultSet, Tuple... etc.? + optionalCachedResult = uow.cacheLookupByFacet(facets); + if (optionalCachedResult.isPresent()) { + Either> eitherCachedResult = optionalCachedResult.get(); + if (eitherCachedResult.isLeft()) { + uowCacheHits.mark(); + logger.info("UnitOfWork({}) cache hit using facets", uow.hashCode()); + result = (E) eitherCachedResult.getLeft(); + } + } + } + + if (result == null && statementKeys != null) { + // Then check to see if this query happens to uniquely identify a single object + // in thecache. + optionalCachedResult = uow.cacheLookupByStatement(statementKeys); + if (optionalCachedResult.isPresent()) { + Either> eitherCachedResult = optionalCachedResult.get(); + // Statements always store Set as the value in the cache. + if (eitherCachedResult.isRight()) { + Set cachedResult = eitherCachedResult.getRight(); + if (cachedResult.size() == 1) { + Optional maybeResult = cachedResult.stream().findFirst(); + if (maybeResult.isPresent()) { + uowCacheHits.mark(); + logger.info("UnitOfWork({}) cache hit for stmt", uow.hashCode()); + } else { + result = null; + } + } + } + } + } + + if (result == null) { + uowCacheMiss.mark(); + logger.info("UnitOfWork({}) cache miss", uow.hashCode()); + } + + return result; + } + + protected void updateCache(UnitOfWork uow, E pojo, Map facetMap, + String[] statementKeys) { + + // Insert this entity into the cache for each facet for this entity that we can + // fully bind. + Map boundFacets = new HashMap(); + Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; + facetMap.forEach((facetName, facet) -> { + if (!facet.isFullyBound()) { + EntityIdentifyingFacet.Binder binder = facet.binder(); + facet.getProperties().forEach(prop -> { + if (valueMap == null) { + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false); + binder.setValueForProperty(prop, prop.getColumnName().toCql() + "==" + value.toString()); + } else { + binder.setValueForProperty(prop, + prop.getColumnName().toCql() + "==" + valueMap.get(prop.getPropertyName()).toString()); + } + }); + boundFacets.put(facetName, binder.bind()); + } + }); + + // Cache the value (pojo), the statement key, and the fully bound facets. + uow.cacheUpdate(Either.left(pojo), statementKeys, boundFacets); + } } diff --git a/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java b/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java index e588bda..4f349b9 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java @@ -15,126 +15,115 @@ */ package net.helenus.core.operation; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.TimeoutException; +import java.util.stream.Stream; + import com.codahale.metrics.Timer; import com.datastax.driver.core.PreparedStatement; import com.datastax.driver.core.ResultSet; import com.google.common.base.Function; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.concurrent.TimeoutException; -import java.util.stream.Stream; + import net.helenus.core.AbstractSessionOperations; import net.helenus.core.UnitOfWork; -import net.helenus.core.cache.BoundFacet; +import net.helenus.core.cache.Facet; public abstract class AbstractStreamOperation> - extends AbstractStatementOperation { + extends + AbstractStatementOperation { - public AbstractStreamOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } + public AbstractStreamOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } - public abstract Stream transform(ResultSet resultSet); + public abstract Stream transform(ResultSet resultSet); - public PreparedStreamOperation prepare() { - return new PreparedStreamOperation(prepareStatement(), this); - } + public PreparedStreamOperation prepare() { + return new PreparedStreamOperation(prepareStatement(), this); + } - public ListenableFuture> prepareAsync() { - final O _this = (O) this; - return Futures.transform( - prepareStatementAsync(), - new Function>() { - @Override - public PreparedStreamOperation apply(PreparedStatement preparedStatement) { - return new PreparedStreamOperation(preparedStatement, _this); - } - }); - } + public ListenableFuture> prepareAsync() { + final O _this = (O) this; + return Futures.transform(prepareStatementAsync(), + new Function>() { + @Override + public PreparedStreamOperation apply(PreparedStatement preparedStatement) { + return new PreparedStreamOperation(preparedStatement, _this); + } + }); + } - public Stream sync() throws TimeoutException { - final Timer.Context context = requestLatency.time(); - try { - ResultSet resultSet = - this.execute( - sessionOps, - null, - traceContext, - queryExecutionTimeout, - queryTimeoutUnits, - showValues, - false); - return transform(resultSet); - } finally { - context.stop(); - } - } + public Stream sync() throws TimeoutException { + final Timer.Context context = requestLatency.time(); + try { + ResultSet resultSet = this.execute(sessionOps, null, traceContext, queryExecutionTimeout, queryTimeoutUnits, + showValues, false); + return transform(resultSet); + } finally { + context.stop(); + } + } - public Stream sync(UnitOfWork uow) throws TimeoutException { - if (uow == null) return sync(); + public Stream sync(UnitOfWork uow) throws TimeoutException { + if (uow == null) + return sync(); - final Timer.Context context = requestLatency.time(); - try { - Stream result = null; - E cachedResult = null; - String[] statementKeys = null; + final Timer.Context context = requestLatency.time(); + try { + Stream result = null; + E cachedResult = null; + String[] statementKeys = null; - if (enableCache) { - Set facets = bindFacetValues(); - statementKeys = getQueryKeys(); - cachedResult = checkCache(uow, facets, statementKeys); - if (cachedResult != null) { - result = Stream.of(cachedResult); - } - } + if (enableCache) { + Set facets = bindFacetValues(); + statementKeys = getQueryKeys(); + cachedResult = checkCache(uow, facets, statementKeys); + if (cachedResult != null) { + result = Stream.of(cachedResult); + } + } - if (result == null) { - ResultSet resultSet = - execute( - sessionOps, - uow, - traceContext, - queryExecutionTimeout, - queryTimeoutUnits, - showValues, - true); - result = transform(resultSet); - } + if (result == null) { + ResultSet resultSet = execute(sessionOps, uow, traceContext, queryExecutionTimeout, queryTimeoutUnits, + showValues, true); + result = transform(resultSet); + } - // If we have a result and we're caching then we need to put it into the cache for future requests to find. - if (enableCache && cachedResult != null) { - updateCache(uow, cachedResult, getIdentifyingFacets(), statementKeys); - } + // If we have a result and we're caching then we need to put it into the cache + // for future requests to find. + if (enableCache && cachedResult != null) { + updateCache(uow, cachedResult, getIdentifyingFacets(), statementKeys); + } - return result; - } finally { - context.stop(); - } - } + return result; + } finally { + context.stop(); + } + } - public CompletableFuture> async() { - return CompletableFuture.>supplyAsync( - () -> { - try { - return sync(); - } catch (TimeoutException ex) { - throw new CompletionException(ex); - } - }); - } + public CompletableFuture> async() { + return CompletableFuture.>supplyAsync(() -> { + try { + return sync(); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } + }); + } - public CompletableFuture> async(UnitOfWork uow) { - if (uow == null) return async(); - return CompletableFuture.>supplyAsync( - () -> { - try { - return sync(); - } catch (TimeoutException ex) { - throw new CompletionException(ex); - } - }); - } + public CompletableFuture> async(UnitOfWork uow) { + if (uow == null) + return async(); + return CompletableFuture.>supplyAsync(() -> { + try { + return sync(); + } catch (TimeoutException ex) { + throw new CompletionException(ex); + } + }); + } } diff --git a/src/main/java/net/helenus/core/operation/BoundOperation.java b/src/main/java/net/helenus/core/operation/BoundOperation.java index 28c134f..0c29913 100644 --- a/src/main/java/net/helenus/core/operation/BoundOperation.java +++ b/src/main/java/net/helenus/core/operation/BoundOperation.java @@ -21,22 +21,22 @@ import com.datastax.driver.core.Statement; public final class BoundOperation extends AbstractOperation> { - private final BoundStatement boundStatement; - private final AbstractOperation delegate; + private final BoundStatement boundStatement; + private final AbstractOperation delegate; - public BoundOperation(BoundStatement boundStatement, AbstractOperation operation) { - super(operation.sessionOps); - this.boundStatement = boundStatement; - this.delegate = operation; - } + public BoundOperation(BoundStatement boundStatement, AbstractOperation operation) { + super(operation.sessionOps); + this.boundStatement = boundStatement; + this.delegate = operation; + } - @Override - public E transform(ResultSet resultSet) { - return delegate.transform(resultSet); - } + @Override + public E transform(ResultSet resultSet) { + return delegate.transform(resultSet); + } - @Override - public Statement buildStatement(boolean cached) { - return boundStatement; - } + @Override + public Statement buildStatement(boolean cached) { + return boundStatement; + } } diff --git a/src/main/java/net/helenus/core/operation/BoundOptionalOperation.java b/src/main/java/net/helenus/core/operation/BoundOptionalOperation.java index c3f5332..9be7209 100644 --- a/src/main/java/net/helenus/core/operation/BoundOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/BoundOptionalOperation.java @@ -15,31 +15,30 @@ */ package net.helenus.core.operation; +import java.util.Optional; + import com.datastax.driver.core.BoundStatement; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Statement; -import java.util.Optional; -public final class BoundOptionalOperation - extends AbstractOptionalOperation> { +public final class BoundOptionalOperation extends AbstractOptionalOperation> { - private final BoundStatement boundStatement; - private final AbstractOptionalOperation delegate; + private final BoundStatement boundStatement; + private final AbstractOptionalOperation delegate; - public BoundOptionalOperation( - BoundStatement boundStatement, AbstractOptionalOperation operation) { - super(operation.sessionOps); - this.boundStatement = boundStatement; - this.delegate = operation; - } + public BoundOptionalOperation(BoundStatement boundStatement, AbstractOptionalOperation operation) { + super(operation.sessionOps); + this.boundStatement = boundStatement; + this.delegate = operation; + } - @Override - public Optional transform(ResultSet resultSet) { - return delegate.transform(resultSet); - } + @Override + public Optional transform(ResultSet resultSet) { + return delegate.transform(resultSet); + } - @Override - public Statement buildStatement(boolean cached) { - return boundStatement; - } + @Override + public Statement buildStatement(boolean cached) { + return boundStatement; + } } diff --git a/src/main/java/net/helenus/core/operation/BoundStreamOperation.java b/src/main/java/net/helenus/core/operation/BoundStreamOperation.java index d89128d..bbc2e79 100644 --- a/src/main/java/net/helenus/core/operation/BoundStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/BoundStreamOperation.java @@ -15,43 +15,43 @@ */ package net.helenus.core.operation; +import java.util.Set; +import java.util.stream.Stream; + import com.datastax.driver.core.BoundStatement; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Statement; -import java.util.Set; -import java.util.stream.Stream; -import net.helenus.core.cache.BoundFacet; -public final class BoundStreamOperation - extends AbstractStreamOperation> { +import net.helenus.core.cache.Facet; - private final BoundStatement boundStatement; - private final AbstractStreamOperation delegate; +public final class BoundStreamOperation extends AbstractStreamOperation> { - public BoundStreamOperation( - BoundStatement boundStatement, AbstractStreamOperation operation) { - super(operation.sessionOps); - this.boundStatement = boundStatement; - this.delegate = operation; - } + private final BoundStatement boundStatement; + private final AbstractStreamOperation delegate; - @Override - public String[] getQueryKeys() { - return delegate.getQueryKeys(); - } + public BoundStreamOperation(BoundStatement boundStatement, AbstractStreamOperation operation) { + super(operation.sessionOps); + this.boundStatement = boundStatement; + this.delegate = operation; + } - @Override - public Set bindFacetValues() { - return delegate.bindFacetValues(); - } + @Override + public String[] getQueryKeys() { + return delegate.getQueryKeys(); + } - @Override - public Stream transform(ResultSet resultSet) { - return delegate.transform(resultSet); - } + @Override + public Set bindFacetValues() { + return delegate.bindFacetValues(); + } - @Override - public Statement buildStatement(boolean cached) { - return boundStatement; - } + @Override + public Stream transform(ResultSet resultSet) { + return delegate.transform(resultSet); + } + + @Override + public Statement buildStatement(boolean cached) { + return boundStatement; + } } diff --git a/src/main/java/net/helenus/core/operation/CountOperation.java b/src/main/java/net/helenus/core/operation/CountOperation.java index b751cfb..3631b93 100644 --- a/src/main/java/net/helenus/core/operation/CountOperation.java +++ b/src/main/java/net/helenus/core/operation/CountOperation.java @@ -20,6 +20,7 @@ import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Select; import com.datastax.driver.core.querybuilder.Select.Where; + import net.helenus.core.AbstractSessionOperations; import net.helenus.core.Filter; import net.helenus.core.reflect.HelenusPropertyNode; @@ -28,56 +29,53 @@ import net.helenus.support.HelenusMappingException; public final class CountOperation extends AbstractFilterOperation { - private HelenusEntity entity; + private HelenusEntity entity; - public CountOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } + public CountOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } - public CountOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity) { - super(sessionOperations); - this.entity = entity; - } + public CountOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity) { + super(sessionOperations); + this.entity = entity; + } - @Override - public BuiltStatement buildStatement(boolean cached) { + @Override + public BuiltStatement buildStatement(boolean cached) { - if (filters != null && !filters.isEmpty()) { - filters.forEach(f -> addPropertyNode(f.getNode())); - } + if (filters != null && !filters.isEmpty()) { + filters.forEach(f -> addPropertyNode(f.getNode())); + } - if (entity == null) { - throw new HelenusMappingException("unknown entity"); - } + if (entity == null) { + throw new HelenusMappingException("unknown entity"); + } - Select select = QueryBuilder.select().countAll().from(entity.getName().toCql()); + Select select = QueryBuilder.select().countAll().from(entity.getName().toCql()); - if (filters != null && !filters.isEmpty()) { + if (filters != null && !filters.isEmpty()) { - Where where = select.where(); + Where where = select.where(); - for (Filter filter : filters) { - where.and(filter.getClause(sessionOps.getValuePreparer())); - } - } + for (Filter filter : filters) { + where.and(filter.getClause(sessionOps.getValuePreparer())); + } + } - return select; - } + return select; + } - @Override - public Long transform(ResultSet resultSet) { - return resultSet.one().getLong(0); - } + @Override + public Long transform(ResultSet resultSet) { + return resultSet.one().getLong(0); + } - private void addPropertyNode(HelenusPropertyNode p) { - if (entity == null) { - entity = p.getEntity(); - } else if (entity != p.getEntity()) { - throw new HelenusMappingException( - "you can count columns only in single entity " - + entity.getMappingInterface() - + " or " - + p.getEntity().getMappingInterface()); - } - } + private void addPropertyNode(HelenusPropertyNode p) { + if (entity == null) { + entity = p.getEntity(); + } else if (entity != p.getEntity()) { + throw new HelenusMappingException("you can count columns only in single entity " + + entity.getMappingInterface() + " or " + p.getEntity().getMappingInterface()); + } + } } diff --git a/src/main/java/net/helenus/core/operation/DeleteOperation.java b/src/main/java/net/helenus/core/operation/DeleteOperation.java index 7b6dffb..d95c567 100644 --- a/src/main/java/net/helenus/core/operation/DeleteOperation.java +++ b/src/main/java/net/helenus/core/operation/DeleteOperation.java @@ -20,6 +20,7 @@ import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.Delete; import com.datastax.driver.core.querybuilder.Delete.Where; import com.datastax.driver.core.querybuilder.QueryBuilder; + import net.helenus.core.AbstractSessionOperations; import net.helenus.core.Filter; import net.helenus.core.reflect.HelenusPropertyNode; @@ -28,100 +29,97 @@ import net.helenus.support.HelenusMappingException; public final class DeleteOperation extends AbstractFilterOperation { - private HelenusEntity entity; + private HelenusEntity entity; - private boolean ifExists = false; + private boolean ifExists = false; - private int[] ttl; - private long[] timestamp; + private int[] ttl; + private long[] timestamp; - public DeleteOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - } + public DeleteOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + } - public DeleteOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity) { - super(sessionOperations); + public DeleteOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity) { + super(sessionOperations); - this.entity = entity; - } + this.entity = entity; + } - @Override - public BuiltStatement buildStatement(boolean cached) { + @Override + public BuiltStatement buildStatement(boolean cached) { - if (filters != null && !filters.isEmpty()) { - filters.forEach(f -> addPropertyNode(f.getNode())); - } + if (filters != null && !filters.isEmpty()) { + filters.forEach(f -> addPropertyNode(f.getNode())); + } - if (entity == null) { - throw new HelenusMappingException("unknown entity"); - } + if (entity == null) { + throw new HelenusMappingException("unknown entity"); + } - if (filters != null && !filters.isEmpty()) { + if (filters != null && !filters.isEmpty()) { - Delete delete = QueryBuilder.delete().from(entity.getName().toCql()); + Delete delete = QueryBuilder.delete().from(entity.getName().toCql()); - if (this.ifExists) { - delete.ifExists(); - } + if (this.ifExists) { + delete.ifExists(); + } - Where where = delete.where(); + Where where = delete.where(); - for (Filter filter : filters) { - where.and(filter.getClause(sessionOps.getValuePreparer())); - } + for (Filter filter : filters) { + where.and(filter.getClause(sessionOps.getValuePreparer())); + } - if (ifFilters != null && !ifFilters.isEmpty()) { + if (ifFilters != null && !ifFilters.isEmpty()) { - for (Filter filter : ifFilters) { - delete.onlyIf(filter.getClause(sessionOps.getValuePreparer())); - } - } + for (Filter filter : ifFilters) { + delete.onlyIf(filter.getClause(sessionOps.getValuePreparer())); + } + } - if (this.ttl != null) { - delete.using(QueryBuilder.ttl(this.ttl[0])); - } - if (this.timestamp != null) { - delete.using(QueryBuilder.timestamp(this.timestamp[0])); - } + if (this.ttl != null) { + delete.using(QueryBuilder.ttl(this.ttl[0])); + } + if (this.timestamp != null) { + delete.using(QueryBuilder.timestamp(this.timestamp[0])); + } - return delete; + return delete; - } else { - return QueryBuilder.truncate(entity.getName().toCql()); - } - } + } else { + return QueryBuilder.truncate(entity.getName().toCql()); + } + } - @Override - public ResultSet transform(ResultSet resultSet) { - return resultSet; - } + @Override + public ResultSet transform(ResultSet resultSet) { + return resultSet; + } - public DeleteOperation ifExists() { - this.ifExists = true; - return this; - } + public DeleteOperation ifExists() { + this.ifExists = true; + return this; + } - public DeleteOperation usingTtl(int ttl) { - this.ttl = new int[1]; - this.ttl[0] = ttl; - return this; - } + public DeleteOperation usingTtl(int ttl) { + this.ttl = new int[1]; + this.ttl[0] = ttl; + return this; + } - public DeleteOperation usingTimestamp(long timestamp) { - this.timestamp = new long[1]; - this.timestamp[0] = timestamp; - return this; - } + public DeleteOperation usingTimestamp(long timestamp) { + this.timestamp = new long[1]; + this.timestamp[0] = timestamp; + return this; + } - private void addPropertyNode(HelenusPropertyNode p) { - if (entity == null) { - entity = p.getEntity(); - } else if (entity != p.getEntity()) { - throw new HelenusMappingException( - "you can delete rows only in single entity " - + entity.getMappingInterface() - + " or " - + p.getEntity().getMappingInterface()); - } - } + private void addPropertyNode(HelenusPropertyNode p) { + if (entity == null) { + entity = p.getEntity(); + } else if (entity != p.getEntity()) { + throw new HelenusMappingException("you can delete rows only in single entity " + + entity.getMappingInterface() + " or " + p.getEntity().getMappingInterface()); + } + } } diff --git a/src/main/java/net/helenus/core/operation/InsertOperation.java b/src/main/java/net/helenus/core/operation/InsertOperation.java index 18c7e6a..4812df3 100644 --- a/src/main/java/net/helenus/core/operation/InsertOperation.java +++ b/src/main/java/net/helenus/core/operation/InsertOperation.java @@ -15,13 +15,15 @@ */ package net.helenus.core.operation; +import java.util.*; +import java.util.concurrent.TimeoutException; +import java.util.function.Function; + import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.Insert; import com.datastax.driver.core.querybuilder.QueryBuilder; -import java.util.*; -import java.util.concurrent.TimeoutException; -import java.util.function.Function; + import net.helenus.core.AbstractSessionOperations; import net.helenus.core.Getter; import net.helenus.core.Helenus; @@ -39,237 +41,228 @@ import net.helenus.support.HelenusMappingException; public final class InsertOperation extends AbstractOperation> { - private HelenusEntity entity; + private HelenusEntity entity; - private final List> values = - new ArrayList>(); - private final T pojo; - private final Class resultType; - private boolean ifNotExists; + private final List> values = new ArrayList>(); + private final T pojo; + private final Class resultType; + private boolean ifNotExists; - private int[] ttl; - private long[] timestamp; + private int[] ttl; + private long[] timestamp; - public InsertOperation(AbstractSessionOperations sessionOperations, boolean ifNotExists) { - super(sessionOperations); + public InsertOperation(AbstractSessionOperations sessionOperations, boolean ifNotExists) { + super(sessionOperations); - this.ifNotExists = ifNotExists; - this.pojo = null; - this.resultType = ResultSet.class; - } + this.ifNotExists = ifNotExists; + this.pojo = null; + this.resultType = ResultSet.class; + } - public InsertOperation( - AbstractSessionOperations sessionOperations, Class resultType, boolean ifNotExists) { - super(sessionOperations); + public InsertOperation(AbstractSessionOperations sessionOperations, Class resultType, boolean ifNotExists) { + super(sessionOperations); - this.ifNotExists = ifNotExists; - this.pojo = null; - this.resultType = resultType; - } + this.ifNotExists = ifNotExists; + this.pojo = null; + this.resultType = resultType; + } - public InsertOperation( - AbstractSessionOperations sessionOperations, - HelenusEntity entity, - T pojo, - Set mutations, - boolean ifNotExists) { - super(sessionOperations); + public InsertOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity, T pojo, + Set mutations, boolean ifNotExists) { + super(sessionOperations); - this.entity = entity; - this.pojo = pojo; - this.ifNotExists = ifNotExists; - this.resultType = entity.getMappingInterface(); + this.entity = entity; + this.pojo = pojo; + this.ifNotExists = ifNotExists; + this.resultType = entity.getMappingInterface(); - Collection properties = entity.getOrderedProperties(); - Set keys = (mutations == null) ? null : mutations; + Collection properties = entity.getOrderedProperties(); + Set keys = (mutations == null) ? null : mutations; - for (HelenusProperty prop : properties) { - boolean addProp = false; + for (HelenusProperty prop : properties) { + boolean addProp = false; - switch (prop.getColumnType()) { - case PARTITION_KEY: - case CLUSTERING_COLUMN: - addProp = true; - break; - default: - addProp = (keys == null || keys.contains(prop.getPropertyName())); - } + switch (prop.getColumnType()) { + case PARTITION_KEY : + case CLUSTERING_COLUMN : + addProp = true; + break; + default : + addProp = (keys == null || keys.contains(prop.getPropertyName())); + } - if (addProp) { - Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop); - value = sessionOps.getValuePreparer().prepareColumnValue(value, prop); + if (addProp) { + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop); + value = sessionOps.getValuePreparer().prepareColumnValue(value, prop); - if (value != null) { - HelenusPropertyNode node = new HelenusPropertyNode(prop, Optional.empty()); - values.add(Fun.Tuple2.of(node, value)); - } - } - } - } + if (value != null) { + HelenusPropertyNode node = new HelenusPropertyNode(prop, Optional.empty()); + values.add(Fun.Tuple2.of(node, value)); + } + } + } + } - public InsertOperation ifNotExists() { - this.ifNotExists = true; - return this; - } + public InsertOperation ifNotExists() { + this.ifNotExists = true; + return this; + } - public InsertOperation ifNotExists(boolean enable) { - this.ifNotExists = enable; - return this; - } + public InsertOperation ifNotExists(boolean enable) { + this.ifNotExists = enable; + return this; + } - public InsertOperation value(Getter getter, V val) { + public InsertOperation value(Getter getter, V val) { - Objects.requireNonNull(getter, "getter is empty"); + Objects.requireNonNull(getter, "getter is empty"); - if (val != null) { - HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); - Object value = sessionOps.getValuePreparer().prepareColumnValue(val, node.getProperty()); + if (val != null) { + HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); + Object value = sessionOps.getValuePreparer().prepareColumnValue(val, node.getProperty()); - if (value != null) { - values.add(Fun.Tuple2.of(node, value)); - } - } + if (value != null) { + values.add(Fun.Tuple2.of(node, value)); + } + } - return this; - } + return this; + } - @Override - public BuiltStatement buildStatement(boolean cached) { + @Override + public BuiltStatement buildStatement(boolean cached) { - values.forEach(t -> addPropertyNode(t._1)); + values.forEach(t -> addPropertyNode(t._1)); - if (values.isEmpty()) return null; + if (values.isEmpty()) + return null; - if (entity == null) { - throw new HelenusMappingException("unknown entity"); - } + if (entity == null) { + throw new HelenusMappingException("unknown entity"); + } - Insert insert = QueryBuilder.insertInto(entity.getName().toCql()); + Insert insert = QueryBuilder.insertInto(entity.getName().toCql()); - if (ifNotExists) { - insert.ifNotExists(); - } + if (ifNotExists) { + insert.ifNotExists(); + } - values.forEach( - t -> { - insert.value(t._1.getColumnName(), t._2); - }); + values.forEach(t -> { + insert.value(t._1.getColumnName(), t._2); + }); - if (this.ttl != null) { - insert.using(QueryBuilder.ttl(this.ttl[0])); - } - if (this.timestamp != null) { - insert.using(QueryBuilder.timestamp(this.timestamp[0])); - } + if (this.ttl != null) { + insert.using(QueryBuilder.ttl(this.ttl[0])); + } + if (this.timestamp != null) { + insert.using(QueryBuilder.timestamp(this.timestamp[0])); + } - return insert; - } + return insert; + } - @Override - public T transform(ResultSet resultSet) { - Class iface = entity.getMappingInterface(); - if (resultType == iface) { - if (values.size() > 0) { - boolean immutable = iface.isAssignableFrom(Drafted.class); - Collection properties = entity.getOrderedProperties(); - Map backingMap = new HashMap(properties.size()); + @Override + public T transform(ResultSet resultSet) { + Class iface = entity.getMappingInterface(); + if (resultType == iface) { + if (values.size() > 0) { + boolean immutable = iface.isAssignableFrom(Drafted.class); + Collection properties = entity.getOrderedProperties(); + Map backingMap = new HashMap(properties.size()); - // First, add all the inserted values into our new map. - values.forEach(t -> backingMap.put(t._1.getProperty().getPropertyName(), t._2)); + // First, add all the inserted values into our new map. + values.forEach(t -> backingMap.put(t._1.getProperty().getPropertyName(), t._2)); - // Then, fill in all the rest of the properties. - for (HelenusProperty prop : properties) { - String key = prop.getPropertyName(); - if (backingMap.containsKey(key)) { - // Some values man need to be converted (e.g. from String to Enum). This is done - // within the BeanColumnValueProvider below. - Optional> converter = - prop.getReadConverter(sessionOps.getSessionRepository()); - if (converter.isPresent()) { - backingMap.put(key, converter.get().apply(backingMap.get(key))); - } - } else { - // If we started this operation with an instance of this type, use values from that. - if (pojo != null) { - backingMap.put( - key, BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, immutable)); - } else { - // Otherwise we'll use default values for the property type if available. - Class propType = prop.getJavaType(); - if (propType.isPrimitive()) { - DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(propType); - if (type == null) { - throw new HelenusException("unknown primitive type " + propType); - } - backingMap.put(key, type.getDefaultValue()); - } - } - } - } + // Then, fill in all the rest of the properties. + for (HelenusProperty prop : properties) { + String key = prop.getPropertyName(); + if (backingMap.containsKey(key)) { + // Some values man need to be converted (e.g. from String to Enum). This is done + // within the BeanColumnValueProvider below. + Optional> converter = prop + .getReadConverter(sessionOps.getSessionRepository()); + if (converter.isPresent()) { + backingMap.put(key, converter.get().apply(backingMap.get(key))); + } + } else { + // If we started this operation with an instance of this type, use values from + // that. + if (pojo != null) { + backingMap.put(key, + BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, immutable)); + } else { + // Otherwise we'll use default values for the property type if available. + Class propType = prop.getJavaType(); + if (propType.isPrimitive()) { + DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(propType); + if (type == null) { + throw new HelenusException("unknown primitive type " + propType); + } + backingMap.put(key, type.getDefaultValue()); + } + } + } + } - // Lastly, create a new proxy object for the entity and return the new instance. - return (T) Helenus.map(iface, backingMap); - } - // Oddly, this insert didn't change any value so simply return the pojo. - // TODO(gburd): this pojo is the result of a Draft.build() call which will not preserve object identity (o1 == o2), ... fix me. - return (T) pojo; - } - return (T) resultSet; - } + // Lastly, create a new proxy object for the entity and return the new instance. + return (T) Helenus.map(iface, backingMap); + } + // Oddly, this insert didn't change any value so simply return the pojo. + // TODO(gburd): this pojo is the result of a Draft.build() call which will not + // preserve object identity (o1 == o2), ... fix me. + return (T) pojo; + } + return (T) resultSet; + } - public InsertOperation usingTtl(int ttl) { - this.ttl = new int[1]; - this.ttl[0] = ttl; - return this; - } + public InsertOperation usingTtl(int ttl) { + this.ttl = new int[1]; + this.ttl[0] = ttl; + return this; + } - public InsertOperation usingTimestamp(long timestamp) { - this.timestamp = new long[1]; - this.timestamp[0] = timestamp; - return this; - } + public InsertOperation usingTimestamp(long timestamp) { + this.timestamp = new long[1]; + this.timestamp[0] = timestamp; + return this; + } - private void addPropertyNode(HelenusPropertyNode p) { - if (entity == null) { - entity = p.getEntity(); - } else if (entity != p.getEntity()) { - throw new HelenusMappingException( - "you can insert only single entity " - + entity.getMappingInterface() - + " or " - + p.getEntity().getMappingInterface()); - } - } + private void addPropertyNode(HelenusPropertyNode p) { + if (entity == null) { + entity = p.getEntity(); + } else if (entity != p.getEntity()) { + throw new HelenusMappingException("you can insert only single entity " + entity.getMappingInterface() + + " or " + p.getEntity().getMappingInterface()); + } + } - @Override - public String[] getQueryKeys() { - List keys = new ArrayList<>(values.size()); - values.forEach( - t -> { - HelenusPropertyNode prop = t._1; - switch (prop.getProperty().getColumnType()) { - case PARTITION_KEY: - case CLUSTERING_COLUMN: - keys.add( - entity.getName().toCql() + '.' + prop.getColumnName() + "==" + t._2.toString()); - break; - default: - break; - } - }); - return keys.toArray(new String[keys.size()]); - } + @Override + public String[] getQueryKeys() { + List keys = new ArrayList<>(values.size()); + values.forEach(t -> { + HelenusPropertyNode prop = t._1; + switch (prop.getProperty().getColumnType()) { + case PARTITION_KEY : + case CLUSTERING_COLUMN : + keys.add(entity.getName().toCql() + '.' + prop.getColumnName() + "==" + t._2.toString()); + break; + default : + break; + } + }); + return keys.toArray(new String[keys.size()]); + } - @Override - public T sync(UnitOfWork uow) throws TimeoutException { - if (uow == null) { - return sync(); - } - T result = super.sync(uow); - Class iface = entity.getMappingInterface(); - if (resultType == iface) { - updateCache(uow, result, entity.getIdentifyingFacets(), getQueryKeys()); - } - return result; - } + @Override + public T sync(UnitOfWork uow) throws TimeoutException { + if (uow == null) { + return sync(); + } + T result = super.sync(uow); + Class iface = entity.getMappingInterface(); + if (resultType == iface) { + updateCache(uow, result, entity.getIdentifyingFacets(), getQueryKeys()); + } + return result; + } } diff --git a/src/main/java/net/helenus/core/operation/Operation.java b/src/main/java/net/helenus/core/operation/Operation.java index 3f07ec2..0953dc7 100644 --- a/src/main/java/net/helenus/core/operation/Operation.java +++ b/src/main/java/net/helenus/core/operation/Operation.java @@ -15,91 +15,87 @@ */ package net.helenus.core.operation; -import brave.Span; -import brave.Tracer; -import brave.propagation.TraceContext; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + import com.codahale.metrics.Meter; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.Timer; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.ResultSetFuture; import com.datastax.driver.core.Statement; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; + +import brave.Span; +import brave.Tracer; +import brave.propagation.TraceContext; import net.helenus.core.AbstractSessionOperations; import net.helenus.core.UnitOfWork; -import net.helenus.core.cache.BoundFacet; import net.helenus.core.cache.EntityIdentifyingFacet; +import net.helenus.core.cache.Facet; public abstract class Operation { - protected final AbstractSessionOperations sessionOps; - protected final Meter uowCacheHits; - protected final Meter uowCacheMiss; - protected final Timer requestLatency; + protected final AbstractSessionOperations sessionOps; + protected final Meter uowCacheHits; + protected final Meter uowCacheMiss; + protected final Timer requestLatency; - Operation(AbstractSessionOperations sessionOperations) { - this.sessionOps = sessionOperations; - MetricRegistry metrics = sessionOperations.getMetricRegistry(); - this.uowCacheHits = metrics.meter("net.helenus.UOW-cache-hits"); - this.uowCacheMiss = metrics.meter("net.helenus.UOW-cache-miss"); - this.requestLatency = metrics.timer("net.helenus.request-latency"); - } + Operation(AbstractSessionOperations sessionOperations) { + this.sessionOps = sessionOperations; + MetricRegistry metrics = sessionOperations.getMetricRegistry(); + this.uowCacheHits = metrics.meter("net.helenus.UOW-cache-hits"); + this.uowCacheMiss = metrics.meter("net.helenus.UOW-cache-miss"); + this.requestLatency = metrics.timer("net.helenus.request-latency"); + } - public ResultSet execute( - AbstractSessionOperations session, - UnitOfWork uow, - TraceContext traceContext, - long timeout, - TimeUnit units, - boolean showValues, - boolean cached) - throws TimeoutException { + public ResultSet execute(AbstractSessionOperations session, UnitOfWork uow, TraceContext traceContext, long timeout, + TimeUnit units, boolean showValues, boolean cached) throws TimeoutException { - // Start recording in a Zipkin sub-span our execution time to perform this operation. - Tracer tracer = session.getZipkinTracer(); - Span span = null; - if (tracer != null && traceContext != null) { - span = tracer.newChild(traceContext); - } + // Start recording in a Zipkin sub-span our execution time to perform this + // operation. + Tracer tracer = session.getZipkinTracer(); + Span span = null; + if (tracer != null && traceContext != null) { + span = tracer.newChild(traceContext); + } - try { + try { - if (span != null) { - span.name("cassandra"); - span.start(); - } + if (span != null) { + span.name("cassandra"); + span.start(); + } - Statement statement = options(buildStatement(cached)); - ResultSetFuture futureResultSet = session.executeAsync(statement, showValues); - return futureResultSet.getUninterruptibly(timeout, units); - } finally { + Statement statement = options(buildStatement(cached)); + ResultSetFuture futureResultSet = session.executeAsync(statement, showValues); + return futureResultSet.getUninterruptibly(timeout, units); + } finally { - if (span != null) { - span.finish(); - } - } - } + if (span != null) { + span.finish(); + } + } + } - public Statement options(Statement statement) { - return statement; - } + public Statement options(Statement statement) { + return statement; + } - public Statement buildStatement(boolean cached) { - return null; - } + public Statement buildStatement(boolean cached) { + return null; + } - public String[] getQueryKeys() { - return null; - } + public String[] getQueryKeys() { + return null; + } - public Map getIdentifyingFacets() { - return null; - } + public Map getIdentifyingFacets() { + return null; + } - public Set bindFacetValues() { - return null; - } + public Set bindFacetValues() { + return null; + } } diff --git a/src/main/java/net/helenus/core/operation/PreparedOperation.java b/src/main/java/net/helenus/core/operation/PreparedOperation.java index baba8df..950bc9a 100644 --- a/src/main/java/net/helenus/core/operation/PreparedOperation.java +++ b/src/main/java/net/helenus/core/operation/PreparedOperation.java @@ -20,27 +20,27 @@ import com.datastax.driver.core.PreparedStatement; public final class PreparedOperation { - private final PreparedStatement preparedStatement; - private final AbstractOperation operation; + private final PreparedStatement preparedStatement; + private final AbstractOperation operation; - public PreparedOperation(PreparedStatement statement, AbstractOperation operation) { - this.preparedStatement = statement; - this.operation = operation; - } + public PreparedOperation(PreparedStatement statement, AbstractOperation operation) { + this.preparedStatement = statement; + this.operation = operation; + } - public PreparedStatement getPreparedStatement() { - return preparedStatement; - } + public PreparedStatement getPreparedStatement() { + return preparedStatement; + } - public BoundOperation bind(Object... params) { + public BoundOperation bind(Object... params) { - BoundStatement boundStatement = preparedStatement.bind(params); + BoundStatement boundStatement = preparedStatement.bind(params); - return new BoundOperation(boundStatement, operation); - } + return new BoundOperation(boundStatement, operation); + } - @Override - public String toString() { - return preparedStatement.getQueryString(); - } + @Override + public String toString() { + return preparedStatement.getQueryString(); + } } diff --git a/src/main/java/net/helenus/core/operation/PreparedOptionalOperation.java b/src/main/java/net/helenus/core/operation/PreparedOptionalOperation.java index 2ee7e29..31feb2b 100644 --- a/src/main/java/net/helenus/core/operation/PreparedOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/PreparedOptionalOperation.java @@ -20,28 +20,27 @@ import com.datastax.driver.core.PreparedStatement; public final class PreparedOptionalOperation { - private final PreparedStatement preparedStatement; - private final AbstractOptionalOperation operation; + private final PreparedStatement preparedStatement; + private final AbstractOptionalOperation operation; - public PreparedOptionalOperation( - PreparedStatement statement, AbstractOptionalOperation operation) { - this.preparedStatement = statement; - this.operation = operation; - } + public PreparedOptionalOperation(PreparedStatement statement, AbstractOptionalOperation operation) { + this.preparedStatement = statement; + this.operation = operation; + } - public PreparedStatement getPreparedStatement() { - return preparedStatement; - } + public PreparedStatement getPreparedStatement() { + return preparedStatement; + } - public BoundOptionalOperation bind(Object... params) { + public BoundOptionalOperation bind(Object... params) { - BoundStatement boundStatement = preparedStatement.bind(params); + BoundStatement boundStatement = preparedStatement.bind(params); - return new BoundOptionalOperation(boundStatement, operation); - } + return new BoundOptionalOperation(boundStatement, operation); + } - @Override - public String toString() { - return preparedStatement.getQueryString(); - } + @Override + public String toString() { + return preparedStatement.getQueryString(); + } } diff --git a/src/main/java/net/helenus/core/operation/PreparedStreamOperation.java b/src/main/java/net/helenus/core/operation/PreparedStreamOperation.java index cd0f6be..132e39c 100644 --- a/src/main/java/net/helenus/core/operation/PreparedStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/PreparedStreamOperation.java @@ -20,26 +20,25 @@ import com.datastax.driver.core.PreparedStatement; public final class PreparedStreamOperation { - private final PreparedStatement preparedStatement; - private final AbstractStreamOperation operation; + private final PreparedStatement preparedStatement; + private final AbstractStreamOperation operation; - public PreparedStreamOperation( - PreparedStatement statement, AbstractStreamOperation operation) { - this.preparedStatement = statement; - this.operation = operation; - } + public PreparedStreamOperation(PreparedStatement statement, AbstractStreamOperation operation) { + this.preparedStatement = statement; + this.operation = operation; + } - public PreparedStatement getPreparedStatement() { - return preparedStatement; - } + public PreparedStatement getPreparedStatement() { + return preparedStatement; + } - public BoundStreamOperation bind(Object... params) { - BoundStatement boundStatement = preparedStatement.bind(params); - return new BoundStreamOperation(boundStatement, operation); - } + public BoundStreamOperation bind(Object... params) { + BoundStatement boundStatement = preparedStatement.bind(params); + return new BoundStreamOperation(boundStatement, operation); + } - @Override - public String toString() { - return preparedStatement.getQueryString(); - } + @Override + public String toString() { + return preparedStatement.getQueryString(); + } } diff --git a/src/main/java/net/helenus/core/operation/SelectFirstOperation.java b/src/main/java/net/helenus/core/operation/SelectFirstOperation.java index 74970ff..e34d933 100644 --- a/src/main/java/net/helenus/core/operation/SelectFirstOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectFirstOperation.java @@ -15,54 +15,55 @@ */ package net.helenus.core.operation; -import com.datastax.driver.core.ResultSet; -import com.datastax.driver.core.querybuilder.BuiltStatement; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.function.Function; -import net.helenus.core.cache.BoundFacet; + +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.querybuilder.BuiltStatement; + import net.helenus.core.cache.EntityIdentifyingFacet; +import net.helenus.core.cache.Facet; -public final class SelectFirstOperation - extends AbstractFilterOptionalOperation> { +public final class SelectFirstOperation extends AbstractFilterOptionalOperation> { - private final SelectOperation delegate; + private final SelectOperation delegate; - public SelectFirstOperation(SelectOperation delegate) { - super(delegate.sessionOps); + public SelectFirstOperation(SelectOperation delegate) { + super(delegate.sessionOps); - this.delegate = delegate; - this.filters = delegate.filters; - this.ifFilters = delegate.ifFilters; - } + this.delegate = delegate; + this.filters = delegate.filters; + this.ifFilters = delegate.ifFilters; + } - public SelectFirstTransformingOperation map(Function fn) { - return new SelectFirstTransformingOperation(delegate, fn); - } + public SelectFirstTransformingOperation map(Function fn) { + return new SelectFirstTransformingOperation(delegate, fn); + } - @Override - public BuiltStatement buildStatement(boolean cached) { - return delegate.buildStatement(cached); - } + @Override + public BuiltStatement buildStatement(boolean cached) { + return delegate.buildStatement(cached); + } - @Override - public String[] getQueryKeys() { - return delegate.getQueryKeys(); - } + @Override + public String[] getQueryKeys() { + return delegate.getQueryKeys(); + } - @Override - public Map getIdentifyingFacets() { - return delegate.getIdentifyingFacets(); - } + @Override + public Map getIdentifyingFacets() { + return delegate.getIdentifyingFacets(); + } - @Override - public Set bindFacetValues() { - return delegate.bindFacetValues(); - } + @Override + public Set bindFacetValues() { + return delegate.bindFacetValues(); + } - @Override - public Optional transform(ResultSet resultSet) { - return delegate.transform(resultSet).findFirst(); - } + @Override + public Optional transform(ResultSet resultSet) { + return delegate.transform(resultSet).findFirst(); + } } diff --git a/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java b/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java index 4ecf46d..15dfed5 100644 --- a/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java @@ -15,45 +15,48 @@ */ package net.helenus.core.operation; -import com.datastax.driver.core.ResultSet; -import com.datastax.driver.core.querybuilder.BuiltStatement; import java.util.Optional; import java.util.Set; import java.util.function.Function; -import net.helenus.core.cache.BoundFacet; + +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.querybuilder.BuiltStatement; + +import net.helenus.core.cache.Facet; public final class SelectFirstTransformingOperation - extends AbstractFilterOptionalOperation> { + extends + AbstractFilterOptionalOperation> { - private final SelectOperation delegate; - private final Function fn; + private final SelectOperation delegate; + private final Function fn; - public SelectFirstTransformingOperation(SelectOperation delegate, Function fn) { - super(delegate.sessionOps); + public SelectFirstTransformingOperation(SelectOperation delegate, Function fn) { + super(delegate.sessionOps); - this.delegate = delegate; - this.fn = fn; - this.filters = delegate.filters; - this.ifFilters = delegate.ifFilters; - } + this.delegate = delegate; + this.fn = fn; + this.filters = delegate.filters; + this.ifFilters = delegate.ifFilters; + } - @Override - public String[] getQueryKeys() { - return delegate.getQueryKeys(); - } + @Override + public String[] getQueryKeys() { + return delegate.getQueryKeys(); + } - @Override - public Set bindFacetValues() { - return delegate.bindFacetValues(); - } + @Override + public Set bindFacetValues() { + return delegate.bindFacetValues(); + } - @Override - public BuiltStatement buildStatement(boolean cached) { - return delegate.buildStatement(cached); - } + @Override + public BuiltStatement buildStatement(boolean cached) { + return delegate.buildStatement(cached); + } - @Override - public Optional transform(ResultSet resultSet) { - return delegate.transform(resultSet).findFirst().map(fn); - } + @Override + public Optional transform(ResultSet resultSet) { + return delegate.transform(resultSet).findFirst().map(fn); + } } diff --git a/src/main/java/net/helenus/core/operation/SelectOperation.java b/src/main/java/net/helenus/core/operation/SelectOperation.java index 7435d0f..1a9908e 100644 --- a/src/main/java/net/helenus/core/operation/SelectOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectOperation.java @@ -15,6 +15,11 @@ */ package net.helenus.core.operation; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.querybuilder.BuiltStatement; @@ -24,13 +29,10 @@ import com.datastax.driver.core.querybuilder.Select; import com.datastax.driver.core.querybuilder.Select.Selection; import com.datastax.driver.core.querybuilder.Select.Where; import com.google.common.collect.Iterables; -import java.util.*; -import java.util.function.Function; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; + import net.helenus.core.*; -import net.helenus.core.cache.BoundFacet; import net.helenus.core.cache.EntityIdentifyingFacet; +import net.helenus.core.cache.Facet; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.MappingUtil; @@ -42,302 +44,260 @@ import net.helenus.support.HelenusMappingException; public final class SelectOperation extends AbstractFilterStreamOperation> { - protected Function rowMapper = null; - protected final List props = new ArrayList(); + protected final List props = new ArrayList(); + protected Function rowMapper = null; + protected List ordering = null; + protected Integer limit = null; + protected boolean allowFiltering = false; + protected String alternateTableName = null; - protected List ordering = null; - protected Integer limit = null; - protected boolean allowFiltering = false; - protected String alternateTableName = null; + @SuppressWarnings("unchecked") + public SelectOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); - @SuppressWarnings("unchecked") - public SelectOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); + this.rowMapper = new Function() { - this.rowMapper = - new Function() { + @Override + public E apply(Row source) { - @Override - public E apply(Row source) { + ColumnValueProvider valueProvider = sessionOps.getValueProvider(); + Object[] arr = new Object[props.size()]; - ColumnValueProvider valueProvider = sessionOps.getValueProvider(); - Object[] arr = new Object[props.size()]; + int i = 0; + for (HelenusPropertyNode p : props) { + Object value = valueProvider.getColumnValue(source, -1, p.getProperty()); + arr[i++] = value; + } - int i = 0; - for (HelenusPropertyNode p : props) { - Object value = valueProvider.getColumnValue(source, -1, p.getProperty()); - arr[i++] = value; - } + return (E) Fun.ArrayTuple.of(arr); + } + }; + } - return (E) Fun.ArrayTuple.of(arr); - } - }; - } + public SelectOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity) { - public SelectOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity) { + super(sessionOperations); - super(sessionOperations); + entity.getOrderedProperties().stream().map(p -> new HelenusPropertyNode(p, Optional.empty())) + .forEach(p -> this.props.add(p)); + } - entity - .getOrderedProperties() - .stream() - .map(p -> new HelenusPropertyNode(p, Optional.empty())) - .forEach(p -> this.props.add(p)); - } + public SelectOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity, + Function rowMapper) { - public SelectOperation( - AbstractSessionOperations sessionOperations, - HelenusEntity entity, - Function rowMapper) { + super(sessionOperations); + this.rowMapper = rowMapper; - super(sessionOperations); - this.rowMapper = rowMapper; + entity.getOrderedProperties().stream().map(p -> new HelenusPropertyNode(p, Optional.empty())) + .forEach(p -> this.props.add(p)); + } - entity - .getOrderedProperties() - .stream() - .map(p -> new HelenusPropertyNode(p, Optional.empty())) - .forEach(p -> this.props.add(p)); - } + public SelectOperation(AbstractSessionOperations sessionOperations, Function rowMapper, + HelenusPropertyNode... props) { - public SelectOperation( - AbstractSessionOperations sessionOperations, - Function rowMapper, - HelenusPropertyNode... props) { + super(sessionOperations); - super(sessionOperations); + this.rowMapper = rowMapper; + Collections.addAll(this.props, props); + } - this.rowMapper = rowMapper; - Collections.addAll(this.props, props); - } + public CountOperation count() { - public CountOperation count() { + HelenusEntity entity = null; + for (HelenusPropertyNode prop : props) { - HelenusEntity entity = null; - for (HelenusPropertyNode prop : props) { + if (entity == null) { + entity = prop.getEntity(); + } else if (entity != prop.getEntity()) { + throw new HelenusMappingException("you can count records only from a single entity " + + entity.getMappingInterface() + " or " + prop.getEntity().getMappingInterface()); + } + } - if (entity == null) { - entity = prop.getEntity(); - } else if (entity != prop.getEntity()) { - throw new HelenusMappingException( - "you can count records only from a single entity " - + entity.getMappingInterface() - + " or " - + prop.getEntity().getMappingInterface()); - } - } + return new CountOperation(sessionOps, entity); + } - return new CountOperation(sessionOps, entity); - } + public SelectOperation from(Class materializedViewClass) { + Objects.requireNonNull(materializedViewClass); + HelenusEntity entity = Helenus.entity(materializedViewClass); + this.alternateTableName = entity.getName().toCql(); + this.props.clear(); + entity.getOrderedProperties().stream().map(p -> new HelenusPropertyNode(p, Optional.empty())) + .forEach(p -> this.props.add(p)); + return this; + } - public SelectOperation from(Class materializedViewClass) { - Objects.requireNonNull(materializedViewClass); - HelenusEntity entity = Helenus.entity(materializedViewClass); - this.alternateTableName = entity.getName().toCql(); - this.props.clear(); - entity - .getOrderedProperties() - .stream() - .map(p -> new HelenusPropertyNode(p, Optional.empty())) - .forEach(p -> this.props.add(p)); - return this; - } + public SelectFirstOperation single() { + limit(1); + return new SelectFirstOperation(this); + } - public SelectFirstOperation single() { - limit(1); - return new SelectFirstOperation(this); - } + public SelectTransformingOperation mapTo(Class entityClass) { - public SelectTransformingOperation mapTo(Class entityClass) { + Objects.requireNonNull(entityClass, "entityClass is null"); - Objects.requireNonNull(entityClass, "entityClass is null"); + HelenusEntity entity = Helenus.entity(entityClass); - HelenusEntity entity = Helenus.entity(entityClass); + this.rowMapper = null; - this.rowMapper = null; + return new SelectTransformingOperation(this, (r) -> { + Map map = new ValueProviderMap(r, sessionOps.getValueProvider(), entity); + return (R) Helenus.map(entityClass, map); + }); + } - return new SelectTransformingOperation( - this, - (r) -> { - Map map = new ValueProviderMap(r, sessionOps.getValueProvider(), entity); - return (R) Helenus.map(entityClass, map); - }); - } + public SelectTransformingOperation map(Function fn) { + return new SelectTransformingOperation(this, fn); + } - public SelectTransformingOperation map(Function fn) { - return new SelectTransformingOperation(this, fn); - } + public SelectOperation column(Getter getter) { + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(getter); + this.props.add(p); + return this; + } - public SelectOperation column(Getter getter) { - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(getter); - this.props.add(p); - return this; - } + public SelectOperation orderBy(Getter getter, OrderingDirection direction) { + getOrCreateOrdering().add(new Ordered(getter, direction).getOrdering()); + return this; + } - public SelectOperation orderBy(Getter getter, OrderingDirection direction) { - getOrCreateOrdering().add(new Ordered(getter, direction).getOrdering()); - return this; - } + public SelectOperation orderBy(Ordered ordered) { + getOrCreateOrdering().add(ordered.getOrdering()); + return this; + } - public SelectOperation orderBy(Ordered ordered) { - getOrCreateOrdering().add(ordered.getOrdering()); - return this; - } + public SelectOperation limit(Integer limit) { + this.limit = limit; + return this; + } - public SelectOperation limit(Integer limit) { - this.limit = limit; - return this; - } + public SelectOperation allowFiltering() { + this.allowFiltering = true; + return this; + } - public SelectOperation allowFiltering() { - this.allowFiltering = true; - return this; - } + @Override + public Map getIdentifyingFacets() { + HelenusEntity entity = props.get(0).getEntity(); + return entity.getIdentifyingFacets(); + } - @Override - public String[] getQueryKeys() { - int i = 0; - String[] keys = new String[filters.size()]; - HelenusEntity entity = props.get(0).getEntity(); - String entityName = entity.getName().toCql(); - for (Filter filter : filters.values()) { - keys[i++] = entityName + '.' + filter.toString(); - } - return keys; - } + @Override + public Set bindFacetValues() { + HelenusEntity entity = props.get(0).getEntity(); + Set boundFacets = new HashSet(); + // Check to see if this select statement has enough information to build one or + // more identifying facets. + entity.getIdentifyingFacets().forEach((facetName, facet) -> { + EntityIdentifyingFacet.Binder binder = facet.binder(); + facet.getProperties().forEach(prop -> { + Filter filter = filters.get(prop); + if (filter != null) { + binder.setValueForProperty(prop, filter.toString()); + } else if (facetName.equals("*")) { + binder.setValueForProperty(prop, ""); + } + }); + if (binder.isFullyBound()) { + boundFacets.add(binder.bind()); + } + }); + return boundFacets; + } - @Override - public Map getIdentifyingFacets() { - HelenusEntity entity = props.get(0).getEntity(); - return entity.getIdentifyingFacets(); - } + @Override + public BuiltStatement buildStatement(boolean cached) { - @Override - public Set bindFacetValues() { - HelenusEntity entity = props.get(0).getEntity(); - Set boundFacets = new HashSet(); - // Check to see if this select statement has enough information to build one or - // more identifying facets. - entity - .getIdentifyingFacets() - .forEach( - (facetName, facet) -> { - EntityIdentifyingFacet.Binder binder = facet.binder(); - facet - .getProperties() - .forEach( - prop -> { - Filter filter = filters.get(prop); - if (filter != null) { - binder.setValueForProperty(prop, filter.toString()); - } - }); - if (binder.isFullyBound()) { - boundFacets.add(binder.bind()); - } - }); - return boundFacets; - } + HelenusEntity entity = null; + Selection selection = QueryBuilder.select(); - @Override - public BuiltStatement buildStatement(boolean cached) { + for (HelenusPropertyNode prop : props) { + String columnName = prop.getColumnName(); + selection = selection.column(columnName); - HelenusEntity entity = null; - Selection selection = QueryBuilder.select(); + if (prop.getProperty().caseSensitiveIndex()) { + allowFiltering = true; + } - for (HelenusPropertyNode prop : props) { - String columnName = prop.getColumnName(); - selection = selection.column(columnName); + if (entity == null) { + entity = prop.getEntity(); + } else if (entity != prop.getEntity()) { + throw new HelenusMappingException("you can select columns only from a single entity " + + entity.getMappingInterface() + " or " + prop.getEntity().getMappingInterface()); + } - if (prop.getProperty().caseSensitiveIndex()) { - allowFiltering = true; - } + if (cached) { + switch (prop.getProperty().getColumnType()) { + case PARTITION_KEY : + case CLUSTERING_COLUMN : + break; + default : + if (entity.equals(prop.getEntity())) { + if (prop.getNext().isPresent()) { + columnName = Iterables.getLast(prop).getColumnName().toCql(true); + } + if (!prop.getProperty().getDataType().isCollectionType()) { + selection.writeTime(columnName).as(columnName + "_writeTime"); + selection.ttl(columnName).as(columnName + "_ttl"); + } + } + break; + } + } + } - if (entity == null) { - entity = prop.getEntity(); - } else if (entity != prop.getEntity()) { - throw new HelenusMappingException( - "you can select columns only from a single entity " - + entity.getMappingInterface() - + " or " - + prop.getEntity().getMappingInterface()); - } + if (entity == null) { + throw new HelenusMappingException("no entity or table to select data"); + } - if (cached) { - switch (prop.getProperty().getColumnType()) { - case PARTITION_KEY: - case CLUSTERING_COLUMN: - break; - default: - if (entity.equals(prop.getEntity())) { - if (prop.getNext().isPresent()) { - columnName = Iterables.getLast(prop).getColumnName().toCql(true); - } - if (!prop.getProperty().getDataType().isCollectionType()) { - selection.writeTime(columnName).as(columnName + "_writeTime"); - selection.ttl(columnName).as(columnName + "_ttl"); - } - } - break; - } - } - } + String tableName = alternateTableName == null ? entity.getName().toCql() : alternateTableName; + Select select = selection.from(tableName); - if (entity == null) { - throw new HelenusMappingException("no entity or table to select data"); - } + if (ordering != null && !ordering.isEmpty()) { + select.orderBy(ordering.toArray(new Ordering[ordering.size()])); + } - String tableName = alternateTableName == null ? entity.getName().toCql() : alternateTableName; - Select select = selection.from(tableName); + if (limit != null) { + select.limit(limit); + } - if (ordering != null && !ordering.isEmpty()) { - select.orderBy(ordering.toArray(new Ordering[ordering.size()])); - } + if (filters != null && !filters.isEmpty()) { - if (limit != null) { - select.limit(limit); - } + Where where = select.where(); - if (filters != null && !filters.isEmpty()) { + for (Filter filter : filters.values()) { + where.and(filter.getClause(sessionOps.getValuePreparer())); + } + } - Where where = select.where(); + if (ifFilters != null && !ifFilters.isEmpty()) { + logger.error("onlyIf conditions " + ifFilters + " would be ignored in the statement " + select); + } - for (Filter filter : filters.values()) { - where.and(filter.getClause(sessionOps.getValuePreparer())); - } - } + if (allowFiltering) { + select.allowFiltering(); + } - if (ifFilters != null && !ifFilters.isEmpty()) { - logger.error( - "onlyIf conditions " + ifFilters + " would be ignored in the statement " + select); - } + return select; + } - if (allowFiltering) { - select.allowFiltering(); - } + @SuppressWarnings("unchecked") + @Override + public Stream transform(ResultSet resultSet) { + if (rowMapper != null) { + return StreamSupport + .stream(Spliterators.spliteratorUnknownSize(resultSet.iterator(), Spliterator.ORDERED), false) + .map(rowMapper); + } else { + return (Stream) StreamSupport + .stream(Spliterators.spliteratorUnknownSize(resultSet.iterator(), Spliterator.ORDERED), false); + } + } - return select; - } - - @SuppressWarnings("unchecked") - @Override - public Stream transform(ResultSet resultSet) { - if (rowMapper != null) { - return StreamSupport.stream( - Spliterators.spliteratorUnknownSize(resultSet.iterator(), Spliterator.ORDERED), false) - .map(rowMapper); - } else { - return (Stream) - StreamSupport.stream( - Spliterators.spliteratorUnknownSize(resultSet.iterator(), Spliterator.ORDERED), - false); - } - } - - private List getOrCreateOrdering() { - if (ordering == null) { - ordering = new ArrayList(); - } - return ordering; - } + private List getOrCreateOrdering() { + if (ordering == null) { + ordering = new ArrayList(); + } + return ordering; + } } diff --git a/src/main/java/net/helenus/core/operation/SelectTransformingOperation.java b/src/main/java/net/helenus/core/operation/SelectTransformingOperation.java index d6eb20b..1d43ae9 100644 --- a/src/main/java/net/helenus/core/operation/SelectTransformingOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectTransformingOperation.java @@ -15,52 +15,55 @@ */ package net.helenus.core.operation; -import com.datastax.driver.core.ResultSet; -import com.datastax.driver.core.querybuilder.BuiltStatement; import java.util.Map; import java.util.Set; import java.util.function.Function; import java.util.stream.Stream; -import net.helenus.core.cache.BoundFacet; + +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.querybuilder.BuiltStatement; + import net.helenus.core.cache.EntityIdentifyingFacet; +import net.helenus.core.cache.Facet; public final class SelectTransformingOperation - extends AbstractFilterStreamOperation> { + extends + AbstractFilterStreamOperation> { - private final SelectOperation delegate; - private final Function fn; + private final SelectOperation delegate; + private final Function fn; - public SelectTransformingOperation(SelectOperation delegate, Function fn) { - super(delegate.sessionOps); + public SelectTransformingOperation(SelectOperation delegate, Function fn) { + super(delegate.sessionOps); - this.delegate = delegate; - this.fn = fn; - this.filters = delegate.filters; - this.ifFilters = delegate.ifFilters; - } + this.delegate = delegate; + this.fn = fn; + this.filters = delegate.filters; + this.ifFilters = delegate.ifFilters; + } - @Override - public String[] getQueryKeys() { - return delegate.getQueryKeys(); - } + @Override + public String[] getQueryKeys() { + return delegate.getQueryKeys(); + } - @Override - public Set bindFacetValues() { - return delegate.bindFacetValues(); - } + @Override + public Set bindFacetValues() { + return delegate.bindFacetValues(); + } - @Override - public Map getIdentifyingFacets() { - return delegate.getIdentifyingFacets(); - } + @Override + public Map getIdentifyingFacets() { + return delegate.getIdentifyingFacets(); + } - @Override - public BuiltStatement buildStatement(boolean cached) { - return delegate.buildStatement(cached); - } + @Override + public BuiltStatement buildStatement(boolean cached) { + return delegate.buildStatement(cached); + } - @Override - public Stream transform(ResultSet resultSet) { - return delegate.transform(resultSet).map(fn); - } + @Override + public Stream transform(ResultSet resultSet) { + return delegate.transform(resultSet).map(fn); + } } diff --git a/src/main/java/net/helenus/core/operation/UpdateOperation.java b/src/main/java/net/helenus/core/operation/UpdateOperation.java index a86d0d7..9237526 100644 --- a/src/main/java/net/helenus/core/operation/UpdateOperation.java +++ b/src/main/java/net/helenus/core/operation/UpdateOperation.java @@ -15,14 +15,16 @@ */ package net.helenus.core.operation; +import java.util.*; +import java.util.concurrent.TimeoutException; +import java.util.function.Function; + import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.Assignment; import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Update; -import java.util.*; -import java.util.concurrent.TimeoutException; -import java.util.function.Function; + import net.helenus.core.*; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; @@ -33,561 +35,551 @@ import net.helenus.support.Immutables; public final class UpdateOperation extends AbstractFilterOperation> { - private HelenusEntity entity = null; + private HelenusEntity entity = null; - private final List assignments = new ArrayList(); - private final AbstractEntityDraft draft; - private final Map draftMap; + private final List assignments = new ArrayList(); + private final AbstractEntityDraft draft; + private final Map draftMap; - private int[] ttl; - private long[] timestamp; + private int[] ttl; + private long[] timestamp; - public UpdateOperation(AbstractSessionOperations sessionOperations) { - super(sessionOperations); - this.draft = null; - this.draftMap = null; - } + public UpdateOperation(AbstractSessionOperations sessionOperations) { + super(sessionOperations); + this.draft = null; + this.draftMap = null; + } - public UpdateOperation( - AbstractSessionOperations sessionOperations, AbstractEntityDraft draft) { - super(sessionOperations); - this.draft = draft; - this.draftMap = draft.toMap(); - } + public UpdateOperation(AbstractSessionOperations sessionOperations, AbstractEntityDraft draft) { + super(sessionOperations); + this.draft = draft; + this.draftMap = draft.toMap(); + } - public UpdateOperation( - AbstractSessionOperations sessionOperations, HelenusPropertyNode p, Object v) { - super(sessionOperations); - this.draft = null; - this.draftMap = null; + public UpdateOperation(AbstractSessionOperations sessionOperations, HelenusPropertyNode p, Object v) { + super(sessionOperations); + this.draft = null; + this.draftMap = null; - Object value = sessionOps.getValuePreparer().prepareColumnValue(v, p.getProperty()); - assignments.add(QueryBuilder.set(p.getColumnName(), value)); + Object value = sessionOps.getValuePreparer().prepareColumnValue(v, p.getProperty()); + assignments.add(QueryBuilder.set(p.getColumnName(), value)); - addPropertyNode(p); - } + addPropertyNode(p); + } - public UpdateOperation set(Getter getter, V v) { - Objects.requireNonNull(getter, "getter is empty"); + public UpdateOperation set(Getter getter, V v) { + Objects.requireNonNull(getter, "getter is empty"); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(getter); + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(getter); - Object value = sessionOps.getValuePreparer().prepareColumnValue(v, p.getProperty()); - assignments.add(QueryBuilder.set(p.getColumnName(), value)); + Object value = sessionOps.getValuePreparer().prepareColumnValue(v, p.getProperty()); + assignments.add(QueryBuilder.set(p.getColumnName(), value)); - addPropertyNode(p); + addPropertyNode(p); - return this; - } + return this; + } - /* - * - * - * COUNTER - * - * - */ + /* + * + * + * COUNTER + * + * + */ - public UpdateOperation increment(Getter counterGetter) { - return increment(counterGetter, 1L); - } + public UpdateOperation increment(Getter counterGetter) { + return increment(counterGetter, 1L); + } - public UpdateOperation increment(Getter counterGetter, long delta) { + public UpdateOperation increment(Getter counterGetter, long delta) { - Objects.requireNonNull(counterGetter, "counterGetter is empty"); + Objects.requireNonNull(counterGetter, "counterGetter is empty"); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(counterGetter); + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(counterGetter); - assignments.add(QueryBuilder.incr(p.getColumnName(), delta)); + assignments.add(QueryBuilder.incr(p.getColumnName(), delta)); - addPropertyNode(p); + addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - draftMap.put(key, (Long) draftMap.get(key) + delta); - } + if (draft != null) { + String key = p.getProperty().getPropertyName(); + draftMap.put(key, (Long) draftMap.get(key) + delta); + } - return this; - } + return this; + } - public UpdateOperation decrement(Getter counterGetter) { - return decrement(counterGetter, 1L); - } + public UpdateOperation decrement(Getter counterGetter) { + return decrement(counterGetter, 1L); + } - public UpdateOperation decrement(Getter counterGetter, long delta) { + public UpdateOperation decrement(Getter counterGetter, long delta) { - Objects.requireNonNull(counterGetter, "counterGetter is empty"); + Objects.requireNonNull(counterGetter, "counterGetter is empty"); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(counterGetter); + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(counterGetter); - assignments.add(QueryBuilder.decr(p.getColumnName(), delta)); + assignments.add(QueryBuilder.decr(p.getColumnName(), delta)); - addPropertyNode(p); + addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - draftMap.put(key, (Long) draftMap.get(key) - delta); - } + if (draft != null) { + String key = p.getProperty().getPropertyName(); + draftMap.put(key, (Long) draftMap.get(key) - delta); + } - return this; - } + return this; + } - /* - * - * - * LIST - * - */ + /* + * + * + * LIST + * + */ - public UpdateOperation prepend(Getter> listGetter, V value) { + public UpdateOperation prepend(Getter> listGetter, V value) { - Objects.requireNonNull(listGetter, "listGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + Objects.requireNonNull(listGetter, "listGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); - Object valueObj = prepareSingleListValue(p, value); + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); + Object valueObj = prepareSingleListValue(p, value); - assignments.add(QueryBuilder.prepend(p.getColumnName(), valueObj)); + assignments.add(QueryBuilder.prepend(p.getColumnName(), valueObj)); - addPropertyNode(p); + addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.add(0, value); - } + if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.add(0, value); + } - return this; - } + return this; + } - public UpdateOperation prependAll(Getter> listGetter, List value) { + public UpdateOperation prependAll(Getter> listGetter, List value) { - Objects.requireNonNull(listGetter, "listGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + Objects.requireNonNull(listGetter, "listGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); - List valueObj = prepareListValue(p, value); + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); + List valueObj = prepareListValue(p, value); - assignments.add(QueryBuilder.prependAll(p.getColumnName(), valueObj)); + assignments.add(QueryBuilder.prependAll(p.getColumnName(), valueObj)); - addPropertyNode(p); + addPropertyNode(p); - if (draft != null && value.size() > 0) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.addAll(0, value); - } + if (draft != null && value.size() > 0) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.addAll(0, value); + } - return this; - } + return this; + } - public UpdateOperation setIdx(Getter> listGetter, int idx, V value) { + public UpdateOperation setIdx(Getter> listGetter, int idx, V value) { - Objects.requireNonNull(listGetter, "listGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + Objects.requireNonNull(listGetter, "listGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); - Object valueObj = prepareSingleListValue(p, value); + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); + Object valueObj = prepareSingleListValue(p, value); - assignments.add(QueryBuilder.setIdx(p.getColumnName(), idx, valueObj)); + assignments.add(QueryBuilder.setIdx(p.getColumnName(), idx, valueObj)); - addPropertyNode(p); + addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - List 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); - } + if (draft != null) { + String key = p.getProperty().getPropertyName(); + List 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); + } - return this; - } + return this; + } - public UpdateOperation append(Getter> listGetter, V value) { + public UpdateOperation append(Getter> listGetter, V value) { - Objects.requireNonNull(listGetter, "listGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + Objects.requireNonNull(listGetter, "listGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); - Object valueObj = prepareSingleListValue(p, value); + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); + Object valueObj = prepareSingleListValue(p, value); - assignments.add(QueryBuilder.append(p.getColumnName(), valueObj)); + assignments.add(QueryBuilder.append(p.getColumnName(), valueObj)); - addPropertyNode(p); + addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.add(value); - } + if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.add(value); + } - return this; - } + return this; + } - public UpdateOperation appendAll(Getter> listGetter, List value) { + public UpdateOperation appendAll(Getter> listGetter, List value) { - Objects.requireNonNull(listGetter, "listGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + Objects.requireNonNull(listGetter, "listGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); - List valueObj = prepareListValue(p, value); + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); + List valueObj = prepareListValue(p, value); - assignments.add(QueryBuilder.appendAll(p.getColumnName(), valueObj)); + assignments.add(QueryBuilder.appendAll(p.getColumnName(), valueObj)); - addPropertyNode(p); + addPropertyNode(p); - if (draft != null && value.size() > 0) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.addAll(value); - } + if (draft != null && value.size() > 0) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.addAll(value); + } - return this; - } + return this; + } - public UpdateOperation discard(Getter> listGetter, V value) { + public UpdateOperation discard(Getter> listGetter, V value) { - Objects.requireNonNull(listGetter, "listGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + Objects.requireNonNull(listGetter, "listGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); - Object valueObj = prepareSingleListValue(p, value); + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); + Object valueObj = prepareSingleListValue(p, value); - assignments.add(QueryBuilder.discard(p.getColumnName(), valueObj)); + assignments.add(QueryBuilder.discard(p.getColumnName(), valueObj)); - addPropertyNode(p); + addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.remove(value); - } + if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.remove(value); + } - return this; - } + return this; + } - public UpdateOperation discardAll(Getter> listGetter, List value) { + public UpdateOperation discardAll(Getter> listGetter, List value) { - Objects.requireNonNull(listGetter, "listGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + Objects.requireNonNull(listGetter, "listGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); - List valueObj = prepareListValue(p, value); + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(listGetter); + List valueObj = prepareListValue(p, value); - assignments.add(QueryBuilder.discardAll(p.getColumnName(), valueObj)); + assignments.add(QueryBuilder.discardAll(p.getColumnName(), valueObj)); - addPropertyNode(p); + addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - List list = (List) draftMap.get(key); - list.removeAll(value); - } + if (draft != null) { + String key = p.getProperty().getPropertyName(); + List list = (List) draftMap.get(key); + list.removeAll(value); + } - return this; - } + return this; + } - private Object prepareSingleListValue(HelenusPropertyNode p, Object value) { - HelenusProperty prop = p.getProperty(); + private Object prepareSingleListValue(HelenusPropertyNode p, Object value) { + HelenusProperty prop = p.getProperty(); - Object valueObj = value; + Object valueObj = value; - Optional> converter = - prop.getWriteConverter(sessionOps.getSessionRepository()); - if (converter.isPresent()) { - List convertedList = (List) converter.get().apply(Immutables.listOf(value)); - valueObj = convertedList.get(0); - } + Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); + if (converter.isPresent()) { + List convertedList = (List) converter.get().apply(Immutables.listOf(value)); + valueObj = convertedList.get(0); + } - return valueObj; - } + return valueObj; + } - private List prepareListValue(HelenusPropertyNode p, List value) { + private List prepareListValue(HelenusPropertyNode p, List value) { - HelenusProperty prop = p.getProperty(); + HelenusProperty prop = p.getProperty(); - List valueObj = value; + List valueObj = value; - Optional> converter = - prop.getWriteConverter(sessionOps.getSessionRepository()); - if (converter.isPresent()) { - valueObj = (List) converter.get().apply(value); - } + Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); + if (converter.isPresent()) { + valueObj = (List) converter.get().apply(value); + } - return valueObj; - } + return valueObj; + } - /* - * - * - * SET - * - * - */ + /* + * + * + * SET + * + * + */ - public UpdateOperation add(Getter> setGetter, V value) { + public UpdateOperation add(Getter> setGetter, V value) { - Objects.requireNonNull(setGetter, "setGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + Objects.requireNonNull(setGetter, "setGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(setGetter); - Object valueObj = prepareSingleSetValue(p, value); + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(setGetter); + Object valueObj = prepareSingleSetValue(p, value); - assignments.add(QueryBuilder.add(p.getColumnName(), valueObj)); + assignments.add(QueryBuilder.add(p.getColumnName(), valueObj)); - addPropertyNode(p); + addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.add(value); - } + if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.add(value); + } - return this; - } + return this; + } - public UpdateOperation addAll(Getter> setGetter, Set value) { + public UpdateOperation addAll(Getter> setGetter, Set value) { - Objects.requireNonNull(setGetter, "setGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + Objects.requireNonNull(setGetter, "setGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(setGetter); - Set valueObj = prepareSetValue(p, value); + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(setGetter); + Set valueObj = prepareSetValue(p, value); - assignments.add(QueryBuilder.addAll(p.getColumnName(), valueObj)); + assignments.add(QueryBuilder.addAll(p.getColumnName(), valueObj)); - addPropertyNode(p); + addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.addAll(value); - } + if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.addAll(value); + } - return this; - } + return this; + } - public UpdateOperation remove(Getter> setGetter, V value) { + public UpdateOperation remove(Getter> setGetter, V value) { - Objects.requireNonNull(setGetter, "setGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + Objects.requireNonNull(setGetter, "setGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(setGetter); - Object valueObj = prepareSingleSetValue(p, value); + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(setGetter); + Object valueObj = prepareSingleSetValue(p, value); - assignments.add(QueryBuilder.remove(p.getColumnName(), valueObj)); + assignments.add(QueryBuilder.remove(p.getColumnName(), valueObj)); - addPropertyNode(p); + addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.remove(value); - } + if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.remove(value); + } - return this; - } + return this; + } - public UpdateOperation removeAll(Getter> setGetter, Set value) { + public UpdateOperation removeAll(Getter> setGetter, Set value) { - Objects.requireNonNull(setGetter, "setGetter is empty"); - Objects.requireNonNull(value, "value is empty"); + Objects.requireNonNull(setGetter, "setGetter is empty"); + Objects.requireNonNull(value, "value is empty"); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(setGetter); - Set valueObj = prepareSetValue(p, value); + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(setGetter); + Set valueObj = prepareSetValue(p, value); - assignments.add(QueryBuilder.removeAll(p.getColumnName(), valueObj)); + assignments.add(QueryBuilder.removeAll(p.getColumnName(), valueObj)); - addPropertyNode(p); + addPropertyNode(p); - if (draft != null) { - String key = p.getProperty().getPropertyName(); - Set set = (Set) draftMap.get(key); - set.removeAll(value); - } + if (draft != null) { + String key = p.getProperty().getPropertyName(); + Set set = (Set) draftMap.get(key); + set.removeAll(value); + } - return this; - } + return this; + } - private Object prepareSingleSetValue(HelenusPropertyNode p, Object value) { + private Object prepareSingleSetValue(HelenusPropertyNode p, Object value) { - HelenusProperty prop = p.getProperty(); - Object valueObj = value; + HelenusProperty prop = p.getProperty(); + Object valueObj = value; - Optional> converter = - prop.getWriteConverter(sessionOps.getSessionRepository()); - if (converter.isPresent()) { - Set convertedSet = (Set) converter.get().apply(Immutables.setOf(value)); - valueObj = convertedSet.iterator().next(); - } + Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); + if (converter.isPresent()) { + Set convertedSet = (Set) converter.get().apply(Immutables.setOf(value)); + valueObj = convertedSet.iterator().next(); + } - return valueObj; - } + return valueObj; + } - private Set prepareSetValue(HelenusPropertyNode p, Set value) { + private Set prepareSetValue(HelenusPropertyNode p, Set value) { - HelenusProperty prop = p.getProperty(); - Set valueObj = value; + HelenusProperty prop = p.getProperty(); + Set valueObj = value; - Optional> converter = - prop.getWriteConverter(sessionOps.getSessionRepository()); - if (converter.isPresent()) { - valueObj = (Set) converter.get().apply(value); - } + Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); + if (converter.isPresent()) { + valueObj = (Set) converter.get().apply(value); + } - return valueObj; - } + return valueObj; + } - /* - * - * - * MAP - * - * - */ + /* + * + * + * MAP + * + * + */ - public UpdateOperation put(Getter> mapGetter, K key, V value) { + public UpdateOperation put(Getter> mapGetter, K key, V value) { - Objects.requireNonNull(mapGetter, "mapGetter is empty"); - Objects.requireNonNull(key, "key is empty"); + Objects.requireNonNull(mapGetter, "mapGetter is empty"); + Objects.requireNonNull(key, "key is empty"); - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(mapGetter); - HelenusProperty prop = p.getProperty(); + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(mapGetter); + HelenusProperty prop = p.getProperty(); - Optional> converter = - prop.getWriteConverter(sessionOps.getSessionRepository()); - if (converter.isPresent()) { - Map convertedMap = - (Map) converter.get().apply(Immutables.mapOf(key, value)); - for (Map.Entry e : convertedMap.entrySet()) { - assignments.add(QueryBuilder.put(p.getColumnName(), e.getKey(), e.getValue())); - } - } else { - assignments.add(QueryBuilder.put(p.getColumnName(), key, value)); - } + Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); + if (converter.isPresent()) { + Map convertedMap = (Map) converter.get() + .apply(Immutables.mapOf(key, value)); + for (Map.Entry e : convertedMap.entrySet()) { + assignments.add(QueryBuilder.put(p.getColumnName(), e.getKey(), e.getValue())); + } + } else { + assignments.add(QueryBuilder.put(p.getColumnName(), key, value)); + } - addPropertyNode(p); + addPropertyNode(p); - if (draft != null) { - ((Map) draftMap.get(prop.getPropertyName())).put(key, value); - } + if (draft != null) { + ((Map) draftMap.get(prop.getPropertyName())).put(key, value); + } - return this; - } + return this; + } - public UpdateOperation putAll(Getter> mapGetter, Map map) { - - Objects.requireNonNull(mapGetter, "mapGetter is empty"); - Objects.requireNonNull(map, "map is empty"); - - HelenusPropertyNode p = MappingUtil.resolveMappingProperty(mapGetter); - HelenusProperty prop = p.getProperty(); - - Optional> converter = - prop.getWriteConverter(sessionOps.getSessionRepository()); - if (converter.isPresent()) { - Map convertedMap = (Map) converter.get().apply(map); - assignments.add(QueryBuilder.putAll(p.getColumnName(), convertedMap)); - } else { - assignments.add(QueryBuilder.putAll(p.getColumnName(), map)); - } - - addPropertyNode(p); - - if (draft != null) { - ((Map) draftMap.get(prop.getPropertyName())).putAll(map); - } - - return this; - } - - @Override - public BuiltStatement buildStatement(boolean cached) { - - if (entity == null) { - throw new HelenusMappingException("empty update operation"); - } - - Update update = QueryBuilder.update(entity.getName().toCql()); - - for (Assignment assignment : assignments) { - update.with(assignment); - } - - if (filters != null && !filters.isEmpty()) { - - for (Filter filter : filters) { - update.where(filter.getClause(sessionOps.getValuePreparer())); - } - } - - if (ifFilters != null && !ifFilters.isEmpty()) { - - for (Filter filter : ifFilters) { - update.onlyIf(filter.getClause(sessionOps.getValuePreparer())); - } - } - - if (this.ttl != null) { - update.using(QueryBuilder.ttl(this.ttl[0])); - } - - if (this.timestamp != null) { - update.using(QueryBuilder.timestamp(this.timestamp[0])); - } - - return update; - } - - @Override - public E transform(ResultSet resultSet) { - if (draft != null) { - return Helenus.map(draft.getEntityClass(), draft.toMap(draftMap)); - } else { - return (E) resultSet; - } - } - - public UpdateOperation usingTtl(int ttl) { - this.ttl = new int[1]; - this.ttl[0] = ttl; - return this; - } - - public UpdateOperation usingTimestamp(long timestamp) { - this.timestamp = new long[1]; - this.timestamp[0] = timestamp; - return this; - } - - private void addPropertyNode(HelenusPropertyNode p) { - if (entity == null) { - entity = p.getEntity(); - } else if (entity != p.getEntity()) { - throw new HelenusMappingException( - "you can update columns only in single entity " - + entity.getMappingInterface() - + " or " - + p.getEntity().getMappingInterface()); - } - } - - @Override - public E sync(UnitOfWork uow) throws TimeoutException { - if (uow == null) { - return sync(); - } - E result = super.sync(uow); - // TODO(gburd): Only drafted entity objects are updated in the cache at this time. - if (draft != null) { - updateCache(uow, result, getIdentifyingFacets(), getQueryKeys()); - } - return result; - } + public UpdateOperation putAll(Getter> mapGetter, Map map) { + + Objects.requireNonNull(mapGetter, "mapGetter is empty"); + Objects.requireNonNull(map, "map is empty"); + + HelenusPropertyNode p = MappingUtil.resolveMappingProperty(mapGetter); + HelenusProperty prop = p.getProperty(); + + Optional> converter = prop.getWriteConverter(sessionOps.getSessionRepository()); + if (converter.isPresent()) { + Map convertedMap = (Map) converter.get().apply(map); + assignments.add(QueryBuilder.putAll(p.getColumnName(), convertedMap)); + } else { + assignments.add(QueryBuilder.putAll(p.getColumnName(), map)); + } + + addPropertyNode(p); + + if (draft != null) { + ((Map) draftMap.get(prop.getPropertyName())).putAll(map); + } + + return this; + } + + @Override + public BuiltStatement buildStatement(boolean cached) { + + if (entity == null) { + throw new HelenusMappingException("empty update operation"); + } + + Update update = QueryBuilder.update(entity.getName().toCql()); + + for (Assignment assignment : assignments) { + update.with(assignment); + } + + if (filters != null && !filters.isEmpty()) { + + for (Filter filter : filters) { + update.where(filter.getClause(sessionOps.getValuePreparer())); + } + } + + if (ifFilters != null && !ifFilters.isEmpty()) { + + for (Filter filter : ifFilters) { + update.onlyIf(filter.getClause(sessionOps.getValuePreparer())); + } + } + + if (this.ttl != null) { + update.using(QueryBuilder.ttl(this.ttl[0])); + } + + if (this.timestamp != null) { + update.using(QueryBuilder.timestamp(this.timestamp[0])); + } + + return update; + } + + @Override + public E transform(ResultSet resultSet) { + if (draft != null) { + return Helenus.map(draft.getEntityClass(), draft.toMap(draftMap)); + } else { + return (E) resultSet; + } + } + + public UpdateOperation usingTtl(int ttl) { + this.ttl = new int[1]; + this.ttl[0] = ttl; + return this; + } + + public UpdateOperation usingTimestamp(long timestamp) { + this.timestamp = new long[1]; + this.timestamp[0] = timestamp; + return this; + } + + private void addPropertyNode(HelenusPropertyNode p) { + if (entity == null) { + entity = p.getEntity(); + } else if (entity != p.getEntity()) { + throw new HelenusMappingException("you can update columns only in single entity " + + entity.getMappingInterface() + " or " + p.getEntity().getMappingInterface()); + } + } + + @Override + public E sync(UnitOfWork uow) throws TimeoutException { + if (uow == null) { + return sync(); + } + E result = super.sync(uow); + // TODO(gburd): Only drafted entity objects are updated in the cache at this + // time. + if (draft != null) { + updateCache(uow, result, getIdentifyingFacets(), getQueryKeys()); + } + return result; + } } diff --git a/src/main/java/net/helenus/core/reflect/DefaultPrimitiveTypes.java b/src/main/java/net/helenus/core/reflect/DefaultPrimitiveTypes.java index 10eedcb..171de31 100644 --- a/src/main/java/net/helenus/core/reflect/DefaultPrimitiveTypes.java +++ b/src/main/java/net/helenus/core/reflect/DefaultPrimitiveTypes.java @@ -19,41 +19,34 @@ import java.util.HashMap; import java.util.Map; public enum DefaultPrimitiveTypes { - BOOLEAN(boolean.class, false), - BYTE(byte.class, (byte) 0x0), - CHAR(char.class, (char) 0x0), - SHORT(short.class, (short) 0), - INT(int.class, 0), - LONG(long.class, 0L), - FLOAT(float.class, 0.0f), - DOUBLE(double.class, 0.0); + BOOLEAN(boolean.class, false), BYTE(byte.class, (byte) 0x0), CHAR(char.class, (char) 0x0), SHORT(short.class, + (short) 0), INT(int.class, 0), LONG(long.class, 0L), FLOAT(float.class, 0.0f), DOUBLE(double.class, 0.0); - private final Class primitiveClass; - private final Object defaultValue; + private final Class primitiveClass; + private final Object defaultValue; - private static final Map, DefaultPrimitiveTypes> map = - new HashMap, DefaultPrimitiveTypes>(); + private static final Map, DefaultPrimitiveTypes> map = new HashMap, DefaultPrimitiveTypes>(); - static { - for (DefaultPrimitiveTypes type : DefaultPrimitiveTypes.values()) { - map.put(type.getPrimitiveClass(), type); - } - } + static { + for (DefaultPrimitiveTypes type : DefaultPrimitiveTypes.values()) { + map.put(type.getPrimitiveClass(), type); + } + } - private DefaultPrimitiveTypes(Class primitiveClass, Object defaultValue) { - this.primitiveClass = primitiveClass; - this.defaultValue = defaultValue; - } + private DefaultPrimitiveTypes(Class primitiveClass, Object defaultValue) { + this.primitiveClass = primitiveClass; + this.defaultValue = defaultValue; + } - public static DefaultPrimitiveTypes lookup(Class primitiveClass) { - return map.get(primitiveClass); - } + public static DefaultPrimitiveTypes lookup(Class primitiveClass) { + return map.get(primitiveClass); + } - public Class getPrimitiveClass() { - return primitiveClass; - } + public Class getPrimitiveClass() { + return primitiveClass; + } - public Object getDefaultValue() { - return defaultValue; - } + public Object getDefaultValue() { + return defaultValue; + } } diff --git a/src/main/java/net/helenus/core/reflect/Drafted.java b/src/main/java/net/helenus/core/reflect/Drafted.java index 17196b8..52810b6 100644 --- a/src/main/java/net/helenus/core/reflect/Drafted.java +++ b/src/main/java/net/helenus/core/reflect/Drafted.java @@ -19,7 +19,7 @@ import java.util.Set; public interface Drafted extends MapExportable { - Set mutated(); + Set mutated(); - T build(); + T build(); } diff --git a/src/main/java/net/helenus/core/reflect/DslExportable.java b/src/main/java/net/helenus/core/reflect/DslExportable.java index df9597b..fbe7cbc 100644 --- a/src/main/java/net/helenus/core/reflect/DslExportable.java +++ b/src/main/java/net/helenus/core/reflect/DslExportable.java @@ -16,17 +16,18 @@ package net.helenus.core.reflect; import com.datastax.driver.core.Metadata; + import net.helenus.mapping.HelenusEntity; public interface DslExportable { - String GET_ENTITY_METHOD = "getHelenusMappingEntity"; - String GET_PARENT_METHOD = "getParentDslHelenusPropertyNode"; - String SET_METADATA_METHOD = "setCassandraMetadataForHelenusSession"; + String GET_ENTITY_METHOD = "getHelenusMappingEntity"; + String GET_PARENT_METHOD = "getParentDslHelenusPropertyNode"; + String SET_METADATA_METHOD = "setCassandraMetadataForHelenusSession"; - HelenusEntity getHelenusMappingEntity(); + HelenusEntity getHelenusMappingEntity(); - HelenusPropertyNode getParentDslHelenusPropertyNode(); + HelenusPropertyNode getParentDslHelenusPropertyNode(); - void setCassandraMetadataForHelenusSession(Metadata metadata); + void setCassandraMetadataForHelenusSession(Metadata metadata); } diff --git a/src/main/java/net/helenus/core/reflect/DslInvocationHandler.java b/src/main/java/net/helenus/core/reflect/DslInvocationHandler.java index b9c333c..fd85c44 100644 --- a/src/main/java/net/helenus/core/reflect/DslInvocationHandler.java +++ b/src/main/java/net/helenus/core/reflect/DslInvocationHandler.java @@ -15,13 +15,15 @@ */ package net.helenus.core.reflect; -import com.datastax.driver.core.*; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map; import java.util.Optional; + +import com.datastax.driver.core.*; + import net.helenus.core.Helenus; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusMappingEntity; @@ -34,180 +36,166 @@ import net.helenus.support.HelenusException; public class DslInvocationHandler implements InvocationHandler { - private HelenusEntity entity = null; - private Metadata metadata = null; + private HelenusEntity entity = null; + private Metadata metadata = null; - private final Class iface; - private final ClassLoader classLoader; + private final Class iface; + private final ClassLoader classLoader; - private final Optional parent; + private final Optional parent; - private final Map map = new HashMap(); + private final Map map = new HashMap(); - private final Map udtMap = new HashMap(); - private final Map tupleMap = new HashMap(); + private final Map udtMap = new HashMap(); + private final Map tupleMap = new HashMap(); - public DslInvocationHandler( - Class iface, - ClassLoader classLoader, - Optional parent, - Metadata metadata) { + public DslInvocationHandler(Class iface, ClassLoader classLoader, Optional parent, + Metadata metadata) { - this.metadata = metadata; - this.parent = parent; - this.iface = iface; - this.classLoader = classLoader; - } + this.metadata = metadata; + this.parent = parent; + this.iface = iface; + this.classLoader = classLoader; + } - public void setCassandraMetadataForHelenusSession(Metadata metadata) { - if (metadata != null) { - this.metadata = metadata; - entity = init(metadata); - } - } + public void setCassandraMetadataForHelenusSession(Metadata metadata) { + if (metadata != null) { + this.metadata = metadata; + entity = init(metadata); + } + } - private HelenusEntity init(Metadata metadata) { - HelenusEntity entity = new HelenusMappingEntity(iface, metadata); + private HelenusEntity init(Metadata metadata) { + HelenusEntity entity = new HelenusMappingEntity(iface, metadata); - for (HelenusProperty prop : entity.getOrderedProperties()) { + for (HelenusProperty prop : entity.getOrderedProperties()) { - map.put(prop.getGetterMethod(), prop); + map.put(prop.getGetterMethod(), prop); - AbstractDataType type = prop.getDataType(); - Class javaType = prop.getJavaType(); + AbstractDataType type = prop.getDataType(); + Class javaType = prop.getJavaType(); - if (type instanceof UDTDataType && !UDTValue.class.isAssignableFrom(javaType)) { + if (type instanceof UDTDataType && !UDTValue.class.isAssignableFrom(javaType)) { - Object childDsl = - Helenus.dsl( - javaType, - classLoader, - Optional.of(new HelenusPropertyNode(prop, parent)), - metadata); + Object childDsl = Helenus.dsl(javaType, classLoader, Optional.of(new HelenusPropertyNode(prop, parent)), + metadata); - udtMap.put(prop.getGetterMethod(), childDsl); - } + udtMap.put(prop.getGetterMethod(), childDsl); + } - if (type instanceof DTDataType) { - DTDataType dataType = (DTDataType) type; + if (type instanceof DTDataType) { + DTDataType dataType = (DTDataType) type; - if (dataType.getDataType() instanceof TupleType - && !TupleValue.class.isAssignableFrom(javaType)) { + if (dataType.getDataType() instanceof TupleType && !TupleValue.class.isAssignableFrom(javaType)) { - Object childDsl = - Helenus.dsl( - javaType, - classLoader, - Optional.of(new HelenusPropertyNode(prop, parent)), - metadata); + Object childDsl = Helenus.dsl(javaType, classLoader, + Optional.of(new HelenusPropertyNode(prop, parent)), metadata); - tupleMap.put(prop.getGetterMethod(), childDsl); - } - } - } + tupleMap.put(prop.getGetterMethod(), childDsl); + } + } + } - return entity; - } + return entity; + } - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - HelenusEntity entity = this.entity; - String methodName = method.getName(); + HelenusEntity entity = this.entity; + String methodName = method.getName(); - if ("equals".equals(methodName) && method.getParameterCount() == 1) { - Object otherObj = args[0]; - if (otherObj == null) { - return false; - } - if (Proxy.isProxyClass(otherObj.getClass())) { - return this == Proxy.getInvocationHandler(otherObj); - } - return false; - } + if ("equals".equals(methodName) && method.getParameterCount() == 1) { + Object otherObj = args[0]; + if (otherObj == null) { + return false; + } + if (Proxy.isProxyClass(otherObj.getClass())) { + return this == Proxy.getInvocationHandler(otherObj); + } + return false; + } - if (DslExportable.SET_METADATA_METHOD.equals(methodName) - && args.length == 1 - && args[0] instanceof Metadata) { - if (metadata == null) { - this.setCassandraMetadataForHelenusSession((Metadata) args[0]); - } - return null; - } + if (DslExportable.SET_METADATA_METHOD.equals(methodName) && args.length == 1 && args[0] instanceof Metadata) { + if (metadata == null) { + this.setCassandraMetadataForHelenusSession((Metadata) args[0]); + } + return null; + } - if (method.getParameterCount() != 0 || method.getReturnType() == void.class) { - throw new HelenusException("invalid getter method " + method); - } + if (method.getParameterCount() != 0 || method.getReturnType() == void.class) { + throw new HelenusException("invalid getter method " + method); + } - if ("hashCode".equals(methodName)) { - return hashCode(); - } + if ("hashCode".equals(methodName)) { + return hashCode(); + } - if (DslExportable.GET_PARENT_METHOD.equals(methodName)) { - return parent.get(); - } + if (DslExportable.GET_PARENT_METHOD.equals(methodName)) { + return parent.get(); + } - if (entity == null) { - entity = init(metadata); - } + if (entity == null) { + entity = init(metadata); + } - if ("toString".equals(methodName)) { - return entity.toString(); - } + if ("toString".equals(methodName)) { + return entity.toString(); + } - if (DslExportable.GET_ENTITY_METHOD.equals(methodName)) { - return entity; - } + if (DslExportable.GET_ENTITY_METHOD.equals(methodName)) { + return entity; + } - HelenusProperty prop = map.get(method); - if (prop == null) { - prop = entity.getProperty(methodName); - } + HelenusProperty prop = map.get(method); + if (prop == null) { + prop = entity.getProperty(methodName); + } - if (prop != null) { + if (prop != null) { - AbstractDataType type = prop.getDataType(); + AbstractDataType type = prop.getDataType(); - if (type instanceof UDTDataType) { + if (type instanceof UDTDataType) { - Object childDsl = udtMap.get(method); + Object childDsl = udtMap.get(method); - if (childDsl != null) { - return childDsl; - } - } + if (childDsl != null) { + return childDsl; + } + } - if (type instanceof DTDataType) { - DTDataType dataType = (DTDataType) type; - DataType dt = dataType.getDataType(); + if (type instanceof DTDataType) { + DTDataType dataType = (DTDataType) type; + DataType dt = dataType.getDataType(); - switch (dt.getName()) { - case TUPLE: - Object childDsl = tupleMap.get(method); + switch (dt.getName()) { + case TUPLE : + Object childDsl = tupleMap.get(method); - if (childDsl != null) { - return childDsl; - } + if (childDsl != null) { + return childDsl; + } - break; + break; - case SET: - return new SetDsl(new HelenusPropertyNode(prop, parent)); + case SET : + return new SetDsl(new HelenusPropertyNode(prop, parent)); - case LIST: - return new ListDsl(new HelenusPropertyNode(prop, parent)); + case LIST : + return new ListDsl(new HelenusPropertyNode(prop, parent)); - case MAP: - return new MapDsl(new HelenusPropertyNode(prop, parent)); + case MAP : + return new MapDsl(new HelenusPropertyNode(prop, parent)); - default: - break; - } - } + default : + break; + } + } - throw new DslPropertyException(new HelenusPropertyNode(prop, parent)); - } + throw new DslPropertyException(new HelenusPropertyNode(prop, parent)); + } - throw new HelenusException("invalid method call " + method); - } + throw new HelenusException("invalid method call " + method); + } } diff --git a/src/main/java/net/helenus/core/reflect/HelenusNamedProperty.java b/src/main/java/net/helenus/core/reflect/HelenusNamedProperty.java index 9c4e448..93bfdf2 100644 --- a/src/main/java/net/helenus/core/reflect/HelenusNamedProperty.java +++ b/src/main/java/net/helenus/core/reflect/HelenusNamedProperty.java @@ -19,7 +19,9 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Optional; import java.util.function.Function; + import javax.validation.ConstraintValidator; + import net.helenus.core.SessionRepository; import net.helenus.mapping.*; import net.helenus.mapping.type.AbstractDataType; @@ -27,79 +29,79 @@ import net.helenus.support.HelenusMappingException; public final class HelenusNamedProperty implements HelenusProperty { - private final String name; + private final String name; - public HelenusNamedProperty(String name) { - this.name = name; - } + public HelenusNamedProperty(String name) { + this.name = name; + } - @Override - public HelenusEntity getEntity() { - throw new HelenusMappingException("will never called"); - } + @Override + public HelenusEntity getEntity() { + throw new HelenusMappingException("will never called"); + } - @Override - public String getPropertyName() { - return name; - } + @Override + public String getPropertyName() { + return name; + } - @Override - public Method getGetterMethod() { - throw new HelenusMappingException("will never called"); - } + @Override + public Method getGetterMethod() { + throw new HelenusMappingException("will never called"); + } - @Override - public IdentityName getColumnName() { - return IdentityName.of(name, false); - } + @Override + public IdentityName getColumnName() { + return IdentityName.of(name, false); + } - @Override - public Optional getIndexName() { - return Optional.empty(); - } + @Override + public Optional getIndexName() { + return Optional.empty(); + } - @Override - public boolean caseSensitiveIndex() { - return false; - } + @Override + public boolean caseSensitiveIndex() { + return false; + } - @Override - public Class getJavaType() { - throw new HelenusMappingException("will never called"); - } + @Override + public Class getJavaType() { + throw new HelenusMappingException("will never called"); + } - @Override - public AbstractDataType getDataType() { - throw new HelenusMappingException("will never called"); - } + @Override + public AbstractDataType getDataType() { + throw new HelenusMappingException("will never called"); + } - @Override - public ColumnType getColumnType() { - return ColumnType.COLUMN; - } + @Override + public ColumnType getColumnType() { + return ColumnType.COLUMN; + } - @Override - public int getOrdinal() { - return 0; - } + @Override + public int getOrdinal() { + return 0; + } - @Override - public OrderingDirection getOrdering() { - return OrderingDirection.ASC; - } + @Override + public OrderingDirection getOrdering() { + return OrderingDirection.ASC; + } - @Override - public Optional> getReadConverter(SessionRepository repository) { - return Optional.empty(); - } + @Override + public Optional> getReadConverter(SessionRepository repository) { + return Optional.empty(); + } - @Override - public Optional> getWriteConverter(SessionRepository repository) { - return Optional.empty(); - } + @Override + public Optional> getWriteConverter(SessionRepository repository) { + return Optional.empty(); + } - @Override - public ConstraintValidator[] getValidators() { - return MappingUtil.EMPTY_VALIDATORS; - } + @Override + public ConstraintValidator[] getValidators() { + return MappingUtil.EMPTY_VALIDATORS; + } } diff --git a/src/main/java/net/helenus/core/reflect/HelenusPropertyNode.java b/src/main/java/net/helenus/core/reflect/HelenusPropertyNode.java index b148433..0c28931 100644 --- a/src/main/java/net/helenus/core/reflect/HelenusPropertyNode.java +++ b/src/main/java/net/helenus/core/reflect/HelenusPropertyNode.java @@ -17,89 +17,90 @@ package net.helenus.core.reflect; import java.util.*; import java.util.stream.Collectors; + import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusProperty; public final class HelenusPropertyNode implements Iterable { - private final HelenusProperty prop; - private final Optional next; + private final HelenusProperty prop; + private final Optional next; - public HelenusPropertyNode(HelenusProperty prop, Optional next) { - this.prop = prop; - this.next = next; - } + public HelenusPropertyNode(HelenusProperty prop, Optional next) { + this.prop = prop; + this.next = next; + } - public String getColumnName() { - if (next.isPresent()) { + public String getColumnName() { + if (next.isPresent()) { - List columnNames = new ArrayList(); - for (HelenusProperty p : this) { - columnNames.add(p.getColumnName().toCql(true)); - } - Collections.reverse(columnNames); + List columnNames = new ArrayList(); + for (HelenusProperty p : this) { + columnNames.add(p.getColumnName().toCql(true)); + } + Collections.reverse(columnNames); - if (prop instanceof HelenusNamedProperty) { - int size = columnNames.size(); - StringBuilder str = new StringBuilder(); - for (int i = 0; i != size - 1; ++i) { - if (str.length() != 0) { - str.append("."); - } - str.append(columnNames.get(i)); - } - str.append("[").append(columnNames.get(size - 1)).append("]"); - return str.toString(); - } else { - return columnNames.stream().collect(Collectors.joining(".")); - } - } else { - return prop.getColumnName().toCql(); - } - } + if (prop instanceof HelenusNamedProperty) { + int size = columnNames.size(); + StringBuilder str = new StringBuilder(); + for (int i = 0; i != size - 1; ++i) { + if (str.length() != 0) { + str.append("."); + } + str.append(columnNames.get(i)); + } + str.append("[").append(columnNames.get(size - 1)).append("]"); + return str.toString(); + } else { + return columnNames.stream().collect(Collectors.joining(".")); + } + } else { + return prop.getColumnName().toCql(); + } + } - public HelenusEntity getEntity() { - if (next.isPresent()) { - HelenusProperty last = prop; - for (HelenusProperty p : this) { - last = p; - } - return last.getEntity(); - } else { - return prop.getEntity(); - } - } + public HelenusEntity getEntity() { + if (next.isPresent()) { + HelenusProperty last = prop; + for (HelenusProperty p : this) { + last = p; + } + return last.getEntity(); + } else { + return prop.getEntity(); + } + } - public HelenusProperty getProperty() { - return prop; - } + public HelenusProperty getProperty() { + return prop; + } - public Optional getNext() { - return next; - } + public Optional getNext() { + return next; + } - public Iterator iterator() { - return new PropertyNodeIterator(Optional.of(this)); - } + public Iterator iterator() { + return new PropertyNodeIterator(Optional.of(this)); + } - private static class PropertyNodeIterator implements Iterator { + private static class PropertyNodeIterator implements Iterator { - private Optional next; + private Optional next; - public PropertyNodeIterator(Optional next) { - this.next = next; - } + public PropertyNodeIterator(Optional next) { + this.next = next; + } - @Override - public boolean hasNext() { - return next.isPresent(); - } + @Override + public boolean hasNext() { + return next.isPresent(); + } - @Override - public HelenusProperty next() { - HelenusPropertyNode node = next.get(); - next = node.next; - return node.prop; - } - } + @Override + public HelenusProperty next() { + HelenusPropertyNode node = next.get(); + next = node.next; + return node.prop; + } + } } diff --git a/src/main/java/net/helenus/core/reflect/ListDsl.java b/src/main/java/net/helenus/core/reflect/ListDsl.java index b834098..3a8755f 100644 --- a/src/main/java/net/helenus/core/reflect/ListDsl.java +++ b/src/main/java/net/helenus/core/reflect/ListDsl.java @@ -16,164 +16,165 @@ package net.helenus.core.reflect; import java.util.*; + import net.helenus.mapping.HelenusProperty; import net.helenus.support.DslPropertyException; import net.helenus.support.HelenusMappingException; public final class ListDsl implements List { - private final HelenusPropertyNode parent; + private final HelenusPropertyNode parent; - public ListDsl(HelenusPropertyNode parent) { - this.parent = parent; - } + public ListDsl(HelenusPropertyNode parent) { + this.parent = parent; + } - public HelenusPropertyNode getParent() { - return parent; - } + public HelenusPropertyNode getParent() { + return parent; + } - @Override - public V get(int index) { - HelenusProperty prop = new HelenusNamedProperty(Integer.toString(index)); - throw new DslPropertyException(new HelenusPropertyNode(prop, Optional.of(parent))); - } + @Override + public V get(int index) { + HelenusProperty prop = new HelenusNamedProperty(Integer.toString(index)); + throw new DslPropertyException(new HelenusPropertyNode(prop, Optional.of(parent))); + } - @Override - public int size() { - throwShouldNeverCall(); - return 0; - } + @Override + public int size() { + throwShouldNeverCall(); + return 0; + } - @Override - public boolean isEmpty() { - throwShouldNeverCall(); - return false; - } + @Override + public boolean isEmpty() { + throwShouldNeverCall(); + return false; + } - @Override - public boolean contains(Object o) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean contains(Object o) { + throwShouldNeverCall(); + return false; + } - @Override - public Iterator iterator() { - throwShouldNeverCall(); - return null; - } + @Override + public Iterator iterator() { + throwShouldNeverCall(); + return null; + } - @Override - public Object[] toArray() { - throwShouldNeverCall(); - return null; - } + @Override + public Object[] toArray() { + throwShouldNeverCall(); + return null; + } - @Override - public T[] toArray(T[] a) { - throwShouldNeverCall(); - return null; - } + @Override + public T[] toArray(T[] a) { + throwShouldNeverCall(); + return null; + } - @Override - public boolean add(V e) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean add(V e) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean remove(Object o) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean remove(Object o) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean containsAll(Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean containsAll(Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean addAll(Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean addAll(Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean addAll(int index, Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean addAll(int index, Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean removeAll(Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean removeAll(Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean retainAll(Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean retainAll(Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public void clear() { - throwShouldNeverCall(); - } + @Override + public void clear() { + throwShouldNeverCall(); + } - @Override - public V set(int index, V element) { - throwShouldNeverCall(); - return null; - } + @Override + public V set(int index, V element) { + throwShouldNeverCall(); + return null; + } - @Override - public void add(int index, V element) { - throwShouldNeverCall(); - } + @Override + public void add(int index, V element) { + throwShouldNeverCall(); + } - @Override - public V remove(int index) { - throwShouldNeverCall(); - return null; - } + @Override + public V remove(int index) { + throwShouldNeverCall(); + return null; + } - @Override - public int indexOf(Object o) { - throwShouldNeverCall(); - return 0; - } + @Override + public int indexOf(Object o) { + throwShouldNeverCall(); + return 0; + } - @Override - public int lastIndexOf(Object o) { - throwShouldNeverCall(); - return 0; - } + @Override + public int lastIndexOf(Object o) { + throwShouldNeverCall(); + return 0; + } - @Override - public ListIterator listIterator() { - throwShouldNeverCall(); - return null; - } + @Override + public ListIterator listIterator() { + throwShouldNeverCall(); + return null; + } - @Override - public ListIterator listIterator(int index) { - throwShouldNeverCall(); - return null; - } + @Override + public ListIterator listIterator(int index) { + throwShouldNeverCall(); + return null; + } - @Override - public List subList(int fromIndex, int toIndex) { - throwShouldNeverCall(); - return null; - } + @Override + public List subList(int fromIndex, int toIndex) { + throwShouldNeverCall(); + return null; + } - private void throwShouldNeverCall() { - throw new HelenusMappingException("should be never called"); - } + private void throwShouldNeverCall() { + throw new HelenusMappingException("should be never called"); + } - @Override - public String toString() { - return "ListDsl"; - } + @Override + public String toString() { + return "ListDsl"; + } } diff --git a/src/main/java/net/helenus/core/reflect/MapDsl.java b/src/main/java/net/helenus/core/reflect/MapDsl.java index 7c1828d..c6d4cc6 100644 --- a/src/main/java/net/helenus/core/reflect/MapDsl.java +++ b/src/main/java/net/helenus/core/reflect/MapDsl.java @@ -19,98 +19,99 @@ import java.util.Collection; import java.util.Map; import java.util.Optional; import java.util.Set; + import net.helenus.mapping.HelenusProperty; import net.helenus.support.DslPropertyException; import net.helenus.support.HelenusMappingException; public final class MapDsl implements Map { - private final HelenusPropertyNode parent; + private final HelenusPropertyNode parent; - public MapDsl(HelenusPropertyNode parent) { - this.parent = parent; - } + public MapDsl(HelenusPropertyNode parent) { + this.parent = parent; + } - public HelenusPropertyNode getParent() { - return parent; - } + public HelenusPropertyNode getParent() { + return parent; + } - @Override - public V get(Object key) { - HelenusProperty prop = new HelenusNamedProperty(key.toString()); - throw new DslPropertyException(new HelenusPropertyNode(prop, Optional.of(parent))); - } + @Override + public V get(Object key) { + HelenusProperty prop = new HelenusNamedProperty(key.toString()); + throw new DslPropertyException(new HelenusPropertyNode(prop, Optional.of(parent))); + } - @Override - public int size() { - throwShouldNeverCall(); - return 0; - } + @Override + public int size() { + throwShouldNeverCall(); + return 0; + } - @Override - public boolean isEmpty() { - throwShouldNeverCall(); - return false; - } + @Override + public boolean isEmpty() { + throwShouldNeverCall(); + return false; + } - @Override - public boolean containsKey(Object key) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean containsKey(Object key) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean containsValue(Object value) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean containsValue(Object value) { + throwShouldNeverCall(); + return false; + } - @Override - public V put(K key, V value) { - throwShouldNeverCall(); - return null; - } + @Override + public V put(K key, V value) { + throwShouldNeverCall(); + return null; + } - @Override - public V remove(Object key) { - throwShouldNeverCall(); - return null; - } + @Override + public V remove(Object key) { + throwShouldNeverCall(); + return null; + } - @Override - public void putAll(Map m) { - throwShouldNeverCall(); - } + @Override + public void putAll(Map m) { + throwShouldNeverCall(); + } - @Override - public void clear() { - throwShouldNeverCall(); - } + @Override + public void clear() { + throwShouldNeverCall(); + } - @Override - public Set keySet() { - throwShouldNeverCall(); - return null; - } + @Override + public Set keySet() { + throwShouldNeverCall(); + return null; + } - @Override - public Collection values() { - throwShouldNeverCall(); - return null; - } + @Override + public Collection values() { + throwShouldNeverCall(); + return null; + } - @Override - public Set> entrySet() { - throwShouldNeverCall(); - return null; - } + @Override + public Set> entrySet() { + throwShouldNeverCall(); + return null; + } - private void throwShouldNeverCall() { - throw new HelenusMappingException("should be never called"); - } + private void throwShouldNeverCall() { + throw new HelenusMappingException("should be never called"); + } - @Override - public String toString() { - return "MapDsl"; - } + @Override + public String toString() { + return "MapDsl"; + } } diff --git a/src/main/java/net/helenus/core/reflect/MapExportable.java b/src/main/java/net/helenus/core/reflect/MapExportable.java index 9160cc8..2e71bdf 100644 --- a/src/main/java/net/helenus/core/reflect/MapExportable.java +++ b/src/main/java/net/helenus/core/reflect/MapExportable.java @@ -19,7 +19,7 @@ import java.util.Map; public interface MapExportable { - public static final String TO_MAP_METHOD = "toMap"; + public static final String TO_MAP_METHOD = "toMap"; - Map toMap(); + Map toMap(); } diff --git a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java index 105c2fc..e45b6f7 100644 --- a/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java +++ b/src/main/java/net/helenus/core/reflect/MapperInvocationHandler.java @@ -23,111 +23,113 @@ import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Collections; import java.util.Map; + import net.helenus.core.Helenus; import net.helenus.mapping.annotation.Transient; import net.helenus.support.HelenusException; public class MapperInvocationHandler implements InvocationHandler, Serializable { - private static final long serialVersionUID = -7044209982830584984L; + private static final long serialVersionUID = -7044209982830584984L; - private final Map src; - private final Class iface; + private final Map src; + private final Class iface; - public MapperInvocationHandler(Class iface, Map src) { - this.src = src; - this.iface = iface; - } + public MapperInvocationHandler(Class iface, Map src) { + this.src = src; + this.iface = iface; + } - private Object invokeDefault(Object proxy, Method method, Object[] args) throws Throwable { - // NOTE: This is reflection magic to invoke (non-recursively) a default method implemented on an interface - // that we've proxied (in ReflectionDslInstantiator). I found the answer in this article. - // https://zeroturnaround.com/rebellabs/recognize-and-conquer-java-proxies-default-methods-and-method-handles/ + private Object invokeDefault(Object proxy, Method method, Object[] args) throws Throwable { + // NOTE: This is reflection magic to invoke (non-recursively) a default method + // implemented on an interface + // that we've proxied (in ReflectionDslInstantiator). I found the answer in this + // article. + // https://zeroturnaround.com/rebellabs/recognize-and-conquer-java-proxies-default-methods-and-method-handles/ - // First, we need an instance of a private inner-class found in MethodHandles. - Constructor constructor = - MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class); - constructor.setAccessible(true); + // First, we need an instance of a private inner-class found in MethodHandles. + Constructor constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, + int.class); + constructor.setAccessible(true); - // Now we need to lookup and invoke special the default method on the interface class. - final Class declaringClass = method.getDeclaringClass(); - Object result = - constructor - .newInstance(declaringClass, MethodHandles.Lookup.PRIVATE) - .unreflectSpecial(method, declaringClass) - .bindTo(proxy) - .invokeWithArguments(args); - return result; - } + // Now we need to lookup and invoke special the default method on the interface + // class. + final Class declaringClass = method.getDeclaringClass(); + Object result = constructor.newInstance(declaringClass, MethodHandles.Lookup.PRIVATE) + .unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args); + return result; + } - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - // Transient, default methods should simply be invoked as-is. - if (method.isDefault() && method.getDeclaredAnnotation(Transient.class) != null) { - return invokeDefault(proxy, method, args); - } + // Transient, default methods should simply be invoked as-is. + if (method.isDefault() && method.getDeclaredAnnotation(Transient.class) != null) { + return invokeDefault(proxy, method, args); + } - String methodName = method.getName(); + String methodName = method.getName(); - if ("equals".equals(methodName) && method.getParameterCount() == 1) { - Object otherObj = args[0]; - if (otherObj == null) { - return false; - } - if (Proxy.isProxyClass(otherObj.getClass())) { - if (this == Proxy.getInvocationHandler(otherObj)) { - return true; - } - } - if (otherObj instanceof MapExportable && src.equals(((MapExportable) otherObj).toMap())) { - return true; - } - return false; - } + if ("equals".equals(methodName) && method.getParameterCount() == 1) { + Object otherObj = args[0]; + if (otherObj == null) { + return false; + } + if (Proxy.isProxyClass(otherObj.getClass())) { + if (this == Proxy.getInvocationHandler(otherObj)) { + return true; + } + } + if (otherObj instanceof MapExportable && src.equals(((MapExportable) otherObj).toMap())) { + return true; + } + return false; + } - if (method.getParameterCount() != 0 || method.getReturnType() == void.class) { - throw new HelenusException("invalid getter method " + method); - } + if (method.getParameterCount() != 0 || method.getReturnType() == void.class) { + throw new HelenusException("invalid getter method " + method); + } - if ("hashCode".equals(methodName)) { - return hashCode(); - } + if ("hashCode".equals(methodName)) { + return hashCode(); + } - if ("toString".equals(methodName)) { - return iface.getSimpleName() + ": " + src.toString(); - } + if ("toString".equals(methodName)) { + return iface.getSimpleName() + ": " + src.toString(); + } - if ("dsl".equals(methodName)) { - return Helenus.dsl(iface); - } + if ("dsl".equals(methodName)) { + return Helenus.dsl(iface); + } - if (MapExportable.TO_MAP_METHOD.equals(methodName)) { - return Collections.unmodifiableMap(src); - } + if (MapExportable.TO_MAP_METHOD.equals(methodName)) { + return Collections.unmodifiableMap(src); + } - Object value = src.get(methodName); + Object value = src.get(methodName); - Class returnType = method.getReturnType(); + Class returnType = method.getReturnType(); - if (value == null) { + if (value == null) { - // Default implementations of non-Transient methods in entities are the default value when the - // map contains 'null'. - if (method.isDefault()) { - return invokeDefault(proxy, method, args); - } + // Default implementations of non-Transient methods in entities are the default + // value when the + // map contains 'null'. + if (method.isDefault()) { + return invokeDefault(proxy, method, args); + } - // Otherwise, if the return type of the method is a primitive Java type then we'll return the standard - // default values to avoid a NPE in user code. - if (returnType.isPrimitive()) { - DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(returnType); - if (type == null) { - throw new HelenusException("unknown primitive type " + returnType); - } - return type.getDefaultValue(); - } - } + // Otherwise, if the return type of the method is a primitive Java type then + // we'll return the standard + // default values to avoid a NPE in user code. + if (returnType.isPrimitive()) { + DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(returnType); + if (type == null) { + throw new HelenusException("unknown primitive type " + returnType); + } + return type.getDefaultValue(); + } + } - return value; - } + return value; + } } diff --git a/src/main/java/net/helenus/core/reflect/ReflectionDslInstantiator.java b/src/main/java/net/helenus/core/reflect/ReflectionDslInstantiator.java index 7f1b218..7e30435 100644 --- a/src/main/java/net/helenus/core/reflect/ReflectionDslInstantiator.java +++ b/src/main/java/net/helenus/core/reflect/ReflectionDslInstantiator.java @@ -15,25 +15,22 @@ */ package net.helenus.core.reflect; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Proxy; import java.util.Optional; + +import com.datastax.driver.core.Metadata; + import net.helenus.core.DslInstantiator; public enum ReflectionDslInstantiator implements DslInstantiator { - INSTANCE; + INSTANCE; - @Override - @SuppressWarnings("unchecked") - public E instantiate( - Class iface, - ClassLoader classLoader, - Optional parent, - Metadata metadata) { - DslInvocationHandler handler = - new DslInvocationHandler(iface, classLoader, parent, metadata); - E proxy = - (E) Proxy.newProxyInstance(classLoader, new Class[] {iface, DslExportable.class}, handler); - return proxy; - } + @Override + @SuppressWarnings("unchecked") + public E instantiate(Class iface, ClassLoader classLoader, Optional parent, + Metadata metadata) { + DslInvocationHandler handler = new DslInvocationHandler(iface, classLoader, parent, metadata); + E proxy = (E) Proxy.newProxyInstance(classLoader, new Class[]{iface, DslExportable.class}, handler); + return proxy; + } } diff --git a/src/main/java/net/helenus/core/reflect/ReflectionInstantiator.java b/src/main/java/net/helenus/core/reflect/ReflectionInstantiator.java index c7e40f8..748d88a 100644 --- a/src/main/java/net/helenus/core/reflect/ReflectionInstantiator.java +++ b/src/main/java/net/helenus/core/reflect/ReflectionInstantiator.java @@ -19,14 +19,15 @@ import net.helenus.support.HelenusMappingException; public final class ReflectionInstantiator { - private ReflectionInstantiator() {} + private ReflectionInstantiator() { + } - public static T instantiateClass(Class clazz) { + public static T instantiateClass(Class clazz) { - try { - return clazz.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - throw new HelenusMappingException("invalid class " + clazz, e); - } - } + try { + return clazz.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new HelenusMappingException("invalid class " + clazz, e); + } + } } diff --git a/src/main/java/net/helenus/core/reflect/ReflectionMapperInstantiator.java b/src/main/java/net/helenus/core/reflect/ReflectionMapperInstantiator.java index a3df3f1..811a682 100644 --- a/src/main/java/net/helenus/core/reflect/ReflectionMapperInstantiator.java +++ b/src/main/java/net/helenus/core/reflect/ReflectionMapperInstantiator.java @@ -17,18 +17,18 @@ package net.helenus.core.reflect; import java.lang.reflect.Proxy; import java.util.Map; + import net.helenus.core.MapperInstantiator; public enum ReflectionMapperInstantiator implements MapperInstantiator { - INSTANCE; + INSTANCE; - @Override - @SuppressWarnings("unchecked") - public E instantiate(Class iface, Map src, ClassLoader classLoader) { + @Override + @SuppressWarnings("unchecked") + public E instantiate(Class iface, Map src, ClassLoader classLoader) { - MapperInvocationHandler handler = new MapperInvocationHandler(iface, src); - E proxy = - (E) Proxy.newProxyInstance(classLoader, new Class[] {iface, MapExportable.class}, handler); - return proxy; - } + MapperInvocationHandler handler = new MapperInvocationHandler(iface, src); + E proxy = (E) Proxy.newProxyInstance(classLoader, new Class[]{iface, MapExportable.class}, handler); + return proxy; + } } diff --git a/src/main/java/net/helenus/core/reflect/SetDsl.java b/src/main/java/net/helenus/core/reflect/SetDsl.java index 6a55118..663b945 100644 --- a/src/main/java/net/helenus/core/reflect/SetDsl.java +++ b/src/main/java/net/helenus/core/reflect/SetDsl.java @@ -18,103 +18,104 @@ package net.helenus.core.reflect; import java.util.Collection; import java.util.Iterator; import java.util.Set; + import net.helenus.support.HelenusMappingException; public final class SetDsl implements Set { - private final HelenusPropertyNode parent; + private final HelenusPropertyNode parent; - public SetDsl(HelenusPropertyNode parent) { - this.parent = parent; - } + public SetDsl(HelenusPropertyNode parent) { + this.parent = parent; + } - public HelenusPropertyNode getParent() { - return parent; - } + public HelenusPropertyNode getParent() { + return parent; + } - @Override - public int size() { - throwShouldNeverCall(); - return 0; - } + @Override + public int size() { + throwShouldNeverCall(); + return 0; + } - @Override - public boolean isEmpty() { - throwShouldNeverCall(); - return false; - } + @Override + public boolean isEmpty() { + throwShouldNeverCall(); + return false; + } - @Override - public boolean contains(Object o) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean contains(Object o) { + throwShouldNeverCall(); + return false; + } - @Override - public Iterator iterator() { - throwShouldNeverCall(); - return null; - } + @Override + public Iterator iterator() { + throwShouldNeverCall(); + return null; + } - @Override - public Object[] toArray() { - throwShouldNeverCall(); - return null; - } + @Override + public Object[] toArray() { + throwShouldNeverCall(); + return null; + } - @Override - public T[] toArray(T[] a) { - throwShouldNeverCall(); - return null; - } + @Override + public T[] toArray(T[] a) { + throwShouldNeverCall(); + return null; + } - @Override - public boolean add(V e) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean add(V e) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean remove(Object o) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean remove(Object o) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean containsAll(Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean containsAll(Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean addAll(Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean addAll(Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean retainAll(Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean retainAll(Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public boolean removeAll(Collection c) { - throwShouldNeverCall(); - return false; - } + @Override + public boolean removeAll(Collection c) { + throwShouldNeverCall(); + return false; + } - @Override - public void clear() { - throwShouldNeverCall(); - } + @Override + public void clear() { + throwShouldNeverCall(); + } - private void throwShouldNeverCall() { - throw new HelenusMappingException("should be never called"); - } + private void throwShouldNeverCall() { + throw new HelenusMappingException("should be never called"); + } - @Override - public String toString() { - return "SetDsl"; - } + @Override + public String toString() { + return "SetDsl"; + } } diff --git a/src/main/java/net/helenus/mapping/ColumnInformation.java b/src/main/java/net/helenus/mapping/ColumnInformation.java index fa6d25f..5ba9ddd 100644 --- a/src/main/java/net/helenus/mapping/ColumnInformation.java +++ b/src/main/java/net/helenus/mapping/ColumnInformation.java @@ -16,6 +16,7 @@ package net.helenus.mapping; import java.lang.reflect.Method; + import net.helenus.mapping.annotation.ClusteringColumn; import net.helenus.mapping.annotation.Column; import net.helenus.mapping.annotation.PartitionKey; @@ -24,99 +25,91 @@ import net.helenus.support.HelenusMappingException; public final class ColumnInformation { - private final IdentityName columnName; - private final ColumnType columnType; - private final int ordinal; - private final OrderingDirection ordering; + private final IdentityName columnName; + private final ColumnType columnType; + private final int ordinal; + private final OrderingDirection ordering; - public ColumnInformation(Method getter) { + public ColumnInformation(Method getter) { - String columnName = null; - boolean forceQuote = false; - ColumnType columnTypeLocal = ColumnType.COLUMN; - int ordinalLocal = 0; - OrderingDirection orderingLocal = OrderingDirection.ASC; + String columnName = null; + boolean forceQuote = false; + ColumnType columnTypeLocal = ColumnType.COLUMN; + int ordinalLocal = 0; + OrderingDirection orderingLocal = OrderingDirection.ASC; - PartitionKey partitionKey = getter.getDeclaredAnnotation(PartitionKey.class); - if (partitionKey != null) { - columnName = partitionKey.value(); - forceQuote = partitionKey.forceQuote(); - columnTypeLocal = ColumnType.PARTITION_KEY; - ordinalLocal = partitionKey.ordinal(); - } + PartitionKey partitionKey = getter.getDeclaredAnnotation(PartitionKey.class); + if (partitionKey != null) { + columnName = partitionKey.value(); + forceQuote = partitionKey.forceQuote(); + columnTypeLocal = ColumnType.PARTITION_KEY; + ordinalLocal = partitionKey.ordinal(); + } - ClusteringColumn clusteringColumn = getter.getDeclaredAnnotation(ClusteringColumn.class); - if (clusteringColumn != null) { - ensureSingleColumnType(columnTypeLocal, getter); - columnName = clusteringColumn.value(); - forceQuote = clusteringColumn.forceQuote(); - columnTypeLocal = ColumnType.CLUSTERING_COLUMN; - ordinalLocal = clusteringColumn.ordinal(); - orderingLocal = clusteringColumn.ordering(); - } + ClusteringColumn clusteringColumn = getter.getDeclaredAnnotation(ClusteringColumn.class); + if (clusteringColumn != null) { + ensureSingleColumnType(columnTypeLocal, getter); + columnName = clusteringColumn.value(); + forceQuote = clusteringColumn.forceQuote(); + columnTypeLocal = ColumnType.CLUSTERING_COLUMN; + ordinalLocal = clusteringColumn.ordinal(); + orderingLocal = clusteringColumn.ordering(); + } - StaticColumn staticColumn = getter.getDeclaredAnnotation(StaticColumn.class); - if (staticColumn != null) { - ensureSingleColumnType(columnTypeLocal, getter); - columnName = staticColumn.value(); - forceQuote = staticColumn.forceQuote(); - columnTypeLocal = ColumnType.STATIC_COLUMN; - ordinalLocal = staticColumn.ordinal(); - } + StaticColumn staticColumn = getter.getDeclaredAnnotation(StaticColumn.class); + if (staticColumn != null) { + ensureSingleColumnType(columnTypeLocal, getter); + columnName = staticColumn.value(); + forceQuote = staticColumn.forceQuote(); + columnTypeLocal = ColumnType.STATIC_COLUMN; + ordinalLocal = staticColumn.ordinal(); + } - Column column = getter.getDeclaredAnnotation(Column.class); - if (column != null) { - ensureSingleColumnType(columnTypeLocal, getter); - columnName = column.value(); - forceQuote = column.forceQuote(); - columnTypeLocal = ColumnType.COLUMN; - ordinalLocal = column.ordinal(); - } + Column column = getter.getDeclaredAnnotation(Column.class); + if (column != null) { + ensureSingleColumnType(columnTypeLocal, getter); + columnName = column.value(); + forceQuote = column.forceQuote(); + columnTypeLocal = ColumnType.COLUMN; + ordinalLocal = column.ordinal(); + } - if (columnName == null || columnName.isEmpty()) { - columnName = MappingUtil.getDefaultColumnName(getter); - } + if (columnName == null || columnName.isEmpty()) { + columnName = MappingUtil.getDefaultColumnName(getter); + } - this.columnName = new IdentityName(columnName, forceQuote); - this.columnType = columnTypeLocal; - this.ordinal = ordinalLocal; - this.ordering = orderingLocal; - } + this.columnName = new IdentityName(columnName, forceQuote); + this.columnType = columnTypeLocal; + this.ordinal = ordinalLocal; + this.ordering = orderingLocal; + } - public IdentityName getColumnName() { - return columnName; - } + public IdentityName getColumnName() { + return columnName; + } - public ColumnType getColumnType() { - return columnType; - } + public ColumnType getColumnType() { + return columnType; + } - public int getOrdinal() { - return ordinal; - } + public int getOrdinal() { + return ordinal; + } - public OrderingDirection getOrdering() { - return ordering; - } + public OrderingDirection getOrdering() { + return ordering; + } - private void ensureSingleColumnType(ColumnType columnTypeLocal, Method getter) { + private void ensureSingleColumnType(ColumnType columnTypeLocal, Method getter) { - if (columnTypeLocal != ColumnType.COLUMN) { - throw new HelenusMappingException( - "property can be annotated only by a single column type " + getter); - } - } + if (columnTypeLocal != ColumnType.COLUMN) { + throw new HelenusMappingException("property can be annotated only by a single column type " + getter); + } + } - @Override - public String toString() { - return "ColumnInformation [columnName=" - + columnName - + ", columnType=" - + columnType - + ", ordinal=" - + ordinal - + ", ordering=" - + ordering - + "]"; - } + @Override + public String toString() { + return "ColumnInformation [columnName=" + columnName + ", columnType=" + columnType + ", ordinal=" + ordinal + + ", ordering=" + ordering + "]"; + } } diff --git a/src/main/java/net/helenus/mapping/ColumnType.java b/src/main/java/net/helenus/mapping/ColumnType.java index eb8407d..e56b079 100644 --- a/src/main/java/net/helenus/mapping/ColumnType.java +++ b/src/main/java/net/helenus/mapping/ColumnType.java @@ -16,8 +16,5 @@ package net.helenus.mapping; public enum ColumnType { - PARTITION_KEY, - CLUSTERING_COLUMN, - STATIC_COLUMN, - COLUMN; + PARTITION_KEY, CLUSTERING_COLUMN, STATIC_COLUMN, COLUMN; } diff --git a/src/main/java/net/helenus/mapping/HelenusEntity.java b/src/main/java/net/helenus/mapping/HelenusEntity.java index 681d8d1..0f6b8f6 100644 --- a/src/main/java/net/helenus/mapping/HelenusEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusEntity.java @@ -17,21 +17,22 @@ package net.helenus.mapping; import java.util.Collection; import java.util.Map; + import net.helenus.core.cache.EntityIdentifyingFacet; public interface HelenusEntity { - HelenusEntityType getType(); + HelenusEntityType getType(); - boolean isCacheable(); + boolean isCacheable(); - Class getMappingInterface(); + Class getMappingInterface(); - IdentityName getName(); + IdentityName getName(); - Collection getOrderedProperties(); + Collection getOrderedProperties(); - HelenusProperty getProperty(String name); + HelenusProperty getProperty(String name); - Map getIdentifyingFacets(); + Map getIdentifyingFacets(); } diff --git a/src/main/java/net/helenus/mapping/HelenusEntityType.java b/src/main/java/net/helenus/mapping/HelenusEntityType.java index 2ef8d63..0924ec7 100644 --- a/src/main/java/net/helenus/mapping/HelenusEntityType.java +++ b/src/main/java/net/helenus/mapping/HelenusEntityType.java @@ -16,8 +16,5 @@ package net.helenus.mapping; public enum HelenusEntityType { - TABLE, - VIEW, - TUPLE, - UDT; + TABLE, VIEW, TUPLE, UDT; } diff --git a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java index f510a34..509cac2 100644 --- a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java @@ -15,315 +15,296 @@ */ package net.helenus.mapping; -import com.datastax.driver.core.*; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import java.lang.reflect.Method; import java.util.*; + +import org.apache.commons.lang3.ClassUtils; + +import com.datastax.driver.core.DefaultMetadata; +import com.datastax.driver.core.Metadata; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + import net.helenus.config.HelenusSettings; import net.helenus.core.Helenus; import net.helenus.core.annotation.Cacheable; import net.helenus.core.cache.EntityIdentifyingFacet; import net.helenus.mapping.annotation.*; import net.helenus.support.HelenusMappingException; -import org.apache.commons.lang3.ClassUtils; public final class HelenusMappingEntity implements HelenusEntity { - private final Class iface; - private final HelenusEntityType type; - private final IdentityName name; - private final boolean cacheable; - private final ImmutableMap methods; - private final ImmutableMap props; - private final ImmutableList orderedProps; - private final EntityIdentifyingFacet primaryIdentityFacet; - private final ImmutableMap allIdentityFacets; - private final ImmutableMap ancillaryIdentityFacets; + private final Class iface; + private final HelenusEntityType type; + private final IdentityName name; + private final boolean cacheable; + private final ImmutableMap methods; + private final ImmutableMap props; + private final ImmutableList orderedProps; + private final EntityIdentifyingFacet primaryIdentityFacet; + private final ImmutableMap allIdentityFacets; + private final ImmutableMap ancillaryIdentityFacets; - public HelenusMappingEntity(Class iface, Metadata metadata) { - this(iface, autoDetectType(iface), metadata); - } + public HelenusMappingEntity(Class iface, Metadata metadata) { + this(iface, autoDetectType(iface), metadata); + } - public HelenusMappingEntity(Class iface, HelenusEntityType type, Metadata metadata) { + public HelenusMappingEntity(Class iface, HelenusEntityType type, Metadata metadata) { - if (iface == null || !iface.isInterface()) { - throw new IllegalArgumentException("invalid parameter " + iface); - } + if (iface == null || !iface.isInterface()) { + throw new IllegalArgumentException("invalid parameter " + iface); + } - this.iface = iface; - this.type = Objects.requireNonNull(type, "type is empty"); - this.name = resolveName(iface, type); + this.iface = iface; + this.type = Objects.requireNonNull(type, "type is empty"); + this.name = resolveName(iface, type); - HelenusSettings settings = Helenus.settings(); + HelenusSettings settings = Helenus.settings(); - Map methods = new HashMap(); - for (Method m : iface.getDeclaredMethods()) { - methods.put(m.getName(), m); - } + Map methods = new HashMap(); + for (Method m : iface.getDeclaredMethods()) { + methods.put(m.getName(), m); + } - for (Class c : ClassUtils.getAllInterfaces(iface)) { - if (c.getDeclaredAnnotation(Table.class) != null - || c.getDeclaredAnnotation(InheritedTable.class) != null) { - for (Method m : c.getDeclaredMethods()) { - Method o = methods.get(m.getName()); - if (o != null) { - // Prefer overridden method implementation. - if (o.getDeclaringClass().isAssignableFrom(m.getDeclaringClass())) { - methods.put(m.getName(), m); - } - } else { - methods.put(m.getName(), m); - } - } - } - } + for (Class c : ClassUtils.getAllInterfaces(iface)) { + if (c.getDeclaredAnnotation(Table.class) != null || c.getDeclaredAnnotation(InheritedTable.class) != null) { + for (Method m : c.getDeclaredMethods()) { + Method o = methods.get(m.getName()); + if (o != null) { + // Prefer overridden method implementation. + if (o.getDeclaringClass().isAssignableFrom(m.getDeclaringClass())) { + methods.put(m.getName(), m); + } + } else { + methods.put(m.getName(), m); + } + } + } + } - List propsLocal = new ArrayList(); - ImmutableMap.Builder propsBuilder = ImmutableMap.builder(); - ImmutableMap.Builder methodsBuilder = ImmutableMap.builder(); + List propsLocal = new ArrayList(); + ImmutableMap.Builder propsBuilder = ImmutableMap.builder(); + ImmutableMap.Builder methodsBuilder = ImmutableMap.builder(); - for (Method method : methods.values()) { + for (Method method : methods.values()) { - if (settings.getGetterMethodDetector().apply(method)) { + if (settings.getGetterMethodDetector().apply(method)) { - methodsBuilder.put(method.getName(), method); + methodsBuilder.put(method.getName(), method); - if (metadata != null) { - HelenusProperty prop = new HelenusMappingProperty(this, method, metadata); + if (metadata != null) { + HelenusProperty prop = new HelenusMappingProperty(this, method, metadata); - propsBuilder.put(prop.getPropertyName(), prop); - propsLocal.add(prop); - } - } - } + propsBuilder.put(prop.getPropertyName(), prop); + propsLocal.add(prop); + } + } + } - this.methods = methodsBuilder.build(); - this.props = propsBuilder.build(); + this.methods = methodsBuilder.build(); + this.props = propsBuilder.build(); - Collections.sort(propsLocal, TypeAndOrdinalColumnComparator.INSTANCE); - this.orderedProps = ImmutableList.copyOf(propsLocal); + Collections.sort(propsLocal, TypeAndOrdinalColumnComparator.INSTANCE); + this.orderedProps = ImmutableList.copyOf(propsLocal); - validateOrdinals(); + validateOrdinals(); - // Caching - cacheable = (null != iface.getDeclaredAnnotation(Cacheable.class)); + // Caching + cacheable = (null != iface.getDeclaredAnnotation(Cacheable.class)); - ImmutableMap.Builder allFacetsBuilder = ImmutableMap.builder(); - ImmutableMap.Builder ancillaryFacetsBuilder = - ImmutableMap.builder(); - EntityIdentifyingFacet primaryFacet = null; - List primaryProperties = new ArrayList(4); - for (HelenusProperty prop : propsLocal) { - switch (prop.getColumnType()) { - case PARTITION_KEY: - case CLUSTERING_COLUMN: - primaryProperties.add(prop); - break; - default: - if (primaryProperties != null) { - primaryFacet = - new EntityIdentifyingFacet(new HashSet(primaryProperties)); - allFacetsBuilder.put("*", primaryFacet); - primaryProperties = null; - } - Optional optionalIndexName = prop.getIndexName(); - if (optionalIndexName.isPresent()) { - EntityIdentifyingFacet facet = new EntityIdentifyingFacet(prop); - ancillaryFacetsBuilder.put(prop.getPropertyName(), facet); - allFacetsBuilder.put(prop.getPropertyName(), facet); - } - } - } - this.primaryIdentityFacet = primaryFacet; - this.ancillaryIdentityFacets = ancillaryFacetsBuilder.build(); - this.allIdentityFacets = allFacetsBuilder.build(); - } + ImmutableMap.Builder allFacetsBuilder = ImmutableMap.builder(); + ImmutableMap.Builder ancillaryFacetsBuilder = ImmutableMap.builder(); + EntityIdentifyingFacet primaryFacet = null; + List primaryProperties = new ArrayList(4); + for (HelenusProperty prop : propsLocal) { + switch (prop.getColumnType()) { + case PARTITION_KEY : + case CLUSTERING_COLUMN : + primaryProperties.add(prop); + break; + default : + if (primaryProperties != null) { + primaryFacet = new EntityIdentifyingFacet(new HashSet(primaryProperties)); + allFacetsBuilder.put("*", primaryFacet); + primaryProperties = null; + } + Optional optionalIndexName = prop.getIndexName(); + if (optionalIndexName.isPresent()) { + EntityIdentifyingFacet facet = new EntityIdentifyingFacet(prop); + ancillaryFacetsBuilder.put(prop.getPropertyName(), facet); + allFacetsBuilder.put(prop.getPropertyName(), facet); + } + } + } + this.primaryIdentityFacet = primaryFacet; + this.ancillaryIdentityFacets = ancillaryFacetsBuilder.build(); + this.allIdentityFacets = allFacetsBuilder.build(); + } - @Override - public HelenusEntityType getType() { - return type; - } + @Override + public HelenusEntityType getType() { + return type; + } - @Override - public boolean isCacheable() { - return cacheable; - } + @Override + public boolean isCacheable() { + return cacheable; + } - @Override - public Class getMappingInterface() { - return iface; - } + @Override + public Class getMappingInterface() { + return iface; + } - @Override - public Collection getOrderedProperties() { - return orderedProps; - } + @Override + public Collection getOrderedProperties() { + return orderedProps; + } - @Override - public HelenusProperty getProperty(String name) { - HelenusProperty property = props.get(name); - if (property == null && methods.containsKey(name)) { - property = new HelenusMappingProperty(this, methods.get(name), new DefaultMetadata()); - return property; //TODO(gburd): review adding these into the props map... - } - return props.get(name); - } + @Override + public HelenusProperty getProperty(String name) { + HelenusProperty property = props.get(name); + if (property == null && methods.containsKey(name)) { + property = new HelenusMappingProperty(this, methods.get(name), new DefaultMetadata()); + return property; // TODO(gburd): review adding these into the props map... + } + return props.get(name); + } - @Override - public Map getIdentifyingFacets() { - return allIdentityFacets; - } + @Override + public Map getIdentifyingFacets() { + return allIdentityFacets; + } - @Override - public IdentityName getName() { - return name; - } + @Override + public IdentityName getName() { + return name; + } - private static IdentityName resolveName(Class iface, HelenusEntityType type) { + private static IdentityName resolveName(Class iface, HelenusEntityType type) { - switch (type) { - case TABLE: - return MappingUtil.getTableName(iface, true); + switch (type) { + case TABLE : + return MappingUtil.getTableName(iface, true); - case VIEW: - return MappingUtil.getViewName(iface, true); + case VIEW : + return MappingUtil.getViewName(iface, true); - case TUPLE: - return IdentityName.of(MappingUtil.getDefaultEntityName(iface), false); + case TUPLE : + return IdentityName.of(MappingUtil.getDefaultEntityName(iface), false); - case UDT: - return MappingUtil.getUserDefinedTypeName(iface, true); - } + case UDT : + return MappingUtil.getUserDefinedTypeName(iface, true); + } - throw new HelenusMappingException("invalid entity type " + type + " in " + type); - } + throw new HelenusMappingException("invalid entity type " + type + " in " + type); + } - private static HelenusEntityType autoDetectType(Class iface) { + private static HelenusEntityType autoDetectType(Class iface) { - Objects.requireNonNull(iface, "empty iface"); + Objects.requireNonNull(iface, "empty iface"); - if (null != iface.getDeclaredAnnotation(Table.class)) { - return HelenusEntityType.TABLE; - } else if (null != iface.getDeclaredAnnotation(MaterializedView.class)) { - return HelenusEntityType.VIEW; - } else if (null != iface.getDeclaredAnnotation(Tuple.class)) { - return HelenusEntityType.TUPLE; - } else if (null != iface.getDeclaredAnnotation(UDT.class)) { - return HelenusEntityType.UDT; - } + if (null != iface.getDeclaredAnnotation(Table.class)) { + return HelenusEntityType.TABLE; + } else if (null != iface.getDeclaredAnnotation(MaterializedView.class)) { + return HelenusEntityType.VIEW; + } else if (null != iface.getDeclaredAnnotation(Tuple.class)) { + return HelenusEntityType.TUPLE; + } else if (null != iface.getDeclaredAnnotation(UDT.class)) { + return HelenusEntityType.UDT; + } - throw new HelenusMappingException( - "entity must be annotated by @Table or @Tuple or @UserDefinedType " + iface); - } + throw new HelenusMappingException("entity must be annotated by @Table or @Tuple or @UserDefinedType " + iface); + } - private void validateOrdinals() { + private void validateOrdinals() { - switch (getType()) { - case TABLE: - validateOrdinalsForTable(); - break; + switch (getType()) { + case TABLE : + validateOrdinalsForTable(); + break; - case TUPLE: - validateOrdinalsInTuple(); - break; + case TUPLE : + validateOrdinalsInTuple(); + break; - default: - break; - } - } + default : + break; + } + } - private void validateOrdinalsForTable() { + private void validateOrdinalsForTable() { - BitSet partitionKeys = new BitSet(); - BitSet clusteringColumns = new BitSet(); + BitSet partitionKeys = new BitSet(); + BitSet clusteringColumns = new BitSet(); - for (HelenusProperty prop : getOrderedProperties()) { + for (HelenusProperty prop : getOrderedProperties()) { - ColumnType type = prop.getColumnType(); + ColumnType type = prop.getColumnType(); - int ordinal = prop.getOrdinal(); + int ordinal = prop.getOrdinal(); - switch (type) { - case PARTITION_KEY: - if (partitionKeys.get(ordinal)) { - throw new HelenusMappingException( - "detected two or more partition key columns with the same ordinal " - + ordinal - + " in " - + prop.getEntity()); - } - partitionKeys.set(ordinal); - break; + switch (type) { + case PARTITION_KEY : + if (partitionKeys.get(ordinal)) { + throw new HelenusMappingException( + "detected two or more partition key columns with the same ordinal " + ordinal + " in " + + prop.getEntity()); + } + partitionKeys.set(ordinal); + break; - case CLUSTERING_COLUMN: - if (clusteringColumns.get(ordinal)) { - throw new HelenusMappingException( - "detected two or clustering columns with the same ordinal " - + ordinal - + " in " - + prop.getEntity()); - } - clusteringColumns.set(ordinal); - break; + case CLUSTERING_COLUMN : + if (clusteringColumns.get(ordinal)) { + throw new HelenusMappingException("detected two or clustering columns with the same ordinal " + + ordinal + " in " + prop.getEntity()); + } + clusteringColumns.set(ordinal); + break; - default: - break; - } - } - } + default : + break; + } + } + } - private void validateOrdinalsInTuple() { - boolean[] ordinals = new boolean[props.size()]; + private void validateOrdinalsInTuple() { + boolean[] ordinals = new boolean[props.size()]; - getOrderedProperties() - .forEach( - p -> { - int ordinal = p.getOrdinal(); + getOrderedProperties().forEach(p -> { + int ordinal = p.getOrdinal(); - if (ordinal < 0 || ordinal >= ordinals.length) { - throw new HelenusMappingException( - "invalid ordinal " - + ordinal - + " found for property " - + p.getPropertyName() - + " in " - + p.getEntity()); - } + if (ordinal < 0 || ordinal >= ordinals.length) { + throw new HelenusMappingException("invalid ordinal " + ordinal + " found for property " + + p.getPropertyName() + " in " + p.getEntity()); + } - if (ordinals[ordinal]) { - throw new HelenusMappingException( - "detected two or more properties with the same ordinal " - + ordinal - + " in " - + p.getEntity()); - } + if (ordinals[ordinal]) { + throw new HelenusMappingException( + "detected two or more properties with the same ordinal " + ordinal + " in " + p.getEntity()); + } - ordinals[ordinal] = true; - }); + ordinals[ordinal] = true; + }); - for (int i = 0; i != ordinals.length; ++i) { - if (!ordinals[i]) { - throw new HelenusMappingException("detected absent ordinal " + i + " in " + this); - } - } - } + for (int i = 0; i != ordinals.length; ++i) { + if (!ordinals[i]) { + throw new HelenusMappingException("detected absent ordinal " + i + " in " + this); + } + } + } - @Override - public String toString() { + @Override + public String toString() { - StringBuilder str = new StringBuilder(); - str.append(iface.getSimpleName()) - .append("(") - .append(name.getName()) - .append(") ") - .append(type.name().toLowerCase()) - .append(":\n"); + StringBuilder str = new StringBuilder(); + str.append(iface.getSimpleName()).append("(").append(name.getName()).append(") ") + .append(type.name().toLowerCase()).append(":\n"); - for (HelenusProperty prop : getOrderedProperties()) { - str.append(prop.toString()); - str.append("\n"); - } - return str.toString(); - } + for (HelenusProperty prop : getOrderedProperties()) { + str.append(prop.toString()); + str.append("\n"); + } + return str.toString(); + } } diff --git a/src/main/java/net/helenus/mapping/HelenusMappingProperty.java b/src/main/java/net/helenus/mapping/HelenusMappingProperty.java index b7927f2..9c54d25 100644 --- a/src/main/java/net/helenus/mapping/HelenusMappingProperty.java +++ b/src/main/java/net/helenus/mapping/HelenusMappingProperty.java @@ -15,13 +15,16 @@ */ package net.helenus.mapping; -import com.datastax.driver.core.Metadata; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Optional; import java.util.function.Function; + import javax.validation.ConstraintValidator; + +import com.datastax.driver.core.Metadata; + import net.helenus.core.SessionRepository; import net.helenus.mapping.javatype.AbstractJavaType; import net.helenus.mapping.javatype.MappingJavaTypes; @@ -29,174 +32,173 @@ import net.helenus.mapping.type.AbstractDataType; public final class HelenusMappingProperty implements HelenusProperty { - private final HelenusEntity entity; - private final Method getter; + private final HelenusEntity entity; + private final Method getter; - private final String propertyName; - private final Optional indexName; - private final boolean caseSensitiveIndex; + private final String propertyName; + private final Optional indexName; + private final boolean caseSensitiveIndex; - private final ColumnInformation columnInfo; + private final ColumnInformation columnInfo; - private final Type genericJavaType; - private final Class javaType; - private final AbstractJavaType abstractJavaType; - private final AbstractDataType dataType; + private final Type genericJavaType; + private final Class javaType; + private final AbstractJavaType abstractJavaType; + private final AbstractDataType dataType; - private volatile Optional> readConverter = null; - private volatile Optional> writeConverter = null; + private volatile Optional> readConverter = null; + private volatile Optional> writeConverter = null; - private final ConstraintValidator[] validators; + private final ConstraintValidator[] validators; - public HelenusMappingProperty(HelenusMappingEntity entity, Method getter, Metadata metadata) { - this.entity = entity; - this.getter = getter; + public HelenusMappingProperty(HelenusMappingEntity entity, Method getter, Metadata metadata) { + this.entity = entity; + this.getter = getter; - this.propertyName = MappingUtil.getPropertyName(getter); - this.indexName = MappingUtil.getIndexName(getter); - this.caseSensitiveIndex = MappingUtil.caseSensitiveIndex(getter); + this.propertyName = MappingUtil.getPropertyName(getter); + this.indexName = MappingUtil.getIndexName(getter); + this.caseSensitiveIndex = MappingUtil.caseSensitiveIndex(getter); - this.columnInfo = new ColumnInformation(getter); + this.columnInfo = new ColumnInformation(getter); - this.genericJavaType = getter.getGenericReturnType(); - this.javaType = getter.getReturnType(); - this.abstractJavaType = MappingJavaTypes.resolveJavaType(this.javaType); + this.genericJavaType = getter.getGenericReturnType(); + this.javaType = getter.getReturnType(); + this.abstractJavaType = MappingJavaTypes.resolveJavaType(this.javaType); - this.dataType = - abstractJavaType.resolveDataType( - this.getter, this.genericJavaType, this.columnInfo.getColumnType(), metadata); + this.dataType = abstractJavaType.resolveDataType(this.getter, this.genericJavaType, + this.columnInfo.getColumnType(), metadata); - this.validators = MappingUtil.getValidators(getter); - } + this.validators = MappingUtil.getValidators(getter); + } - @Override - public HelenusEntity getEntity() { - return entity; - } + @Override + public HelenusEntity getEntity() { + return entity; + } - @Override - public Class getJavaType() { - return (Class) javaType; - } + @Override + public Class getJavaType() { + return (Class) javaType; + } - @Override - public AbstractDataType getDataType() { - return dataType; - } + @Override + public AbstractDataType getDataType() { + return dataType; + } - @Override - public ColumnType getColumnType() { - return columnInfo.getColumnType(); - } + @Override + public ColumnType getColumnType() { + return columnInfo.getColumnType(); + } - @Override - public int getOrdinal() { - return columnInfo.getOrdinal(); - } + @Override + public int getOrdinal() { + return columnInfo.getOrdinal(); + } - @Override - public OrderingDirection getOrdering() { - return columnInfo.getOrdering(); - } + @Override + public OrderingDirection getOrdering() { + return columnInfo.getOrdering(); + } - @Override - public IdentityName getColumnName() { - return columnInfo.getColumnName(); - } + @Override + public IdentityName getColumnName() { + return columnInfo.getColumnName(); + } - @Override - public Optional getIndexName() { - return indexName; - } + @Override + public Optional getIndexName() { + return indexName; + } - @Override - public boolean caseSensitiveIndex() { - return caseSensitiveIndex; - } + @Override + public boolean caseSensitiveIndex() { + return caseSensitiveIndex; + } - @Override - public String getPropertyName() { - return propertyName; - } + @Override + public String getPropertyName() { + return propertyName; + } - @Override - public Method getGetterMethod() { - return getter; - } + @Override + public Method getGetterMethod() { + return getter; + } - @Override - public Optional> getReadConverter(SessionRepository repository) { + @Override + public Optional> getReadConverter(SessionRepository repository) { - if (readConverter == null) { - readConverter = abstractJavaType.resolveReadConverter(this.dataType, repository); - } + if (readConverter == null) { + readConverter = abstractJavaType.resolveReadConverter(this.dataType, repository); + } - return readConverter; - } + return readConverter; + } - @Override - public Optional> getWriteConverter(SessionRepository repository) { + @Override + public Optional> getWriteConverter(SessionRepository repository) { - if (writeConverter == null) { - writeConverter = abstractJavaType.resolveWriteConverter(this.dataType, repository); - } + if (writeConverter == null) { + writeConverter = abstractJavaType.resolveWriteConverter(this.dataType, repository); + } - return writeConverter; - } + return writeConverter; + } - @Override - public ConstraintValidator[] getValidators() { - return validators; - } + @Override + public ConstraintValidator[] getValidators() { + return validators; + } - @Override - public String toString() { + @Override + public String toString() { - StringBuilder str = new StringBuilder(); + StringBuilder str = new StringBuilder(); - String columnName = this.getColumnName().getName(); - str.append(" "); - str.append(this.getDataType()); - str.append(" "); - str.append(this.getPropertyName()); - str.append("("); - if (!columnName.equals(this.getPropertyName())) { - str.append(columnName); - } - str.append(") "); + String columnName = this.getColumnName().getName(); + str.append(" "); + str.append(this.getDataType()); + str.append(" "); + str.append(this.getPropertyName()); + str.append("("); + if (!columnName.equals(this.getPropertyName())) { + str.append(columnName); + } + str.append(") "); - ColumnType type = this.getColumnType(); + ColumnType type = this.getColumnType(); - switch (type) { - case PARTITION_KEY: - str.append("partition_key["); - str.append(this.getOrdinal()); - str.append("] "); - break; + switch (type) { + case PARTITION_KEY : + str.append("partition_key["); + str.append(this.getOrdinal()); + str.append("] "); + break; - case CLUSTERING_COLUMN: - str.append("clustering_column["); - str.append(this.getOrdinal()); - str.append("] "); - OrderingDirection od = this.getOrdering(); - if (od != null) { - str.append(od.name().toLowerCase()).append(" "); - } - break; + case CLUSTERING_COLUMN : + str.append("clustering_column["); + str.append(this.getOrdinal()); + str.append("] "); + OrderingDirection od = this.getOrdering(); + if (od != null) { + str.append(od.name().toLowerCase()).append(" "); + } + break; - case STATIC_COLUMN: - str.append("static "); - break; + case STATIC_COLUMN : + str.append("static "); + break; - case COLUMN: - break; - } + case COLUMN : + break; + } - Optional idx = this.getIndexName(); - if (idx.isPresent()) { - str.append("index(").append(idx.get().getName()).append(") "); - } + Optional idx = this.getIndexName(); + if (idx.isPresent()) { + str.append("index(").append(idx.get().getName()).append(") "); + } - return str.toString(); - } + return str.toString(); + } } diff --git a/src/main/java/net/helenus/mapping/HelenusProperty.java b/src/main/java/net/helenus/mapping/HelenusProperty.java index 08b428e..fecc550 100644 --- a/src/main/java/net/helenus/mapping/HelenusProperty.java +++ b/src/main/java/net/helenus/mapping/HelenusProperty.java @@ -19,37 +19,39 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Optional; import java.util.function.Function; + import javax.validation.ConstraintValidator; + import net.helenus.core.SessionRepository; import net.helenus.mapping.type.AbstractDataType; public interface HelenusProperty { - HelenusEntity getEntity(); + HelenusEntity getEntity(); - String getPropertyName(); + String getPropertyName(); - Method getGetterMethod(); + Method getGetterMethod(); - IdentityName getColumnName(); + IdentityName getColumnName(); - Optional getIndexName(); + Optional getIndexName(); - boolean caseSensitiveIndex(); + boolean caseSensitiveIndex(); - Class getJavaType(); + Class getJavaType(); - AbstractDataType getDataType(); + AbstractDataType getDataType(); - ColumnType getColumnType(); + ColumnType getColumnType(); - int getOrdinal(); + int getOrdinal(); - OrderingDirection getOrdering(); + OrderingDirection getOrdering(); - Optional> getReadConverter(SessionRepository repository); + Optional> getReadConverter(SessionRepository repository); - Optional> getWriteConverter(SessionRepository repository); + Optional> getWriteConverter(SessionRepository repository); - ConstraintValidator[] getValidators(); + ConstraintValidator[] getValidators(); } diff --git a/src/main/java/net/helenus/mapping/IdentityName.java b/src/main/java/net/helenus/mapping/IdentityName.java index 02f0858..cf61cbe 100644 --- a/src/main/java/net/helenus/mapping/IdentityName.java +++ b/src/main/java/net/helenus/mapping/IdentityName.java @@ -19,41 +19,41 @@ import net.helenus.support.CqlUtil; public final class IdentityName { - private final String name; + private final String name; - private final boolean forceQuote; + private final boolean forceQuote; - public IdentityName(String name, boolean forceQuote) { - this.name = name.toLowerCase(); - this.forceQuote = forceQuote; - } + public IdentityName(String name, boolean forceQuote) { + this.name = name.toLowerCase(); + this.forceQuote = forceQuote; + } - public static IdentityName of(String name, boolean forceQuote) { - return new IdentityName(name, forceQuote); - } + public static IdentityName of(String name, boolean forceQuote) { + return new IdentityName(name, forceQuote); + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public boolean isForceQuote() { - return forceQuote; - } + public boolean isForceQuote() { + return forceQuote; + } - public String toCql(boolean overrideForceQuote) { - if (overrideForceQuote) { - return CqlUtil.forceQuote(name); - } else { - return name; - } - } + public String toCql(boolean overrideForceQuote) { + if (overrideForceQuote) { + return CqlUtil.forceQuote(name); + } else { + return name; + } + } - public String toCql() { - return toCql(forceQuote); - } + public String toCql() { + return toCql(forceQuote); + } - @Override - public String toString() { - return toCql(); - } + @Override + public String toString() { + return toCql(); + } } diff --git a/src/main/java/net/helenus/mapping/MappingUtil.java b/src/main/java/net/helenus/mapping/MappingUtil.java index cf84c05..8eadfac 100644 --- a/src/main/java/net/helenus/mapping/MappingUtil.java +++ b/src/main/java/net/helenus/mapping/MappingUtil.java @@ -20,8 +20,10 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Optional; + import javax.validation.Constraint; import javax.validation.ConstraintValidator; + import net.helenus.core.Getter; import net.helenus.core.Helenus; import net.helenus.core.reflect.*; @@ -31,255 +33,253 @@ import net.helenus.support.HelenusMappingException; public final class MappingUtil { - @SuppressWarnings("unchecked") - public static final ConstraintValidator[] EMPTY_VALIDATORS = - new ConstraintValidator[0]; + @SuppressWarnings("unchecked") + public static final ConstraintValidator[] EMPTY_VALIDATORS = new ConstraintValidator[0]; - private MappingUtil() {} + private MappingUtil() { + } - public static ConstraintValidator[] getValidators(Method getterMethod) { + public static ConstraintValidator[] getValidators(Method getterMethod) { - List> list = null; + List> list = null; - for (Annotation constraintAnnotation : getterMethod.getDeclaredAnnotations()) { + for (Annotation constraintAnnotation : getterMethod.getDeclaredAnnotations()) { - list = addValidators(constraintAnnotation, list); + list = addValidators(constraintAnnotation, list); - Class annotationType = constraintAnnotation.annotationType(); + Class annotationType = constraintAnnotation.annotationType(); - for (Annotation possibleConstraint : annotationType.getDeclaredAnnotations()) { + for (Annotation possibleConstraint : annotationType.getDeclaredAnnotations()) { - list = addValidators(possibleConstraint, list); - } - } + list = addValidators(possibleConstraint, list); + } + } - if (list == null) { - return EMPTY_VALIDATORS; - } else { - return list.toArray(EMPTY_VALIDATORS); - } - } + if (list == null) { + return EMPTY_VALIDATORS; + } else { + return list.toArray(EMPTY_VALIDATORS); + } + } - private static List> addValidators( - Annotation constraintAnnotation, List> list) { + private static List> addValidators(Annotation constraintAnnotation, + List> list) { - Class annotationType = constraintAnnotation.annotationType(); + Class annotationType = constraintAnnotation.annotationType(); - for (Annotation possibleConstraint : annotationType.getDeclaredAnnotations()) { + for (Annotation possibleConstraint : annotationType.getDeclaredAnnotations()) { - if (possibleConstraint instanceof Constraint) { + if (possibleConstraint instanceof Constraint) { - Constraint constraint = (Constraint) possibleConstraint; + Constraint constraint = (Constraint) possibleConstraint; - for (Class> clazz : constraint.validatedBy()) { + for (Class> clazz : constraint.validatedBy()) { - ConstraintValidator validator = - ReflectionInstantiator.instantiateClass(clazz); + ConstraintValidator validator = ReflectionInstantiator + .instantiateClass(clazz); - ((ConstraintValidator) validator).initialize(constraintAnnotation); + ((ConstraintValidator) validator).initialize(constraintAnnotation); - if (list == null) { - list = new ArrayList>(); - } + if (list == null) { + list = new ArrayList>(); + } - list.add(validator); - } - } - } + list.add(validator); + } + } + } - return list; - } + return list; + } - public static Optional getIndexName(Method getterMethod) { + public static Optional getIndexName(Method getterMethod) { - String indexName = null; - boolean forceQuote = false; + String indexName = null; + boolean forceQuote = false; - Index index = getterMethod.getDeclaredAnnotation(Index.class); + Index index = getterMethod.getDeclaredAnnotation(Index.class); - if (index != null) { - indexName = index.value(); - forceQuote = index.forceQuote(); + if (index != null) { + indexName = index.value(); + forceQuote = index.forceQuote(); - if (indexName == null || indexName.isEmpty()) { - indexName = getDefaultColumnName(getterMethod); - } - } + if (indexName == null || indexName.isEmpty()) { + indexName = getDefaultColumnName(getterMethod); + } + } - return indexName != null - ? Optional.of(new IdentityName(indexName, forceQuote)) - : Optional.empty(); - } + return indexName != null ? Optional.of(new IdentityName(indexName, forceQuote)) : Optional.empty(); + } - public static boolean caseSensitiveIndex(Method getterMethod) { - Index index = getterMethod.getDeclaredAnnotation(Index.class); + public static boolean caseSensitiveIndex(Method getterMethod) { + Index index = getterMethod.getDeclaredAnnotation(Index.class); - if (index != null) { - return index.caseSensitive(); - } + if (index != null) { + return index.caseSensitive(); + } - return false; - } + return false; + } - public static String getPropertyName(Method getter) { - return getter.getName(); - } + public static String getPropertyName(Method getter) { + return getter.getName(); + } - public static String getDefaultColumnName(Method getter) { - return Helenus.settings().getPropertyToColumnConverter().apply(getPropertyName(getter)); - } + public static String getDefaultColumnName(Method getter) { + return Helenus.settings().getPropertyToColumnConverter().apply(getPropertyName(getter)); + } - public static IdentityName getUserDefinedTypeName(Class iface, boolean required) { + public static IdentityName getUserDefinedTypeName(Class iface, boolean required) { - String userTypeName = null; - boolean forceQuote = false; + String userTypeName = null; + boolean forceQuote = false; - UDT userDefinedType = iface.getDeclaredAnnotation(UDT.class); + UDT userDefinedType = iface.getDeclaredAnnotation(UDT.class); - if (userDefinedType != null) { + if (userDefinedType != null) { - userTypeName = userDefinedType.value(); - forceQuote = userDefinedType.forceQuote(); + userTypeName = userDefinedType.value(); + forceQuote = userDefinedType.forceQuote(); - if (userTypeName == null || userTypeName.isEmpty()) { - userTypeName = getDefaultEntityName(iface); - } + if (userTypeName == null || userTypeName.isEmpty()) { + userTypeName = getDefaultEntityName(iface); + } - return new IdentityName(userTypeName, forceQuote); - } + return new IdentityName(userTypeName, forceQuote); + } - if (required) { - throw new HelenusMappingException("entity must have annotation @UserDefinedType " + iface); - } + if (required) { + throw new HelenusMappingException("entity must have annotation @UserDefinedType " + iface); + } - return null; - } + return null; + } - public static boolean isTuple(Class iface) { + public static boolean isTuple(Class iface) { - Tuple tuple = iface.getDeclaredAnnotation(Tuple.class); + Tuple tuple = iface.getDeclaredAnnotation(Tuple.class); - return tuple != null; - } + return tuple != null; + } - public static boolean isUDT(Class iface) { + public static boolean isUDT(Class iface) { - UDT udt = iface.getDeclaredAnnotation(UDT.class); + UDT udt = iface.getDeclaredAnnotation(UDT.class); - return udt != null; - } + return udt != null; + } - public static IdentityName getViewName(Class iface, boolean required) { + public static IdentityName getViewName(Class iface, boolean required) { - String viewName = null; - boolean forceQuote = false; + String viewName = null; + boolean forceQuote = false; - MaterializedView view = iface.getDeclaredAnnotation(MaterializedView.class); + MaterializedView view = iface.getDeclaredAnnotation(MaterializedView.class); - if (view != null) { - viewName = view.value(); - forceQuote = view.forceQuote(); + if (view != null) { + viewName = view.value(); + forceQuote = view.forceQuote(); - } else if (required) { - throw new HelenusMappingException("entity must have annotation @Table " + iface); - } + } else if (required) { + throw new HelenusMappingException("entity must have annotation @Table " + iface); + } - if (viewName == null || viewName.isEmpty()) { - viewName = getDefaultEntityName(iface); - } + if (viewName == null || viewName.isEmpty()) { + viewName = getDefaultEntityName(iface); + } - return new IdentityName(viewName, forceQuote); - } + return new IdentityName(viewName, forceQuote); + } - public static IdentityName getTableName(Class iface, boolean required) { + public static IdentityName getTableName(Class iface, boolean required) { - String tableName = null; - boolean forceQuote = false; + String tableName = null; + boolean forceQuote = false; - Table table = iface.getDeclaredAnnotation(Table.class); + Table table = iface.getDeclaredAnnotation(Table.class); - if (table != null) { - tableName = table.value(); - forceQuote = table.forceQuote(); + if (table != null) { + tableName = table.value(); + forceQuote = table.forceQuote(); - } else if (required) { - throw new HelenusMappingException("entity must have annotation @Table " + iface); - } + } else if (required) { + throw new HelenusMappingException("entity must have annotation @Table " + iface); + } - if (tableName == null || tableName.isEmpty()) { - tableName = getDefaultEntityName(iface); - } + if (tableName == null || tableName.isEmpty()) { + tableName = getDefaultEntityName(iface); + } - return new IdentityName(tableName, forceQuote); - } + return new IdentityName(tableName, forceQuote); + } - public static String getDefaultEntityName(Class iface) { - return Helenus.settings().getPropertyToColumnConverter().apply(iface.getSimpleName()); - } + public static String getDefaultEntityName(Class iface) { + return Helenus.settings().getPropertyToColumnConverter().apply(iface.getSimpleName()); + } - public static Class getMappingInterface(Object pojo) { + public static Class getMappingInterface(Object pojo) { - Class iface = null; + Class iface = null; - if (pojo instanceof Class) { - iface = (Class) pojo; + if (pojo instanceof Class) { + iface = (Class) pojo; - if (!iface.isInterface()) { - throw new HelenusMappingException("expected interface " + iface); - } + if (!iface.isInterface()) { + throw new HelenusMappingException("expected interface " + iface); + } - } else { - Class[] ifaces = pojo.getClass().getInterfaces(); + } else { + Class[] ifaces = pojo.getClass().getInterfaces(); - int len = ifaces.length; - for (int i = 0; i != len; ++i) { + int len = ifaces.length; + for (int i = 0; i != len; ++i) { - iface = ifaces[0]; + iface = ifaces[0]; - if (MapExportable.class.isAssignableFrom(iface)) { - continue; - } + if (MapExportable.class.isAssignableFrom(iface)) { + continue; + } - if (iface.getDeclaredAnnotation(Table.class) != null - || iface.getDeclaredAnnotation(MaterializedView.class) != null - || iface.getDeclaredAnnotation(UDT.class) != null - || iface.getDeclaredAnnotation(Tuple.class) != null) { + if (iface.getDeclaredAnnotation(Table.class) != null + || iface.getDeclaredAnnotation(MaterializedView.class) != null + || iface.getDeclaredAnnotation(UDT.class) != null + || iface.getDeclaredAnnotation(Tuple.class) != null) { - break; - } - } - } + break; + } + } + } - if (iface == null) { - throw new HelenusMappingException("dsl interface not found for " + pojo); - } + if (iface == null) { + throw new HelenusMappingException("dsl interface not found for " + pojo); + } - return iface; - } + return iface; + } - public static HelenusPropertyNode resolveMappingProperty(Getter getter) { + public static HelenusPropertyNode resolveMappingProperty(Getter getter) { - try { - Object childDsl = getter.get(); + try { + Object childDsl = getter.get(); - if (childDsl instanceof DslExportable) { - DslExportable e = (DslExportable) childDsl; - return e.getParentDslHelenusPropertyNode(); - } else if (childDsl instanceof MapDsl) { - MapDsl mapDsl = (MapDsl) childDsl; - return mapDsl.getParent(); - } else if (childDsl instanceof ListDsl) { - ListDsl listDsl = (ListDsl) childDsl; - return listDsl.getParent(); - } else if (childDsl instanceof SetDsl) { - SetDsl setDsl = (SetDsl) childDsl; - return setDsl.getParent(); - } + if (childDsl instanceof DslExportable) { + DslExportable e = (DslExportable) childDsl; + return e.getParentDslHelenusPropertyNode(); + } else if (childDsl instanceof MapDsl) { + MapDsl mapDsl = (MapDsl) childDsl; + return mapDsl.getParent(); + } else if (childDsl instanceof ListDsl) { + ListDsl listDsl = (ListDsl) childDsl; + return listDsl.getParent(); + } else if (childDsl instanceof SetDsl) { + SetDsl setDsl = (SetDsl) childDsl; + return setDsl.getParent(); + } - throw new HelenusMappingException("getter must reference to the dsl object " + getter); + throw new HelenusMappingException("getter must reference to the dsl object " + getter); - } catch (DslPropertyException e) { - return e.getPropertyNode(); - } - } + } catch (DslPropertyException e) { + return e.getPropertyNode(); + } + } } diff --git a/src/main/java/net/helenus/mapping/OrderingDirection.java b/src/main/java/net/helenus/mapping/OrderingDirection.java index 47680d6..bdae06a 100644 --- a/src/main/java/net/helenus/mapping/OrderingDirection.java +++ b/src/main/java/net/helenus/mapping/OrderingDirection.java @@ -18,28 +18,28 @@ package net.helenus.mapping; import net.helenus.support.HelenusMappingException; public enum OrderingDirection { - ASC("ASC"), + ASC("ASC"), - DESC("DESC"); + DESC("DESC"); - private final String cql; + private final String cql; - private OrderingDirection(String cql) { - this.cql = cql; - } + private OrderingDirection(String cql) { + this.cql = cql; + } - public String cql() { - return cql; - } + public String cql() { + return cql; + } - public static OrderingDirection parseString(String name) { + public static OrderingDirection parseString(String name) { - if (ASC.cql.equalsIgnoreCase(name)) { - return ASC; - } else if (DESC.cql.equalsIgnoreCase(name)) { - return DESC; - } + if (ASC.cql.equalsIgnoreCase(name)) { + return ASC; + } else if (DESC.cql.equalsIgnoreCase(name)) { + return DESC; + } - throw new HelenusMappingException("invalid ordering direction name " + name); - } + throw new HelenusMappingException("invalid ordering direction name " + name); + } } diff --git a/src/main/java/net/helenus/mapping/TypeAndOrdinalColumnComparator.java b/src/main/java/net/helenus/mapping/TypeAndOrdinalColumnComparator.java index ef925ea..825e0dc 100644 --- a/src/main/java/net/helenus/mapping/TypeAndOrdinalColumnComparator.java +++ b/src/main/java/net/helenus/mapping/TypeAndOrdinalColumnComparator.java @@ -18,17 +18,16 @@ package net.helenus.mapping; import java.util.Comparator; public enum TypeAndOrdinalColumnComparator implements Comparator { - INSTANCE; + INSTANCE; - public int compare(HelenusProperty thisVal, HelenusProperty anotherVal) { + public int compare(HelenusProperty thisVal, HelenusProperty anotherVal) { - int c = - Integer.compare(thisVal.getColumnType().ordinal(), anotherVal.getColumnType().ordinal()); + int c = Integer.compare(thisVal.getColumnType().ordinal(), anotherVal.getColumnType().ordinal()); - if (c == 0) { - c = Integer.compare(thisVal.getOrdinal(), anotherVal.getOrdinal()); - } + if (c == 0) { + c = Integer.compare(thisVal.getOrdinal(), anotherVal.getOrdinal()); + } - return c; - } + return c; + } } diff --git a/src/main/java/net/helenus/mapping/annotation/ClusteringColumn.java b/src/main/java/net/helenus/mapping/annotation/ClusteringColumn.java index 4a6228b..c1f72de 100644 --- a/src/main/java/net/helenus/mapping/annotation/ClusteringColumn.java +++ b/src/main/java/net/helenus/mapping/annotation/ClusteringColumn.java @@ -19,78 +19,93 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; + import net.helenus.mapping.OrderingDirection; /** * ClusteringColumn is the family column in legacy Cassandra API * - *

The purpose of this column is have additional dimension in the table. Both @PartitionKey - * and @ClusteringColumn together are parts of the primary key of the table. The primary difference - * between them is that the first one is using for routing purposes in order to locate a data node - * in the cluster, otherwise the second one is using inside the node to locate peace of data in + *

+ * The purpose of this column is have additional dimension in the table. + * Both @PartitionKey and @ClusteringColumn together are parts of the primary + * key of the table. The primary difference between them is that the first one + * is using for routing purposes in order to locate a data node in the cluster, + * otherwise the second one is using inside the node to locate peace of data in * concrete machine. * - *

ClusteringColumn can be represented as a Key in SortedMap that fully stored in a single node. - * All developers must be careful for selecting fields for clustering columns, because all data - * inside this SortedMap must fit in to one node. + *

+ * ClusteringColumn can be represented as a Key in SortedMap that fully stored + * in a single node. All developers must be careful for selecting fields for + * clustering columns, because all data inside this SortedMap must fit in to one + * node. * - *

ClusteringColumn can have more than one part and the order of parts is important. This order - * defines the way how Cassandra joins the parts and influence of data retrieval operations. Each - * part can have ordering property that defines default ascending or descending order of data. In - * case of two and more parts in select queries developer needs to have consisdent order of all - * parts as they defined in table. + *

+ * ClusteringColumn can have more than one part and the order of parts is + * important. This order defines the way how Cassandra joins the parts and + * influence of data retrieval operations. Each part can have ordering property + * that defines default ascending or descending order of data. In case of two + * and more parts in select queries developer needs to have consisdent order of + * all parts as they defined in table. * - *

For example, first part is ASC ordering, second is also ASC, so Cassandra will sort entries - * like this: a-a a-b b-a b-b In this case we are able run queries: ORDER BY first ASC, second ASC - * ORDER BY first DESC, second DESC WHERE first=? ORDER BY second ASC WHERE first=? ORDER BY second - * DESC WHERE first=? AND second=? + *

+ * For example, first part is ASC ordering, second is also ASC, so Cassandra + * will sort entries like this: a-a a-b b-a b-b In this case we are able run + * queries: ORDER BY first ASC, second ASC ORDER BY first DESC, second DESC + * WHERE first=? ORDER BY second ASC WHERE first=? ORDER BY second DESC WHERE + * first=? AND second=? * - *

But, we can not run queries: ORDER BY first DESC, second ASC ORDER BY first ASC, second DESC - * WHERE second=? ORDER BY first (ASC,DESC) + *

+ * But, we can not run queries: ORDER BY first DESC, second ASC ORDER BY first + * ASC, second DESC WHERE second=? ORDER BY first (ASC,DESC) */ @Retention(value = RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) public @interface ClusteringColumn { - /** - * Default value is the name of the method normalized to underscore - * - * @return name of the column - */ - String value() default ""; + /** + * Default value is the name of the method normalized to underscore + * + * @return name of the column + */ + String value() default ""; - /** - * ClusteringColumn parts must be ordered in the @Table. It is the requirement of Cassandra. - * Cassandra joins all parts to the final clustering key that is stored in column family name. - * Additionally all parts can have some ordering (ASC, DESC) that with sequence of parts - * determines key comparison function, so Cassandra storing column family names always in sorted - * order. - * - *

Be default ordinal has 0 value, that's because in most cases @Table have single column for - * ClusteringColumn If you have 2 and more parts of the ClusteringColumn, then you need to use - * ordinal() to define the sequence of the parts - * - * @return number that used to sort clustering columns - */ - int ordinal() default 0; + /** + * ClusteringColumn parts must be ordered in the @Table. It is the requirement + * of Cassandra. Cassandra joins all parts to the final clustering key that is + * stored in column family name. Additionally all parts can have some ordering + * (ASC, DESC) that with sequence of parts determines key comparison function, + * so Cassandra storing column family names always in sorted order. + * + *

+ * Be default ordinal has 0 value, that's because in most cases @Table have + * single column for ClusteringColumn If you have 2 and more parts of the + * ClusteringColumn, then you need to use ordinal() to define the sequence of + * the parts + * + * @return number that used to sort clustering columns + */ + int ordinal() default 0; - /** - * Default order of values in the ClusteringColumn This ordering is using for comparison of the - * clustering column values when Cassandra stores it in the sorted order. - * - *

Default value is the ascending order - * - * @return ascending order or descending order of clustering column values - */ - OrderingDirection ordering() default OrderingDirection.ASC; + /** + * Default order of values in the ClusteringColumn This ordering is using for + * comparison of the clustering column values when Cassandra stores it in the + * sorted order. + * + *

+ * Default value is the ascending order + * + * @return ascending order or descending order of clustering column values + */ + OrderingDirection ordering() default OrderingDirection.ASC; - /** - * For reserved words in Cassandra we need quotation in CQL queries. This property marks that the - * name of the UDT type needs to be quoted. - * - *

Default value is false, we are quoting only selected names. - * - * @return true if name have to be quoted - */ - boolean forceQuote() default false; + /** + * For reserved words in Cassandra we need quotation in CQL queries. This + * property marks that the name of the UDT type needs to be quoted. + * + *

+ * Default value is false, we are quoting only selected names. + * + * @return true if name have to be quoted + */ + boolean forceQuote() default false; } diff --git a/src/main/java/net/helenus/mapping/annotation/Column.java b/src/main/java/net/helenus/mapping/annotation/Column.java index ab4b2d4..466f26c 100644 --- a/src/main/java/net/helenus/mapping/annotation/Column.java +++ b/src/main/java/net/helenus/mapping/annotation/Column.java @@ -18,45 +18,51 @@ package net.helenus.mapping.annotation; import java.lang.annotation.*; /** - * Column annotation is used to define additional properties of the column in entity mapping - * interfaces: @Table, @UDT, @Tuple + * Column annotation is used to define additional properties of the column in + * entity mapping interfaces: @Table, @UDT, @Tuple * - *

Column annotation can be used to override default name of the column or to setup order of the - * columns in the mapping + *

+ * Column annotation can be used to override default name of the column or to + * setup order of the columns in the mapping * - *

Usually for @Table and @UDT types it is not important to define order of the columns, but - * in @Tuple mapping it is required, because tuple itself represents the sequence of the types with - * particular order in the table's column + *

+ * Usually for @Table and @UDT types it is not important to define order of the + * columns, but in @Tuple mapping it is required, because tuple itself + * represents the sequence of the types with particular order in the table's + * column */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) public @interface Column { - /** - * Default value is the name of the method normalized to underscore - * - * @return name of the column - */ - String value() default ""; + /** + * Default value is the name of the method normalized to underscore + * + * @return name of the column + */ + String value() default ""; - /** - * Ordinal will be used for ascending sorting of columns - * - *

Default value is 0, because not all mapping entities require all fields to have unique - * ordinals, only @Tuple mapping entity requires all of them to be unique. - * - * @return number that used to sort columns, usually for @Tuple only - */ - int ordinal() default 0; + /** + * Ordinal will be used for ascending sorting of columns + * + *

+ * Default value is 0, because not all mapping entities require all fields to + * have unique ordinals, only @Tuple mapping entity requires all of them to be + * unique. + * + * @return number that used to sort columns, usually for @Tuple only + */ + int ordinal() default 0; - /** - * For reserved words in Cassandra we need quotation in CQL queries. This property marks that the - * name of the UDT type needs to be quoted. - * - *

Default value is false, we are quoting only selected names. - * - * @return true if name have to be quoted - */ - boolean forceQuote() default false; + /** + * For reserved words in Cassandra we need quotation in CQL queries. This + * property marks that the name of the UDT type needs to be quoted. + * + *

+ * Default value is false, we are quoting only selected names. + * + * @return true if name have to be quoted + */ + boolean forceQuote() default false; } diff --git a/src/main/java/net/helenus/mapping/annotation/Constraints.java b/src/main/java/net/helenus/mapping/annotation/Constraints.java index 54110ba..5ed755e 100644 --- a/src/main/java/net/helenus/mapping/annotation/Constraints.java +++ b/src/main/java/net/helenus/mapping/annotation/Constraints.java @@ -16,200 +16,240 @@ package net.helenus.mapping.annotation; import java.lang.annotation.*; + import javax.validation.Constraint; + import net.helenus.mapping.validator.*; /** - * Constraint annotations are using for data integrity mostly for @java.lang.String types. The place - * of the annotation is the particular method in model interface. + * Constraint annotations are using for data integrity mostly + * for @java.lang.String types. The place of the annotation is the particular + * method in model interface. * - *

All of them does not have effect on selects and data retrieval operations. + *

+ * All of them does not have effect on selects and data retrieval operations. * - *

Support types: - @NotNull supports any @java.lang.Object type - All annotations - * support @java.lang.String type + *

+ * Support types: - @NotNull supports any @java.lang.Object type - All + * annotations support @java.lang.String type */ public final class Constraints { - private Constraints() {} + private Constraints() { + } - /** - * NotNull annotation is using to check that value is not null before storing it - * - *

Applicable to use in any @java.lang.Object - * - *

It does not check on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = NotNullValidator.class) - public @interface NotNull {} + /** + * NotNull annotation is using to check that value is not null before storing it + * + *

+ * Applicable to use in any @java.lang.Object + * + *

+ * It does not check on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = NotNullValidator.class) + public @interface NotNull { + } - /** - * NotEmpty annotation is using to check that value has text before storing it - * - *

Also checks for the null and it is more strict annotation then @NotNull - * - *

Can be used for @java.lang.CharSequence, @ByteBuffer and any array - * - *

It does not check on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = NotEmptyValidator.class) - public @interface NotEmpty {} + /** + * NotEmpty annotation is using to check that value has text before storing it + * + *

+ * Also checks for the null and it is more strict annotation then @NotNull + * + *

+ * Can be used for @java.lang.CharSequence, @ByteBuffer and any array + * + *

+ * It does not check on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = NotEmptyValidator.class) + public @interface NotEmpty { + } - /** - * Email annotation is using to check that value has a valid email before storing it - * - *

Can be used only for @CharSequence - * - *

It does not check on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = EmailValidator.class) - public @interface Email {} + /** + * Email annotation is using to check that value has a valid email before + * storing it + * + *

+ * Can be used only for @CharSequence + * + *

+ * It does not check on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = EmailValidator.class) + public @interface Email { + } - /** - * Number annotation is using to check that all letters in value are digits before storing it - * - *

Can be used only for @java.lang.CharSequence - * - *

It does not check on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = NumberValidator.class) - public @interface Number {} + /** + * Number annotation is using to check that all letters in value are digits + * before storing it + * + *

+ * Can be used only for @java.lang.CharSequence + * + *

+ * It does not check on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = NumberValidator.class) + public @interface Number { + } - /** - * Alphabet annotation is using to check that all letters in value are in specific alphabet before - * storing it - * - *

Can be used only for @java.lang.CharSequence - * - *

It does not check on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = AlphabetValidator.class) - public @interface Alphabet { + /** + * Alphabet annotation is using to check that all letters in value are in + * specific alphabet before storing it + * + *

+ * Can be used only for @java.lang.CharSequence + * + *

+ * It does not check on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = AlphabetValidator.class) + public @interface Alphabet { - /** - * Defines alphabet that will be used to check value - * - * @return alphabet characters in the string - */ - String value(); - } + /** + * Defines alphabet that will be used to check value + * + * @return alphabet characters in the string + */ + String value(); + } - /** - * Length annotation is using to ensure that value has exact length before storing it - * - *

Can be used for @java.lang.CharSequence, @ByteBuffer and any array - * - *

It does not have effect on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = LengthValidator.class) - public @interface Length { + /** + * Length annotation is using to ensure that value has exact length before + * storing it + * + *

+ * Can be used for @java.lang.CharSequence, @ByteBuffer and any array + * + *

+ * It does not have effect on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = LengthValidator.class) + public @interface Length { - int value(); - } + int value(); + } - /** - * MaxLength annotation is using to ensure that value has length less or equal to some threshold - * before storing it - * - *

Can be used for @java.lang.CharSequence, @ByteBuffer and byte[] - * - *

It does not have effect on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = MaxLengthValidator.class) - public @interface MaxLength { + /** + * MaxLength annotation is using to ensure that value has length less or equal + * to some threshold before storing it + * + *

+ * Can be used for @java.lang.CharSequence, @ByteBuffer and byte[] + * + *

+ * It does not have effect on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = MaxLengthValidator.class) + public @interface MaxLength { - int value(); - } + int value(); + } - /** - * MinLength annotation is using to ensure that value has length greater or equal to some - * threshold before storing it - * - *

Can be used for @java.lang.CharSequence, @ByteBuffer and byte[] - * - *

It does not have effect on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = MinLengthValidator.class) - public @interface MinLength { + /** + * MinLength annotation is using to ensure that value has length greater or + * equal to some threshold before storing it + * + *

+ * Can be used for @java.lang.CharSequence, @ByteBuffer and byte[] + * + *

+ * It does not have effect on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = MinLengthValidator.class) + public @interface MinLength { - int value(); - } + int value(); + } - /** - * LowerCase annotation is using to ensure that value is in lower case before storing it - * - *

Can be used only for @java.lang.CharSequence - * - *

It does not have effect on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = LowerCaseValidator.class) - public @interface LowerCase {} + /** + * LowerCase annotation is using to ensure that value is in lower case before + * storing it + * + *

+ * Can be used only for @java.lang.CharSequence + * + *

+ * It does not have effect on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = LowerCaseValidator.class) + public @interface LowerCase { + } - /** - * UpperCase annotation is using to ensure that value is in upper case before storing it - * - *

Can be used only for @java.lang.CharSequence - * - *

It does not have effect on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = UpperCaseValidator.class) - public @interface UpperCase {} + /** + * UpperCase annotation is using to ensure that value is in upper case before + * storing it + * + *

+ * Can be used only for @java.lang.CharSequence + * + *

+ * It does not have effect on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = UpperCaseValidator.class) + public @interface UpperCase { + } - /** - * Pattern annotation is LowerCase annotation is using to ensure that value is upper case before - * storing it - * - *

Can be used only for @java.lang.CharSequence - * - *

It does not have effect on selects and data retrieval operations - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - @Constraint(validatedBy = PatternValidator.class) - public @interface Pattern { + /** + * Pattern annotation is LowerCase annotation is using to ensure that value is + * upper case before storing it + * + *

+ * Can be used only for @java.lang.CharSequence + * + *

+ * It does not have effect on selects and data retrieval operations + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + @Constraint(validatedBy = PatternValidator.class) + public @interface Pattern { - /** - * User defined regex expression to check match of the value - * - * @return Java regex pattern - */ - String value(); + /** + * User defined regex expression to check match of the value + * + * @return Java regex pattern + */ + String value(); - /** - * Regex flags composition - * - * @return Java regex flags - */ - int flags(); - } + /** + * Regex flags composition + * + * @return Java regex flags + */ + int flags(); + } } diff --git a/src/main/java/net/helenus/mapping/annotation/CoveringIndex.java b/src/main/java/net/helenus/mapping/annotation/CoveringIndex.java index 6271e8e..33d8bf4 100644 --- a/src/main/java/net/helenus/mapping/annotation/CoveringIndex.java +++ b/src/main/java/net/helenus/mapping/annotation/CoveringIndex.java @@ -3,48 +3,52 @@ package net.helenus.mapping.annotation; import java.lang.annotation.*; /** - * CoveringIndex annotation is using under the specific column or method in entity interface - * with @Table annotation. + * CoveringIndex annotation is using under the specific column or method in + * entity interface with @Table annotation. * - *

A corresponding materialized view will be created based on the underline @Table for the - * specific column. + *

+ * A corresponding materialized view will be created based on the + * underline @Table for the specific column. * - *

This is useful when you need to perform IN or SORT/ORDER-BY queries and to do so you'll need - * different materialized table on disk in Cassandra. + *

+ * This is useful when you need to perform IN or SORT/ORDER-BY queries and to do + * so you'll need different materialized table on disk in Cassandra. * - *

For each @Table annotated interface Helenus will create/update/verify Cassandra Materialized - * Views and some indexes if needed on startup. + *

+ * For each @Table annotated interface Helenus will create/update/verify + * Cassandra Materialized Views and some indexes if needed on startup. */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface CoveringIndex { - /** - * Defined the name of the index. By default the entity name with column name as suffix. - * - * @return name of the covering index - */ - String name() default ""; + /** + * Defined the name of the index. By default the entity name with column name as + * suffix. + * + * @return name of the covering index + */ + String name() default ""; - /** - * Set of fields in this entity to replicate in the index. - * - * @return array of the string names of the fields. - */ - String[] covering() default ""; + /** + * Set of fields in this entity to replicate in the index. + * + * @return array of the string names of the fields. + */ + String[] covering() default ""; - /** - * Set of fields to use as the partition keys for this projection. - * - * @return array of the string names of the fields. - */ - String[] partitionKeys() default ""; + /** + * Set of fields to use as the partition keys for this projection. + * + * @return array of the string names of the fields. + */ + String[] partitionKeys() default ""; - /** - * Set of fields to use as the clustering columns for this projection. - * - * @return array of the string names of the fields. - */ - String[] clusteringColumns() default ""; + /** + * Set of fields to use as the clustering columns for this projection. + * + * @return array of the string names of the fields. + */ + String[] clusteringColumns() default ""; } diff --git a/src/main/java/net/helenus/mapping/annotation/Index.java b/src/main/java/net/helenus/mapping/annotation/Index.java index b6599df..5222824 100644 --- a/src/main/java/net/helenus/mapping/annotation/Index.java +++ b/src/main/java/net/helenus/mapping/annotation/Index.java @@ -18,45 +18,51 @@ package net.helenus.mapping.annotation; import java.lang.annotation.*; /** - * Index annotation is using under the specific column or method in entity interface with @Table - * annotation. + * Index annotation is using under the specific column or method in entity + * interface with @Table annotation. * - *

The corresponding secondary index will be created in the underline @Table for the specific - * column. + *

+ * The corresponding secondary index will be created in the underline @Table for + * the specific column. * - *

Currently Cassandra supports only single column index, so this index works only for single - * column. + *

+ * Currently Cassandra supports only single column index, so this index works + * only for single column. * - *

Make sure that you are using low cardinality columns for this index, that is the requirement - * of the Cassandra. Low cardinality fields examples: gender, country, age, status and etc High - * cardinality fields examples: id, email, timestamp, UUID and etc + *

+ * Make sure that you are using low cardinality columns for this index, that is + * the requirement of the Cassandra. Low cardinality fields examples: gender, + * country, age, status and etc High cardinality fields examples: id, email, + * timestamp, UUID and etc */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) public @interface Index { - /** - * Defined the name of the index. By default will be used the column name. - * - * @return name of the index - */ - String value() default ""; + /** + * Defined the name of the index. By default will be used the column name. + * + * @return name of the index + */ + String value() default ""; - /** - * For reserved words in Cassandra we need quotation in CQL queries. This property marks that the - * name of the UDT type needs to be quoted. - * - *

Default value is false, we are quoting only selected names. - * - * @return true if name have to be quoted - */ - boolean forceQuote() default false; + /** + * For reserved words in Cassandra we need quotation in CQL queries. This + * property marks that the name of the UDT type needs to be quoted. + * + *

+ * Default value is false, we are quoting only selected names. + * + * @return true if name have to be quoted + */ + boolean forceQuote() default false; - /** - * Create a case-insensitive index using Cassandra 3.x+ support for SASI indexing. - * - * @return true if the index should ignore case when comparing - */ - boolean caseSensitive() default true; + /** + * Create a case-insensitive index using Cassandra 3.x+ support for SASI + * indexing. + * + * @return true if the index should ignore case when comparing + */ + boolean caseSensitive() default true; } diff --git a/src/main/java/net/helenus/mapping/annotation/InheritedTable.java b/src/main/java/net/helenus/mapping/annotation/InheritedTable.java index af1f1dd..a7649bd 100644 --- a/src/main/java/net/helenus/mapping/annotation/InheritedTable.java +++ b/src/main/java/net/helenus/mapping/annotation/InheritedTable.java @@ -20,11 +20,13 @@ import java.lang.annotation.*; /** * Inherited Entity annotation * - *

Inherited Table annotation is used to indicate that the methods should also be mapped + *

+ * Inherited Table annotation is used to indicate that the methods should also + * be mapped */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface InheritedTable { - String value() default ""; + String value() default ""; } diff --git a/src/main/java/net/helenus/mapping/annotation/MaterializedView.java b/src/main/java/net/helenus/mapping/annotation/MaterializedView.java index 112d8ce..6e8468d 100644 --- a/src/main/java/net/helenus/mapping/annotation/MaterializedView.java +++ b/src/main/java/net/helenus/mapping/annotation/MaterializedView.java @@ -20,33 +20,38 @@ import java.lang.annotation.*; /** * Materialized alternate view of another Entity annotation * - *

MaterializedView annotation is used to define different mapping to some other Table interface + *

+ * MaterializedView annotation is used to define different mapping to some other + * Table interface * - *

This is useful when you need to perform IN or SORT/ORDER-BY queries and to do so you'll need - * different materialized table on disk in Cassandra. + *

+ * This is useful when you need to perform IN or SORT/ORDER-BY queries and to do + * so you'll need different materialized table on disk in Cassandra. * - *

For each @Table annotated interface Helenus will create/update/verify Cassandra Materialized - * Views and some indexes if needed on startup. + *

+ * For each @Table annotated interface Helenus will create/update/verify + * Cassandra Materialized Views and some indexes if needed on startup. */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface MaterializedView { - /** - * Default value is the SimpleName of the interface normalized to underscore - * - * @return name of the type - */ - String value() default ""; + /** + * Default value is the SimpleName of the interface normalized to underscore + * + * @return name of the type + */ + String value() default ""; - /** - * For reserved words in Cassandra we need quotation in CQL queries. This property marks that the - * name of the type needs to be quoted. - * - *

Default value is false, we are quoting only selected names. - * - * @return true if name have to be quoted - */ - boolean forceQuote() default false; + /** + * For reserved words in Cassandra we need quotation in CQL queries. This + * property marks that the name of the type needs to be quoted. + * + *

+ * Default value is false, we are quoting only selected names. + * + * @return true if name have to be quoted + */ + boolean forceQuote() default false; } diff --git a/src/main/java/net/helenus/mapping/annotation/PartitionKey.java b/src/main/java/net/helenus/mapping/annotation/PartitionKey.java index 946d9e4..bca9204 100644 --- a/src/main/java/net/helenus/mapping/annotation/PartitionKey.java +++ b/src/main/java/net/helenus/mapping/annotation/PartitionKey.java @@ -21,48 +21,55 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * PartitionKey annotation is using to define that particular column is the part of partition key in - * the table. + * PartitionKey annotation is using to define that particular column is the part + * of partition key in the table. * - *

Partition Key is the routing key. Cassandra is using it to find the primary data node in the - * cluster that holds data. Cassandra combines all parts of the partition key to byte array and then - * calculates hash function by using good distribution algorithm (by default MurMur3). After that it - * uses hash number as a token in the ring to find a virtual and then a physical data server. + *

+ * Partition Key is the routing key. Cassandra is using it to find the primary + * data node in the cluster that holds data. Cassandra combines all parts of the + * partition key to byte array and then calculates hash function by using good + * distribution algorithm (by default MurMur3). After that it uses hash number + * as a token in the ring to find a virtual and then a physical data server. * - *

For @Table mapping entity it is required to have as minimum one PartitionKey column. For @UDT - * and @Tuple mapping entities @PartitionKey annotation is not using. + *

+ * For @Table mapping entity it is required to have as minimum one PartitionKey + * column. For @UDT and @Tuple mapping entities @PartitionKey annotation is not + * using. */ @Retention(value = RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) public @interface PartitionKey { - /** - * Default value is the name of the method normalized to underscore - * - * @return name of the column - */ - String value() default ""; + /** + * Default value is the name of the method normalized to underscore + * + * @return name of the column + */ + String value() default ""; - /** - * PartitionKey parts must be ordered in the @Table. It is the requirement of Cassandra. That is - * how the partition key calculation works, column parts will be joined based on some order and - * final hash/token will be calculated. - * - *

Be default ordinal has 0 value, that's because in most cases @Table have single column - * for @PartitionKey If you have 2 and more parts of the PartitionKey, then you need to use - * ordinal() to define the sequence of the parts - * - * @return number that used to sort columns in PartitionKey - */ - int ordinal() default 0; + /** + * PartitionKey parts must be ordered in the @Table. It is the requirement of + * Cassandra. That is how the partition key calculation works, column parts will + * be joined based on some order and final hash/token will be calculated. + * + *

+ * Be default ordinal has 0 value, that's because in most cases @Table have + * single column for @PartitionKey If you have 2 and more parts of the + * PartitionKey, then you need to use ordinal() to define the sequence of the + * parts + * + * @return number that used to sort columns in PartitionKey + */ + int ordinal() default 0; - /** - * For reserved words in Cassandra we need quotation in CQL queries. This property marks that the - * name of the UDT type needs to be quoted. - * - *

Default value is false, we are quoting only selected names. - * - * @return true if name have to be quoted - */ - boolean forceQuote() default false; + /** + * For reserved words in Cassandra we need quotation in CQL queries. This + * property marks that the name of the UDT type needs to be quoted. + * + *

+ * Default value is false, we are quoting only selected names. + * + * @return true if name have to be quoted + */ + boolean forceQuote() default false; } diff --git a/src/main/java/net/helenus/mapping/annotation/StaticColumn.java b/src/main/java/net/helenus/mapping/annotation/StaticColumn.java index c538560..dde3a2d 100644 --- a/src/main/java/net/helenus/mapping/annotation/StaticColumn.java +++ b/src/main/java/net/helenus/mapping/annotation/StaticColumn.java @@ -23,38 +23,41 @@ import java.lang.annotation.Target; /** * StaticColumn annotation is using to define a static column in Cassandra Table * - *

It does not have effect in @UDT and @Tuple types and in @Table-s that does not - * have @ClusteringColumn-s + *

+ * It does not have effect in @UDT and @Tuple types and in @Table-s that does + * not have @ClusteringColumn-s * - *

In case of using @ClusteringColumn we can repeat some information that is unique for a row. - * For this purpose we can define @StaticColumn annotation, that will create static column in the - * table + *

+ * In case of using @ClusteringColumn we can repeat some information that is + * unique for a row. For this purpose we can define @StaticColumn annotation, + * that will create static column in the table */ @Retention(value = RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) public @interface StaticColumn { - /** - * Default value is the name of the method normalized to underscore - * - * @return name of the column - */ - String value() default ""; + /** + * Default value is the name of the method normalized to underscore + * + * @return name of the column + */ + String value() default ""; - /** - * Ordinal will be used for ascending sorting of static columns - * - * @return number that used to sort columns in PartitionKey - */ - int ordinal() default 0; + /** + * Ordinal will be used for ascending sorting of static columns + * + * @return number that used to sort columns in PartitionKey + */ + int ordinal() default 0; - /** - * For reserved words in Cassandra we need quotation in CQL queries. This property marks that the - * name of the UDT type needs to be quoted. - * - *

Default value is false, we are quoting only selected names. - * - * @return true if name have to be quoted - */ - boolean forceQuote() default false; + /** + * For reserved words in Cassandra we need quotation in CQL queries. This + * property marks that the name of the UDT type needs to be quoted. + * + *

+ * Default value is false, we are quoting only selected names. + * + * @return true if name have to be quoted + */ + boolean forceQuote() default false; } diff --git a/src/main/java/net/helenus/mapping/annotation/Table.java b/src/main/java/net/helenus/mapping/annotation/Table.java index 0ddd4af..352f6d8 100644 --- a/src/main/java/net/helenus/mapping/annotation/Table.java +++ b/src/main/java/net/helenus/mapping/annotation/Table.java @@ -20,32 +20,36 @@ import java.lang.annotation.*; /** * Entity annotation * - *

Table annotation is used to define Table mapping to some interface + *

+ * Table annotation is used to define Table mapping to some interface * - *

There are three types of Entity mapping annotations: @Table, @UDT, @Tuple + *

+ * There are three types of Entity mapping annotations: @Table, @UDT, @Tuple * - *

For each @Table annotated interface Helenus will create/update/verify Cassandra Table and some - * indexes if needed on startup. + *

+ * For each @Table annotated interface Helenus will create/update/verify + * Cassandra Table and some indexes if needed on startup. */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface Table { - /** - * Default value is the SimpleName of the interface normalized to underscore - * - * @return name of the UDT type - */ - String value() default ""; + /** + * Default value is the SimpleName of the interface normalized to underscore + * + * @return name of the UDT type + */ + String value() default ""; - /** - * For reserved words in Cassandra we need quotation in CQL queries. This property marks that the - * name of the UDT type needs to be quoted. - * - *

Default value is false, we are quoting only selected names. - * - * @return true if name have to be quoted - */ - boolean forceQuote() default false; + /** + * For reserved words in Cassandra we need quotation in CQL queries. This + * property marks that the name of the UDT type needs to be quoted. + * + *

+ * Default value is false, we are quoting only selected names. + * + * @return true if name have to be quoted + */ + boolean forceQuote() default false; } diff --git a/src/main/java/net/helenus/mapping/annotation/Transient.java b/src/main/java/net/helenus/mapping/annotation/Transient.java index b988122..d4c67fd 100644 --- a/src/main/java/net/helenus/mapping/annotation/Transient.java +++ b/src/main/java/net/helenus/mapping/annotation/Transient.java @@ -17,8 +17,12 @@ package net.helenus.mapping.annotation; import java.lang.annotation.*; -/** Transient annotation is used to mark properties that are need not be mapped to the database. */ +/** + * Transient annotation is used to mark properties that are need not be mapped + * to the database. + */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) -public @interface Transient {} +public @interface Transient { +} diff --git a/src/main/java/net/helenus/mapping/annotation/Tuple.java b/src/main/java/net/helenus/mapping/annotation/Tuple.java index e2da9e1..5f1ca4a 100644 --- a/src/main/java/net/helenus/mapping/annotation/Tuple.java +++ b/src/main/java/net/helenus/mapping/annotation/Tuple.java @@ -20,15 +20,19 @@ import java.lang.annotation.*; /** * Entity annotation * - *

Tuple annotation is used to define Tuple type mapping to some interface + *

+ * Tuple annotation is used to define Tuple type mapping to some interface * - *

There are three types of Entity mapping annotations: @Table, @UDT, @Tuple + *

+ * There are three types of Entity mapping annotations: @Table, @UDT, @Tuple * - *

Tuple is fully embedded type, it is the sequence of the underline types and the order of the - * sub-types is important, therefore all @Column-s must have ordinal() and only @Column annotation - * supported for underline types + *

+ * Tuple is fully embedded type, it is the sequence of the underline types and + * the order of the sub-types is important, therefore all @Column-s must have + * ordinal() and only @Column annotation supported for underline types */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) -public @interface Tuple {} +public @interface Tuple { +} diff --git a/src/main/java/net/helenus/mapping/annotation/Types.java b/src/main/java/net/helenus/mapping/annotation/Types.java index eedb398..682396d 100644 --- a/src/main/java/net/helenus/mapping/annotation/Types.java +++ b/src/main/java/net/helenus/mapping/annotation/Types.java @@ -15,412 +15,511 @@ */ package net.helenus.mapping.annotation; -import com.datastax.driver.core.DataType; import java.lang.annotation.*; +import com.datastax.driver.core.DataType; + /** - * Types annotations are using for clarification of Cassandra data type for particular Java type. + * Types annotations are using for clarification of Cassandra data type for + * particular Java type. * - *

Sometimes it is possible to have for single Java type multiple Cassandra data types: - @String - * can be @DataType.Name.ASCII or @DataType.Name.TEXT or @DataType.Name.VARCHAR - @Long can - * be @DataType.Name.BIGINT or @DataType.Name.COUNTER + *

+ * Sometimes it is possible to have for single Java type multiple Cassandra data + * types: - @String can be @DataType.Name.ASCII or @DataType.Name.TEXT + * or @DataType.Name.VARCHAR - @Long can be @DataType.Name.BIGINT + * or @DataType.Name.COUNTER * - *

All those type annotations simplify mapping between Java types and Cassandra data types. They - * are not required, for each Java type there is a default Cassandra data type in Helenus, but in - * some cases you would like to control mapping to make sure that the right Cassandra data type is - * using. + *

+ * All those type annotations simplify mapping between Java types and Cassandra + * data types. They are not required, for each Java type there is a default + * Cassandra data type in Helenus, but in some cases you would like to control + * mapping to make sure that the right Cassandra data type is using. * - *

For complex types like collections, UDF and Tuple types all those annotations are using to - * clarify the sub-type(s) or class/UDF names. + *

+ * For complex types like collections, UDF and Tuple types all those annotations + * are using to clarify the sub-type(s) or class/UDF names. * - *

Has significant effect on schema operations. + *

+ * Has significant effect on schema operations. */ public final class Types { - private Types() {} + private Types() { + } - /** Says to use @DataType.Name.ASCII data type in schema Java type is @String */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Ascii {} + /** Says to use @DataType.Name.ASCII data type in schema Java type is @String */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Ascii { + } - /** Says to use @DataType.Name.BIGINT data type in schema Java type is @Long */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Bigint {} + /** Says to use @DataType.Name.BIGINT data type in schema Java type is @Long */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Bigint { + } - /** - * Says to use @DataType.Name.BLOB data type in schema Java type is @ByteBuffer or @byte[] Using - * by default - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Blob {} + /** + * Says to use @DataType.Name.BLOB data type in schema Java type is @ByteBuffer + * or @byte[] Using by default + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Blob { + } - /** - * Says to use @DataType.Name.LIST data type in schema with specific sub-type Java type is @List - * - *

Helenus does not allow to use a specific implementation of the collection thereof data - * retrieval operation result can be a collection with another implementation. - * - *

This annotation is usually used only for sub-types clarification and only in case if - * sub-type is Java type that corresponds to multiple Cassandra data types. - * - *

For this type there are special operations: prepend, prependAll, setIdx, append, appendAll, - * discard and discardAll in @UpdateOperation - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface List { + /** + * Says to use @DataType.Name.LIST data type in schema with specific sub-type + * Java type is @List + * + *

+ * Helenus does not allow to use a specific implementation of the collection + * thereof data retrieval operation result can be a collection with another + * implementation. + * + *

+ * This annotation is usually used only for sub-types clarification and only in + * case if sub-type is Java type that corresponds to multiple Cassandra data + * types. + * + *

+ * For this type there are special operations: prepend, prependAll, setIdx, + * append, appendAll, discard and discardAll in @UpdateOperation + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface List { - /** - * Clarification of using the sub-type data type in the collection. It supports only simple data - * type (not Collection, UDT or Tuple) - * - *

In case if you need UDT sub-type in the list, consider @UDTList annotation - * - * @return data type name of the value - */ - DataType.Name value(); - } + /** + * Clarification of using the sub-type data type in the collection. It supports + * only simple data type (not Collection, UDT or Tuple) + * + *

+ * In case if you need UDT sub-type in the list, consider @UDTList annotation + * + * @return data type name of the value + */ + DataType.Name value(); + } - /** - * Says to use @DataType.Name.MAP data type in schema with specific sub-types Java type is @Map - * - *

Helenus does not allow to use a specific implementation of the collection thereof data - * retrieval operation result can be a collection with another implementation. - * - *

This annotation is usually used only for sub-types clarification and only in case if - * sub-type is Java type that corresponds to multiple Cassandra data types. - * - *

For this type there are special operations: put and putAll in @UpdateOperation. - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Map { + /** + * Says to use @DataType.Name.MAP data type in schema with specific sub-types + * Java type is @Map + * + *

+ * Helenus does not allow to use a specific implementation of the collection + * thereof data retrieval operation result can be a collection with another + * implementation. + * + *

+ * This annotation is usually used only for sub-types clarification and only in + * case if sub-type is Java type that corresponds to multiple Cassandra data + * types. + * + *

+ * For this type there are special operations: put and putAll + * in @UpdateOperation. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Map { - /** - * Clarification of using the sub-type data type in the collection. It supports only simple data - * type (not Collection, UDT or Tuple) - * - *

In case if you need UDT key sub-type in the map, consider @UDTKeyMap or @UDTMap - * annotations - * - * @return data type name of the key - */ - DataType.Name key(); + /** + * Clarification of using the sub-type data type in the collection. It supports + * only simple data type (not Collection, UDT or Tuple) + * + *

+ * In case if you need UDT key sub-type in the map, consider @UDTKeyMap + * or @UDTMap annotations + * + * @return data type name of the key + */ + DataType.Name key(); - /** - * Clarification of using the sub-type data type in the collection. It supports only simple data - * type (not Collection, UDT or Tuple) - * - *

In case if you need UDT value sub-type in the map, consider @UDTValueMap or @UDTMap - * annotations - * - * @return data type name of the value - */ - DataType.Name value(); - } + /** + * Clarification of using the sub-type data type in the collection. It supports + * only simple data type (not Collection, UDT or Tuple) + * + *

+ * In case if you need UDT value sub-type in the map, consider @UDTValueMap + * or @UDTMap annotations + * + * @return data type name of the value + */ + DataType.Name value(); + } - /** - * Says to use @DataType.Name.COUNTER type in schema Java type is @Long - * - *

For this type there are special operations: increment and decrement in @UpdateOperation. You - * do not need to initialize counter value, it will be done automatically by Cassandra. - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Counter {} + /** + * Says to use @DataType.Name.COUNTER type in schema Java type is @Long + * + *

+ * For this type there are special operations: increment and decrement + * in @UpdateOperation. You do not need to initialize counter value, it will be + * done automatically by Cassandra. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Counter { + } - /** - * Says to use @DataType.Name.SET data type in schema with specific sub-type Java type is @Set - * - *

Helenus does not allow to use a specific implementation of the collection thereof data - * retrieval operation result can be a collection with another implementation. - * - *

This annotation is usually used only for sub-types clarification and only in case if - * sub-type is Java type that corresponds to multiple Cassandra data types. - * - *

For this type there are special operations: add, addAll, remove and removeAll - * in @UpdateOperation. - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Set { + /** + * Says to use @DataType.Name.SET data type in schema with specific sub-type + * Java type is @Set + * + *

+ * Helenus does not allow to use a specific implementation of the collection + * thereof data retrieval operation result can be a collection with another + * implementation. + * + *

+ * This annotation is usually used only for sub-types clarification and only in + * case if sub-type is Java type that corresponds to multiple Cassandra data + * types. + * + *

+ * For this type there are special operations: add, addAll, remove and removeAll + * in @UpdateOperation. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Set { - /** - * Clarification of using the sub-type data type in the collection. It supports only simple data - * type (not Collection, UDT or Tuple) - * - *

In case if you need UDT sub-type in the set, consider @UDTSet annotation - * - * @return data type name of the value - */ - DataType.Name value(); - } + /** + * Clarification of using the sub-type data type in the collection. It supports + * only simple data type (not Collection, UDT or Tuple) + * + *

+ * In case if you need UDT sub-type in the set, consider @UDTSet annotation + * + * @return data type name of the value + */ + DataType.Name value(); + } - /** - * Says to use @DataType.Name.CUSTOM type in schema Java type is @ByteBuffer or @byte[] - * - *

Uses for custom user types that has special implementation. Helenus does not deal with this - * class directly for now, uses only in serialized form. - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Custom { + /** + * Says to use @DataType.Name.CUSTOM type in schema Java type is @ByteBuffer + * or @byte[] + * + *

+ * Uses for custom user types that has special implementation. Helenus does not + * deal with this class directly for now, uses only in serialized form. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Custom { - /** - * Class name of the custom user type that is implementation of the type - * - * @return class name of the custom type implementation - */ - String className(); - } + /** + * Class name of the custom user type that is implementation of the type + * + * @return class name of the custom type implementation + */ + String className(); + } - /** Says to use @DataType.Name.TEXT type in schema Java type is @String Using by default */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Text {} + /** + * Says to use @DataType.Name.TEXT type in schema Java type is @String Using by + * default + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Text { + } - /** Says to use @DataType.Name.TIMESTAMP type in schema Java type is @Date Using by default */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Timestamp {} + /** + * Says to use @DataType.Name.TIMESTAMP type in schema Java type is @Date Using + * by default + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Timestamp { + } - /** Says to use @DataType.Name.TIMEUUID type in schema Java type is @UUID or @Date */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Timeuuid {} + /** + * Says to use @DataType.Name.TIMEUUID type in schema Java type is @UUID + * or @Date + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Timeuuid { + } - /** - * Says to use @DataType.Name.TUPLE type in schema Java type is @TupleValue or model interface - * with @Tuple annotation - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - public @interface Tuple { + /** + * Says to use @DataType.Name.TUPLE type in schema Java type is @TupleValue or + * model interface with @Tuple annotation + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + public @interface Tuple { - /** - * If Java type is the @TupleValue then this field is required. Any Cassandra Tuple is the - * sequence of Cassandra types. For now Helenus supports only simple data types in tuples - * for @TupleValue Java type - * - *

In case if Java type is the model interface with @Tuple annotation then all methods in - * this interface can have Types annotations that can be complex types as well. - * - * @return data type name sequence - */ - DataType.Name[] value() default {}; - } + /** + * If Java type is the @TupleValue then this field is required. Any Cassandra + * Tuple is the sequence of Cassandra types. For now Helenus supports only + * simple data types in tuples for @TupleValue Java type + * + *

+ * In case if Java type is the model interface with @Tuple annotation then all + * methods in this interface can have Types annotations that can be complex + * types as well. + * + * @return data type name sequence + */ + DataType.Name[] value() default {}; + } - /** - * Says to use @DataType.Name.UDT type in schema Java type is @UDTValue or model interface - * with @UDT annotation - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface UDT { + /** + * Says to use @DataType.Name.UDT type in schema Java type is @UDTValue or model + * interface with @UDT annotation + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface UDT { - /** - * If Java type is the @UDTValue then this field is required. Any Cassandra UDT has name and - * must be created before this use as a Cassandra Type. - * - *

This value is the UDT name of the Cassandra Type that was already created in the schema - * - *

In case of Java type is the model interface with @UDT annotation then this field is not - * using since model interface defines UserDefinedType with specific name - * - * @return UDT name - */ - String value() default ""; + /** + * If Java type is the @UDTValue then this field is required. Any Cassandra UDT + * has name and must be created before this use as a Cassandra Type. + * + *

+ * This value is the UDT name of the Cassandra Type that was already created in + * the schema + * + *

+ * In case of Java type is the model interface with @UDT annotation then this + * field is not using since model interface defines UserDefinedType with + * specific name + * + * @return UDT name + */ + String value() default ""; - /** - * Only used for JavaType @UDTValue - * - *

In case if value() method returns reserved word that can not be used as a name of UDT then - * forceQuote will add additional quotes around this name in all CQL queries. - * - *

Default value is false. - * - * @return true if quotation is needed - */ - boolean forceQuote() default false; - } + /** + * Only used for JavaType @UDTValue + * + *

+ * In case if value() method returns reserved word that can not be used as a + * name of UDT then forceQuote will add additional quotes around this name in + * all CQL queries. + * + *

+ * Default value is false. + * + * @return true if quotation is needed + */ + boolean forceQuote() default false; + } - /** - * Says to use @DataType.Name.MAP data type in schema with specific UDT sub-type as a key and - * simple sub-type as a value Java type is @Map - * - *

Helenus does not allow to use a specific implementation of the collection thereof data - * retrieval operation result can be a collection with another implementation. - * - *

This annotation is usually used only for sub-types clarification and only in case if - * sub-type is Java type that corresponds to multiple Cassandra data types. - * - *

For this type there are special operations: put and putAll in @UpdateOperation. - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface UDTKeyMap { + /** + * Says to use @DataType.Name.MAP data type in schema with specific UDT sub-type + * as a key and simple sub-type as a value Java type is @Map + * + *

+ * Helenus does not allow to use a specific implementation of the collection + * thereof data retrieval operation result can be a collection with another + * implementation. + * + *

+ * This annotation is usually used only for sub-types clarification and only in + * case if sub-type is Java type that corresponds to multiple Cassandra data + * types. + * + *

+ * For this type there are special operations: put and putAll + * in @UpdateOperation. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface UDTKeyMap { - /** - * Clarification of using the UDT data type as a key sub-type in the collection. - * - * @return annotation of UDT type - */ - UDT key(); + /** + * Clarification of using the UDT data type as a key sub-type in the collection. + * + * @return annotation of UDT type + */ + UDT key(); - /** - * Clarification of using the sub-type data type in the collection. It supports only simple data - * type (not Collection, UDT or Tuple) - * - *

In case if you need UDT value sub-type in the map, consider @UDTMap annotations - * - * @return data type name of the value - */ - DataType.Name value(); - } + /** + * Clarification of using the sub-type data type in the collection. It supports + * only simple data type (not Collection, UDT or Tuple) + * + *

+ * In case if you need UDT value sub-type in the map, consider @UDTMap + * annotations + * + * @return data type name of the value + */ + DataType.Name value(); + } - /** - * Says to use @DataType.Name.LIST data type in schema with specific UDT sub-type Java type - * is @List - * - *

Helenus does not allow to use a specific implementation of the collection thereof data - * retrieval operation result can be a collection with another implementation. - * - *

This annotation is usually used only for sub-types clarification and only in case if - * sub-type is Java type that corresponds to multiple Cassandra data types. - * - *

For this type there are special operations: prepend, prependAll, setIdx, append, appendAll, - * discard and discardAll in @UpdateOperation - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface UDTList { + /** + * Says to use @DataType.Name.LIST data type in schema with specific UDT + * sub-type Java type is @List + * + *

+ * Helenus does not allow to use a specific implementation of the collection + * thereof data retrieval operation result can be a collection with another + * implementation. + * + *

+ * This annotation is usually used only for sub-types clarification and only in + * case if sub-type is Java type that corresponds to multiple Cassandra data + * types. + * + *

+ * For this type there are special operations: prepend, prependAll, setIdx, + * append, appendAll, discard and discardAll in @UpdateOperation + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface UDTList { - /** - * Clarification of using the UDT data type as a sub-type in the collection. - * - * @return annotation of the UDT value - */ - UDT value(); - } + /** + * Clarification of using the UDT data type as a sub-type in the collection. + * + * @return annotation of the UDT value + */ + UDT value(); + } - /** - * Says to use @DataType.Name.MAP data type in schema with specific UDT sub-types Java type - * is @Map - * - *

Helenus does not allow to use a specific implementation of the collection thereof data - * retrieval operation result can be a collection with another implementation. - * - *

This annotation is usually used only for sub-types clarification and only in case if - * sub-type is Java type that corresponds to multiple Cassandra data types. - * - *

For this type there are special operations: put and putAll in @UpdateOperation. - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface UDTMap { + /** + * Says to use @DataType.Name.MAP data type in schema with specific UDT + * sub-types Java type is @Map + * + *

+ * Helenus does not allow to use a specific implementation of the collection + * thereof data retrieval operation result can be a collection with another + * implementation. + * + *

+ * This annotation is usually used only for sub-types clarification and only in + * case if sub-type is Java type that corresponds to multiple Cassandra data + * types. + * + *

+ * For this type there are special operations: put and putAll + * in @UpdateOperation. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface UDTMap { - /** - * Clarification of using the UDT data type as a key sub-type in the collection. - * - * @return annotation of the UDT key - */ - UDT key(); + /** + * Clarification of using the UDT data type as a key sub-type in the collection. + * + * @return annotation of the UDT key + */ + UDT key(); - /** - * Clarification of using the UDT data type as a value sub-type in the collection. - * - * @return annotation of the UDT value - */ - UDT value(); - } + /** + * Clarification of using the UDT data type as a value sub-type in the + * collection. + * + * @return annotation of the UDT value + */ + UDT value(); + } - /** - * Says to use @DataType.Name.SET data type in schema with specific UDT sub-type Java type is @Set - * - *

Helenus does not allow to use a specific implementation of the collection thereof data - * retrieval operation result can be a collection with another implementation. - * - *

This annotation is usually used only for sub-types clarification and only in case if - * sub-type is Java type that corresponds to multiple Cassandra data types. - * - *

For this type there are special operations: add, addAll, remove and removeAll - * in @UpdateOperation. - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface UDTSet { + /** + * Says to use @DataType.Name.SET data type in schema with specific UDT sub-type + * Java type is @Set + * + *

+ * Helenus does not allow to use a specific implementation of the collection + * thereof data retrieval operation result can be a collection with another + * implementation. + * + *

+ * This annotation is usually used only for sub-types clarification and only in + * case if sub-type is Java type that corresponds to multiple Cassandra data + * types. + * + *

+ * For this type there are special operations: add, addAll, remove and removeAll + * in @UpdateOperation. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface UDTSet { - /** - * Clarification of using the UDT data type as a sub-type in the collection. - * - * @return annotation of the UDT value - */ - UDT value(); - } + /** + * Clarification of using the UDT data type as a sub-type in the collection. + * + * @return annotation of the UDT value + */ + UDT value(); + } - /** - * Says to use @DataType.Name.MAP data type in schema with specific simple sub-type as a key and - * UDT sub-type as a value Java type is @Map - * - *

Helenus does not allow to use a specific implementation of the collection thereof data - * retrieval operation result can be a collection with another implementation. - * - *

This annotation is usually used only for sub-types clarification and only in case if - * sub-type is Java type that corresponds to multiple Cassandra data types. - * - *

For this type there are special operations: put and putAll in @UpdateOperation. - */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface UDTValueMap { + /** + * Says to use @DataType.Name.MAP data type in schema with specific simple + * sub-type as a key and UDT sub-type as a value Java type is @Map + * + *

+ * Helenus does not allow to use a specific implementation of the collection + * thereof data retrieval operation result can be a collection with another + * implementation. + * + *

+ * This annotation is usually used only for sub-types clarification and only in + * case if sub-type is Java type that corresponds to multiple Cassandra data + * types. + * + *

+ * For this type there are special operations: put and putAll + * in @UpdateOperation. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface UDTValueMap { - /** - * Clarification of using the sub-type data type in the collection. It supports only simple data - * type (not Collection, UDT or Tuple) - * - *

In case if you need UDT key sub-type in the map, consider @UDTMap annotations - * - * @return data type name of the key - */ - DataType.Name key(); + /** + * Clarification of using the sub-type data type in the collection. It supports + * only simple data type (not Collection, UDT or Tuple) + * + *

+ * In case if you need UDT key sub-type in the map, consider @UDTMap annotations + * + * @return data type name of the key + */ + DataType.Name key(); - /** - * Clarification of using the UDT data type as a value sub-type in the collection. - * - * @return annotation of the UDT value - */ - UDT value(); - } + /** + * Clarification of using the UDT data type as a value sub-type in the + * collection. + * + * @return annotation of the UDT value + */ + UDT value(); + } - /** Says to use @DataType.Name.UUID type in schema Java type is @UUID Using by default */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Uuid {} + /** + * Says to use @DataType.Name.UUID type in schema Java type is @UUID Using by + * default + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Uuid { + } - /** Says to use @DataType.Name.VARCHAR type in schema Java type is @String */ - @Documented - @Retention(RetentionPolicy.RUNTIME) - @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) - public @interface Varchar {} + /** Says to use @DataType.Name.VARCHAR type in schema Java type is @String */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) + public @interface Varchar { + } } diff --git a/src/main/java/net/helenus/mapping/annotation/UDT.java b/src/main/java/net/helenus/mapping/annotation/UDT.java index e330221..573688a 100644 --- a/src/main/java/net/helenus/mapping/annotation/UDT.java +++ b/src/main/java/net/helenus/mapping/annotation/UDT.java @@ -31,20 +31,21 @@ import java.lang.annotation.*; @Target({ElementType.TYPE}) public @interface UDT { - /** - * Default value is the SimpleName of the interface normalized to underscore - * - * @return name of the UDT type - */ - String value() default ""; + /** + * Default value is the SimpleName of the interface normalized to underscore + * + * @return name of the UDT type + */ + String value() default ""; - /** - * For reserved words in Cassandra we need quotation in CQL queries. This property marks that the - * name of the UDT type needs to be quoted. - * - *

Default value is false, we are quoting only selected names. - * - * @return true if name have to be quoted - */ - boolean forceQuote() default false; + /** + * For reserved words in Cassandra we need quotation in CQL queries. This + * property marks that the name of the UDT type needs to be quoted. + * + *

+ * Default value is false, we are quoting only selected names. + * + * @return true if name have to be quoted + */ + boolean forceQuote() default false; } diff --git a/src/main/java/net/helenus/mapping/convert/AbstractEntityValueWriter.java b/src/main/java/net/helenus/mapping/convert/AbstractEntityValueWriter.java index 1172dbe..7a38c37 100644 --- a/src/main/java/net/helenus/mapping/convert/AbstractEntityValueWriter.java +++ b/src/main/java/net/helenus/mapping/convert/AbstractEntityValueWriter.java @@ -16,6 +16,7 @@ package net.helenus.mapping.convert; import java.util.Map; + import net.helenus.core.Helenus; import net.helenus.core.reflect.MapExportable; import net.helenus.mapping.HelenusEntity; @@ -24,48 +25,48 @@ import net.helenus.mapping.value.BeanColumnValueProvider; public abstract class AbstractEntityValueWriter { - abstract void writeColumn(V outValue, Object value, HelenusProperty prop); + abstract void writeColumn(V outValue, Object value, HelenusProperty prop); - final HelenusEntity entity; + final HelenusEntity entity; - public AbstractEntityValueWriter(Class iface) { - this.entity = Helenus.entity(iface); - } + public AbstractEntityValueWriter(Class iface) { + this.entity = Helenus.entity(iface); + } - public void write(V outValue, Object source) { + public void write(V outValue, Object source) { - if (source instanceof MapExportable) { + if (source instanceof MapExportable) { - MapExportable exportable = (MapExportable) source; + MapExportable exportable = (MapExportable) source; - Map propertyToValueMap = exportable.toMap(); + Map propertyToValueMap = exportable.toMap(); - for (Map.Entry entry : propertyToValueMap.entrySet()) { + for (Map.Entry entry : propertyToValueMap.entrySet()) { - Object value = entry.getValue(); + Object value = entry.getValue(); - if (value == null) { - continue; - } + if (value == null) { + continue; + } - HelenusProperty prop = entity.getProperty(entry.getKey()); + HelenusProperty prop = entity.getProperty(entry.getKey()); - if (prop != null) { + if (prop != null) { - writeColumn(outValue, value, prop); - } - } + writeColumn(outValue, value, prop); + } + } - } else { + } else { - for (HelenusProperty prop : entity.getOrderedProperties()) { + for (HelenusProperty prop : entity.getOrderedProperties()) { - Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(source, -1, prop); + Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(source, -1, prop); - if (value != null) { - writeColumn(outValue, value, prop); - } - } - } - } + if (value != null) { + writeColumn(outValue, value, prop); + } + } + } + } } diff --git a/src/main/java/net/helenus/mapping/convert/ByteArrayToByteBufferConverter.java b/src/main/java/net/helenus/mapping/convert/ByteArrayToByteBufferConverter.java index f54b332..21a121b 100644 --- a/src/main/java/net/helenus/mapping/convert/ByteArrayToByteBufferConverter.java +++ b/src/main/java/net/helenus/mapping/convert/ByteArrayToByteBufferConverter.java @@ -19,15 +19,15 @@ import java.nio.ByteBuffer; import java.util.function.Function; public enum ByteArrayToByteBufferConverter implements Function { - INSTANCE; + INSTANCE; - @Override - public ByteBuffer apply(byte[] t) { + @Override + public ByteBuffer apply(byte[] t) { - if (t == null) { - return null; - } + if (t == null) { + return null; + } - return ByteBuffer.wrap(t); - } + return ByteBuffer.wrap(t); + } } diff --git a/src/main/java/net/helenus/mapping/convert/ByteBufferToByteArrayConverter.java b/src/main/java/net/helenus/mapping/convert/ByteBufferToByteArrayConverter.java index c8183ab..bf9e130 100644 --- a/src/main/java/net/helenus/mapping/convert/ByteBufferToByteArrayConverter.java +++ b/src/main/java/net/helenus/mapping/convert/ByteBufferToByteArrayConverter.java @@ -19,15 +19,15 @@ import java.nio.ByteBuffer; import java.util.function.Function; public enum ByteBufferToByteArrayConverter implements Function { - INSTANCE; + INSTANCE; - @Override - public byte[] apply(ByteBuffer t) { + @Override + public byte[] apply(ByteBuffer t) { - if (t == null) { - return null; - } + if (t == null) { + return null; + } - return t.array(); - } + return t.array(); + } } diff --git a/src/main/java/net/helenus/mapping/convert/CamelCaseToUnderscoreConverter.java b/src/main/java/net/helenus/mapping/convert/CamelCaseToUnderscoreConverter.java index 6f2ce20..b09d820 100644 --- a/src/main/java/net/helenus/mapping/convert/CamelCaseToUnderscoreConverter.java +++ b/src/main/java/net/helenus/mapping/convert/CamelCaseToUnderscoreConverter.java @@ -15,19 +15,20 @@ */ package net.helenus.mapping.convert; -import com.google.common.base.CaseFormat; import java.util.function.Function; +import com.google.common.base.CaseFormat; + public enum CamelCaseToUnderscoreConverter implements Function { - INSTANCE; + INSTANCE; - @Override - public String apply(String source) { + @Override + public String apply(String source) { - if (source == null) { - throw new IllegalArgumentException("empty parameter"); - } + if (source == null) { + throw new IllegalArgumentException("empty parameter"); + } - return CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, source); - } + return CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, source); + } } diff --git a/src/main/java/net/helenus/mapping/convert/DateToTimeuuidConverter.java b/src/main/java/net/helenus/mapping/convert/DateToTimeuuidConverter.java index 7db03d9..c4eae86 100644 --- a/src/main/java/net/helenus/mapping/convert/DateToTimeuuidConverter.java +++ b/src/main/java/net/helenus/mapping/convert/DateToTimeuuidConverter.java @@ -18,15 +18,16 @@ package net.helenus.mapping.convert; import java.util.Date; import java.util.UUID; import java.util.function.Function; + import net.helenus.support.Timeuuid; /** Simple Date to TimeUUID Converter */ public enum DateToTimeuuidConverter implements Function { - INSTANCE; + INSTANCE; - @Override - public UUID apply(Date source) { - long milliseconds = source.getTime(); - return Timeuuid.of(milliseconds); - } + @Override + public UUID apply(Date source) { + long milliseconds = source.getTime(); + return Timeuuid.of(milliseconds); + } } diff --git a/src/main/java/net/helenus/mapping/convert/EnumToStringConverter.java b/src/main/java/net/helenus/mapping/convert/EnumToStringConverter.java index 15e7d04..7020f7e 100644 --- a/src/main/java/net/helenus/mapping/convert/EnumToStringConverter.java +++ b/src/main/java/net/helenus/mapping/convert/EnumToStringConverter.java @@ -19,10 +19,10 @@ import java.util.function.Function; /** Enum to String Converter */ public enum EnumToStringConverter implements Function { - INSTANCE; + INSTANCE; - @Override - public String apply(Enum source) { - return source.name(); - } + @Override + public String apply(Enum source) { + return source.name(); + } } diff --git a/src/main/java/net/helenus/mapping/convert/ProxyValueReader.java b/src/main/java/net/helenus/mapping/convert/ProxyValueReader.java index 8100679..07b4419 100644 --- a/src/main/java/net/helenus/mapping/convert/ProxyValueReader.java +++ b/src/main/java/net/helenus/mapping/convert/ProxyValueReader.java @@ -17,6 +17,7 @@ package net.helenus.mapping.convert; import java.util.Map; import java.util.function.Function; + import net.helenus.core.Helenus; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.value.ColumnValueProvider; @@ -24,23 +25,23 @@ import net.helenus.mapping.value.ValueProviderMap; public class ProxyValueReader implements Function { - private final Class iface; - private final HelenusEntity entity; - private final ColumnValueProvider valueProvider; + private final Class iface; + private final HelenusEntity entity; + private final ColumnValueProvider valueProvider; - public ProxyValueReader(Class iface, ColumnValueProvider valueProvider) { - this.iface = iface; - this.entity = Helenus.entity(iface); - this.valueProvider = valueProvider; - } + public ProxyValueReader(Class iface, ColumnValueProvider valueProvider) { + this.iface = iface; + this.entity = Helenus.entity(iface); + this.valueProvider = valueProvider; + } - @Override - public Object apply(T source) { - if (source != null) { - Map map = new ValueProviderMap(source, valueProvider, entity); + @Override + public Object apply(T source) { + if (source != null) { + Map map = new ValueProviderMap(source, valueProvider, entity); - return Helenus.map(iface, map); - } - return null; - } + return Helenus.map(iface, map); + } + return null; + } } diff --git a/src/main/java/net/helenus/mapping/convert/StringToEnumConverter.java b/src/main/java/net/helenus/mapping/convert/StringToEnumConverter.java index ec632f5..41358ab 100644 --- a/src/main/java/net/helenus/mapping/convert/StringToEnumConverter.java +++ b/src/main/java/net/helenus/mapping/convert/StringToEnumConverter.java @@ -19,14 +19,14 @@ import java.util.function.Function; public class StringToEnumConverter implements Function { - private final Class enumClass; + private final Class enumClass; - public StringToEnumConverter(Class enumClass) { - this.enumClass = (Class) enumClass; - } + public StringToEnumConverter(Class enumClass) { + this.enumClass = (Class) enumClass; + } - @Override - public Enum apply(String source) { - return Enum.valueOf(enumClass, source); - } + @Override + public Enum apply(String source) { + return Enum.valueOf(enumClass, source); + } } diff --git a/src/main/java/net/helenus/mapping/convert/TimeuuidToDateConverter.java b/src/main/java/net/helenus/mapping/convert/TimeuuidToDateConverter.java index 352e019..51ee3df 100644 --- a/src/main/java/net/helenus/mapping/convert/TimeuuidToDateConverter.java +++ b/src/main/java/net/helenus/mapping/convert/TimeuuidToDateConverter.java @@ -18,13 +18,14 @@ package net.helenus.mapping.convert; import java.util.Date; import java.util.UUID; import java.util.function.Function; + import net.helenus.support.Timeuuid; public enum TimeuuidToDateConverter implements Function { - INSTANCE; + INSTANCE; - @Override - public Date apply(UUID source) { - return new Date(Timeuuid.getTimestampMillis(source)); - } + @Override + public Date apply(UUID source) { + return new Date(Timeuuid.getTimestampMillis(source)); + } } diff --git a/src/main/java/net/helenus/mapping/convert/TupleValueWriter.java b/src/main/java/net/helenus/mapping/convert/TupleValueWriter.java index b197d5c..4ab4ebb 100644 --- a/src/main/java/net/helenus/mapping/convert/TupleValueWriter.java +++ b/src/main/java/net/helenus/mapping/convert/TupleValueWriter.java @@ -15,44 +15,45 @@ */ package net.helenus.mapping.convert; -import com.datastax.driver.core.TupleType; -import com.datastax.driver.core.TupleValue; import java.nio.ByteBuffer; import java.util.function.Function; + +import com.datastax.driver.core.TupleType; +import com.datastax.driver.core.TupleValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; import net.helenus.mapping.value.TupleColumnValuePreparer; -public class TupleValueWriter extends AbstractEntityValueWriter - implements Function { +public class TupleValueWriter extends AbstractEntityValueWriter implements Function { - private final TupleType tupleType; - private final TupleColumnValuePreparer valuePreparer; + private final TupleType tupleType; + private final TupleColumnValuePreparer valuePreparer; - public TupleValueWriter(Class iface, TupleType tupleType, SessionRepository repository) { - super(iface); + public TupleValueWriter(Class iface, TupleType tupleType, SessionRepository repository) { + super(iface); - this.tupleType = tupleType; - this.valuePreparer = new TupleColumnValuePreparer(tupleType, repository); - } + this.tupleType = tupleType; + this.valuePreparer = new TupleColumnValuePreparer(tupleType, repository); + } - @Override - void writeColumn(TupleValue udtValue, Object value, HelenusProperty prop) { + @Override + void writeColumn(TupleValue udtValue, Object value, HelenusProperty prop) { - ByteBuffer bytes = (ByteBuffer) valuePreparer.prepareColumnValue(value, prop); + ByteBuffer bytes = (ByteBuffer) valuePreparer.prepareColumnValue(value, prop); - if (bytes != null) { - udtValue.setBytesUnsafe(prop.getOrdinal(), bytes); - } - } + if (bytes != null) { + udtValue.setBytesUnsafe(prop.getOrdinal(), bytes); + } + } - @Override - public TupleValue apply(Object source) { - if (source != null) { - TupleValue outValue = tupleType.newValue(); - write(outValue, source); - return outValue; - } - return null; - } + @Override + public TupleValue apply(Object source) { + if (source != null) { + TupleValue outValue = tupleType.newValue(); + write(outValue, source); + return outValue; + } + return null; + } } diff --git a/src/main/java/net/helenus/mapping/convert/TypedConverter.java b/src/main/java/net/helenus/mapping/convert/TypedConverter.java index 52642d2..d9242ce 100644 --- a/src/main/java/net/helenus/mapping/convert/TypedConverter.java +++ b/src/main/java/net/helenus/mapping/convert/TypedConverter.java @@ -16,50 +16,50 @@ package net.helenus.mapping.convert; import java.util.function.Function; + import net.helenus.support.HelenusMappingException; public class TypedConverter implements Function { - private final Class inputType; - private final Class outputType; - private final Function delegate; + private final Class inputType; + private final Class outputType; + private final Function delegate; - public TypedConverter(Class inputType, Class outputType, Function delegate) { - this.inputType = inputType; - this.outputType = outputType; - this.delegate = delegate; - } + public TypedConverter(Class inputType, Class outputType, Function delegate) { + this.inputType = inputType; + this.outputType = outputType; + this.delegate = delegate; + } - public static TypedConverter create( - Class inputType, Class outputType, Function delegate) { - return new TypedConverter(inputType, outputType, delegate); - } + public static TypedConverter create(Class inputType, Class outputType, Function delegate) { + return new TypedConverter(inputType, outputType, delegate); + } - @Override - public Object apply(Object inputUnknown) { + @Override + public Object apply(Object inputUnknown) { - if (inputUnknown == null) { - return null; - } + if (inputUnknown == null) { + return null; + } - if (!inputType.isAssignableFrom(inputUnknown.getClass())) { - throw new HelenusMappingException( - "expected " + inputType + " type for input parameter " + inputUnknown.getClass()); - } + if (!inputType.isAssignableFrom(inputUnknown.getClass())) { + throw new HelenusMappingException( + "expected " + inputType + " type for input parameter " + inputUnknown.getClass()); + } - I input = (I) inputUnknown; + I input = (I) inputUnknown; - O outputUnknown = delegate.apply(input); + O outputUnknown = delegate.apply(input); - if (outputUnknown == null) { - return null; - } + if (outputUnknown == null) { + return null; + } - if (!outputType.isAssignableFrom(outputUnknown.getClass())) { - throw new HelenusMappingException( - "expected " + outputType + " type for output result " + outputUnknown.getClass()); - } + if (!outputType.isAssignableFrom(outputUnknown.getClass())) { + throw new HelenusMappingException( + "expected " + outputType + " type for output result " + outputUnknown.getClass()); + } - return outputUnknown; - } + return outputUnknown; + } } diff --git a/src/main/java/net/helenus/mapping/convert/UDTValueWriter.java b/src/main/java/net/helenus/mapping/convert/UDTValueWriter.java index 8156470..75d2c9e 100644 --- a/src/main/java/net/helenus/mapping/convert/UDTValueWriter.java +++ b/src/main/java/net/helenus/mapping/convert/UDTValueWriter.java @@ -15,44 +15,45 @@ */ package net.helenus.mapping.convert; -import com.datastax.driver.core.UDTValue; -import com.datastax.driver.core.UserType; import java.nio.ByteBuffer; import java.util.function.Function; + +import com.datastax.driver.core.UDTValue; +import com.datastax.driver.core.UserType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; import net.helenus.mapping.value.UDTColumnValuePreparer; -public class UDTValueWriter extends AbstractEntityValueWriter - implements Function { +public class UDTValueWriter extends AbstractEntityValueWriter implements Function { - final UserType userType; - final UDTColumnValuePreparer valuePreparer; + final UserType userType; + final UDTColumnValuePreparer valuePreparer; - public UDTValueWriter(Class iface, UserType userType, SessionRepository repository) { - super(iface); + public UDTValueWriter(Class iface, UserType userType, SessionRepository repository) { + super(iface); - this.userType = userType; - this.valuePreparer = new UDTColumnValuePreparer(userType, repository); - } + this.userType = userType; + this.valuePreparer = new UDTColumnValuePreparer(userType, repository); + } - @Override - void writeColumn(UDTValue udtValue, Object value, HelenusProperty prop) { + @Override + void writeColumn(UDTValue udtValue, Object value, HelenusProperty prop) { - ByteBuffer bytes = (ByteBuffer) valuePreparer.prepareColumnValue(value, prop); + ByteBuffer bytes = (ByteBuffer) valuePreparer.prepareColumnValue(value, prop); - if (bytes != null) { - udtValue.setBytesUnsafe(prop.getColumnName().getName(), bytes); - } - } + if (bytes != null) { + udtValue.setBytesUnsafe(prop.getColumnName().getName(), bytes); + } + } - @Override - public UDTValue apply(Object source) { - if (source != null) { - UDTValue outValue = userType.newValue(); - write(outValue, source); - return outValue; - } - return null; - } + @Override + public UDTValue apply(Object source) { + if (source != null) { + UDTValue outValue = userType.newValue(); + write(outValue, source); + return outValue; + } + return null; + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/EntityToTupleValueConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/EntityToTupleValueConverter.java index ded9f55..0717c04 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/EntityToTupleValueConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/EntityToTupleValueConverter.java @@ -15,17 +15,17 @@ */ package net.helenus.mapping.convert.tuple; +import java.util.function.Function; + import com.datastax.driver.core.TupleType; import com.datastax.driver.core.TupleValue; -import java.util.function.Function; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.TupleValueWriter; -public final class EntityToTupleValueConverter extends TupleValueWriter - implements Function { +public final class EntityToTupleValueConverter extends TupleValueWriter implements Function { - public EntityToTupleValueConverter( - Class iface, TupleType tupleType, SessionRepository repository) { - super(iface, tupleType, repository); - } + public EntityToTupleValueConverter(Class iface, TupleType tupleType, SessionRepository repository) { + super(iface, tupleType, repository); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleKeyMapConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleKeyMapConverter.java index f8f1c81..9b4ee51 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleKeyMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleKeyMapConverter.java @@ -15,24 +15,25 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleType; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.TupleType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.TupleValueWriter; import net.helenus.support.Transformers; public final class MapToTupleKeyMapConverter implements Function { - final TupleValueWriter writer; + final TupleValueWriter writer; - public MapToTupleKeyMapConverter( - Class iface, TupleType tupleType, SessionRepository repository) { - this.writer = new TupleValueWriter(iface, tupleType, repository); - } + public MapToTupleKeyMapConverter(Class iface, TupleType tupleType, SessionRepository repository) { + this.writer = new TupleValueWriter(iface, tupleType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformMapKey((Map) t, writer); - } + @Override + public Object apply(Object t) { + return Transformers.transformMapKey((Map) t, writer); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleMapConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleMapConverter.java index d99a7a1..821855f 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleMapConverter.java @@ -15,30 +15,28 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleType; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.TupleType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.TupleValueWriter; import net.helenus.support.Transformers; public final class MapToTupleMapConverter implements Function { - final TupleValueWriter keyWriter; - final TupleValueWriter valueWriter; + final TupleValueWriter keyWriter; + final TupleValueWriter valueWriter; - public MapToTupleMapConverter( - Class keyClass, - TupleType keyType, - Class valueClass, - TupleType valueType, - SessionRepository repository) { - this.keyWriter = new TupleValueWriter(keyClass, keyType, repository); - this.valueWriter = new TupleValueWriter(valueClass, valueType, repository); - } + public MapToTupleMapConverter(Class keyClass, TupleType keyType, Class valueClass, TupleType valueType, + SessionRepository repository) { + this.keyWriter = new TupleValueWriter(keyClass, keyType, repository); + this.valueWriter = new TupleValueWriter(valueClass, valueType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformMap((Map) t, keyWriter, valueWriter); - } + @Override + public Object apply(Object t) { + return Transformers.transformMap((Map) t, keyWriter, valueWriter); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleValueMapConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleValueMapConverter.java index 33901f5..4186487 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleValueMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/MapToTupleValueMapConverter.java @@ -15,24 +15,25 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleType; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.TupleType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.TupleValueWriter; import net.helenus.support.Transformers; public final class MapToTupleValueMapConverter implements Function { - final TupleValueWriter writer; + final TupleValueWriter writer; - public MapToTupleValueMapConverter( - Class iface, TupleType tupleType, SessionRepository repository) { - this.writer = new TupleValueWriter(iface, tupleType, repository); - } + public MapToTupleValueMapConverter(Class iface, TupleType tupleType, SessionRepository repository) { + this.writer = new TupleValueWriter(iface, tupleType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformMapValue((Map) t, writer); - } + @Override + public Object apply(Object t) { + return Transformers.transformMapValue((Map) t, writer); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/SetToTupleSetConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/SetToTupleSetConverter.java index db88523..6b1e0ed 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/SetToTupleSetConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/SetToTupleSetConverter.java @@ -15,23 +15,25 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleType; import java.util.Set; import java.util.function.Function; + +import com.datastax.driver.core.TupleType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.TupleValueWriter; import net.helenus.support.Transformers; public final class SetToTupleSetConverter implements Function { - final TupleValueWriter writer; + final TupleValueWriter writer; - public SetToTupleSetConverter(Class iface, TupleType tupleType, SessionRepository repository) { - this.writer = new TupleValueWriter(iface, tupleType, repository); - } + public SetToTupleSetConverter(Class iface, TupleType tupleType, SessionRepository repository) { + this.writer = new TupleValueWriter(iface, tupleType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformSet((Set) t, writer); - } + @Override + public Object apply(Object t) { + return Transformers.transformSet((Set) t, writer); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/TupleKeyMapToMapConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/TupleKeyMapToMapConverter.java index 2f6605b..5142dc5 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/TupleKeyMapToMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/TupleKeyMapToMapConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleValue; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.TupleValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.TupleColumnValueProvider; @@ -25,14 +27,14 @@ import net.helenus.support.Transformers; public final class TupleKeyMapToMapConverter implements Function { - final ProxyValueReader reader; + final ProxyValueReader reader; - public TupleKeyMapToMapConverter(Class iface, SessionRepository repository) { - this.reader = new ProxyValueReader(iface, new TupleColumnValueProvider(repository)); - } + public TupleKeyMapToMapConverter(Class iface, SessionRepository repository) { + this.reader = new ProxyValueReader(iface, new TupleColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformMapKey((Map) t, reader); - } + @Override + public Object apply(Object t) { + return Transformers.transformMapKey((Map) t, reader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/TupleListToListConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/TupleListToListConverter.java index 73a42b4..4fae478 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/TupleListToListConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/TupleListToListConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleValue; import java.util.List; import java.util.function.Function; + +import com.datastax.driver.core.TupleValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.TupleColumnValueProvider; @@ -25,14 +27,14 @@ import net.helenus.support.Transformers; public final class TupleListToListConverter implements Function { - final ProxyValueReader reader; + final ProxyValueReader reader; - public TupleListToListConverter(Class iface, SessionRepository repository) { - this.reader = new ProxyValueReader(iface, new TupleColumnValueProvider(repository)); - } + public TupleListToListConverter(Class iface, SessionRepository repository) { + this.reader = new ProxyValueReader(iface, new TupleColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformList((List) t, reader); - } + @Override + public Object apply(Object t) { + return Transformers.transformList((List) t, reader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/TupleMapToMapConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/TupleMapToMapConverter.java index 50c6a44..dc3e2b3 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/TupleMapToMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/TupleMapToMapConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleValue; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.TupleValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.TupleColumnValueProvider; @@ -25,19 +27,16 @@ import net.helenus.support.Transformers; public final class TupleMapToMapConverter implements Function { - final ProxyValueReader keyReader; - final ProxyValueReader valueReader; + final ProxyValueReader keyReader; + final ProxyValueReader valueReader; - public TupleMapToMapConverter( - Class keyClass, Class valueClass, SessionRepository repository) { - this.keyReader = - new ProxyValueReader(keyClass, new TupleColumnValueProvider(repository)); - this.valueReader = - new ProxyValueReader(valueClass, new TupleColumnValueProvider(repository)); - } + public TupleMapToMapConverter(Class keyClass, Class valueClass, SessionRepository repository) { + this.keyReader = new ProxyValueReader(keyClass, new TupleColumnValueProvider(repository)); + this.valueReader = new ProxyValueReader(valueClass, new TupleColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformMap((Map) t, keyReader, valueReader); - } + @Override + public Object apply(Object t) { + return Transformers.transformMap((Map) t, keyReader, valueReader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/TupleSetToSetConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/TupleSetToSetConverter.java index 125e93a..5a9c8b5 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/TupleSetToSetConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/TupleSetToSetConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleValue; import java.util.Set; import java.util.function.Function; + +import com.datastax.driver.core.TupleValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.TupleColumnValueProvider; @@ -25,14 +27,14 @@ import net.helenus.support.Transformers; public final class TupleSetToSetConverter implements Function { - final ProxyValueReader reader; + final ProxyValueReader reader; - public TupleSetToSetConverter(Class iface, SessionRepository repository) { - this.reader = new ProxyValueReader(iface, new TupleColumnValueProvider(repository)); - } + public TupleSetToSetConverter(Class iface, SessionRepository repository) { + this.reader = new ProxyValueReader(iface, new TupleColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformSet((Set) t, reader); - } + @Override + public Object apply(Object t) { + return Transformers.transformSet((Set) t, reader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/TupleValueMapToMapConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/TupleValueMapToMapConverter.java index 95ccff3..2816c9c 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/TupleValueMapToMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/TupleValueMapToMapConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleValue; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.TupleValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.TupleColumnValueProvider; @@ -25,14 +27,14 @@ import net.helenus.support.Transformers; public final class TupleValueMapToMapConverter implements Function { - final ProxyValueReader reader; + final ProxyValueReader reader; - public TupleValueMapToMapConverter(Class iface, SessionRepository repository) { - this.reader = new ProxyValueReader(iface, new TupleColumnValueProvider(repository)); - } + public TupleValueMapToMapConverter(Class iface, SessionRepository repository) { + this.reader = new ProxyValueReader(iface, new TupleColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformMapValue((Map) t, reader); - } + @Override + public Object apply(Object t) { + return Transformers.transformMapValue((Map) t, reader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/tuple/TupleValueToEntityConverter.java b/src/main/java/net/helenus/mapping/convert/tuple/TupleValueToEntityConverter.java index 43d1d1f..7e5b5f3 100644 --- a/src/main/java/net/helenus/mapping/convert/tuple/TupleValueToEntityConverter.java +++ b/src/main/java/net/helenus/mapping/convert/tuple/TupleValueToEntityConverter.java @@ -15,16 +15,19 @@ */ package net.helenus.mapping.convert.tuple; -import com.datastax.driver.core.TupleValue; import java.util.function.Function; + +import com.datastax.driver.core.TupleValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.TupleColumnValueProvider; public final class TupleValueToEntityConverter extends ProxyValueReader - implements Function { + implements + Function { - public TupleValueToEntityConverter(Class iface, SessionRepository repository) { - super(iface, new TupleColumnValueProvider(repository)); - } + public TupleValueToEntityConverter(Class iface, SessionRepository repository) { + super(iface, new TupleColumnValueProvider(repository)); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/EntityToUDTValueConverter.java b/src/main/java/net/helenus/mapping/convert/udt/EntityToUDTValueConverter.java index 56f9932..58b9c9a 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/EntityToUDTValueConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/EntityToUDTValueConverter.java @@ -16,13 +16,13 @@ package net.helenus.mapping.convert.udt; import com.datastax.driver.core.UserType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.UDTValueWriter; public final class EntityToUDTValueConverter extends UDTValueWriter { - public EntityToUDTValueConverter( - Class iface, UserType userType, SessionRepository repository) { - super(iface, userType, repository); - } + public EntityToUDTValueConverter(Class iface, UserType userType, SessionRepository repository) { + super(iface, userType, repository); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/ListToUDTListConverter.java b/src/main/java/net/helenus/mapping/convert/udt/ListToUDTListConverter.java index 4d3e318..66c3e15 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/ListToUDTListConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/ListToUDTListConverter.java @@ -15,23 +15,25 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UserType; import java.util.List; import java.util.function.Function; + +import com.datastax.driver.core.UserType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.UDTValueWriter; import net.helenus.support.Transformers; public final class ListToUDTListConverter implements Function { - final UDTValueWriter writer; + final UDTValueWriter writer; - public ListToUDTListConverter(Class iface, UserType userType, SessionRepository repository) { - this.writer = new UDTValueWriter(iface, userType, repository); - } + public ListToUDTListConverter(Class iface, UserType userType, SessionRepository repository) { + this.writer = new UDTValueWriter(iface, userType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformList((List) t, writer); - } + @Override + public Object apply(Object t) { + return Transformers.transformList((List) t, writer); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/MapToUDTKeyMapConverter.java b/src/main/java/net/helenus/mapping/convert/udt/MapToUDTKeyMapConverter.java index 63a51a2..64c228c 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/MapToUDTKeyMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/MapToUDTKeyMapConverter.java @@ -15,23 +15,25 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UserType; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.UserType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.UDTValueWriter; import net.helenus.support.Transformers; public final class MapToUDTKeyMapConverter implements Function { - final UDTValueWriter writer; + final UDTValueWriter writer; - public MapToUDTKeyMapConverter(Class iface, UserType userType, SessionRepository repository) { - this.writer = new UDTValueWriter(iface, userType, repository); - } + public MapToUDTKeyMapConverter(Class iface, UserType userType, SessionRepository repository) { + this.writer = new UDTValueWriter(iface, userType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformMapKey((Map) t, writer); - } + @Override + public Object apply(Object t) { + return Transformers.transformMapKey((Map) t, writer); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/MapToUDTMapConverter.java b/src/main/java/net/helenus/mapping/convert/udt/MapToUDTMapConverter.java index a888647..e40bc0e 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/MapToUDTMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/MapToUDTMapConverter.java @@ -15,30 +15,28 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UserType; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.UserType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.UDTValueWriter; import net.helenus.support.Transformers; public final class MapToUDTMapConverter implements Function { - final UDTValueWriter keyWriter; - final UDTValueWriter valueWriter; + final UDTValueWriter keyWriter; + final UDTValueWriter valueWriter; - public MapToUDTMapConverter( - Class keyClass, - UserType keyType, - Class valueClass, - UserType valueType, - SessionRepository repository) { - this.keyWriter = new UDTValueWriter(keyClass, keyType, repository); - this.valueWriter = new UDTValueWriter(valueClass, valueType, repository); - } + public MapToUDTMapConverter(Class keyClass, UserType keyType, Class valueClass, UserType valueType, + SessionRepository repository) { + this.keyWriter = new UDTValueWriter(keyClass, keyType, repository); + this.valueWriter = new UDTValueWriter(valueClass, valueType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformMap((Map) t, keyWriter, valueWriter); - } + @Override + public Object apply(Object t) { + return Transformers.transformMap((Map) t, keyWriter, valueWriter); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/MapToUDTValueMapConverter.java b/src/main/java/net/helenus/mapping/convert/udt/MapToUDTValueMapConverter.java index 9ca2936..1c4f1ff 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/MapToUDTValueMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/MapToUDTValueMapConverter.java @@ -15,24 +15,25 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UserType; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.UserType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.UDTValueWriter; import net.helenus.support.Transformers; public final class MapToUDTValueMapConverter implements Function { - final UDTValueWriter writer; + final UDTValueWriter writer; - public MapToUDTValueMapConverter( - Class iface, UserType userType, SessionRepository repository) { - this.writer = new UDTValueWriter(iface, userType, repository); - } + public MapToUDTValueMapConverter(Class iface, UserType userType, SessionRepository repository) { + this.writer = new UDTValueWriter(iface, userType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformMapValue((Map) t, writer); - } + @Override + public Object apply(Object t) { + return Transformers.transformMapValue((Map) t, writer); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/SetToUDTSetConverter.java b/src/main/java/net/helenus/mapping/convert/udt/SetToUDTSetConverter.java index 9de5185..d2f8a23 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/SetToUDTSetConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/SetToUDTSetConverter.java @@ -15,23 +15,25 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UserType; import java.util.Set; import java.util.function.Function; + +import com.datastax.driver.core.UserType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.UDTValueWriter; import net.helenus.support.Transformers; public final class SetToUDTSetConverter implements Function { - final UDTValueWriter writer; + final UDTValueWriter writer; - public SetToUDTSetConverter(Class iface, UserType userType, SessionRepository repository) { - this.writer = new UDTValueWriter(iface, userType, repository); - } + public SetToUDTSetConverter(Class iface, UserType userType, SessionRepository repository) { + this.writer = new UDTValueWriter(iface, userType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformSet((Set) t, writer); - } + @Override + public Object apply(Object t) { + return Transformers.transformSet((Set) t, writer); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/UDTKeyMapToMapConverter.java b/src/main/java/net/helenus/mapping/convert/udt/UDTKeyMapToMapConverter.java index 7744fc0..a3e1775 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/UDTKeyMapToMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/UDTKeyMapToMapConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UDTValue; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.UDTValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.UDTColumnValueProvider; @@ -25,14 +27,14 @@ import net.helenus.support.Transformers; public final class UDTKeyMapToMapConverter implements Function { - final ProxyValueReader reader; + final ProxyValueReader reader; - public UDTKeyMapToMapConverter(Class iface, SessionRepository repository) { - this.reader = new ProxyValueReader(iface, new UDTColumnValueProvider(repository)); - } + public UDTKeyMapToMapConverter(Class iface, SessionRepository repository) { + this.reader = new ProxyValueReader(iface, new UDTColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformMapKey((Map) t, reader); - } + @Override + public Object apply(Object t) { + return Transformers.transformMapKey((Map) t, reader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/UDTListToListConverter.java b/src/main/java/net/helenus/mapping/convert/udt/UDTListToListConverter.java index 078a7aa..f711ce2 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/UDTListToListConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/UDTListToListConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UDTValue; import java.util.List; import java.util.function.Function; + +import com.datastax.driver.core.UDTValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.UDTColumnValueProvider; @@ -25,14 +27,14 @@ import net.helenus.support.Transformers; public final class UDTListToListConverter implements Function { - final ProxyValueReader reader; + final ProxyValueReader reader; - public UDTListToListConverter(Class iface, SessionRepository repository) { - this.reader = new ProxyValueReader(iface, new UDTColumnValueProvider(repository)); - } + public UDTListToListConverter(Class iface, SessionRepository repository) { + this.reader = new ProxyValueReader(iface, new UDTColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformList((List) t, reader); - } + @Override + public Object apply(Object t) { + return Transformers.transformList((List) t, reader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/UDTMapToMapConverter.java b/src/main/java/net/helenus/mapping/convert/udt/UDTMapToMapConverter.java index 4ae3de5..e314bb3 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/UDTMapToMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/UDTMapToMapConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UDTValue; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.UDTValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.UDTColumnValueProvider; @@ -25,19 +27,16 @@ import net.helenus.support.Transformers; public final class UDTMapToMapConverter implements Function { - final ProxyValueReader keyReader; - final ProxyValueReader valueReader; + final ProxyValueReader keyReader; + final ProxyValueReader valueReader; - public UDTMapToMapConverter( - Class keyClass, Class valueClass, SessionRepository repository) { - this.keyReader = - new ProxyValueReader(keyClass, new UDTColumnValueProvider(repository)); - this.valueReader = - new ProxyValueReader(valueClass, new UDTColumnValueProvider(repository)); - } + public UDTMapToMapConverter(Class keyClass, Class valueClass, SessionRepository repository) { + this.keyReader = new ProxyValueReader(keyClass, new UDTColumnValueProvider(repository)); + this.valueReader = new ProxyValueReader(valueClass, new UDTColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformMap((Map) t, keyReader, valueReader); - } + @Override + public Object apply(Object t) { + return Transformers.transformMap((Map) t, keyReader, valueReader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/UDTSetToSetConverter.java b/src/main/java/net/helenus/mapping/convert/udt/UDTSetToSetConverter.java index 0adae72..3f5c267 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/UDTSetToSetConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/UDTSetToSetConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UDTValue; import java.util.Set; import java.util.function.Function; + +import com.datastax.driver.core.UDTValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.UDTColumnValueProvider; @@ -25,14 +27,14 @@ import net.helenus.support.Transformers; public final class UDTSetToSetConverter implements Function { - final ProxyValueReader reader; + final ProxyValueReader reader; - public UDTSetToSetConverter(Class iface, SessionRepository repository) { - this.reader = new ProxyValueReader(iface, new UDTColumnValueProvider(repository)); - } + public UDTSetToSetConverter(Class iface, SessionRepository repository) { + this.reader = new ProxyValueReader(iface, new UDTColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformSet((Set) t, reader); - } + @Override + public Object apply(Object t) { + return Transformers.transformSet((Set) t, reader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/UDTValueMapToMapConverter.java b/src/main/java/net/helenus/mapping/convert/udt/UDTValueMapToMapConverter.java index 8bb4f27..8772f5c 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/UDTValueMapToMapConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/UDTValueMapToMapConverter.java @@ -15,9 +15,11 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UDTValue; import java.util.Map; import java.util.function.Function; + +import com.datastax.driver.core.UDTValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.UDTColumnValueProvider; @@ -25,14 +27,14 @@ import net.helenus.support.Transformers; public final class UDTValueMapToMapConverter implements Function { - final ProxyValueReader reader; + final ProxyValueReader reader; - public UDTValueMapToMapConverter(Class iface, SessionRepository repository) { - this.reader = new ProxyValueReader(iface, new UDTColumnValueProvider(repository)); - } + public UDTValueMapToMapConverter(Class iface, SessionRepository repository) { + this.reader = new ProxyValueReader(iface, new UDTColumnValueProvider(repository)); + } - @Override - public Object apply(Object t) { - return Transformers.transformMapValue((Map) t, reader); - } + @Override + public Object apply(Object t) { + return Transformers.transformMapValue((Map) t, reader); + } } diff --git a/src/main/java/net/helenus/mapping/convert/udt/UDTValueToEntityConverter.java b/src/main/java/net/helenus/mapping/convert/udt/UDTValueToEntityConverter.java index 6e7e082..a48024a 100644 --- a/src/main/java/net/helenus/mapping/convert/udt/UDTValueToEntityConverter.java +++ b/src/main/java/net/helenus/mapping/convert/udt/UDTValueToEntityConverter.java @@ -15,16 +15,17 @@ */ package net.helenus.mapping.convert.udt; -import com.datastax.driver.core.UDTValue; import java.util.function.Function; + +import com.datastax.driver.core.UDTValue; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.ProxyValueReader; import net.helenus.mapping.value.UDTColumnValueProvider; -public final class UDTValueToEntityConverter extends ProxyValueReader - implements Function { +public final class UDTValueToEntityConverter extends ProxyValueReader implements Function { - public UDTValueToEntityConverter(Class iface, SessionRepository repository) { - super(iface, new UDTColumnValueProvider(repository)); - } + public UDTValueToEntityConverter(Class iface, SessionRepository repository) { + super(iface, new UDTColumnValueProvider(repository)); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/AbstractCollectionJavaType.java b/src/main/java/net/helenus/mapping/javatype/AbstractCollectionJavaType.java index a882398..090d202 100644 --- a/src/main/java/net/helenus/mapping/javatype/AbstractCollectionJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/AbstractCollectionJavaType.java @@ -2,7 +2,7 @@ package net.helenus.mapping.javatype; public abstract class AbstractCollectionJavaType extends AbstractJavaType { - public static boolean isCollectionType() { - return true; - } + public static boolean isCollectionType() { + return true; + } } diff --git a/src/main/java/net/helenus/mapping/javatype/AbstractJavaType.java b/src/main/java/net/helenus/mapping/javatype/AbstractJavaType.java index abd7e21..152af5c 100644 --- a/src/main/java/net/helenus/mapping/javatype/AbstractJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/AbstractJavaType.java @@ -15,13 +15,15 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; + import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; @@ -33,107 +35,106 @@ import net.helenus.support.HelenusMappingException; public abstract class AbstractJavaType { - public static boolean isCollectionType() { - return false; - } + public static boolean isCollectionType() { + return false; + } - public abstract Class getJavaClass(); + public abstract Class getJavaClass(); - public boolean isApplicable(Class javaClass) { - return false; - } + public boolean isApplicable(Class javaClass) { + return false; + } - public abstract AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata); + public abstract AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata); - public Optional> getPrimitiveJavaClass() { - return Optional.empty(); - } + public Optional> getPrimitiveJavaClass() { + return Optional.empty(); + } - public Optional> resolveReadConverter( - AbstractDataType dataType, SessionRepository repository) { - return Optional.empty(); - } + public Optional> resolveReadConverter(AbstractDataType dataType, + SessionRepository repository) { + return Optional.empty(); + } - public Optional> resolveWriteConverter( - AbstractDataType dataType, SessionRepository repository) { - return Optional.empty(); - } + public Optional> resolveWriteConverter(AbstractDataType dataType, + SessionRepository repository) { + return Optional.empty(); + } - static IdentityName resolveUDT(Types.UDT annotation) { - return IdentityName.of(annotation.value(), annotation.forceQuote()); - } + static IdentityName resolveUDT(Types.UDT annotation) { + return IdentityName.of(annotation.value(), annotation.forceQuote()); + } - static DataType resolveSimpleType(Method getter, DataType.Name typeName) { - DataType dataType = SimpleJavaTypes.getDataTypeByName(typeName); - if (dataType == null) { - throw new HelenusMappingException( - "only primitive types are allowed inside collections for the property " + getter); - } - return dataType; - } + static DataType resolveSimpleType(Method getter, DataType.Name typeName) { + DataType dataType = SimpleJavaTypes.getDataTypeByName(typeName); + if (dataType == null) { + throw new HelenusMappingException( + "only primitive types are allowed inside collections for the property " + getter); + } + return dataType; + } - static void ensureTypeArguments(Method getter, int args, int expected) { - if (args != expected) { - throw new HelenusMappingException( - "expected " + expected + " of typed arguments for the property " + getter); - } - } + static void ensureTypeArguments(Method getter, int args, int expected) { + if (args != expected) { + throw new HelenusMappingException( + "expected " + expected + " of typed arguments for the property " + getter); + } + } - static class DataTypeInfo { - final DataType dataType; - final Class typeArgument; + static class DataTypeInfo { + final DataType dataType; + final Class typeArgument; - DataTypeInfo(DataType dataType) { - this.dataType = dataType; - this.typeArgument = null; - } + DataTypeInfo(DataType dataType) { + this.dataType = dataType; + this.typeArgument = null; + } - DataTypeInfo(DataType dataType, Class typeArgument) { - this.dataType = dataType; - this.typeArgument = typeArgument; - } - } + DataTypeInfo(DataType dataType, Class typeArgument) { + this.dataType = dataType; + this.typeArgument = typeArgument; + } + } - static Either autodetectParameterType( - Method getter, Type type, Metadata metadata) { + static Either autodetectParameterType(Method getter, Type type, Metadata metadata) { - DataType dataType = null; + DataType dataType = null; - if (type instanceof Class) { + if (type instanceof Class) { - Class javaType = (Class) type; - dataType = SimpleJavaTypes.getDataTypeByJavaClass(javaType); + Class javaType = (Class) type; + dataType = SimpleJavaTypes.getDataTypeByJavaClass(javaType); - if (dataType != null) { - return Either.left(dataType); - } + if (dataType != null) { + return Either.left(dataType); + } - if (MappingUtil.isTuple(javaType)) { - dataType = TupleValueJavaType.toTupleType(javaType, metadata); - return Either.left(dataType); - } + if (MappingUtil.isTuple(javaType)) { + dataType = TupleValueJavaType.toTupleType(javaType, metadata); + return Either.left(dataType); + } - IdentityName udtName = MappingUtil.getUserDefinedTypeName(javaType, false); + IdentityName udtName = MappingUtil.getUserDefinedTypeName(javaType, false); - if (udtName != null) { - return Either.right(udtName); - } - } + if (udtName != null) { + return Either.right(udtName); + } + } - throw new HelenusMappingException( - "unknown parameter type " + type + " in the collection for the property " + getter); - } + throw new HelenusMappingException( + "unknown parameter type " + type + " in the collection for the property " + getter); + } - static Type[] getTypeParameters(Type genericJavaType) { + static Type[] getTypeParameters(Type genericJavaType) { - if (genericJavaType instanceof ParameterizedType) { + if (genericJavaType instanceof ParameterizedType) { - ParameterizedType type = (ParameterizedType) genericJavaType; + ParameterizedType type = (ParameterizedType) genericJavaType; - return type.getActualTypeArguments(); - } + return type.getActualTypeArguments(); + } - return new Type[] {}; - } + return new Type[]{}; + } } diff --git a/src/main/java/net/helenus/mapping/javatype/ByteArrayJavaType.java b/src/main/java/net/helenus/mapping/javatype/ByteArrayJavaType.java index 02ab5af..c566547 100644 --- a/src/main/java/net/helenus/mapping/javatype/ByteArrayJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/ByteArrayJavaType.java @@ -15,13 +15,15 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.nio.ByteBuffer; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; + import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; import net.helenus.mapping.annotation.Types; @@ -33,43 +35,41 @@ import net.helenus.mapping.type.DTDataType; public final class ByteArrayJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return byte[].class; - } + @Override + public Class getJavaClass() { + return byte[].class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - if (null != getter.getDeclaredAnnotation(Types.Blob.class)) { - return new DTDataType(columnType, DataType.blob()); - } + if (null != getter.getDeclaredAnnotation(Types.Blob.class)) { + return new DTDataType(columnType, DataType.blob()); + } - Types.Custom custom = getter.getDeclaredAnnotation(Types.Custom.class); + Types.Custom custom = getter.getDeclaredAnnotation(Types.Custom.class); - if (null != custom) { - return new DTDataType(columnType, DataType.custom(custom.className())); - } + if (null != custom) { + return new DTDataType(columnType, DataType.custom(custom.className())); + } - return new DTDataType(columnType, DataType.blob()); - } + return new DTDataType(columnType, DataType.blob()); + } - @Override - public Optional> resolveReadConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveReadConverter(AbstractDataType dataType, + SessionRepository repository) { - return Optional.of( - TypedConverter.create( - ByteBuffer.class, byte[].class, ByteBufferToByteArrayConverter.INSTANCE)); - } + return Optional + .of(TypedConverter.create(ByteBuffer.class, byte[].class, ByteBufferToByteArrayConverter.INSTANCE)); + } - @Override - public Optional> resolveWriteConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveWriteConverter(AbstractDataType dataType, + SessionRepository repository) { - return Optional.of( - TypedConverter.create( - byte[].class, ByteBuffer.class, ByteArrayToByteBufferConverter.INSTANCE)); - } + return Optional + .of(TypedConverter.create(byte[].class, ByteBuffer.class, ByteArrayToByteBufferConverter.INSTANCE)); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/ByteBufferJavaType.java b/src/main/java/net/helenus/mapping/javatype/ByteBufferJavaType.java index c363a4f..b60e1db 100644 --- a/src/main/java/net/helenus/mapping/javatype/ByteBufferJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/ByteBufferJavaType.java @@ -15,11 +15,13 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.nio.ByteBuffer; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.annotation.Types; import net.helenus.mapping.type.AbstractDataType; @@ -27,25 +29,25 @@ import net.helenus.mapping.type.DTDataType; public final class ByteBufferJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return ByteBuffer.class; - } + @Override + public Class getJavaClass() { + return ByteBuffer.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - if (null != getter.getDeclaredAnnotation(Types.Blob.class)) { - return new DTDataType(columnType, DataType.blob()); - } + if (null != getter.getDeclaredAnnotation(Types.Blob.class)) { + return new DTDataType(columnType, DataType.blob()); + } - Types.Custom custom = getter.getDeclaredAnnotation(Types.Custom.class); + Types.Custom custom = getter.getDeclaredAnnotation(Types.Custom.class); - if (null != custom) { - return new DTDataType(columnType, DataType.custom(custom.className())); - } + if (null != custom) { + return new DTDataType(columnType, DataType.custom(custom.className())); + } - return new DTDataType(columnType, DataType.blob()); - } + return new DTDataType(columnType, DataType.blob()); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/DateJavaType.java b/src/main/java/net/helenus/mapping/javatype/DateJavaType.java index 2a97f30..133853d 100644 --- a/src/main/java/net/helenus/mapping/javatype/DateJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/DateJavaType.java @@ -15,14 +15,16 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Date; import java.util.Optional; import java.util.UUID; import java.util.function.Function; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; + import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; import net.helenus.mapping.annotation.Types; @@ -34,51 +36,49 @@ import net.helenus.mapping.type.DTDataType; public final class DateJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return Date.class; - } + @Override + public Class getJavaClass() { + return Date.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - if (null != getter.getDeclaredAnnotation(Types.Timestamp.class)) { - return new DTDataType(columnType, DataType.timestamp()); - } + if (null != getter.getDeclaredAnnotation(Types.Timestamp.class)) { + return new DTDataType(columnType, DataType.timestamp()); + } - if (null != getter.getDeclaredAnnotation(Types.Timeuuid.class)) { - return new DTDataType(columnType, DataType.timeuuid()); - } + if (null != getter.getDeclaredAnnotation(Types.Timeuuid.class)) { + return new DTDataType(columnType, DataType.timeuuid()); + } - return new DTDataType(columnType, DataType.timestamp()); - } + return new DTDataType(columnType, DataType.timestamp()); + } - @Override - public Optional> resolveReadConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveReadConverter(AbstractDataType dataType, + SessionRepository repository) { - DataType dt = ((DTDataType) dataType).getDataType(); + DataType dt = ((DTDataType) dataType).getDataType(); - if (dt.getName() == DataType.Name.TIMEUUID) { - return Optional.of( - TypedConverter.create(UUID.class, Date.class, TimeuuidToDateConverter.INSTANCE)); - } + if (dt.getName() == DataType.Name.TIMEUUID) { + return Optional.of(TypedConverter.create(UUID.class, Date.class, TimeuuidToDateConverter.INSTANCE)); + } - return Optional.empty(); - } + return Optional.empty(); + } - @Override - public Optional> resolveWriteConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveWriteConverter(AbstractDataType dataType, + SessionRepository repository) { - DataType dt = ((DTDataType) dataType).getDataType(); + DataType dt = ((DTDataType) dataType).getDataType(); - if (dt.getName() == DataType.Name.TIMEUUID) { - return Optional.of( - TypedConverter.create(Date.class, UUID.class, DateToTimeuuidConverter.INSTANCE)); - } + if (dt.getName() == DataType.Name.TIMEUUID) { + return Optional.of(TypedConverter.create(Date.class, UUID.class, DateToTimeuuidConverter.INSTANCE)); + } - return Optional.empty(); - } + return Optional.empty(); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/EnumJavaType.java b/src/main/java/net/helenus/mapping/javatype/EnumJavaType.java index b205a6d..a4b8dad 100644 --- a/src/main/java/net/helenus/mapping/javatype/EnumJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/EnumJavaType.java @@ -15,12 +15,14 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; + import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; import net.helenus.mapping.convert.EnumToStringConverter; @@ -31,33 +33,31 @@ import net.helenus.mapping.type.DTDataType; public final class EnumJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return Enum.class; - } + @Override + public Class getJavaClass() { + return Enum.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - return new DTDataType(columnType, DataType.ascii(), (Class) genericJavaType); - } + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { + return new DTDataType(columnType, DataType.ascii(), (Class) genericJavaType); + } - @Override - public Optional> resolveReadConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveReadConverter(AbstractDataType dataType, + SessionRepository repository) { - DTDataType dt = (DTDataType) dataType; + DTDataType dt = (DTDataType) dataType; - return Optional.of( - TypedConverter.create( - String.class, Enum.class, new StringToEnumConverter(dt.getJavaClass()))); - } + return Optional + .of(TypedConverter.create(String.class, Enum.class, new StringToEnumConverter(dt.getJavaClass()))); + } - @Override - public Optional> resolveWriteConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveWriteConverter(AbstractDataType dataType, + SessionRepository repository) { - return Optional.of( - TypedConverter.create(Enum.class, String.class, EnumToStringConverter.INSTANCE)); - } + return Optional.of(TypedConverter.create(Enum.class, String.class, EnumToStringConverter.INSTANCE)); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/ListJavaType.java b/src/main/java/net/helenus/mapping/javatype/ListJavaType.java index 8e1f937..e4f4a53 100644 --- a/src/main/java/net/helenus/mapping/javatype/ListJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/ListJavaType.java @@ -15,12 +15,14 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.*; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.List; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.*; + import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; @@ -37,112 +39,110 @@ import net.helenus.support.HelenusMappingException; public final class ListJavaType extends AbstractCollectionJavaType { - @Override - public Class getJavaClass() { - return List.class; - } + @Override + public Class getJavaClass() { + return List.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - Types.List clist = getter.getDeclaredAnnotation(Types.List.class); - if (clist != null) { - return new DTDataType(columnType, DataType.list(resolveSimpleType(getter, clist.value()))); - } + Types.List clist = getter.getDeclaredAnnotation(Types.List.class); + if (clist != null) { + return new DTDataType(columnType, DataType.list(resolveSimpleType(getter, clist.value()))); + } - Types.UDTList udtList = getter.getDeclaredAnnotation(Types.UDTList.class); - if (udtList != null) { - return new UDTListDataType(columnType, resolveUDT(udtList.value()), UDTValue.class); - } + Types.UDTList udtList = getter.getDeclaredAnnotation(Types.UDTList.class); + if (udtList != null) { + return new UDTListDataType(columnType, resolveUDT(udtList.value()), UDTValue.class); + } - Type[] args = getTypeParameters(genericJavaType); - ensureTypeArguments(getter, args.length, 1); + Type[] args = getTypeParameters(genericJavaType); + ensureTypeArguments(getter, args.length, 1); - Either parameterType = - autodetectParameterType(getter, args[0], metadata); + Either parameterType = autodetectParameterType(getter, args[0], metadata); - if (parameterType.isLeft()) { - return DTDataType.list(columnType, parameterType.getLeft(), args[0]); - } else { - return new UDTListDataType(columnType, parameterType.getRight(), (Class) args[0]); - } - } + if (parameterType.isLeft()) { + return DTDataType.list(columnType, parameterType.getLeft(), args[0]); + } else { + return new UDTListDataType(columnType, parameterType.getRight(), (Class) args[0]); + } + } - @Override - public Optional> resolveReadConverter( - AbstractDataType abstractDataType, SessionRepository repository) { + @Override + public Optional> resolveReadConverter(AbstractDataType abstractDataType, + SessionRepository repository) { - if (abstractDataType instanceof DTDataType) { + if (abstractDataType instanceof DTDataType) { - DTDataType dt = (DTDataType) abstractDataType; - DataType elementType = dt.getDataType().getTypeArguments().get(0); - if (elementType instanceof TupleType) { + DTDataType dt = (DTDataType) abstractDataType; + DataType elementType = dt.getDataType().getTypeArguments().get(0); + if (elementType instanceof TupleType) { - Class tupleClass = dt.getTypeArguments()[0]; + Class tupleClass = dt.getTypeArguments()[0]; - if (TupleValue.class.isAssignableFrom(tupleClass)) { - return Optional.empty(); - } + if (TupleValue.class.isAssignableFrom(tupleClass)) { + return Optional.empty(); + } - return Optional.of(new TupleListToListConverter(tupleClass, repository)); - } - } else if (abstractDataType instanceof UDTListDataType) { + return Optional.of(new TupleListToListConverter(tupleClass, repository)); + } + } else if (abstractDataType instanceof UDTListDataType) { - UDTListDataType dt = (UDTListDataType) abstractDataType; + UDTListDataType dt = (UDTListDataType) abstractDataType; - Class javaClass = (Class) dt.getTypeArguments()[0]; + Class javaClass = (Class) dt.getTypeArguments()[0]; - if (UDTValue.class.isAssignableFrom(javaClass)) { - return Optional.empty(); - } + if (UDTValue.class.isAssignableFrom(javaClass)) { + return Optional.empty(); + } - return Optional.of(new UDTListToListConverter(javaClass, repository)); - } + return Optional.of(new UDTListToListConverter(javaClass, repository)); + } - return Optional.empty(); - } + return Optional.empty(); + } - @Override - public Optional> resolveWriteConverter( - AbstractDataType abstractDataType, SessionRepository repository) { + @Override + public Optional> resolveWriteConverter(AbstractDataType abstractDataType, + SessionRepository repository) { - if (abstractDataType instanceof DTDataType) { + if (abstractDataType instanceof DTDataType) { - DTDataType dt = (DTDataType) abstractDataType; - DataType elementType = dt.getDataType().getTypeArguments().get(0); + DTDataType dt = (DTDataType) abstractDataType; + DataType elementType = dt.getDataType().getTypeArguments().get(0); - if (elementType instanceof TupleType) { + if (elementType instanceof TupleType) { - Class tupleClass = dt.getTypeArguments()[0]; + Class tupleClass = dt.getTypeArguments()[0]; - if (TupleValue.class.isAssignableFrom(tupleClass)) { - return Optional.empty(); - } + if (TupleValue.class.isAssignableFrom(tupleClass)) { + return Optional.empty(); + } - return Optional.of( - new ListToTupleListConverter(tupleClass, (TupleType) elementType, repository)); - } + return Optional.of(new ListToTupleListConverter(tupleClass, (TupleType) elementType, repository)); + } - } else if (abstractDataType instanceof UDTListDataType) { + } else if (abstractDataType instanceof UDTListDataType) { - UDTListDataType dt = (UDTListDataType) abstractDataType; + UDTListDataType dt = (UDTListDataType) abstractDataType; - Class javaClass = (Class) dt.getTypeArguments()[0]; + Class javaClass = (Class) dt.getTypeArguments()[0]; - if (UDTValue.class.isAssignableFrom(javaClass)) { - return Optional.empty(); - } + if (UDTValue.class.isAssignableFrom(javaClass)) { + return Optional.empty(); + } - UserType userType = repository.findUserType(dt.getUdtName().getName()); - if (userType == null) { - throw new HelenusMappingException( - "UserType not found for " + dt.getUdtName() + " with type " + javaClass); - } + UserType userType = repository.findUserType(dt.getUdtName().getName()); + if (userType == null) { + throw new HelenusMappingException( + "UserType not found for " + dt.getUdtName() + " with type " + javaClass); + } - return Optional.of(new ListToUDTListConverter(javaClass, userType, repository)); - } + return Optional.of(new ListToUDTListConverter(javaClass, userType, repository)); + } - return Optional.empty(); - } + return Optional.empty(); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/LongJavaType.java b/src/main/java/net/helenus/mapping/javatype/LongJavaType.java index b4d1b0d..0ace985 100644 --- a/src/main/java/net/helenus/mapping/javatype/LongJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/LongJavaType.java @@ -15,11 +15,13 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Optional; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.annotation.Types; import net.helenus.mapping.type.AbstractDataType; @@ -27,28 +29,28 @@ import net.helenus.mapping.type.DTDataType; public final class LongJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return Long.class; - } + @Override + public Class getJavaClass() { + return Long.class; + } - @Override - public Optional> getPrimitiveJavaClass() { - return Optional.of(long.class); - } + @Override + public Optional> getPrimitiveJavaClass() { + return Optional.of(long.class); + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - if (null != getter.getDeclaredAnnotation(Types.Counter.class)) { - return new DTDataType(columnType, DataType.counter()); - } + if (null != getter.getDeclaredAnnotation(Types.Counter.class)) { + return new DTDataType(columnType, DataType.counter()); + } - if (null != getter.getDeclaredAnnotation(Types.Bigint.class)) { - return new DTDataType(columnType, DataType.bigint()); - } + if (null != getter.getDeclaredAnnotation(Types.Bigint.class)) { + return new DTDataType(columnType, DataType.bigint()); + } - return new DTDataType(columnType, DataType.bigint()); - } + return new DTDataType(columnType, DataType.bigint()); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/MapJavaType.java b/src/main/java/net/helenus/mapping/javatype/MapJavaType.java index 2a5d187..e4c37ba 100644 --- a/src/main/java/net/helenus/mapping/javatype/MapJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/MapJavaType.java @@ -15,12 +15,14 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.*; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Map; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.*; + import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; @@ -33,322 +35,285 @@ import net.helenus.support.HelenusMappingException; public final class MapJavaType extends AbstractCollectionJavaType { - @Override - public Class getJavaClass() { - return Map.class; - } - - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - - Types.Map cmap = getter.getDeclaredAnnotation(Types.Map.class); - if (cmap != null) { - return new DTDataType( - columnType, - DataType.map( - resolveSimpleType(getter, cmap.key()), resolveSimpleType(getter, cmap.value()))); - } - - Types.UDTKeyMap udtKeyMap = getter.getDeclaredAnnotation(Types.UDTKeyMap.class); - if (udtKeyMap != null) { - return new UDTKeyMapDataType( - columnType, - resolveUDT(udtKeyMap.key()), - UDTValue.class, - resolveSimpleType(getter, udtKeyMap.value())); - } - - Types.UDTValueMap udtValueMap = getter.getDeclaredAnnotation(Types.UDTValueMap.class); - if (udtValueMap != null) { - return new UDTValueMapDataType( - columnType, - resolveSimpleType(getter, udtValueMap.key()), - resolveUDT(udtValueMap.value()), - UDTValue.class); - } + @Override + public Class getJavaClass() { + return Map.class; + } - Types.UDTMap udtMap = getter.getDeclaredAnnotation(Types.UDTMap.class); - if (udtMap != null) { - return new UDTMapDataType( - columnType, - resolveUDT(udtMap.key()), - UDTValue.class, - resolveUDT(udtMap.value()), - UDTValue.class); - } - - Type[] args = getTypeParameters(genericJavaType); - ensureTypeArguments(getter, args.length, 2); - - Either key = autodetectParameterType(getter, args[0], metadata); - Either value = autodetectParameterType(getter, args[1], metadata); + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - if (key.isLeft()) { + Types.Map cmap = getter.getDeclaredAnnotation(Types.Map.class); + if (cmap != null) { + return new DTDataType(columnType, + DataType.map(resolveSimpleType(getter, cmap.key()), resolveSimpleType(getter, cmap.value()))); + } - if (value.isLeft()) { - return DTDataType.map(columnType, key.getLeft(), args[0], value.getLeft(), args[1]); - } else { - return new UDTValueMapDataType( - columnType, key.getLeft(), value.getRight(), (Class) args[1]); - } - } else { + Types.UDTKeyMap udtKeyMap = getter.getDeclaredAnnotation(Types.UDTKeyMap.class); + if (udtKeyMap != null) { + return new UDTKeyMapDataType(columnType, resolveUDT(udtKeyMap.key()), UDTValue.class, + resolveSimpleType(getter, udtKeyMap.value())); + } - if (value.isLeft()) { - return new UDTKeyMapDataType( - columnType, key.getRight(), (Class) args[0], value.getLeft()); - } else { - return new UDTMapDataType( - columnType, key.getRight(), (Class) args[0], value.getRight(), (Class) args[1]); - } - } - } + Types.UDTValueMap udtValueMap = getter.getDeclaredAnnotation(Types.UDTValueMap.class); + if (udtValueMap != null) { + return new UDTValueMapDataType(columnType, resolveSimpleType(getter, udtValueMap.key()), + resolveUDT(udtValueMap.value()), UDTValue.class); + } - @Override - public Optional> resolveReadConverter( - AbstractDataType abstractDataType, SessionRepository repository) { + Types.UDTMap udtMap = getter.getDeclaredAnnotation(Types.UDTMap.class); + if (udtMap != null) { + return new UDTMapDataType(columnType, resolveUDT(udtMap.key()), UDTValue.class, resolveUDT(udtMap.value()), + UDTValue.class); + } - if (abstractDataType instanceof DTDataType) { - return resolveDTReadConverter((DTDataType) abstractDataType, repository); - } else if (abstractDataType instanceof UDTKeyMapDataType) { + Type[] args = getTypeParameters(genericJavaType); + ensureTypeArguments(getter, args.length, 2); - UDTKeyMapDataType dt = (UDTKeyMapDataType) abstractDataType; + Either key = autodetectParameterType(getter, args[0], metadata); + Either value = autodetectParameterType(getter, args[1], metadata); - Class keyClass = (Class) dt.getUdtKeyClass(); + if (key.isLeft()) { - if (UDTValue.class.isAssignableFrom(keyClass)) { - return Optional.empty(); - } + if (value.isLeft()) { + return DTDataType.map(columnType, key.getLeft(), args[0], value.getLeft(), args[1]); + } else { + return new UDTValueMapDataType(columnType, key.getLeft(), value.getRight(), (Class) args[1]); + } + } else { - return Optional.of(new UDTKeyMapToMapConverter(keyClass, repository)); + if (value.isLeft()) { + return new UDTKeyMapDataType(columnType, key.getRight(), (Class) args[0], value.getLeft()); + } else { + return new UDTMapDataType(columnType, key.getRight(), (Class) args[0], value.getRight(), + (Class) args[1]); + } + } + } - } else if (abstractDataType instanceof UDTValueMapDataType) { + @Override + public Optional> resolveReadConverter(AbstractDataType abstractDataType, + SessionRepository repository) { - UDTValueMapDataType dt = (UDTValueMapDataType) abstractDataType; + if (abstractDataType instanceof DTDataType) { + return resolveDTReadConverter((DTDataType) abstractDataType, repository); + } else if (abstractDataType instanceof UDTKeyMapDataType) { - Class valueClass = (Class) dt.getUdtValueClass(); + UDTKeyMapDataType dt = (UDTKeyMapDataType) abstractDataType; - if (UDTValue.class.isAssignableFrom(valueClass)) { - return Optional.empty(); - } + Class keyClass = (Class) dt.getUdtKeyClass(); - return Optional.of(new UDTValueMapToMapConverter(valueClass, repository)); + if (UDTValue.class.isAssignableFrom(keyClass)) { + return Optional.empty(); + } - } else if (abstractDataType instanceof UDTMapDataType) { + return Optional.of(new UDTKeyMapToMapConverter(keyClass, repository)); - UDTMapDataType dt = (UDTMapDataType) abstractDataType; + } else if (abstractDataType instanceof UDTValueMapDataType) { - Class keyClass = (Class) dt.getUdtKeyClass(); - Class valueClass = (Class) dt.getUdtValueClass(); + UDTValueMapDataType dt = (UDTValueMapDataType) abstractDataType; - if (UDTValue.class.isAssignableFrom(keyClass)) { + Class valueClass = (Class) dt.getUdtValueClass(); - if (UDTValue.class.isAssignableFrom(valueClass)) { - return Optional.empty(); - } else { - return Optional.of(new UDTValueMapToMapConverter(valueClass, repository)); - } - } else if (UDTValue.class.isAssignableFrom(valueClass)) { - return Optional.of(new UDTKeyMapToMapConverter(keyClass, repository)); - } + if (UDTValue.class.isAssignableFrom(valueClass)) { + return Optional.empty(); + } - return Optional.of(new UDTMapToMapConverter(keyClass, valueClass, repository)); - } + return Optional.of(new UDTValueMapToMapConverter(valueClass, repository)); - return Optional.empty(); - } + } else if (abstractDataType instanceof UDTMapDataType) { - private Optional> resolveDTReadConverter( - DTDataType dt, SessionRepository repository) { + UDTMapDataType dt = (UDTMapDataType) abstractDataType; - DataType keyDataType = dt.getDataType().getTypeArguments().get(0); - DataType valueDataType = dt.getDataType().getTypeArguments().get(1); + Class keyClass = (Class) dt.getUdtKeyClass(); + Class valueClass = (Class) dt.getUdtValueClass(); - if (keyDataType instanceof TupleType) { + if (UDTValue.class.isAssignableFrom(keyClass)) { - if (valueDataType instanceof TupleType) { + if (UDTValue.class.isAssignableFrom(valueClass)) { + return Optional.empty(); + } else { + return Optional.of(new UDTValueMapToMapConverter(valueClass, repository)); + } + } else if (UDTValue.class.isAssignableFrom(valueClass)) { + return Optional.of(new UDTKeyMapToMapConverter(keyClass, repository)); + } - Class keyClass = dt.getTypeArguments()[0]; - Class valueClass = dt.getTypeArguments()[1]; + return Optional.of(new UDTMapToMapConverter(keyClass, valueClass, repository)); + } - if (TupleValue.class.isAssignableFrom(keyClass)) { + return Optional.empty(); + } - if (TupleValue.class.isAssignableFrom(valueClass)) { - return Optional.empty(); - } else { - return Optional.of(new TupleValueMapToMapConverter(valueClass, repository)); - } + private Optional> resolveDTReadConverter(DTDataType dt, SessionRepository repository) { - } else if (TupleValue.class.isAssignableFrom(valueClass)) { - return Optional.of(new TupleKeyMapToMapConverter(keyClass, repository)); - } + DataType keyDataType = dt.getDataType().getTypeArguments().get(0); + DataType valueDataType = dt.getDataType().getTypeArguments().get(1); - return Optional.of(new TupleMapToMapConverter(keyClass, valueClass, repository)); + if (keyDataType instanceof TupleType) { - } else { - Class keyClass = dt.getTypeArguments()[0]; + if (valueDataType instanceof TupleType) { - if (TupleValue.class.isAssignableFrom(keyClass)) { - return Optional.empty(); - } + Class keyClass = dt.getTypeArguments()[0]; + Class valueClass = dt.getTypeArguments()[1]; - return Optional.of(new TupleKeyMapToMapConverter(keyClass, repository)); - } - } else if (valueDataType instanceof TupleType) { + if (TupleValue.class.isAssignableFrom(keyClass)) { - Class valueClass = dt.getTypeArguments()[0]; + if (TupleValue.class.isAssignableFrom(valueClass)) { + return Optional.empty(); + } else { + return Optional.of(new TupleValueMapToMapConverter(valueClass, repository)); + } - if (TupleValue.class.isAssignableFrom(valueClass)) { - return Optional.empty(); - } + } else if (TupleValue.class.isAssignableFrom(valueClass)) { + return Optional.of(new TupleKeyMapToMapConverter(keyClass, repository)); + } - return Optional.of(new TupleValueMapToMapConverter(valueClass, repository)); - } + return Optional.of(new TupleMapToMapConverter(keyClass, valueClass, repository)); - return Optional.empty(); - } + } else { + Class keyClass = dt.getTypeArguments()[0]; - @Override - public Optional> resolveWriteConverter( - AbstractDataType abstractDataType, SessionRepository repository) { + if (TupleValue.class.isAssignableFrom(keyClass)) { + return Optional.empty(); + } - if (abstractDataType instanceof DTDataType) { - return resolveDTWriteConverter((DTDataType) abstractDataType, repository); - } else if (abstractDataType instanceof UDTKeyMapDataType) { + return Optional.of(new TupleKeyMapToMapConverter(keyClass, repository)); + } + } else if (valueDataType instanceof TupleType) { - UDTKeyMapDataType dt = (UDTKeyMapDataType) abstractDataType; + Class valueClass = dt.getTypeArguments()[0]; - Class keyClass = (Class) dt.getUdtKeyClass(); + if (TupleValue.class.isAssignableFrom(valueClass)) { + return Optional.empty(); + } - if (UDTValue.class.isAssignableFrom(keyClass)) { - return Optional.empty(); - } + return Optional.of(new TupleValueMapToMapConverter(valueClass, repository)); + } - return Optional.of( - new MapToUDTKeyMapConverter( - keyClass, getUserType(dt.getUdtKeyName(), keyClass, repository), repository)); + return Optional.empty(); + } - } else if (abstractDataType instanceof UDTValueMapDataType) { + @Override + public Optional> resolveWriteConverter(AbstractDataType abstractDataType, + SessionRepository repository) { - UDTValueMapDataType dt = (UDTValueMapDataType) abstractDataType; + if (abstractDataType instanceof DTDataType) { + return resolveDTWriteConverter((DTDataType) abstractDataType, repository); + } else if (abstractDataType instanceof UDTKeyMapDataType) { - Class valueClass = (Class) dt.getUdtValueClass(); + UDTKeyMapDataType dt = (UDTKeyMapDataType) abstractDataType; - if (UDTValue.class.isAssignableFrom(valueClass)) { - return Optional.empty(); - } + Class keyClass = (Class) dt.getUdtKeyClass(); - return Optional.of( - new MapToUDTValueMapConverter( - valueClass, getUserType(dt.getUdtValueName(), valueClass, repository), repository)); + if (UDTValue.class.isAssignableFrom(keyClass)) { + return Optional.empty(); + } - } else if (abstractDataType instanceof UDTMapDataType) { + return Optional.of(new MapToUDTKeyMapConverter(keyClass, + getUserType(dt.getUdtKeyName(), keyClass, repository), repository)); - UDTMapDataType dt = (UDTMapDataType) abstractDataType; + } else if (abstractDataType instanceof UDTValueMapDataType) { - Class keyClass = (Class) dt.getUdtKeyClass(); - Class valueClass = (Class) dt.getUdtValueClass(); + UDTValueMapDataType dt = (UDTValueMapDataType) abstractDataType; - if (UDTValue.class.isAssignableFrom(keyClass)) { + Class valueClass = (Class) dt.getUdtValueClass(); - if (UDTValue.class.isAssignableFrom(valueClass)) { - return Optional.empty(); - } else { + if (UDTValue.class.isAssignableFrom(valueClass)) { + return Optional.empty(); + } - return Optional.of( - new MapToUDTValueMapConverter( - valueClass, - getUserType(dt.getUdtValueName(), valueClass, repository), - repository)); - } - } else if (UDTValue.class.isAssignableFrom(valueClass)) { + return Optional.of(new MapToUDTValueMapConverter(valueClass, + getUserType(dt.getUdtValueName(), valueClass, repository), repository)); - return Optional.of( - new MapToUDTKeyMapConverter( - keyClass, getUserType(dt.getUdtKeyName(), keyClass, repository), repository)); - } + } else if (abstractDataType instanceof UDTMapDataType) { - return Optional.of( - new MapToUDTMapConverter( - keyClass, - getUserType(dt.getUdtKeyName(), keyClass, repository), - valueClass, - getUserType(dt.getUdtValueName(), valueClass, repository), - repository)); - } + UDTMapDataType dt = (UDTMapDataType) abstractDataType; - return Optional.empty(); - } + Class keyClass = (Class) dt.getUdtKeyClass(); + Class valueClass = (Class) dt.getUdtValueClass(); - private Optional> resolveDTWriteConverter( - DTDataType dt, SessionRepository repository) { + if (UDTValue.class.isAssignableFrom(keyClass)) { - DataType keyDataType = dt.getDataType().getTypeArguments().get(0); - DataType valueDataType = dt.getDataType().getTypeArguments().get(1); + if (UDTValue.class.isAssignableFrom(valueClass)) { + return Optional.empty(); + } else { - if (keyDataType instanceof TupleType) { + return Optional.of(new MapToUDTValueMapConverter(valueClass, + getUserType(dt.getUdtValueName(), valueClass, repository), repository)); + } + } else if (UDTValue.class.isAssignableFrom(valueClass)) { - if (valueDataType instanceof TupleType) { + return Optional.of(new MapToUDTKeyMapConverter(keyClass, + getUserType(dt.getUdtKeyName(), keyClass, repository), repository)); + } - Class keyClass = dt.getTypeArguments()[0]; - Class valueClass = dt.getTypeArguments()[1]; + return Optional.of(new MapToUDTMapConverter(keyClass, getUserType(dt.getUdtKeyName(), keyClass, repository), + valueClass, getUserType(dt.getUdtValueName(), valueClass, repository), repository)); + } - if (TupleValue.class.isAssignableFrom(keyClass)) { + return Optional.empty(); + } - if (TupleValue.class.isAssignableFrom(valueClass)) { - return Optional.empty(); - } else { - return Optional.of( - new MapToTupleValueMapConverter(valueClass, (TupleType) valueDataType, repository)); - } + private Optional> resolveDTWriteConverter(DTDataType dt, SessionRepository repository) { - } else if (TupleValue.class.isAssignableFrom(valueClass)) { + DataType keyDataType = dt.getDataType().getTypeArguments().get(0); + DataType valueDataType = dt.getDataType().getTypeArguments().get(1); - return Optional.of( - new MapToTupleKeyMapConverter(keyClass, (TupleType) keyDataType, repository)); - } + if (keyDataType instanceof TupleType) { - return Optional.of( - new MapToTupleMapConverter( - keyClass, - (TupleType) keyDataType, - valueClass, - (TupleType) valueDataType, - repository)); + if (valueDataType instanceof TupleType) { - } else { + Class keyClass = dt.getTypeArguments()[0]; + Class valueClass = dt.getTypeArguments()[1]; - Class keyClass = dt.getTypeArguments()[0]; + if (TupleValue.class.isAssignableFrom(keyClass)) { - if (TupleValue.class.isAssignableFrom(keyClass)) { - return Optional.empty(); - } + if (TupleValue.class.isAssignableFrom(valueClass)) { + return Optional.empty(); + } else { + return Optional + .of(new MapToTupleValueMapConverter(valueClass, (TupleType) valueDataType, repository)); + } - return Optional.of( - new MapToTupleKeyMapConverter(keyClass, (TupleType) keyDataType, repository)); - } - } else if (valueDataType instanceof TupleType) { + } else if (TupleValue.class.isAssignableFrom(valueClass)) { - Class valueClass = dt.getTypeArguments()[0]; + return Optional.of(new MapToTupleKeyMapConverter(keyClass, (TupleType) keyDataType, repository)); + } - if (TupleValue.class.isAssignableFrom(valueClass)) { - return Optional.empty(); - } + return Optional.of(new MapToTupleMapConverter(keyClass, (TupleType) keyDataType, valueClass, + (TupleType) valueDataType, repository)); - return Optional.of( - new MapToTupleValueMapConverter(valueClass, (TupleType) valueDataType, repository)); - } + } else { - return Optional.empty(); - } + Class keyClass = dt.getTypeArguments()[0]; - private UserType getUserType( - IdentityName name, Class javaClass, SessionRepository repository) { - UserType userType = repository.findUserType(name.getName()); - if (userType == null) { - throw new HelenusMappingException( - "UserType not found for " + name + " with type " + javaClass); - } - return userType; - } + if (TupleValue.class.isAssignableFrom(keyClass)) { + return Optional.empty(); + } + + return Optional.of(new MapToTupleKeyMapConverter(keyClass, (TupleType) keyDataType, repository)); + } + } else if (valueDataType instanceof TupleType) { + + Class valueClass = dt.getTypeArguments()[0]; + + if (TupleValue.class.isAssignableFrom(valueClass)) { + return Optional.empty(); + } + + return Optional.of(new MapToTupleValueMapConverter(valueClass, (TupleType) valueDataType, repository)); + } + + return Optional.empty(); + } + + private UserType getUserType(IdentityName name, Class javaClass, SessionRepository repository) { + UserType userType = repository.findUserType(name.getName()); + if (userType == null) { + throw new HelenusMappingException("UserType not found for " + name + " with type " + javaClass); + } + return userType; + } } diff --git a/src/main/java/net/helenus/mapping/javatype/MappingJavaTypes.java b/src/main/java/net/helenus/mapping/javatype/MappingJavaTypes.java index 3884425..fa30f23 100644 --- a/src/main/java/net/helenus/mapping/javatype/MappingJavaTypes.java +++ b/src/main/java/net/helenus/mapping/javatype/MappingJavaTypes.java @@ -15,15 +15,17 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; -import com.google.common.collect.ImmutableMap; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.math.BigDecimal; import java.math.BigInteger; import java.net.InetAddress; import java.util.Optional; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; +import com.google.common.collect.ImmutableMap; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.type.AbstractDataType; import net.helenus.mapping.type.DTDataType; @@ -31,189 +33,189 @@ import net.helenus.support.HelenusMappingException; public final class MappingJavaTypes { - private static final EnumJavaType ENUM_JAVA_TYPE = new EnumJavaType(); - private static final UDTValueJavaType UDT_VALUE_JAVA_TYPE = new UDTValueJavaType(); - private static final TupleValueJavaType TUPLE_VALUE_JAVA_TYPE = new TupleValueJavaType(); + private static final EnumJavaType ENUM_JAVA_TYPE = new EnumJavaType(); + private static final UDTValueJavaType UDT_VALUE_JAVA_TYPE = new UDTValueJavaType(); + private static final TupleValueJavaType TUPLE_VALUE_JAVA_TYPE = new TupleValueJavaType(); - private static final ImmutableMap, AbstractJavaType> knownTypes; + private static final ImmutableMap, AbstractJavaType> knownTypes; - static { - ImmutableMap.Builder, AbstractJavaType> builder = ImmutableMap.builder(); + static { + ImmutableMap.Builder, AbstractJavaType> builder = ImmutableMap.builder(); - add(builder, new BooleanJavaType()); - add(builder, new BigDecimalJavaType()); - add(builder, new BigIntegerJavaType()); - add(builder, new DoubleJavaType()); - add(builder, new FloatJavaType()); - add(builder, new IntegerJavaType()); - add(builder, new InetAddressJavaType()); + add(builder, new BooleanJavaType()); + add(builder, new BigDecimalJavaType()); + add(builder, new BigIntegerJavaType()); + add(builder, new DoubleJavaType()); + add(builder, new FloatJavaType()); + add(builder, new IntegerJavaType()); + add(builder, new InetAddressJavaType()); - add(builder, new ByteBufferJavaType()); - add(builder, new ByteArrayJavaType()); - add(builder, new DateJavaType()); - add(builder, new UUIDJavaType()); - add(builder, new LongJavaType()); - add(builder, new StringJavaType()); - add(builder, ENUM_JAVA_TYPE); - add(builder, new ListJavaType()); - add(builder, new SetJavaType()); - add(builder, new MapJavaType()); - add(builder, TUPLE_VALUE_JAVA_TYPE); - add(builder, UDT_VALUE_JAVA_TYPE); + add(builder, new ByteBufferJavaType()); + add(builder, new ByteArrayJavaType()); + add(builder, new DateJavaType()); + add(builder, new UUIDJavaType()); + add(builder, new LongJavaType()); + add(builder, new StringJavaType()); + add(builder, ENUM_JAVA_TYPE); + add(builder, new ListJavaType()); + add(builder, new SetJavaType()); + add(builder, new MapJavaType()); + add(builder, TUPLE_VALUE_JAVA_TYPE); + add(builder, UDT_VALUE_JAVA_TYPE); - knownTypes = builder.build(); - } + knownTypes = builder.build(); + } - private static void add( - ImmutableMap.Builder, AbstractJavaType> builder, AbstractJavaType jt) { + private static void add(ImmutableMap.Builder, AbstractJavaType> builder, AbstractJavaType jt) { - builder.put(jt.getJavaClass(), jt); + builder.put(jt.getJavaClass(), jt); - Optional> primitiveJavaClass = jt.getPrimitiveJavaClass(); - if (primitiveJavaClass.isPresent()) { - builder.put(primitiveJavaClass.get(), jt); - } - } + Optional> primitiveJavaClass = jt.getPrimitiveJavaClass(); + if (primitiveJavaClass.isPresent()) { + builder.put(primitiveJavaClass.get(), jt); + } + } - private MappingJavaTypes() {} + private MappingJavaTypes() { + } - public static AbstractJavaType resolveJavaType(Class javaClass) { + public static AbstractJavaType resolveJavaType(Class javaClass) { - AbstractJavaType ajt = knownTypes.get(javaClass); - if (ajt != null) { - return ajt; - } + AbstractJavaType ajt = knownTypes.get(javaClass); + if (ajt != null) { + return ajt; + } - if (Enum.class.isAssignableFrom(javaClass)) { - return ENUM_JAVA_TYPE; - } + if (Enum.class.isAssignableFrom(javaClass)) { + return ENUM_JAVA_TYPE; + } - if (TUPLE_VALUE_JAVA_TYPE.isApplicable(javaClass)) { - return TUPLE_VALUE_JAVA_TYPE; - } + if (TUPLE_VALUE_JAVA_TYPE.isApplicable(javaClass)) { + return TUPLE_VALUE_JAVA_TYPE; + } - if (UDT_VALUE_JAVA_TYPE.isApplicable(javaClass)) { - return UDT_VALUE_JAVA_TYPE; - } + if (UDT_VALUE_JAVA_TYPE.isApplicable(javaClass)) { + return UDT_VALUE_JAVA_TYPE; + } - throw new HelenusMappingException("unknown java type " + javaClass); - } + throw new HelenusMappingException("unknown java type " + javaClass); + } - public static final class BooleanJavaType extends AbstractJavaType { + public static final class BooleanJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return Boolean.class; - } + @Override + public Class getJavaClass() { + return Boolean.class; + } - @Override - public Optional> getPrimitiveJavaClass() { - return Optional.of(boolean.class); - } + @Override + public Optional> getPrimitiveJavaClass() { + return Optional.of(boolean.class); + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - return new DTDataType(columnType, DataType.cboolean()); - } - } + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { + return new DTDataType(columnType, DataType.cboolean()); + } + } - public static final class BigDecimalJavaType extends AbstractJavaType { + public static final class BigDecimalJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return BigDecimal.class; - } + @Override + public Class getJavaClass() { + return BigDecimal.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - return new DTDataType(columnType, DataType.decimal()); - } - } + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { + return new DTDataType(columnType, DataType.decimal()); + } + } - public static final class BigIntegerJavaType extends AbstractJavaType { + public static final class BigIntegerJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return BigInteger.class; - } + @Override + public Class getJavaClass() { + return BigInteger.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - return new DTDataType(columnType, DataType.varint()); - } - } + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { + return new DTDataType(columnType, DataType.varint()); + } + } - public static final class DoubleJavaType extends AbstractJavaType { + public static final class DoubleJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return Double.class; - } + @Override + public Class getJavaClass() { + return Double.class; + } - @Override - public Optional> getPrimitiveJavaClass() { - return Optional.of(double.class); - } + @Override + public Optional> getPrimitiveJavaClass() { + return Optional.of(double.class); + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - return new DTDataType(columnType, DataType.cdouble()); - } - } + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { + return new DTDataType(columnType, DataType.cdouble()); + } + } - public static final class FloatJavaType extends AbstractJavaType { + public static final class FloatJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return Float.class; - } + @Override + public Class getJavaClass() { + return Float.class; + } - @Override - public Optional> getPrimitiveJavaClass() { - return Optional.of(float.class); - } + @Override + public Optional> getPrimitiveJavaClass() { + return Optional.of(float.class); + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - return new DTDataType(columnType, DataType.cfloat()); - } - } + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { + return new DTDataType(columnType, DataType.cfloat()); + } + } - public static final class IntegerJavaType extends AbstractJavaType { + public static final class IntegerJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return Integer.class; - } + @Override + public Class getJavaClass() { + return Integer.class; + } - @Override - public Optional> getPrimitiveJavaClass() { - return Optional.of(int.class); - } + @Override + public Optional> getPrimitiveJavaClass() { + return Optional.of(int.class); + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - return new DTDataType(columnType, DataType.cint()); - } - } + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { + return new DTDataType(columnType, DataType.cint()); + } + } - public static final class InetAddressJavaType extends AbstractJavaType { + public static final class InetAddressJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return InetAddress.class; - } + @Override + public Class getJavaClass() { + return InetAddress.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { - return new DTDataType(columnType, DataType.inet()); - } - } + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { + return new DTDataType(columnType, DataType.inet()); + } + } } diff --git a/src/main/java/net/helenus/mapping/javatype/SetJavaType.java b/src/main/java/net/helenus/mapping/javatype/SetJavaType.java index 818d862..7d07ad3 100644 --- a/src/main/java/net/helenus/mapping/javatype/SetJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/SetJavaType.java @@ -15,12 +15,14 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.*; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Optional; import java.util.Set; import java.util.function.Function; + +import com.datastax.driver.core.*; + import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; @@ -37,112 +39,110 @@ import net.helenus.support.HelenusMappingException; public final class SetJavaType extends AbstractCollectionJavaType { - @Override - public Class getJavaClass() { - return Set.class; - } + @Override + public Class getJavaClass() { + return Set.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - Types.Set cset = getter.getDeclaredAnnotation(Types.Set.class); - if (cset != null) { - return new DTDataType(columnType, DataType.set(resolveSimpleType(getter, cset.value()))); - } + Types.Set cset = getter.getDeclaredAnnotation(Types.Set.class); + if (cset != null) { + return new DTDataType(columnType, DataType.set(resolveSimpleType(getter, cset.value()))); + } - Types.UDTSet udtSet = getter.getDeclaredAnnotation(Types.UDTSet.class); - if (udtSet != null) { - return new UDTSetDataType(columnType, resolveUDT(udtSet.value()), UDTValue.class); - } + Types.UDTSet udtSet = getter.getDeclaredAnnotation(Types.UDTSet.class); + if (udtSet != null) { + return new UDTSetDataType(columnType, resolveUDT(udtSet.value()), UDTValue.class); + } - Type[] args = getTypeParameters(genericJavaType); - ensureTypeArguments(getter, args.length, 1); + Type[] args = getTypeParameters(genericJavaType); + ensureTypeArguments(getter, args.length, 1); - Either parameterType = - autodetectParameterType(getter, args[0], metadata); + Either parameterType = autodetectParameterType(getter, args[0], metadata); - if (parameterType.isLeft()) { - return DTDataType.set(columnType, parameterType.getLeft(), args[0]); - } else { - return new UDTSetDataType(columnType, parameterType.getRight(), (Class) args[0]); - } - } + if (parameterType.isLeft()) { + return DTDataType.set(columnType, parameterType.getLeft(), args[0]); + } else { + return new UDTSetDataType(columnType, parameterType.getRight(), (Class) args[0]); + } + } - @Override - public Optional> resolveReadConverter( - AbstractDataType abstractDataType, SessionRepository repository) { + @Override + public Optional> resolveReadConverter(AbstractDataType abstractDataType, + SessionRepository repository) { - if (abstractDataType instanceof DTDataType) { + if (abstractDataType instanceof DTDataType) { - DTDataType dt = (DTDataType) abstractDataType; - DataType elementType = dt.getDataType().getTypeArguments().get(0); - if (elementType instanceof TupleType) { + DTDataType dt = (DTDataType) abstractDataType; + DataType elementType = dt.getDataType().getTypeArguments().get(0); + if (elementType instanceof TupleType) { - Class tupleClass = dt.getTypeArguments()[0]; + Class tupleClass = dt.getTypeArguments()[0]; - if (TupleValue.class.isAssignableFrom(tupleClass)) { - return Optional.empty(); - } + if (TupleValue.class.isAssignableFrom(tupleClass)) { + return Optional.empty(); + } - return Optional.of(new TupleSetToSetConverter(tupleClass, repository)); - } - } else if (abstractDataType instanceof UDTSetDataType) { + return Optional.of(new TupleSetToSetConverter(tupleClass, repository)); + } + } else if (abstractDataType instanceof UDTSetDataType) { - UDTSetDataType dt = (UDTSetDataType) abstractDataType; + UDTSetDataType dt = (UDTSetDataType) abstractDataType; - Class udtClass = (Class) dt.getTypeArguments()[0]; + Class udtClass = (Class) dt.getTypeArguments()[0]; - if (UDTValue.class.isAssignableFrom(udtClass)) { - return Optional.empty(); - } + if (UDTValue.class.isAssignableFrom(udtClass)) { + return Optional.empty(); + } - return Optional.of(new UDTSetToSetConverter(udtClass, repository)); - } + return Optional.of(new UDTSetToSetConverter(udtClass, repository)); + } - return Optional.empty(); - } + return Optional.empty(); + } - @Override - public Optional> resolveWriteConverter( - AbstractDataType abstractDataType, SessionRepository repository) { + @Override + public Optional> resolveWriteConverter(AbstractDataType abstractDataType, + SessionRepository repository) { - if (abstractDataType instanceof DTDataType) { + if (abstractDataType instanceof DTDataType) { - DTDataType dt = (DTDataType) abstractDataType; - DataType elementType = dt.getDataType().getTypeArguments().get(0); + DTDataType dt = (DTDataType) abstractDataType; + DataType elementType = dt.getDataType().getTypeArguments().get(0); - if (elementType instanceof TupleType) { + if (elementType instanceof TupleType) { - Class tupleClass = dt.getTypeArguments()[0]; + Class tupleClass = dt.getTypeArguments()[0]; - if (TupleValue.class.isAssignableFrom(tupleClass)) { - return Optional.empty(); - } + if (TupleValue.class.isAssignableFrom(tupleClass)) { + return Optional.empty(); + } - return Optional.of( - new SetToTupleSetConverter(tupleClass, (TupleType) elementType, repository)); - } + return Optional.of(new SetToTupleSetConverter(tupleClass, (TupleType) elementType, repository)); + } - } else if (abstractDataType instanceof UDTSetDataType) { + } else if (abstractDataType instanceof UDTSetDataType) { - UDTSetDataType dt = (UDTSetDataType) abstractDataType; + UDTSetDataType dt = (UDTSetDataType) abstractDataType; - Class udtClass = (Class) dt.getTypeArguments()[0]; + Class udtClass = (Class) dt.getTypeArguments()[0]; - if (UDTValue.class.isAssignableFrom(udtClass)) { - return Optional.empty(); - } + if (UDTValue.class.isAssignableFrom(udtClass)) { + return Optional.empty(); + } - UserType userType = repository.findUserType(dt.getUdtName().getName()); - if (userType == null) { - throw new HelenusMappingException( - "UserType not found for " + dt.getUdtName() + " with type " + udtClass); - } + UserType userType = repository.findUserType(dt.getUdtName().getName()); + if (userType == null) { + throw new HelenusMappingException( + "UserType not found for " + dt.getUdtName() + " with type " + udtClass); + } - return Optional.of(new SetToUDTSetConverter(udtClass, userType, repository)); - } + return Optional.of(new SetToUDTSetConverter(udtClass, userType, repository)); + } - return Optional.empty(); - } + return Optional.empty(); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/SimpleJavaTypes.java b/src/main/java/net/helenus/mapping/javatype/SimpleJavaTypes.java index 2484f24..9d2324b 100644 --- a/src/main/java/net/helenus/mapping/javatype/SimpleJavaTypes.java +++ b/src/main/java/net/helenus/mapping/javatype/SimpleJavaTypes.java @@ -15,53 +15,50 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.CodecRegistry; -import com.datastax.driver.core.DataType; import java.time.LocalTime; import java.util.HashMap; import java.util.Map; +import com.datastax.driver.core.CodecRegistry; +import com.datastax.driver.core.DataType; + public final class SimpleJavaTypes { - private static final Map, DataType> javaClassToDataTypeMap = - new HashMap, DataType>(); + private static final Map, DataType> javaClassToDataTypeMap = new HashMap, DataType>(); - private static final Map nameToDataTypeMap = - new HashMap(); + private static final Map nameToDataTypeMap = new HashMap(); - static { - for (DataType dataType : DataType.allPrimitiveTypes()) { + static { + for (DataType dataType : DataType.allPrimitiveTypes()) { - nameToDataTypeMap.put(dataType.getName(), dataType); + nameToDataTypeMap.put(dataType.getName(), dataType); - if (dataType.equals(DataType.counter()) - || dataType.equals(DataType.ascii()) - || dataType.equals(DataType.timeuuid()) - || dataType.equals(DataType.time())) { - continue; - } + if (dataType.equals(DataType.counter()) || dataType.equals(DataType.ascii()) + || dataType.equals(DataType.timeuuid()) || dataType.equals(DataType.time())) { + continue; + } - Class javaClass = - CodecRegistry.DEFAULT_INSTANCE.codecFor(dataType).getJavaType().getRawType(); + Class javaClass = CodecRegistry.DEFAULT_INSTANCE.codecFor(dataType).getJavaType().getRawType(); - DataType dt = javaClassToDataTypeMap.putIfAbsent(javaClass, dataType); - if (dt != null) { - throw new IllegalStateException( - "java type " + javaClass + " is has two datatypes " + dt + " and " + dataType); - } - } + DataType dt = javaClassToDataTypeMap.putIfAbsent(javaClass, dataType); + if (dt != null) { + throw new IllegalStateException( + "java type " + javaClass + " is has two datatypes " + dt + " and " + dataType); + } + } - javaClassToDataTypeMap.put(String.class, DataType.text()); - javaClassToDataTypeMap.put(LocalTime.class, DataType.time()); - } + javaClassToDataTypeMap.put(String.class, DataType.text()); + javaClassToDataTypeMap.put(LocalTime.class, DataType.time()); + } - private SimpleJavaTypes() {} + private SimpleJavaTypes() { + } - public static DataType getDataTypeByName(DataType.Name name) { - return nameToDataTypeMap.get(name); - } + public static DataType getDataTypeByName(DataType.Name name) { + return nameToDataTypeMap.get(name); + } - public static DataType getDataTypeByJavaClass(Class javaType) { - return javaClassToDataTypeMap.get(javaType); - } + public static DataType getDataTypeByJavaClass(Class javaType) { + return javaClassToDataTypeMap.get(javaType); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/StringJavaType.java b/src/main/java/net/helenus/mapping/javatype/StringJavaType.java index 333e857..d4e9253 100644 --- a/src/main/java/net/helenus/mapping/javatype/StringJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/StringJavaType.java @@ -15,10 +15,12 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Method; import java.lang.reflect.Type; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.annotation.Types; import net.helenus.mapping.type.AbstractDataType; @@ -26,27 +28,27 @@ import net.helenus.mapping.type.DTDataType; public final class StringJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return String.class; - } + @Override + public Class getJavaClass() { + return String.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - if (null != getter.getDeclaredAnnotation(Types.Ascii.class)) { - return new DTDataType(columnType, DataType.ascii()); - } + if (null != getter.getDeclaredAnnotation(Types.Ascii.class)) { + return new DTDataType(columnType, DataType.ascii()); + } - if (null != getter.getDeclaredAnnotation(Types.Text.class)) { - return new DTDataType(columnType, DataType.text()); - } + if (null != getter.getDeclaredAnnotation(Types.Text.class)) { + return new DTDataType(columnType, DataType.text()); + } - if (null != getter.getDeclaredAnnotation(Types.Varchar.class)) { - return new DTDataType(columnType, DataType.varchar()); - } + if (null != getter.getDeclaredAnnotation(Types.Varchar.class)) { + return new DTDataType(columnType, DataType.varchar()); + } - return new DTDataType(columnType, DataType.text()); - } + return new DTDataType(columnType, DataType.text()); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/TupleValueJavaType.java b/src/main/java/net/helenus/mapping/javatype/TupleValueJavaType.java index 47e2be3..0eaeda4 100644 --- a/src/main/java/net/helenus/mapping/javatype/TupleValueJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/TupleValueJavaType.java @@ -15,16 +15,18 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; -import com.datastax.driver.core.TupleType; -import com.datastax.driver.core.TupleValue; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.List; import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; +import com.datastax.driver.core.TupleType; +import com.datastax.driver.core.TupleValue; + import net.helenus.core.Helenus; import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; @@ -41,112 +43,94 @@ import net.helenus.support.HelenusMappingException; public final class TupleValueJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return TupleValue.class; - } + @Override + public Class getJavaClass() { + return TupleValue.class; + } - @Override - public boolean isApplicable(Class javaClass) { - return MappingUtil.isTuple(javaClass); - } + @Override + public boolean isApplicable(Class javaClass) { + return MappingUtil.isTuple(javaClass); + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - Class javaType = (Class) genericJavaType; + Class javaType = (Class) genericJavaType; - if (TupleValue.class.isAssignableFrom(javaType)) { + if (TupleValue.class.isAssignableFrom(javaType)) { - Types.Tuple tuple = getter.getDeclaredAnnotation(Types.Tuple.class); - if (tuple == null) { - throw new HelenusMappingException( - "tuple must be annotated by @Tuple annotation in " + getter); - } + Types.Tuple tuple = getter.getDeclaredAnnotation(Types.Tuple.class); + if (tuple == null) { + throw new HelenusMappingException("tuple must be annotated by @Tuple annotation in " + getter); + } - DataType.Name[] tupleArguments = tuple.value(); - int len = tupleArguments.length; - DataType[] arguments = new DataType[len]; + DataType.Name[] tupleArguments = tuple.value(); + int len = tupleArguments.length; + DataType[] arguments = new DataType[len]; - for (int i = 0; i != len; ++i) { - arguments[i] = resolveSimpleType(getter, tupleArguments[i]); - } + for (int i = 0; i != len; ++i) { + arguments[i] = resolveSimpleType(getter, tupleArguments[i]); + } - TupleType tupleType = metadata.newTupleType(arguments); - return new DTDataType(columnType, tupleType, javaType); + TupleType tupleType = metadata.newTupleType(arguments); + return new DTDataType(columnType, tupleType, javaType); - } else { - return new DTDataType(columnType, toTupleType(javaType, metadata), javaType); - } - } + } else { + return new DTDataType(columnType, toTupleType(javaType, metadata), javaType); + } + } - public static TupleType toTupleType(Class javaType, Metadata metadata) { - HelenusEntity tupleEntity = Helenus.entity(javaType, metadata); + public static TupleType toTupleType(Class javaType, Metadata metadata) { + HelenusEntity tupleEntity = Helenus.entity(javaType, metadata); - List tupleTypes = - tupleEntity - .getOrderedProperties() - .stream() - .map(p -> p.getDataType()) - .filter(d -> d instanceof DTDataType) - .map(d -> (DTDataType) d) - .map(d -> d.getDataType()) - .collect(Collectors.toList()); + List tupleTypes = tupleEntity.getOrderedProperties().stream().map(p -> p.getDataType()) + .filter(d -> d instanceof DTDataType).map(d -> (DTDataType) d).map(d -> d.getDataType()) + .collect(Collectors.toList()); - if (tupleTypes.size() < tupleEntity.getOrderedProperties().size()) { + if (tupleTypes.size() < tupleEntity.getOrderedProperties().size()) { - List wrongColumns = - tupleEntity - .getOrderedProperties() - .stream() - .filter(p -> !(p.getDataType() instanceof DTDataType)) - .map(p -> p.getColumnName()) - .collect(Collectors.toList()); + List wrongColumns = tupleEntity.getOrderedProperties().stream() + .filter(p -> !(p.getDataType() instanceof DTDataType)).map(p -> p.getColumnName()) + .collect(Collectors.toList()); - throw new HelenusMappingException( - "non simple types in tuple " - + tupleEntity.getMappingInterface() - + " in columns: " - + wrongColumns); - } + throw new HelenusMappingException( + "non simple types in tuple " + tupleEntity.getMappingInterface() + " in columns: " + wrongColumns); + } - return metadata.newTupleType(tupleTypes.toArray(new DataType[tupleTypes.size()])); - } + return metadata.newTupleType(tupleTypes.toArray(new DataType[tupleTypes.size()])); + } - @Override - public Optional> resolveReadConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveReadConverter(AbstractDataType dataType, + SessionRepository repository) { - DTDataType dt = (DTDataType) dataType; + DTDataType dt = (DTDataType) dataType; - Class javaClass = (Class) dt.getJavaClass(); + Class javaClass = (Class) dt.getJavaClass(); - if (TupleValue.class.isAssignableFrom(javaClass)) { - return Optional.empty(); - } + if (TupleValue.class.isAssignableFrom(javaClass)) { + return Optional.empty(); + } - return Optional.of( - TypedConverter.create( - TupleValue.class, javaClass, new TupleValueToEntityConverter(javaClass, repository))); - } + return Optional.of(TypedConverter.create(TupleValue.class, javaClass, + new TupleValueToEntityConverter(javaClass, repository))); + } - @Override - public Optional> resolveWriteConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveWriteConverter(AbstractDataType dataType, + SessionRepository repository) { - DTDataType dt = (DTDataType) dataType; + DTDataType dt = (DTDataType) dataType; - Class javaClass = (Class) dt.getJavaClass(); + Class javaClass = (Class) dt.getJavaClass(); - if (TupleValue.class.isAssignableFrom(javaClass)) { - return Optional.empty(); - } + if (TupleValue.class.isAssignableFrom(javaClass)) { + return Optional.empty(); + } - return Optional.of( - TypedConverter.create( - javaClass, - TupleValue.class, - new EntityToTupleValueConverter(javaClass, (TupleType) dt.getDataType(), repository))); - } + return Optional.of(TypedConverter.create(javaClass, TupleValue.class, + new EntityToTupleValueConverter(javaClass, (TupleType) dt.getDataType(), repository))); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/UDTValueJavaType.java b/src/main/java/net/helenus/mapping/javatype/UDTValueJavaType.java index 240bfbd..7c6246c 100644 --- a/src/main/java/net/helenus/mapping/javatype/UDTValueJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/UDTValueJavaType.java @@ -15,13 +15,15 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.Metadata; -import com.datastax.driver.core.UDTValue; -import com.datastax.driver.core.UserType; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.Metadata; +import com.datastax.driver.core.UDTValue; +import com.datastax.driver.core.UserType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; @@ -36,82 +38,77 @@ import net.helenus.support.HelenusMappingException; public final class UDTValueJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return UDTValue.class; - } + @Override + public Class getJavaClass() { + return UDTValue.class; + } - @Override - public boolean isApplicable(Class javaClass) { - return MappingUtil.isUDT(javaClass); - } + @Override + public boolean isApplicable(Class javaClass) { + return MappingUtil.isUDT(javaClass); + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - Class javaType = (Class) genericJavaType; + Class javaType = (Class) genericJavaType; - IdentityName udtName = null; + IdentityName udtName = null; - if (UDTValue.class.isAssignableFrom(javaType)) { + if (UDTValue.class.isAssignableFrom(javaType)) { - Types.UDT userTypeName = getter.getDeclaredAnnotation(Types.UDT.class); - if (userTypeName == null) { - throw new HelenusMappingException("absent UserTypeName annotation for " + getter); - } + Types.UDT userTypeName = getter.getDeclaredAnnotation(Types.UDT.class); + if (userTypeName == null) { + throw new HelenusMappingException("absent UserTypeName annotation for " + getter); + } - udtName = new IdentityName(userTypeName.value(), userTypeName.forceQuote()); - } else { - udtName = MappingUtil.getUserDefinedTypeName(javaType, false); - } + udtName = new IdentityName(userTypeName.value(), userTypeName.forceQuote()); + } else { + udtName = MappingUtil.getUserDefinedTypeName(javaType, false); + } - if (udtName != null) { - return new UDTDataType(columnType, udtName, javaType); - } + if (udtName != null) { + return new UDTDataType(columnType, udtName, javaType); + } - throw new HelenusMappingException("unknown type " + javaType + " in " + getter); - } + throw new HelenusMappingException("unknown type " + javaType + " in " + getter); + } - @Override - public Optional> resolveReadConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveReadConverter(AbstractDataType dataType, + SessionRepository repository) { - UDTDataType dt = (UDTDataType) dataType; + UDTDataType dt = (UDTDataType) dataType; - Class javaClass = (Class) dt.getTypeArguments()[0]; + Class javaClass = (Class) dt.getTypeArguments()[0]; - if (UDTValue.class.isAssignableFrom(javaClass)) { - return Optional.empty(); - } + if (UDTValue.class.isAssignableFrom(javaClass)) { + return Optional.empty(); + } - return Optional.of( - TypedConverter.create( - UDTValue.class, javaClass, new UDTValueToEntityConverter(javaClass, repository))); - } + return Optional.of( + TypedConverter.create(UDTValue.class, javaClass, new UDTValueToEntityConverter(javaClass, repository))); + } - @Override - public Optional> resolveWriteConverter( - AbstractDataType dataType, SessionRepository repository) { + @Override + public Optional> resolveWriteConverter(AbstractDataType dataType, + SessionRepository repository) { - UDTDataType dt = (UDTDataType) dataType; + UDTDataType dt = (UDTDataType) dataType; - Class javaClass = (Class) dt.getTypeArguments()[0]; + Class javaClass = (Class) dt.getTypeArguments()[0]; - if (UDTValue.class.isAssignableFrom(javaClass)) { - return Optional.empty(); - } + if (UDTValue.class.isAssignableFrom(javaClass)) { + return Optional.empty(); + } - UserType userType = repository.findUserType(dt.getUdtName().getName()); - if (userType == null) { - throw new HelenusMappingException( - "UserType not found for " + dt.getUdtName() + " with type " + javaClass); - } + UserType userType = repository.findUserType(dt.getUdtName().getName()); + if (userType == null) { + throw new HelenusMappingException("UserType not found for " + dt.getUdtName() + " with type " + javaClass); + } - return Optional.of( - TypedConverter.create( - javaClass, - UDTValue.class, - new EntityToUDTValueConverter(javaClass, userType, repository))); - } + return Optional.of(TypedConverter.create(javaClass, UDTValue.class, + new EntityToUDTValueConverter(javaClass, userType, repository))); + } } diff --git a/src/main/java/net/helenus/mapping/javatype/UUIDJavaType.java b/src/main/java/net/helenus/mapping/javatype/UUIDJavaType.java index d3c712b..52aca62 100644 --- a/src/main/java/net/helenus/mapping/javatype/UUIDJavaType.java +++ b/src/main/java/net/helenus/mapping/javatype/UUIDJavaType.java @@ -15,11 +15,13 @@ */ package net.helenus.mapping.javatype; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.Metadata; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.UUID; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.Metadata; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.annotation.Types; import net.helenus.mapping.type.AbstractDataType; @@ -27,23 +29,23 @@ import net.helenus.mapping.type.DTDataType; public final class UUIDJavaType extends AbstractJavaType { - @Override - public Class getJavaClass() { - return UUID.class; - } + @Override + public Class getJavaClass() { + return UUID.class; + } - @Override - public AbstractDataType resolveDataType( - Method getter, Type genericJavaType, ColumnType columnType, Metadata metadata) { + @Override + public AbstractDataType resolveDataType(Method getter, Type genericJavaType, ColumnType columnType, + Metadata metadata) { - if (null != getter.getDeclaredAnnotation(Types.Uuid.class)) { - return new DTDataType(columnType, DataType.uuid()); - } + if (null != getter.getDeclaredAnnotation(Types.Uuid.class)) { + return new DTDataType(columnType, DataType.uuid()); + } - if (null != getter.getDeclaredAnnotation(Types.Timeuuid.class)) { - return new DTDataType(columnType, DataType.timeuuid()); - } + if (null != getter.getDeclaredAnnotation(Types.Timeuuid.class)) { + return new DTDataType(columnType, DataType.timeuuid()); + } - return new DTDataType(columnType, DataType.uuid()); - } + return new DTDataType(columnType, DataType.uuid()); + } } diff --git a/src/main/java/net/helenus/mapping/type/AbstractCollectionDataType.java b/src/main/java/net/helenus/mapping/type/AbstractCollectionDataType.java index 7e76d92..ef8b9a1 100644 --- a/src/main/java/net/helenus/mapping/type/AbstractCollectionDataType.java +++ b/src/main/java/net/helenus/mapping/type/AbstractCollectionDataType.java @@ -4,11 +4,11 @@ import net.helenus.mapping.ColumnType; public abstract class AbstractCollectionDataType extends AbstractDataType { - public AbstractCollectionDataType(ColumnType columnType) { - super(columnType); - } + public AbstractCollectionDataType(ColumnType columnType) { + super(columnType); + } - public boolean isCollectionType() { - return true; - } + public boolean isCollectionType() { + return true; + } } diff --git a/src/main/java/net/helenus/mapping/type/AbstractDataType.java b/src/main/java/net/helenus/mapping/type/AbstractDataType.java index cc65d68..5322201 100644 --- a/src/main/java/net/helenus/mapping/type/AbstractDataType.java +++ b/src/main/java/net/helenus/mapping/type/AbstractDataType.java @@ -19,43 +19,44 @@ import com.datastax.driver.core.schemabuilder.Alter; import com.datastax.driver.core.schemabuilder.Create; import com.datastax.driver.core.schemabuilder.CreateType; import com.datastax.driver.core.schemabuilder.SchemaStatement; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; import net.helenus.support.HelenusMappingException; public abstract class AbstractDataType { - public abstract void addColumn(Create create, IdentityName columnName); + public abstract void addColumn(Create create, IdentityName columnName); - public abstract void addColumn(CreateType create, IdentityName columnName); + public abstract void addColumn(CreateType create, IdentityName columnName); - public abstract SchemaStatement alterColumn( - Alter alter, IdentityName columnName, OptionalColumnMetadata columnInformation); + public abstract SchemaStatement alterColumn(Alter alter, IdentityName columnName, + OptionalColumnMetadata columnInformation); - public abstract Class[] getTypeArguments(); + public abstract Class[] getTypeArguments(); - final ColumnType columnType; + final ColumnType columnType; - public AbstractDataType(ColumnType columnType) { - this.columnType = columnType; - } + public AbstractDataType(ColumnType columnType) { + this.columnType = columnType; + } - public ColumnType getColumnType() { - return columnType; - } + public ColumnType getColumnType() { + return columnType; + } - void ensureSimpleColumn(IdentityName columnName) { - if (columnType != ColumnType.COLUMN) { - throwWrongColumnType(columnName); - } - } + void ensureSimpleColumn(IdentityName columnName) { + if (columnType != ColumnType.COLUMN) { + throwWrongColumnType(columnName); + } + } - void throwWrongColumnType(IdentityName columnName) { - throw new HelenusMappingException( - "wrong column type " + columnType + " for UserDefinedType in columnName " + columnName); - } + void throwWrongColumnType(IdentityName columnName) { + throw new HelenusMappingException( + "wrong column type " + columnType + " for UserDefinedType in columnName " + columnName); + } - public boolean isCollectionType() { - return false; - } + public boolean isCollectionType() { + return false; + } } diff --git a/src/main/java/net/helenus/mapping/type/DTDataType.java b/src/main/java/net/helenus/mapping/type/DTDataType.java index e61d171..d4d2e05 100644 --- a/src/main/java/net/helenus/mapping/type/DTDataType.java +++ b/src/main/java/net/helenus/mapping/type/DTDataType.java @@ -15,6 +15,8 @@ */ package net.helenus.mapping.type; +import java.lang.reflect.Type; + import com.datastax.driver.core.CodecRegistry; import com.datastax.driver.core.DataType; import com.datastax.driver.core.TupleType; @@ -22,185 +24,166 @@ import com.datastax.driver.core.schemabuilder.Alter; import com.datastax.driver.core.schemabuilder.Create; import com.datastax.driver.core.schemabuilder.CreateType; import com.datastax.driver.core.schemabuilder.SchemaStatement; -import java.lang.reflect.Type; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; import net.helenus.support.HelenusMappingException; public final class DTDataType extends AbstractDataType { - private static final Class[] EMPTY_CLASSES = new Class[] {}; + private static final Class[] EMPTY_CLASSES = new Class[]{}; - private final DataType dataType; - private final Class javaClass; - private final Class[] typeArguments; - private final boolean isCollectionType; + private final DataType dataType; + private final Class javaClass; + private final Class[] typeArguments; + private final boolean isCollectionType; - public DTDataType(ColumnType columnType, DataType dataType) { - this( - columnType, - dataType, - CodecRegistry.DEFAULT_INSTANCE.codecFor(dataType).getJavaType().getClass(), - EMPTY_CLASSES); - } + public DTDataType(ColumnType columnType, DataType dataType) { + this(columnType, dataType, CodecRegistry.DEFAULT_INSTANCE.codecFor(dataType).getJavaType().getClass(), + EMPTY_CLASSES); + } - public DTDataType(ColumnType columnType, DataType dataType, Class javaClass) { - this(columnType, dataType, javaClass, EMPTY_CLASSES); - } + public DTDataType(ColumnType columnType, DataType dataType, Class javaClass) { + this(columnType, dataType, javaClass, EMPTY_CLASSES); + } - public DTDataType( - ColumnType columnType, DataType dataType, Class javaClass, Class[] typeArguments) { - super(columnType); - this.dataType = dataType; - this.javaClass = javaClass; - this.typeArguments = typeArguments; - this.isCollectionType = dataType.isCollection(); - } + public DTDataType(ColumnType columnType, DataType dataType, Class javaClass, Class[] typeArguments) { + super(columnType); + this.dataType = dataType; + this.javaClass = javaClass; + this.typeArguments = typeArguments; + this.isCollectionType = dataType.isCollection(); + } - public static DTDataType list( - ColumnType columnType, DataType argumentDataType, Type argumentType) { + public static DTDataType list(ColumnType columnType, DataType argumentDataType, Type argumentType) { - DataType listDataType = DataType.list(argumentDataType); + DataType listDataType = DataType.list(argumentDataType); - if (argumentDataType instanceof TupleType) { - return new DTDataType( - columnType, - listDataType, - CodecRegistry.DEFAULT_INSTANCE.codecFor(listDataType).getClass(), - new Class[] {(Class) argumentType}); - } else { - return new DTDataType(columnType, listDataType); - } - } + if (argumentDataType instanceof TupleType) { + return new DTDataType(columnType, listDataType, + CodecRegistry.DEFAULT_INSTANCE.codecFor(listDataType).getClass(), + new Class[]{(Class) argumentType}); + } else { + return new DTDataType(columnType, listDataType); + } + } - public static DTDataType set( - ColumnType columnType, DataType argumentDataType, Type argumentType) { + public static DTDataType set(ColumnType columnType, DataType argumentDataType, Type argumentType) { - DataType setDataType = DataType.set(argumentDataType); + DataType setDataType = DataType.set(argumentDataType); - if (argumentDataType instanceof TupleType) { - return new DTDataType( - columnType, - setDataType, - CodecRegistry.DEFAULT_INSTANCE.codecFor(setDataType).getClass(), - new Class[] {(Class) argumentType}); - } else { - return new DTDataType(columnType, setDataType); - } - } + if (argumentDataType instanceof TupleType) { + return new DTDataType(columnType, setDataType, + CodecRegistry.DEFAULT_INSTANCE.codecFor(setDataType).getClass(), + new Class[]{(Class) argumentType}); + } else { + return new DTDataType(columnType, setDataType); + } + } - public static DTDataType map( - ColumnType columnType, - DataType keyDataType, - Type keyType, - DataType valueDataType, - Type valueType) { + public static DTDataType map(ColumnType columnType, DataType keyDataType, Type keyType, DataType valueDataType, + Type valueType) { - DataType mapDataType = DataType.map(keyDataType, valueDataType); + DataType mapDataType = DataType.map(keyDataType, valueDataType); - Class[] typeArguments = EMPTY_CLASSES; + Class[] typeArguments = EMPTY_CLASSES; - if (keyDataType instanceof TupleType) { - if (valueDataType instanceof TupleType) { - typeArguments = new Class[] {(Class) keyType, (Class) valueType}; - } else { - typeArguments = new Class[] {(Class) keyType}; - } - } else if (valueDataType instanceof TupleType) { - typeArguments = new Class[] {(Class) valueType}; - } + if (keyDataType instanceof TupleType) { + if (valueDataType instanceof TupleType) { + typeArguments = new Class[]{(Class) keyType, (Class) valueType}; + } else { + typeArguments = new Class[]{(Class) keyType}; + } + } else if (valueDataType instanceof TupleType) { + typeArguments = new Class[]{(Class) valueType}; + } - return new DTDataType( - columnType, - mapDataType, - CodecRegistry.DEFAULT_INSTANCE.codecFor(mapDataType).getClass(), - typeArguments); - } + return new DTDataType(columnType, mapDataType, CodecRegistry.DEFAULT_INSTANCE.codecFor(mapDataType).getClass(), + typeArguments); + } - public DataType getDataType() { - return dataType; - } + public DataType getDataType() { + return dataType; + } - public Class getJavaClass() { - return javaClass; - } + public Class getJavaClass() { + return javaClass; + } - @Override - public Class[] getTypeArguments() { - return typeArguments; - } + @Override + public Class[] getTypeArguments() { + return typeArguments; + } - @Override - public void addColumn(Create create, IdentityName columnName) { + @Override + public void addColumn(Create create, IdentityName columnName) { - switch (columnType) { - case PARTITION_KEY: - create.addPartitionKey(columnName.toCql(), dataType); - break; + switch (columnType) { + case PARTITION_KEY : + create.addPartitionKey(columnName.toCql(), dataType); + break; - case CLUSTERING_COLUMN: - create.addClusteringColumn(columnName.toCql(), dataType); - break; + case CLUSTERING_COLUMN : + create.addClusteringColumn(columnName.toCql(), dataType); + break; - case STATIC_COLUMN: - create.addStaticColumn(columnName.toCql(), dataType); - break; + case STATIC_COLUMN : + create.addStaticColumn(columnName.toCql(), dataType); + break; - case COLUMN: - create.addColumn(columnName.toCql(), dataType); - break; + case COLUMN : + create.addColumn(columnName.toCql(), dataType); + break; - default: - throwWrongColumnType(columnName); - } - } + default : + throwWrongColumnType(columnName); + } + } - @Override - public void addColumn(CreateType create, IdentityName columnName) { + @Override + public void addColumn(CreateType create, IdentityName columnName) { - if (columnType != ColumnType.COLUMN) { - throwWrongColumnType(columnName); - } + if (columnType != ColumnType.COLUMN) { + throwWrongColumnType(columnName); + } - create.addColumn(columnName.toCql(), dataType); - } + create.addColumn(columnName.toCql(), dataType); + } - @Override - public SchemaStatement alterColumn( - Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { + @Override + public SchemaStatement alterColumn(Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { - if (columnMetadata != null) { + if (columnMetadata != null) { - if (!dataType.equals(columnMetadata.getType())) { - ensureSimpleColumn(columnName); + if (!dataType.equals(columnMetadata.getType())) { + ensureSimpleColumn(columnName); - return alter.alterColumn(columnName.toCql()).type(dataType); - } + return alter.alterColumn(columnName.toCql()).type(dataType); + } - } else { + } else { - switch (columnType) { - case STATIC_COLUMN: - return alter.addStaticColumn(columnName.toCql()).type(dataType); + switch (columnType) { + case STATIC_COLUMN : + return alter.addStaticColumn(columnName.toCql()).type(dataType); - case COLUMN: - return alter.addColumn(columnName.toCql()).type(dataType); + case COLUMN : + return alter.addColumn(columnName.toCql()).type(dataType); - default: - throw new HelenusMappingException( - "unable to alter " + columnType + " column " + columnName); - } - } + default : + throw new HelenusMappingException("unable to alter " + columnType + " column " + columnName); + } + } - return null; - } + return null; + } - public boolean isCollectionType() { - return isCollectionType; - } + public boolean isCollectionType() { + return isCollectionType; + } - @Override - public String toString() { - return dataType.toString(); - } + @Override + public String toString() { + return dataType.toString(); + } } diff --git a/src/main/java/net/helenus/mapping/type/ListToTupleListConverter.java b/src/main/java/net/helenus/mapping/type/ListToTupleListConverter.java index a364c48..a7fb9d4 100644 --- a/src/main/java/net/helenus/mapping/type/ListToTupleListConverter.java +++ b/src/main/java/net/helenus/mapping/type/ListToTupleListConverter.java @@ -15,24 +15,25 @@ */ package net.helenus.mapping.type; -import com.datastax.driver.core.TupleType; import java.util.List; import java.util.function.Function; + +import com.datastax.driver.core.TupleType; + import net.helenus.core.SessionRepository; import net.helenus.mapping.convert.TupleValueWriter; import net.helenus.support.Transformers; public final class ListToTupleListConverter implements Function { - final TupleValueWriter writer; + final TupleValueWriter writer; - public ListToTupleListConverter( - Class iface, TupleType tupleType, SessionRepository repository) { - this.writer = new TupleValueWriter(iface, tupleType, repository); - } + public ListToTupleListConverter(Class iface, TupleType tupleType, SessionRepository repository) { + this.writer = new TupleValueWriter(iface, tupleType, repository); + } - @Override - public Object apply(Object t) { - return Transformers.transformList((List) t, writer); - } + @Override + public Object apply(Object t) { + return Transformers.transformList((List) t, writer); + } } diff --git a/src/main/java/net/helenus/mapping/type/OptionalColumnMetadata.java b/src/main/java/net/helenus/mapping/type/OptionalColumnMetadata.java index f6d240c..0589c76 100644 --- a/src/main/java/net/helenus/mapping/type/OptionalColumnMetadata.java +++ b/src/main/java/net/helenus/mapping/type/OptionalColumnMetadata.java @@ -19,7 +19,7 @@ import com.datastax.driver.core.DataType; public interface OptionalColumnMetadata { - String getName(); + String getName(); - DataType getType(); + DataType getType(); } diff --git a/src/main/java/net/helenus/mapping/type/UDTDataType.java b/src/main/java/net/helenus/mapping/type/UDTDataType.java index 281529c..d24e9a3 100644 --- a/src/main/java/net/helenus/mapping/type/UDTDataType.java +++ b/src/main/java/net/helenus/mapping/type/UDTDataType.java @@ -18,100 +18,100 @@ package net.helenus.mapping.type; import com.datastax.driver.core.DataType; import com.datastax.driver.core.UserType; import com.datastax.driver.core.schemabuilder.*; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; public final class UDTDataType extends AbstractDataType { - private final IdentityName udtName; - private final Class udtClass; + private final IdentityName udtName; + private final Class udtClass; - public UDTDataType(ColumnType columnType, IdentityName udtName, Class udtClass) { - super(columnType); - this.udtName = udtName; - this.udtClass = udtClass; - } + public UDTDataType(ColumnType columnType, IdentityName udtName, Class udtClass) { + super(columnType); + this.udtName = udtName; + this.udtClass = udtClass; + } - @Override - public Class[] getTypeArguments() { - return new Class[] {udtClass}; - } + @Override + public Class[] getTypeArguments() { + return new Class[]{udtClass}; + } - public IdentityName getUdtName() { - return udtName; - } + public IdentityName getUdtName() { + return udtName; + } - @Override - public void addColumn(Create create, IdentityName columnName) { + @Override + public void addColumn(Create create, IdentityName columnName) { - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - switch (columnType) { - case PARTITION_KEY: - create.addUDTPartitionKey(columnName.toCql(), udtType); - break; + switch (columnType) { + case PARTITION_KEY : + create.addUDTPartitionKey(columnName.toCql(), udtType); + break; - case CLUSTERING_COLUMN: - create.addUDTClusteringColumn(columnName.toCql(), udtType); - break; + case CLUSTERING_COLUMN : + create.addUDTClusteringColumn(columnName.toCql(), udtType); + break; - case STATIC_COLUMN: - create.addUDTStaticColumn(columnName.toCql(), udtType); - break; + case STATIC_COLUMN : + create.addUDTStaticColumn(columnName.toCql(), udtType); + break; - case COLUMN: - create.addUDTColumn(columnName.toCql(), udtType); - break; + case COLUMN : + create.addUDTColumn(columnName.toCql(), udtType); + break; - default: - throwWrongColumnType(columnName); - } - } + default : + throwWrongColumnType(columnName); + } + } - @Override - public void addColumn(CreateType create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(CreateType create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - create.addUDTColumn(columnName.toCql(), udtType); - } + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + create.addUDTColumn(columnName.toCql(), udtType); + } - @Override - public SchemaStatement alterColumn( - Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { + @Override + public SchemaStatement alterColumn(Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { - ensureSimpleColumn(columnName); + ensureSimpleColumn(columnName); - if (columnMetadata != null) { + if (columnMetadata != null) { - DataType metadataType = columnMetadata.getType(); - if (metadataType.getName() == DataType.Name.UDT && metadataType instanceof UserType) { + DataType metadataType = columnMetadata.getType(); + if (metadataType.getName() == DataType.Name.UDT && metadataType instanceof UserType) { - UserType metadataUserType = (UserType) metadataType; + UserType metadataUserType = (UserType) metadataType; - if (!udtName.getName().equals(metadataUserType.getTypeName())) { + if (!udtName.getName().equals(metadataUserType.getTypeName())) { - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - return alter.alterColumn(columnName.toCql()).udtType(udtType); - } + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + return alter.alterColumn(columnName.toCql()).udtType(udtType); + } - } else { + } else { - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - return alter.alterColumn(columnName.toCql()).udtType(udtType); - } + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + return alter.alterColumn(columnName.toCql()).udtType(udtType); + } - } else { + } else { - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - return alter.addColumn(columnName.toCql()).udtType(udtType); - } + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + return alter.addColumn(columnName.toCql()).udtType(udtType); + } - return null; - } + return null; + } - @Override - public String toString() { - return "UDT<" + udtName + ">"; - } + @Override + public String toString() { + return "UDT<" + udtName + ">"; + } } diff --git a/src/main/java/net/helenus/mapping/type/UDTKeyMapDataType.java b/src/main/java/net/helenus/mapping/type/UDTKeyMapDataType.java index e04685c..25c0939 100644 --- a/src/main/java/net/helenus/mapping/type/UDTKeyMapDataType.java +++ b/src/main/java/net/helenus/mapping/type/UDTKeyMapDataType.java @@ -15,97 +15,97 @@ */ package net.helenus.mapping.type; +import java.util.List; + import com.datastax.driver.core.DataType; import com.datastax.driver.core.UserType; import com.datastax.driver.core.schemabuilder.*; -import java.util.List; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; import net.helenus.support.HelenusMappingException; public final class UDTKeyMapDataType extends AbstractCollectionDataType { - private final IdentityName keyType; - private final Class udtKeyClass; - private final DataType valueType; + private final IdentityName keyType; + private final Class udtKeyClass; + private final DataType valueType; - public UDTKeyMapDataType( - ColumnType columnType, IdentityName keyType, Class udtKeyClass, DataType valueType) { - super(columnType); - this.keyType = keyType; - this.udtKeyClass = udtKeyClass; - this.valueType = valueType; - } + public UDTKeyMapDataType(ColumnType columnType, IdentityName keyType, Class udtKeyClass, DataType valueType) { + super(columnType); + this.keyType = keyType; + this.udtKeyClass = udtKeyClass; + this.valueType = valueType; + } - @Override - public Class[] getTypeArguments() { - return new Class[] {udtKeyClass}; - } + @Override + public Class[] getTypeArguments() { + return new Class[]{udtKeyClass}; + } - public IdentityName getUdtKeyName() { - return keyType; - } + public IdentityName getUdtKeyName() { + return keyType; + } - public Class getUdtKeyClass() { - return udtKeyClass; - } + public Class getUdtKeyClass() { + return udtKeyClass; + } - @Override - public void addColumn(Create create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(Create create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType keyUdtType = SchemaBuilder.frozen(keyType.toCql()); - create.addUDTMapColumn(columnName.toCql(), keyUdtType, valueType); - } + UDTType keyUdtType = SchemaBuilder.frozen(keyType.toCql()); + create.addUDTMapColumn(columnName.toCql(), keyUdtType, valueType); + } - @Override - public void addColumn(CreateType create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(CreateType create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType keyUdtType = SchemaBuilder.frozen(keyType.toCql()); - create.addUDTMapColumn(columnName.toCql(), keyUdtType, valueType); - } + UDTType keyUdtType = SchemaBuilder.frozen(keyType.toCql()); + create.addUDTMapColumn(columnName.toCql(), keyUdtType, valueType); + } - @Override - public SchemaStatement alterColumn( - Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { + @Override + public SchemaStatement alterColumn(Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { - if (columnMetadata == null) { - return notSupportedOperation("add", columnName); - } + if (columnMetadata == null) { + return notSupportedOperation("add", columnName); + } - DataType schemaDataType = columnMetadata.getType(); - if (schemaDataType.getName() != DataType.Name.MAP) { - return notSupportedOperation("alter", columnName); - } + DataType schemaDataType = columnMetadata.getType(); + if (schemaDataType.getName() != DataType.Name.MAP) { + return notSupportedOperation("alter", columnName); + } - List args = columnMetadata.getType().getTypeArguments(); - if (args.size() != 2 || !args.get(1).equals(valueType)) { - return notSupportedOperation("alter", columnName); - } + List args = columnMetadata.getType().getTypeArguments(); + if (args.size() != 2 || !args.get(1).equals(valueType)) { + return notSupportedOperation("alter", columnName); + } - DataType keyDataType = args.get(0); - if (keyDataType.getName() != DataType.Name.UDT || !(keyDataType instanceof UserType)) { - return notSupportedOperation("alter", columnName); - } + DataType keyDataType = args.get(0); + if (keyDataType.getName() != DataType.Name.UDT || !(keyDataType instanceof UserType)) { + return notSupportedOperation("alter", columnName); + } - UserType udtKeyType = (UserType) keyDataType; + UserType udtKeyType = (UserType) keyDataType; - if (!keyType.getName().equals(udtKeyType.getTypeName())) { - return notSupportedOperation("alter", columnName); - } + if (!keyType.getName().equals(udtKeyType.getTypeName())) { + return notSupportedOperation("alter", columnName); + } - // equals - return null; - } + // equals + return null; + } - private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { - throw new HelenusMappingException( - op + " UDTMap column is not supported by Cassandra Driver for column '" + columnName + "'"); - } + private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { + throw new HelenusMappingException( + op + " UDTMap column is not supported by Cassandra Driver for column '" + columnName + "'"); + } - @Override - public String toString() { - return "UDTKeyMap<" + keyType + "," + valueType + ">"; - } + @Override + public String toString() { + return "UDTKeyMap<" + keyType + "," + valueType + ">"; + } } diff --git a/src/main/java/net/helenus/mapping/type/UDTListDataType.java b/src/main/java/net/helenus/mapping/type/UDTListDataType.java index 21b2956..2a08410 100644 --- a/src/main/java/net/helenus/mapping/type/UDTListDataType.java +++ b/src/main/java/net/helenus/mapping/type/UDTListDataType.java @@ -15,93 +15,91 @@ */ package net.helenus.mapping.type; +import java.util.List; + import com.datastax.driver.core.DataType; import com.datastax.driver.core.UserType; import com.datastax.driver.core.schemabuilder.*; -import java.util.List; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; import net.helenus.support.HelenusMappingException; public final class UDTListDataType extends AbstractCollectionDataType { - private final IdentityName udtName; - private final Class udtClass; + private final IdentityName udtName; + private final Class udtClass; - public UDTListDataType(ColumnType columnType, IdentityName udtName, Class udtClass) { - super(columnType); - this.udtName = udtName; - this.udtClass = udtClass; - } + public UDTListDataType(ColumnType columnType, IdentityName udtName, Class udtClass) { + super(columnType); + this.udtName = udtName; + this.udtClass = udtClass; + } - @Override - public Class[] getTypeArguments() { - return new Class[] {udtClass}; - } + @Override + public Class[] getTypeArguments() { + return new Class[]{udtClass}; + } - public IdentityName getUdtName() { - return udtName; - } + public IdentityName getUdtName() { + return udtName; + } - @Override - public void addColumn(Create create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(Create create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - create.addUDTListColumn(columnName.toCql(), udtType); - } + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + create.addUDTListColumn(columnName.toCql(), udtType); + } - @Override - public void addColumn(CreateType create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(CreateType create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - create.addUDTListColumn(columnName.toCql(), udtType); - } + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + create.addUDTListColumn(columnName.toCql(), udtType); + } - @Override - public SchemaStatement alterColumn( - Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { + @Override + public SchemaStatement alterColumn(Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { - if (columnMetadata == null) { - return notSupportedOperation("add", columnName); - } + if (columnMetadata == null) { + return notSupportedOperation("add", columnName); + } - DataType schemaDataType = columnMetadata.getType(); - if (schemaDataType.getName() != DataType.Name.LIST) { - return notSupportedOperation("alter", columnName); - } + DataType schemaDataType = columnMetadata.getType(); + if (schemaDataType.getName() != DataType.Name.LIST) { + return notSupportedOperation("alter", columnName); + } - List args = columnMetadata.getType().getTypeArguments(); - if (args.size() != 1) { - return notSupportedOperation("alter", columnName); - } + List args = columnMetadata.getType().getTypeArguments(); + if (args.size() != 1) { + return notSupportedOperation("alter", columnName); + } - DataType valueDataType = args.get(0); - if (valueDataType.getName() != DataType.Name.UDT || !(valueDataType instanceof UserType)) { - return notSupportedOperation("alter", columnName); - } + DataType valueDataType = args.get(0); + if (valueDataType.getName() != DataType.Name.UDT || !(valueDataType instanceof UserType)) { + return notSupportedOperation("alter", columnName); + } - UserType udtValueType = (UserType) valueDataType; + UserType udtValueType = (UserType) valueDataType; - if (!udtName.getName().equals(udtValueType.getTypeName())) { - return notSupportedOperation("alter", columnName); - } + if (!udtName.getName().equals(udtValueType.getTypeName())) { + return notSupportedOperation("alter", columnName); + } - // equals - return null; - } + // equals + return null; + } - private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { - throw new HelenusMappingException( - op - + " UDTList column is not supported by Cassandra Driver for column '" - + columnName - + "'"); - } + private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { + throw new HelenusMappingException( + op + " UDTList column is not supported by Cassandra Driver for column '" + columnName + "'"); + } - @Override - public String toString() { - return "UDTList<" + udtName + ">"; - } + @Override + public String toString() { + return "UDTList<" + udtName + ">"; + } } diff --git a/src/main/java/net/helenus/mapping/type/UDTMapDataType.java b/src/main/java/net/helenus/mapping/type/UDTMapDataType.java index d672fa9..960cfab 100644 --- a/src/main/java/net/helenus/mapping/type/UDTMapDataType.java +++ b/src/main/java/net/helenus/mapping/type/UDTMapDataType.java @@ -15,124 +15,121 @@ */ package net.helenus.mapping.type; +import java.util.List; + import com.datastax.driver.core.DataType; import com.datastax.driver.core.UserType; import com.datastax.driver.core.schemabuilder.*; -import java.util.List; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; import net.helenus.support.HelenusMappingException; public final class UDTMapDataType extends AbstractCollectionDataType { - private final IdentityName keyType; - private final Class udtKeyClass; - private final IdentityName valueType; - private final Class udtValueClass; + private final IdentityName keyType; + private final Class udtKeyClass; + private final IdentityName valueType; + private final Class udtValueClass; - public UDTMapDataType( - ColumnType columnType, - IdentityName keyType, - Class udtKeyClass, - IdentityName valueType, - Class udtValueClass) { - super(columnType); - this.keyType = keyType; - this.udtKeyClass = udtKeyClass; - this.valueType = valueType; - this.udtValueClass = udtValueClass; - } + public UDTMapDataType(ColumnType columnType, IdentityName keyType, Class udtKeyClass, IdentityName valueType, + Class udtValueClass) { + super(columnType); + this.keyType = keyType; + this.udtKeyClass = udtKeyClass; + this.valueType = valueType; + this.udtValueClass = udtValueClass; + } - @Override - public Class[] getTypeArguments() { - return new Class[] {udtKeyClass, udtValueClass}; - } + @Override + public Class[] getTypeArguments() { + return new Class[]{udtKeyClass, udtValueClass}; + } - public IdentityName getUdtKeyName() { - return keyType; - } + public IdentityName getUdtKeyName() { + return keyType; + } - public Class getUdtKeyClass() { - return udtKeyClass; - } + public Class getUdtKeyClass() { + return udtKeyClass; + } - public IdentityName getUdtValueName() { - return valueType; - } + public IdentityName getUdtValueName() { + return valueType; + } - public Class getUdtValueClass() { - return udtValueClass; - } + public Class getUdtValueClass() { + return udtValueClass; + } - @Override - public void addColumn(Create create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(Create create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType keyUdtType = SchemaBuilder.frozen(keyType.toCql()); - UDTType valueUdtType = SchemaBuilder.frozen(valueType.toCql()); - create.addUDTMapColumn(columnName.toCql(), keyUdtType, valueUdtType); - } + UDTType keyUdtType = SchemaBuilder.frozen(keyType.toCql()); + UDTType valueUdtType = SchemaBuilder.frozen(valueType.toCql()); + create.addUDTMapColumn(columnName.toCql(), keyUdtType, valueUdtType); + } - @Override - public void addColumn(CreateType create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(CreateType create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType keyUdtType = SchemaBuilder.frozen(keyType.toCql()); - UDTType valueUdtType = SchemaBuilder.frozen(valueType.toCql()); - create.addUDTMapColumn(columnName.toCql(), keyUdtType, valueUdtType); - } + UDTType keyUdtType = SchemaBuilder.frozen(keyType.toCql()); + UDTType valueUdtType = SchemaBuilder.frozen(valueType.toCql()); + create.addUDTMapColumn(columnName.toCql(), keyUdtType, valueUdtType); + } - @Override - public SchemaStatement alterColumn( - Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { + @Override + public SchemaStatement alterColumn(Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { - if (columnMetadata == null) { - return notSupportedOperation("add", columnName); - } + if (columnMetadata == null) { + return notSupportedOperation("add", columnName); + } - DataType schemaDataType = columnMetadata.getType(); - if (schemaDataType.getName() != DataType.Name.MAP) { - return notSupportedOperation("alter", columnName); - } + DataType schemaDataType = columnMetadata.getType(); + if (schemaDataType.getName() != DataType.Name.MAP) { + return notSupportedOperation("alter", columnName); + } - List args = columnMetadata.getType().getTypeArguments(); - if (args.size() != 2) { - return notSupportedOperation("alter", columnName); - } + List args = columnMetadata.getType().getTypeArguments(); + if (args.size() != 2) { + return notSupportedOperation("alter", columnName); + } - DataType keyDataType = args.get(0); - if (keyDataType.getName() != DataType.Name.UDT || !(keyDataType instanceof UserType)) { - return notSupportedOperation("alter", columnName); - } + DataType keyDataType = args.get(0); + if (keyDataType.getName() != DataType.Name.UDT || !(keyDataType instanceof UserType)) { + return notSupportedOperation("alter", columnName); + } - UserType udtKeyType = (UserType) keyDataType; + UserType udtKeyType = (UserType) keyDataType; - if (!keyType.getName().equals(udtKeyType.getTypeName())) { - return notSupportedOperation("alter", columnName); - } + if (!keyType.getName().equals(udtKeyType.getTypeName())) { + return notSupportedOperation("alter", columnName); + } - DataType valueDataType = args.get(1); - if (valueDataType.getName() != DataType.Name.UDT || !(valueDataType instanceof UserType)) { - return notSupportedOperation("alter", columnName); - } + DataType valueDataType = args.get(1); + if (valueDataType.getName() != DataType.Name.UDT || !(valueDataType instanceof UserType)) { + return notSupportedOperation("alter", columnName); + } - UserType udtValueType = (UserType) valueDataType; + UserType udtValueType = (UserType) valueDataType; - if (!valueType.getName().equals(udtValueType.getTypeName())) { - return notSupportedOperation("alter", columnName); - } + if (!valueType.getName().equals(udtValueType.getTypeName())) { + return notSupportedOperation("alter", columnName); + } - // equals - return null; - } + // equals + return null; + } - private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { - throw new HelenusMappingException( - op + " UDTMap column is not supported by Cassandra Driver for column '" + columnName + "'"); - } + private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { + throw new HelenusMappingException( + op + " UDTMap column is not supported by Cassandra Driver for column '" + columnName + "'"); + } - @Override - public String toString() { - return "UDTMap<" + keyType + "," + valueType + ">"; - } + @Override + public String toString() { + return "UDTMap<" + keyType + "," + valueType + ">"; + } } diff --git a/src/main/java/net/helenus/mapping/type/UDTSetDataType.java b/src/main/java/net/helenus/mapping/type/UDTSetDataType.java index 72ffcb0..c22965f 100644 --- a/src/main/java/net/helenus/mapping/type/UDTSetDataType.java +++ b/src/main/java/net/helenus/mapping/type/UDTSetDataType.java @@ -15,90 +15,91 @@ */ package net.helenus.mapping.type; +import java.util.List; + import com.datastax.driver.core.DataType; import com.datastax.driver.core.UserType; import com.datastax.driver.core.schemabuilder.*; -import java.util.List; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; import net.helenus.support.HelenusMappingException; public final class UDTSetDataType extends AbstractCollectionDataType { - private final IdentityName udtName; - private final Class udtClass; + private final IdentityName udtName; + private final Class udtClass; - public UDTSetDataType(ColumnType columnType, IdentityName udtName, Class udtClass) { - super(columnType); - this.udtName = udtName; - this.udtClass = udtClass; - } + public UDTSetDataType(ColumnType columnType, IdentityName udtName, Class udtClass) { + super(columnType); + this.udtName = udtName; + this.udtClass = udtClass; + } - @Override - public Class[] getTypeArguments() { - return new Class[] {udtClass}; - } + @Override + public Class[] getTypeArguments() { + return new Class[]{udtClass}; + } - public IdentityName getUdtName() { - return udtName; - } + public IdentityName getUdtName() { + return udtName; + } - @Override - public void addColumn(Create create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(Create create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - create.addUDTSetColumn(columnName.toCql(), udtType); - } + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + create.addUDTSetColumn(columnName.toCql(), udtType); + } - @Override - public void addColumn(CreateType create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(CreateType create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); - create.addUDTSetColumn(columnName.toCql(), udtType); - } + UDTType udtType = SchemaBuilder.frozen(udtName.toCql()); + create.addUDTSetColumn(columnName.toCql(), udtType); + } - @Override - public SchemaStatement alterColumn( - Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { + @Override + public SchemaStatement alterColumn(Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { - if (columnMetadata == null) { - return notSupportedOperation("add", columnName); - } + if (columnMetadata == null) { + return notSupportedOperation("add", columnName); + } - DataType schemaDataType = columnMetadata.getType(); - if (schemaDataType.getName() != DataType.Name.SET) { - return notSupportedOperation("alter", columnName); - } + DataType schemaDataType = columnMetadata.getType(); + if (schemaDataType.getName() != DataType.Name.SET) { + return notSupportedOperation("alter", columnName); + } - List args = columnMetadata.getType().getTypeArguments(); - if (args.size() != 1) { - return notSupportedOperation("alter", columnName); - } + List args = columnMetadata.getType().getTypeArguments(); + if (args.size() != 1) { + return notSupportedOperation("alter", columnName); + } - DataType valueDataType = args.get(0); - if (valueDataType.getName() != DataType.Name.UDT || !(valueDataType instanceof UserType)) { - return notSupportedOperation("alter", columnName); - } + DataType valueDataType = args.get(0); + if (valueDataType.getName() != DataType.Name.UDT || !(valueDataType instanceof UserType)) { + return notSupportedOperation("alter", columnName); + } - UserType udtValueType = (UserType) valueDataType; + UserType udtValueType = (UserType) valueDataType; - if (!udtName.getName().equals(udtValueType.getTypeName())) { - return notSupportedOperation("alter", columnName); - } + if (!udtName.getName().equals(udtValueType.getTypeName())) { + return notSupportedOperation("alter", columnName); + } - // equals - return null; - } + // equals + return null; + } - private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { - throw new HelenusMappingException( - op + " UDTSet column is not supported by Cassandra Driver for column '" + columnName + "'"); - } + private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { + throw new HelenusMappingException( + op + " UDTSet column is not supported by Cassandra Driver for column '" + columnName + "'"); + } - @Override - public String toString() { - return "UDTSet<" + udtName + ">"; - } + @Override + public String toString() { + return "UDTSet<" + udtName + ">"; + } } diff --git a/src/main/java/net/helenus/mapping/type/UDTValueMapDataType.java b/src/main/java/net/helenus/mapping/type/UDTValueMapDataType.java index 48683c2..140f84b 100644 --- a/src/main/java/net/helenus/mapping/type/UDTValueMapDataType.java +++ b/src/main/java/net/helenus/mapping/type/UDTValueMapDataType.java @@ -15,97 +15,98 @@ */ package net.helenus.mapping.type; +import java.util.List; + import com.datastax.driver.core.DataType; import com.datastax.driver.core.UserType; import com.datastax.driver.core.schemabuilder.*; -import java.util.List; + import net.helenus.mapping.ColumnType; import net.helenus.mapping.IdentityName; import net.helenus.support.HelenusMappingException; public final class UDTValueMapDataType extends AbstractCollectionDataType { - private final DataType keyType; - private final IdentityName valueType; - private final Class udtValueClass; + private final DataType keyType; + private final IdentityName valueType; + private final Class udtValueClass; - public UDTValueMapDataType( - ColumnType columnType, DataType keyType, IdentityName valueType, Class udtValueClass) { - super(columnType); - this.keyType = keyType; - this.valueType = valueType; - this.udtValueClass = udtValueClass; - } + public UDTValueMapDataType(ColumnType columnType, DataType keyType, IdentityName valueType, + Class udtValueClass) { + super(columnType); + this.keyType = keyType; + this.valueType = valueType; + this.udtValueClass = udtValueClass; + } - @Override - public Class[] getTypeArguments() { - return new Class[] {udtValueClass}; - } + @Override + public Class[] getTypeArguments() { + return new Class[]{udtValueClass}; + } - public IdentityName getUdtValueName() { - return valueType; - } + public IdentityName getUdtValueName() { + return valueType; + } - public Class getUdtValueClass() { - return udtValueClass; - } + public Class getUdtValueClass() { + return udtValueClass; + } - @Override - public void addColumn(Create create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(Create create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType valueUdtType = SchemaBuilder.frozen(valueType.toCql()); - create.addUDTMapColumn(columnName.toCql(), keyType, valueUdtType); - } + UDTType valueUdtType = SchemaBuilder.frozen(valueType.toCql()); + create.addUDTMapColumn(columnName.toCql(), keyType, valueUdtType); + } - @Override - public void addColumn(CreateType create, IdentityName columnName) { - ensureSimpleColumn(columnName); + @Override + public void addColumn(CreateType create, IdentityName columnName) { + ensureSimpleColumn(columnName); - UDTType valueUdtType = SchemaBuilder.frozen(valueType.toCql()); - create.addUDTMapColumn(columnName.toCql(), keyType, valueUdtType); - } + UDTType valueUdtType = SchemaBuilder.frozen(valueType.toCql()); + create.addUDTMapColumn(columnName.toCql(), keyType, valueUdtType); + } - @Override - public SchemaStatement alterColumn( - Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { + @Override + public SchemaStatement alterColumn(Alter alter, IdentityName columnName, OptionalColumnMetadata columnMetadata) { - if (columnMetadata == null) { - return notSupportedOperation("add", columnName); - } + if (columnMetadata == null) { + return notSupportedOperation("add", columnName); + } - DataType schemaDataType = columnMetadata.getType(); - if (schemaDataType.getName() != DataType.Name.MAP) { - return notSupportedOperation("alter", columnName); - } + DataType schemaDataType = columnMetadata.getType(); + if (schemaDataType.getName() != DataType.Name.MAP) { + return notSupportedOperation("alter", columnName); + } - List args = columnMetadata.getType().getTypeArguments(); - if (args.size() != 2 || !args.get(0).equals(keyType)) { - return notSupportedOperation("alter", columnName); - } + List args = columnMetadata.getType().getTypeArguments(); + if (args.size() != 2 || !args.get(0).equals(keyType)) { + return notSupportedOperation("alter", columnName); + } - DataType valueDataType = args.get(1); - if (valueDataType.getName() != DataType.Name.UDT || !(valueDataType instanceof UserType)) { - return notSupportedOperation("alter", columnName); - } + DataType valueDataType = args.get(1); + if (valueDataType.getName() != DataType.Name.UDT || !(valueDataType instanceof UserType)) { + return notSupportedOperation("alter", columnName); + } - UserType udtValueType = (UserType) valueDataType; + UserType udtValueType = (UserType) valueDataType; - if (!valueType.getName().equals(udtValueType.getTypeName())) { - return notSupportedOperation("alter", columnName); - } + if (!valueType.getName().equals(udtValueType.getTypeName())) { + return notSupportedOperation("alter", columnName); + } - // equals - return null; - } + // equals + return null; + } - private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { - throw new HelenusMappingException( - op + " UDTMap column is not supported by Cassandra Driver for column '" + columnName + "'"); - } + private SchemaStatement notSupportedOperation(String op, IdentityName columnName) { + throw new HelenusMappingException( + op + " UDTMap column is not supported by Cassandra Driver for column '" + columnName + "'"); + } - @Override - public String toString() { - return "UDTValueMap<" + keyType + "," + valueType + ">"; - } + @Override + public String toString() { + return "UDTValueMap<" + keyType + "," + valueType + ">"; + } } diff --git a/src/main/java/net/helenus/mapping/validator/AlphabetValidator.java b/src/main/java/net/helenus/mapping/validator/AlphabetValidator.java index 07d67db..a69f447 100644 --- a/src/main/java/net/helenus/mapping/validator/AlphabetValidator.java +++ b/src/main/java/net/helenus/mapping/validator/AlphabetValidator.java @@ -16,38 +16,39 @@ package net.helenus.mapping.validator; import java.util.Arrays; + import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; -public final class AlphabetValidator - implements ConstraintValidator { +public final class AlphabetValidator implements ConstraintValidator { - char[] alphabet; + char[] alphabet; - @Override - public void initialize(Constraints.Alphabet constraintAnnotation) { - alphabet = constraintAnnotation.value().toCharArray(); - Arrays.sort(alphabet); - } + @Override + public void initialize(Constraints.Alphabet constraintAnnotation) { + alphabet = constraintAnnotation.value().toCharArray(); + Arrays.sort(alphabet); + } - @Override - public boolean isValid(CharSequence value, ConstraintValidatorContext context) { + @Override + public boolean isValid(CharSequence value, ConstraintValidatorContext context) { - if (value == null) { - return true; - } + if (value == null) { + return true; + } - final int len = value.length(); - for (int i = 0; i != len; ++i) { + final int len = value.length(); + for (int i = 0; i != len; ++i) { - char ch = value.charAt(i); + char ch = value.charAt(i); - if (Arrays.binarySearch(alphabet, ch) < 0) { - return false; - } - } + if (Arrays.binarySearch(alphabet, ch) < 0) { + return false; + } + } - return true; - } + return true; + } } diff --git a/src/main/java/net/helenus/mapping/validator/EmailValidator.java b/src/main/java/net/helenus/mapping/validator/EmailValidator.java index 9cfbdc0..a00d7f8 100644 --- a/src/main/java/net/helenus/mapping/validator/EmailValidator.java +++ b/src/main/java/net/helenus/mapping/validator/EmailValidator.java @@ -17,33 +17,35 @@ package net.helenus.mapping.validator; import java.net.IDN; import java.util.regex.Pattern; + import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints.Email; public final class EmailValidator implements ConstraintValidator { - static final String ATOM = "[a-z0-9!#$%&'*+/=?^_`{|}~-]"; - static final String DOMAIN = "(" + ATOM + "+(\\." + ATOM + "+)*"; - static final String IP_DOMAIN = "\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\]"; + static final String ATOM = "[a-z0-9!#$%&'*+/=?^_`{|}~-]"; + static final String DOMAIN = "(" + ATOM + "+(\\." + ATOM + "+)*"; + static final String IP_DOMAIN = "\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\]"; - static final String PATTERN = - "^" + ATOM + "+(\\." + ATOM + "+)*@" + DOMAIN + "|" + IP_DOMAIN + ")$"; + static final String PATTERN = "^" + ATOM + "+(\\." + ATOM + "+)*@" + DOMAIN + "|" + IP_DOMAIN + ")$"; - private static final Pattern pattern = Pattern.compile(PATTERN, Pattern.CASE_INSENSITIVE); + private static final Pattern pattern = Pattern.compile(PATTERN, Pattern.CASE_INSENSITIVE); - @Override - public void initialize(Email constraintAnnotation) {} + @Override + public void initialize(Email constraintAnnotation) { + } - @Override - public boolean isValid(CharSequence value, ConstraintValidatorContext context) { + @Override + public boolean isValid(CharSequence value, ConstraintValidatorContext context) { - if (value == null) { - return true; - } + if (value == null) { + return true; + } - String asciiString = IDN.toASCII(value.toString()); + String asciiString = IDN.toASCII(value.toString()); - return pattern.matcher(asciiString).matches(); - } + return pattern.matcher(asciiString).matches(); + } } diff --git a/src/main/java/net/helenus/mapping/validator/LengthValidator.java b/src/main/java/net/helenus/mapping/validator/LengthValidator.java index 1b18bcd..dc58b69 100644 --- a/src/main/java/net/helenus/mapping/validator/LengthValidator.java +++ b/src/main/java/net/helenus/mapping/validator/LengthValidator.java @@ -17,26 +17,27 @@ package net.helenus.mapping.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints.Length; public final class LengthValidator implements ConstraintValidator, SizeConstraint { - int length; + int length; - @Override - public void initialize(Length constraintAnnotation) { - this.length = constraintAnnotation.value(); - } + @Override + public void initialize(Length constraintAnnotation) { + this.length = constraintAnnotation.value(); + } - @Override - public boolean isValid(Object value, ConstraintValidatorContext context) { + @Override + public boolean isValid(Object value, ConstraintValidatorContext context) { - int[] size = getSize(value); + int[] size = getSize(value); - if (size == null || size.length == 0) { - return true; - } + if (size == null || size.length == 0) { + return true; + } - return size[0] == length; - } + return size[0] == length; + } } diff --git a/src/main/java/net/helenus/mapping/validator/LowerCaseValidator.java b/src/main/java/net/helenus/mapping/validator/LowerCaseValidator.java index a05f30f..e915987 100644 --- a/src/main/java/net/helenus/mapping/validator/LowerCaseValidator.java +++ b/src/main/java/net/helenus/mapping/validator/LowerCaseValidator.java @@ -17,38 +17,39 @@ package net.helenus.mapping.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; -public final class LowerCaseValidator - implements ConstraintValidator { +public final class LowerCaseValidator implements ConstraintValidator { - @Override - public void initialize(Constraints.LowerCase constraintAnnotation) {} + @Override + public void initialize(Constraints.LowerCase constraintAnnotation) { + } - @Override - public boolean isValid(CharSequence value, ConstraintValidatorContext context) { + @Override + public boolean isValid(CharSequence value, ConstraintValidatorContext context) { - if (value == null) { - return true; - } + if (value == null) { + return true; + } - final int len = value.length(); - for (int i = 0; i != len; ++i) { - char c = value.charAt(i); - if (c <= 0x7F) { - if (isUpperCaseLetter(c)) { - return false; - } - } - if (c != Character.toLowerCase(c)) { - return false; - } - } + final int len = value.length(); + for (int i = 0; i != len; ++i) { + char c = value.charAt(i); + if (c <= 0x7F) { + if (isUpperCaseLetter(c)) { + return false; + } + } + if (c != Character.toLowerCase(c)) { + return false; + } + } - return true; - } + return true; + } - private static boolean isUpperCaseLetter(char ch) { - return ch >= 'A' && ch <= 'Z'; - } + private static boolean isUpperCaseLetter(char ch) { + return ch >= 'A' && ch <= 'Z'; + } } diff --git a/src/main/java/net/helenus/mapping/validator/MaxLengthValidator.java b/src/main/java/net/helenus/mapping/validator/MaxLengthValidator.java index 31fec70..c30e159 100644 --- a/src/main/java/net/helenus/mapping/validator/MaxLengthValidator.java +++ b/src/main/java/net/helenus/mapping/validator/MaxLengthValidator.java @@ -17,27 +17,27 @@ package net.helenus.mapping.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; -public final class MaxLengthValidator - implements ConstraintValidator, SizeConstraint { +public final class MaxLengthValidator implements ConstraintValidator, SizeConstraint { - int maxLength; + int maxLength; - @Override - public void initialize(Constraints.MaxLength constraintAnnotation) { - this.maxLength = constraintAnnotation.value(); - } + @Override + public void initialize(Constraints.MaxLength constraintAnnotation) { + this.maxLength = constraintAnnotation.value(); + } - @Override - public boolean isValid(Object value, ConstraintValidatorContext context) { + @Override + public boolean isValid(Object value, ConstraintValidatorContext context) { - int[] size = getSize(value); + int[] size = getSize(value); - if (size == null || size.length == 0) { - return true; - } + if (size == null || size.length == 0) { + return true; + } - return size[0] <= maxLength; - } + return size[0] <= maxLength; + } } diff --git a/src/main/java/net/helenus/mapping/validator/MinLengthValidator.java b/src/main/java/net/helenus/mapping/validator/MinLengthValidator.java index f2f3f50..74116df 100644 --- a/src/main/java/net/helenus/mapping/validator/MinLengthValidator.java +++ b/src/main/java/net/helenus/mapping/validator/MinLengthValidator.java @@ -17,27 +17,27 @@ package net.helenus.mapping.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; -public final class MinLengthValidator - implements ConstraintValidator, SizeConstraint { +public final class MinLengthValidator implements ConstraintValidator, SizeConstraint { - int minLength; + int minLength; - @Override - public void initialize(Constraints.MinLength constraintAnnotation) { - this.minLength = constraintAnnotation.value(); - } + @Override + public void initialize(Constraints.MinLength constraintAnnotation) { + this.minLength = constraintAnnotation.value(); + } - @Override - public boolean isValid(Object value, ConstraintValidatorContext context) { + @Override + public boolean isValid(Object value, ConstraintValidatorContext context) { - int[] size = getSize(value); + int[] size = getSize(value); - if (size == null || size.length == 0) { - return true; - } + if (size == null || size.length == 0) { + return true; + } - return size[0] >= minLength; - } + return size[0] >= minLength; + } } diff --git a/src/main/java/net/helenus/mapping/validator/NotEmptyValidator.java b/src/main/java/net/helenus/mapping/validator/NotEmptyValidator.java index a378b61..9c7e03e 100644 --- a/src/main/java/net/helenus/mapping/validator/NotEmptyValidator.java +++ b/src/main/java/net/helenus/mapping/validator/NotEmptyValidator.java @@ -17,28 +17,29 @@ package net.helenus.mapping.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; import net.helenus.mapping.annotation.Constraints.NotEmpty; -public final class NotEmptyValidator - implements ConstraintValidator, SizeConstraint { +public final class NotEmptyValidator implements ConstraintValidator, SizeConstraint { - @Override - public void initialize(NotEmpty constraintAnnotation) {} + @Override + public void initialize(NotEmpty constraintAnnotation) { + } - @Override - public boolean isValid(Object value, ConstraintValidatorContext context) { + @Override + public boolean isValid(Object value, ConstraintValidatorContext context) { - int[] size = getSize(value); + int[] size = getSize(value); - if (size == null) { - return false; - } + if (size == null) { + return false; + } - if (size.length == 0) { - return true; - } + if (size.length == 0) { + return true; + } - return size[0] > 0; - } + return size[0] > 0; + } } diff --git a/src/main/java/net/helenus/mapping/validator/NotNullValidator.java b/src/main/java/net/helenus/mapping/validator/NotNullValidator.java index 5fc6820..7191e53 100644 --- a/src/main/java/net/helenus/mapping/validator/NotNullValidator.java +++ b/src/main/java/net/helenus/mapping/validator/NotNullValidator.java @@ -17,16 +17,18 @@ package net.helenus.mapping.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; import net.helenus.mapping.annotation.Constraints.NotNull; public final class NotNullValidator implements ConstraintValidator { - @Override - public void initialize(NotNull constraintAnnotation) {} + @Override + public void initialize(NotNull constraintAnnotation) { + } - @Override - public boolean isValid(Object value, ConstraintValidatorContext context) { - return value != null; - } + @Override + public boolean isValid(Object value, ConstraintValidatorContext context) { + return value != null; + } } diff --git a/src/main/java/net/helenus/mapping/validator/NumberValidator.java b/src/main/java/net/helenus/mapping/validator/NumberValidator.java index aba6cb5..0770510 100644 --- a/src/main/java/net/helenus/mapping/validator/NumberValidator.java +++ b/src/main/java/net/helenus/mapping/validator/NumberValidator.java @@ -17,34 +17,36 @@ package net.helenus.mapping.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; public class NumberValidator implements ConstraintValidator { - @Override - public void initialize(Constraints.Number constraintAnnotation) {} + @Override + public void initialize(Constraints.Number constraintAnnotation) { + } - @Override - public boolean isValid(CharSequence value, ConstraintValidatorContext context) { + @Override + public boolean isValid(CharSequence value, ConstraintValidatorContext context) { - if (value == null) { - return true; - } + if (value == null) { + return true; + } - final int len = value.length(); - for (int i = 0; i != len; ++i) { + final int len = value.length(); + for (int i = 0; i != len; ++i) { - char ch = value.charAt(i); + char ch = value.charAt(i); - if (!isNumber(ch)) { - return false; - } - } + if (!isNumber(ch)) { + return false; + } + } - return true; - } + return true; + } - private static boolean isNumber(char ch) { - return ch >= '0' && ch <= '9'; - } + private static boolean isNumber(char ch) { + return ch >= '0' && ch <= '9'; + } } diff --git a/src/main/java/net/helenus/mapping/validator/PatternValidator.java b/src/main/java/net/helenus/mapping/validator/PatternValidator.java index 5603179..ac768ca 100644 --- a/src/main/java/net/helenus/mapping/validator/PatternValidator.java +++ b/src/main/java/net/helenus/mapping/validator/PatternValidator.java @@ -16,27 +16,28 @@ package net.helenus.mapping.validator; import java.util.regex.Pattern; + import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; -public final class PatternValidator - implements ConstraintValidator { +public final class PatternValidator implements ConstraintValidator { - private Pattern pattern; + private Pattern pattern; - @Override - public void initialize(Constraints.Pattern constraintAnnotation) { - pattern = Pattern.compile(constraintAnnotation.value(), constraintAnnotation.flags()); - } + @Override + public void initialize(Constraints.Pattern constraintAnnotation) { + pattern = Pattern.compile(constraintAnnotation.value(), constraintAnnotation.flags()); + } - @Override - public boolean isValid(CharSequence value, ConstraintValidatorContext context) { + @Override + public boolean isValid(CharSequence value, ConstraintValidatorContext context) { - if (value == null) { - return true; - } + if (value == null) { + return true; + } - return pattern.matcher(value).matches(); - } + return pattern.matcher(value).matches(); + } } diff --git a/src/main/java/net/helenus/mapping/validator/SizeConstraint.java b/src/main/java/net/helenus/mapping/validator/SizeConstraint.java index e6ff107..a17f72e 100644 --- a/src/main/java/net/helenus/mapping/validator/SizeConstraint.java +++ b/src/main/java/net/helenus/mapping/validator/SizeConstraint.java @@ -22,38 +22,38 @@ import java.util.Map; public interface SizeConstraint { - static final int[] EMPTY = new int[0]; + static final int[] EMPTY = new int[0]; - default int[] getSize(Object value) { + default int[] getSize(Object value) { - if (value == null) { - return null; - } + if (value == null) { + return null; + } - if (value.getClass().isArray()) { - return new int[] {Array.getLength(value)}; - } + if (value.getClass().isArray()) { + return new int[]{Array.getLength(value)}; + } - if (value instanceof CharSequence) { - CharSequence seq = (CharSequence) value; - return new int[] {seq.length()}; - } + if (value instanceof CharSequence) { + CharSequence seq = (CharSequence) value; + return new int[]{seq.length()}; + } - if (value instanceof ByteBuffer) { - ByteBuffer bb = (ByteBuffer) value; - return new int[] {bb.position()}; - } + if (value instanceof ByteBuffer) { + ByteBuffer bb = (ByteBuffer) value; + return new int[]{bb.position()}; + } - if (value instanceof Collection) { - Collection col = (Collection) value; - return new int[] {col.size()}; - } + if (value instanceof Collection) { + Collection col = (Collection) value; + return new int[]{col.size()}; + } - if (value instanceof Map) { - Map map = (Map) value; - return new int[] {map.size()}; - } + if (value instanceof Map) { + Map map = (Map) value; + return new int[]{map.size()}; + } - return EMPTY; - } + return EMPTY; + } } diff --git a/src/main/java/net/helenus/mapping/validator/UpperCaseValidator.java b/src/main/java/net/helenus/mapping/validator/UpperCaseValidator.java index 58abff5..636436a 100644 --- a/src/main/java/net/helenus/mapping/validator/UpperCaseValidator.java +++ b/src/main/java/net/helenus/mapping/validator/UpperCaseValidator.java @@ -17,38 +17,39 @@ package net.helenus.mapping.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + import net.helenus.mapping.annotation.Constraints; -public final class UpperCaseValidator - implements ConstraintValidator { +public final class UpperCaseValidator implements ConstraintValidator { - @Override - public void initialize(Constraints.UpperCase constraintAnnotation) {} + @Override + public void initialize(Constraints.UpperCase constraintAnnotation) { + } - @Override - public boolean isValid(CharSequence value, ConstraintValidatorContext context) { + @Override + public boolean isValid(CharSequence value, ConstraintValidatorContext context) { - if (value == null) { - return true; - } + if (value == null) { + return true; + } - final int len = value.length(); - for (int i = 0; i != len; ++i) { - char c = value.charAt(i); - if (c <= 0x7F) { - if (isLowerCaseLetter(c)) { - return false; - } - } - if (c != Character.toUpperCase(c)) { - return false; - } - } + final int len = value.length(); + for (int i = 0; i != len; ++i) { + char c = value.charAt(i); + if (c <= 0x7F) { + if (isLowerCaseLetter(c)) { + return false; + } + } + if (c != Character.toUpperCase(c)) { + return false; + } + } - return true; - } + return true; + } - private static boolean isLowerCaseLetter(char ch) { - return ch >= 'a' && ch <= 'z'; - } + private static boolean isLowerCaseLetter(char ch) { + return ch >= 'a' && ch <= 'z'; + } } diff --git a/src/main/java/net/helenus/mapping/value/BeanColumnValueProvider.java b/src/main/java/net/helenus/mapping/value/BeanColumnValueProvider.java index 9c1c44d..ae18793 100644 --- a/src/main/java/net/helenus/mapping/value/BeanColumnValueProvider.java +++ b/src/main/java/net/helenus/mapping/value/BeanColumnValueProvider.java @@ -17,32 +17,32 @@ package net.helenus.mapping.value; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; + import net.helenus.mapping.HelenusProperty; import net.helenus.support.HelenusException; import net.helenus.support.HelenusMappingException; public enum BeanColumnValueProvider implements ColumnValueProvider { - INSTANCE; + INSTANCE; - @Override - public V getColumnValue( - Object bean, int columnIndexUnused, HelenusProperty property, boolean immutable) { + @Override + public V getColumnValue(Object bean, int columnIndexUnused, HelenusProperty property, boolean immutable) { - Method getter = property.getGetterMethod(); + Method getter = property.getGetterMethod(); - Object value = null; - try { - value = getter.invoke(bean, new Object[] {}); - } catch (InvocationTargetException e) { - if (e.getCause() != null) { - throw new HelenusException("getter threw an exception", e.getCause()); - } - } catch (ReflectiveOperationException e) { - throw new HelenusMappingException("fail to call getter " + getter, e); - } catch (IllegalArgumentException e) { - throw new HelenusMappingException("invalid getter " + getter, e); - } + Object value = null; + try { + value = getter.invoke(bean, new Object[]{}); + } catch (InvocationTargetException e) { + if (e.getCause() != null) { + throw new HelenusException("getter threw an exception", e.getCause()); + } + } catch (ReflectiveOperationException e) { + throw new HelenusMappingException("fail to call getter " + getter, e); + } catch (IllegalArgumentException e) { + throw new HelenusMappingException("invalid getter " + getter, e); + } - return (V) value; - } + return (V) value; + } } diff --git a/src/main/java/net/helenus/mapping/value/ColumnValuePreparer.java b/src/main/java/net/helenus/mapping/value/ColumnValuePreparer.java index 294f63b..d4e0e5e 100644 --- a/src/main/java/net/helenus/mapping/value/ColumnValuePreparer.java +++ b/src/main/java/net/helenus/mapping/value/ColumnValuePreparer.java @@ -18,13 +18,14 @@ package net.helenus.mapping.value; import com.datastax.driver.core.CodecRegistry; import com.datastax.driver.core.DataType; import com.datastax.driver.core.TypeCodec; + import net.helenus.mapping.HelenusProperty; public interface ColumnValuePreparer { - Object prepareColumnValue(Object source, HelenusProperty prop); + Object prepareColumnValue(Object source, HelenusProperty prop); - default TypeCodec codecFor(DataType type) { - return CodecRegistry.DEFAULT_INSTANCE.codecFor(type); - } + default TypeCodec codecFor(DataType type) { + return CodecRegistry.DEFAULT_INSTANCE.codecFor(type); + } } diff --git a/src/main/java/net/helenus/mapping/value/ColumnValueProvider.java b/src/main/java/net/helenus/mapping/value/ColumnValueProvider.java index 45c604b..447acbd 100644 --- a/src/main/java/net/helenus/mapping/value/ColumnValueProvider.java +++ b/src/main/java/net/helenus/mapping/value/ColumnValueProvider.java @@ -18,17 +18,18 @@ package net.helenus.mapping.value; import com.datastax.driver.core.CodecRegistry; import com.datastax.driver.core.DataType; import com.datastax.driver.core.TypeCodec; + import net.helenus.mapping.HelenusProperty; public interface ColumnValueProvider { - V getColumnValue(Object source, int columnIndex, HelenusProperty property, boolean immutable); + V getColumnValue(Object source, int columnIndex, HelenusProperty property, boolean immutable); - default V getColumnValue(Object source, int columnIndex, HelenusProperty property) { - return getColumnValue(source, columnIndex, property, false); - } + default V getColumnValue(Object source, int columnIndex, HelenusProperty property) { + return getColumnValue(source, columnIndex, property, false); + } - default TypeCodec codecFor(DataType type) { - return CodecRegistry.DEFAULT_INSTANCE.codecFor(type); - } + default TypeCodec codecFor(DataType type) { + return CodecRegistry.DEFAULT_INSTANCE.codecFor(type); + } } diff --git a/src/main/java/net/helenus/mapping/value/RowColumnValueProvider.java b/src/main/java/net/helenus/mapping/value/RowColumnValueProvider.java index 65d5e82..33c5db7 100644 --- a/src/main/java/net/helenus/mapping/value/RowColumnValueProvider.java +++ b/src/main/java/net/helenus/mapping/value/RowColumnValueProvider.java @@ -15,123 +15,121 @@ */ package net.helenus.mapping.value; -import com.datastax.driver.core.*; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import java.nio.ByteBuffer; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.function.Function; + +import com.datastax.driver.core.ColumnDefinitions; +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.ProtocolVersion; +import com.datastax.driver.core.Row; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; public final class RowColumnValueProvider implements ColumnValueProvider { - private final SessionRepository repository; + private final SessionRepository repository; - public RowColumnValueProvider(SessionRepository repository) { - this.repository = repository; - } + public RowColumnValueProvider(SessionRepository repository) { + this.repository = repository; + } - @Override - public V getColumnValue( - Object sourceObj, int columnIndex, HelenusProperty property, boolean immutable) { + @Override + public V getColumnValue(Object sourceObj, int columnIndex, HelenusProperty property, boolean immutable) { - Row source = (Row) sourceObj; + Row source = (Row) sourceObj; - Object value = null; - if (columnIndex != -1) { - value = readValueByIndex(source, columnIndex, immutable); - } else { - value = readValueByName(source, property.getColumnName().getName(), immutable); - } + Object value = null; + if (columnIndex != -1) { + value = readValueByIndex(source, columnIndex, immutable); + } else { + value = readValueByName(source, property.getColumnName().getName(), immutable); + } - if (value != null) { + if (value != null) { - Optional> converter = property.getReadConverter(repository); + Optional> converter = property.getReadConverter(repository); - if (converter.isPresent()) { - value = converter.get().apply(value); - } - } + if (converter.isPresent()) { + value = converter.get().apply(value); + } + } - return (V) value; - } + return (V) value; + } - private Object readValueByIndex(Row source, int columnIndex, boolean immutable) { + private Object readValueByIndex(Row source, int columnIndex, boolean immutable) { - if (source.isNull(columnIndex)) { - return null; - } + if (source.isNull(columnIndex)) { + return null; + } - ColumnDefinitions columnDefinitions = source.getColumnDefinitions(); + ColumnDefinitions columnDefinitions = source.getColumnDefinitions(); - DataType columnType = columnDefinitions.getType(columnIndex); + DataType columnType = columnDefinitions.getType(columnIndex); - if (columnType.isCollection()) { + if (columnType.isCollection()) { - List typeArguments = columnType.getTypeArguments(); + List typeArguments = columnType.getTypeArguments(); - switch (columnType.getName()) { - case SET: - Set set = source.getSet(columnIndex, codecFor(typeArguments.get(0)).getJavaType()); - return immutable ? ImmutableSet.copyOf(set) : set; - case MAP: - Map map = - source.getMap( - columnIndex, - codecFor(typeArguments.get(0)).getJavaType(), - codecFor(typeArguments.get(1)).getJavaType()); - return immutable ? ImmutableMap.copyOf(map) : map; - case LIST: - List list = source.getList(columnIndex, codecFor(typeArguments.get(0)).getJavaType()); - return immutable ? ImmutableList.copyOf(list) : list; - } - } + switch (columnType.getName()) { + case SET : + Set set = source.getSet(columnIndex, codecFor(typeArguments.get(0)).getJavaType()); + return immutable ? ImmutableSet.copyOf(set) : set; + case MAP : + Map map = source.getMap(columnIndex, codecFor(typeArguments.get(0)).getJavaType(), + codecFor(typeArguments.get(1)).getJavaType()); + return immutable ? ImmutableMap.copyOf(map) : map; + case LIST : + List list = source.getList(columnIndex, codecFor(typeArguments.get(0)).getJavaType()); + return immutable ? ImmutableList.copyOf(list) : list; + } + } - ByteBuffer bytes = source.getBytesUnsafe(columnIndex); - Object value = codecFor(columnType).deserialize(bytes, ProtocolVersion.NEWEST_SUPPORTED); + ByteBuffer bytes = source.getBytesUnsafe(columnIndex); + Object value = codecFor(columnType).deserialize(bytes, ProtocolVersion.NEWEST_SUPPORTED); - return value; - } + return value; + } - private Object readValueByName(Row source, String columnName, boolean immutable) { + private Object readValueByName(Row source, String columnName, boolean immutable) { - if (source.isNull(columnName)) { - return null; - } + if (source.isNull(columnName)) { + return null; + } - ColumnDefinitions columnDefinitions = source.getColumnDefinitions(); + ColumnDefinitions columnDefinitions = source.getColumnDefinitions(); - DataType columnType = columnDefinitions.getType(columnName); + DataType columnType = columnDefinitions.getType(columnName); - if (columnType.isCollection()) { + if (columnType.isCollection()) { - List typeArguments = columnType.getTypeArguments(); + List typeArguments = columnType.getTypeArguments(); - switch (columnType.getName()) { - case SET: - Set set = source.getSet(columnName, codecFor(typeArguments.get(0)).getJavaType()); - return immutable ? ImmutableSet.copyOf(set) : set; - case MAP: - Map map = - source.getMap( - columnName, - codecFor(typeArguments.get(0)).getJavaType(), - codecFor(typeArguments.get(1)).getJavaType()); - return immutable ? ImmutableMap.copyOf(map) : map; - case LIST: - List list = source.getList(columnName, codecFor(typeArguments.get(0)).getJavaType()); - return immutable ? ImmutableList.copyOf(list) : list; - } - } + switch (columnType.getName()) { + case SET : + Set set = source.getSet(columnName, codecFor(typeArguments.get(0)).getJavaType()); + return immutable ? ImmutableSet.copyOf(set) : set; + case MAP : + Map map = source.getMap(columnName, codecFor(typeArguments.get(0)).getJavaType(), + codecFor(typeArguments.get(1)).getJavaType()); + return immutable ? ImmutableMap.copyOf(map) : map; + case LIST : + List list = source.getList(columnName, codecFor(typeArguments.get(0)).getJavaType()); + return immutable ? ImmutableList.copyOf(list) : list; + } + } - ByteBuffer bytes = source.getBytesUnsafe(columnName); - Object value = codecFor(columnType).deserialize(bytes, ProtocolVersion.NEWEST_SUPPORTED); + ByteBuffer bytes = source.getBytesUnsafe(columnName); + Object value = codecFor(columnType).deserialize(bytes, ProtocolVersion.NEWEST_SUPPORTED); - return value; - } + return value; + } } diff --git a/src/main/java/net/helenus/mapping/value/StatementColumnValuePreparer.java b/src/main/java/net/helenus/mapping/value/StatementColumnValuePreparer.java index 447431f..1e32b8b 100644 --- a/src/main/java/net/helenus/mapping/value/StatementColumnValuePreparer.java +++ b/src/main/java/net/helenus/mapping/value/StatementColumnValuePreparer.java @@ -15,41 +15,44 @@ */ package net.helenus.mapping.value; -import com.datastax.driver.core.querybuilder.BindMarker; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.querybuilder.BindMarker; + import net.helenus.core.HelenusValidator; import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; public final class StatementColumnValuePreparer implements ColumnValuePreparer { - private final SessionRepository repository; + private final SessionRepository repository; - public StatementColumnValuePreparer(SessionRepository repository) { - this.repository = repository; - } + public StatementColumnValuePreparer(SessionRepository repository) { + this.repository = repository; + } - @Override - public Object prepareColumnValue(Object value, HelenusProperty prop) { + @Override + public Object prepareColumnValue(Object value, HelenusProperty prop) { - if (value == null) return null; + if (value == null) + return null; - if (value instanceof BindMarker) { - return value; - } + if (value instanceof BindMarker) { + return value; + } - HelenusValidator.INSTANCE.validate(prop, value); + HelenusValidator.INSTANCE.validate(prop, value); - if (value != null) { + if (value != null) { - Optional> converter = prop.getWriteConverter(repository); + Optional> converter = prop.getWriteConverter(repository); - if (converter.isPresent()) { - value = converter.get().apply(value); - } - } + if (converter.isPresent()) { + value = converter.get().apply(value); + } + } - return value; - } + return value; + } } diff --git a/src/main/java/net/helenus/mapping/value/TupleColumnValuePreparer.java b/src/main/java/net/helenus/mapping/value/TupleColumnValuePreparer.java index 35b13aa..552b425 100644 --- a/src/main/java/net/helenus/mapping/value/TupleColumnValuePreparer.java +++ b/src/main/java/net/helenus/mapping/value/TupleColumnValuePreparer.java @@ -15,48 +15,52 @@ */ package net.helenus.mapping.value; -import com.datastax.driver.core.*; -import com.datastax.driver.core.querybuilder.BindMarker; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.ProtocolVersion; +import com.datastax.driver.core.TupleType; +import com.datastax.driver.core.querybuilder.BindMarker; + import net.helenus.core.HelenusValidator; import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; public final class TupleColumnValuePreparer implements ColumnValuePreparer { - private final TupleType tupleType; - private final SessionRepository repository; + private final TupleType tupleType; + private final SessionRepository repository; - public TupleColumnValuePreparer(TupleType tupleType, SessionRepository repository) { - this.tupleType = tupleType; - this.repository = repository; - } + public TupleColumnValuePreparer(TupleType tupleType, SessionRepository repository) { + this.tupleType = tupleType; + this.repository = repository; + } - @Override - public Object prepareColumnValue(Object value, HelenusProperty prop) { + @Override + public Object prepareColumnValue(Object value, HelenusProperty prop) { - if (value instanceof BindMarker) { - return value; - } + if (value instanceof BindMarker) { + return value; + } - HelenusValidator.INSTANCE.validate(prop, value); + HelenusValidator.INSTANCE.validate(prop, value); - if (value != null) { + if (value != null) { - Optional> converter = prop.getWriteConverter(repository); + Optional> converter = prop.getWriteConverter(repository); - if (converter.isPresent()) { - value = converter.get().apply(value); - } + if (converter.isPresent()) { + value = converter.get().apply(value); + } - int columnIndex = prop.getOrdinal(); + int columnIndex = prop.getOrdinal(); - DataType dataType = tupleType.getComponentTypes().get(columnIndex); + DataType dataType = tupleType.getComponentTypes().get(columnIndex); - return codecFor(dataType).serialize(value, ProtocolVersion.NEWEST_SUPPORTED); - } + return codecFor(dataType).serialize(value, ProtocolVersion.NEWEST_SUPPORTED); + } - return null; - } + return null; + } } diff --git a/src/main/java/net/helenus/mapping/value/TupleColumnValueProvider.java b/src/main/java/net/helenus/mapping/value/TupleColumnValueProvider.java index 569598c..d005884 100644 --- a/src/main/java/net/helenus/mapping/value/TupleColumnValueProvider.java +++ b/src/main/java/net/helenus/mapping/value/TupleColumnValueProvider.java @@ -15,51 +15,52 @@ */ package net.helenus.mapping.value; +import java.nio.ByteBuffer; +import java.util.Optional; +import java.util.function.Function; + import com.datastax.driver.core.DataType; import com.datastax.driver.core.ProtocolVersion; import com.datastax.driver.core.TupleType; import com.datastax.driver.core.TupleValue; -import java.nio.ByteBuffer; -import java.util.Optional; -import java.util.function.Function; + import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; public final class TupleColumnValueProvider implements ColumnValueProvider { - private final SessionRepository repository; + private final SessionRepository repository; - public TupleColumnValueProvider(SessionRepository repository) { - this.repository = repository; - } + public TupleColumnValueProvider(SessionRepository repository) { + this.repository = repository; + } - @Override - public V getColumnValue( - Object sourceObj, int columnIndexUnused, HelenusProperty property, boolean immutable) { + @Override + public V getColumnValue(Object sourceObj, int columnIndexUnused, HelenusProperty property, boolean immutable) { - int columnIndex = property.getOrdinal(); + int columnIndex = property.getOrdinal(); - TupleValue source = (TupleValue) sourceObj; + TupleValue source = (TupleValue) sourceObj; - ByteBuffer bytes = source.getBytesUnsafe(columnIndex); - if (bytes == null) { - return null; - } + ByteBuffer bytes = source.getBytesUnsafe(columnIndex); + if (bytes == null) { + return null; + } - TupleType tupleType = source.getType(); - DataType fieldType = tupleType.getComponentTypes().get(columnIndex); + TupleType tupleType = source.getType(); + DataType fieldType = tupleType.getComponentTypes().get(columnIndex); - Object value = codecFor(fieldType).deserialize(bytes, ProtocolVersion.NEWEST_SUPPORTED); + Object value = codecFor(fieldType).deserialize(bytes, ProtocolVersion.NEWEST_SUPPORTED); - if (value != null) { + if (value != null) { - Optional> converter = property.getReadConverter(repository); + Optional> converter = property.getReadConverter(repository); - if (converter.isPresent()) { - value = converter.get().apply(value); - } - } + if (converter.isPresent()) { + value = converter.get().apply(value); + } + } - return (V) value; - } + return (V) value; + } } diff --git a/src/main/java/net/helenus/mapping/value/UDTColumnValuePreparer.java b/src/main/java/net/helenus/mapping/value/UDTColumnValuePreparer.java index ce177a6..1ff5b2c 100644 --- a/src/main/java/net/helenus/mapping/value/UDTColumnValuePreparer.java +++ b/src/main/java/net/helenus/mapping/value/UDTColumnValuePreparer.java @@ -15,46 +15,50 @@ */ package net.helenus.mapping.value; -import com.datastax.driver.core.*; -import com.datastax.driver.core.querybuilder.BindMarker; import java.util.Optional; import java.util.function.Function; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.ProtocolVersion; +import com.datastax.driver.core.UserType; +import com.datastax.driver.core.querybuilder.BindMarker; + import net.helenus.core.HelenusValidator; import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; public final class UDTColumnValuePreparer implements ColumnValuePreparer { - private final UserType userType; - private final SessionRepository repository; + private final UserType userType; + private final SessionRepository repository; - public UDTColumnValuePreparer(UserType userType, SessionRepository repository) { - this.userType = userType; - this.repository = repository; - } + public UDTColumnValuePreparer(UserType userType, SessionRepository repository) { + this.userType = userType; + this.repository = repository; + } - @Override - public Object prepareColumnValue(Object value, HelenusProperty prop) { + @Override + public Object prepareColumnValue(Object value, HelenusProperty prop) { - if (value instanceof BindMarker) { - return value; - } + if (value instanceof BindMarker) { + return value; + } - HelenusValidator.INSTANCE.validate(prop, value); + HelenusValidator.INSTANCE.validate(prop, value); - if (value != null) { + if (value != null) { - Optional> converter = prop.getWriteConverter(repository); + Optional> converter = prop.getWriteConverter(repository); - if (converter.isPresent()) { - value = converter.get().apply(value); - } + if (converter.isPresent()) { + value = converter.get().apply(value); + } - DataType dataType = userType.getFieldType(prop.getColumnName().getName()); + DataType dataType = userType.getFieldType(prop.getColumnName().getName()); - return codecFor(dataType).serialize(value, ProtocolVersion.NEWEST_SUPPORTED); - } + return codecFor(dataType).serialize(value, ProtocolVersion.NEWEST_SUPPORTED); + } - return null; - } + return null; + } } diff --git a/src/main/java/net/helenus/mapping/value/UDTColumnValueProvider.java b/src/main/java/net/helenus/mapping/value/UDTColumnValueProvider.java index d6f0c5a..13474d3 100644 --- a/src/main/java/net/helenus/mapping/value/UDTColumnValueProvider.java +++ b/src/main/java/net/helenus/mapping/value/UDTColumnValueProvider.java @@ -15,52 +15,53 @@ */ package net.helenus.mapping.value; +import java.nio.ByteBuffer; +import java.util.Optional; +import java.util.function.Function; + import com.datastax.driver.core.DataType; import com.datastax.driver.core.ProtocolVersion; import com.datastax.driver.core.UDTValue; import com.datastax.driver.core.UserType; -import java.nio.ByteBuffer; -import java.util.Optional; -import java.util.function.Function; + import net.helenus.core.SessionRepository; import net.helenus.mapping.HelenusProperty; public final class UDTColumnValueProvider implements ColumnValueProvider { - private final SessionRepository repository; + private final SessionRepository repository; - public UDTColumnValueProvider(SessionRepository repository) { - this.repository = repository; - } + public UDTColumnValueProvider(SessionRepository repository) { + this.repository = repository; + } - @Override - @SuppressWarnings("unchecked") - public V getColumnValue( - Object sourceObj, int columnIndexUnused, HelenusProperty property, boolean immutable) { + @Override + @SuppressWarnings("unchecked") + public V getColumnValue(Object sourceObj, int columnIndexUnused, HelenusProperty property, boolean immutable) { - UDTValue source = (UDTValue) sourceObj; + UDTValue source = (UDTValue) sourceObj; - UserType userType = source.getType(); + UserType userType = source.getType(); - String name = property.getColumnName().getName(); + String name = property.getColumnName().getName(); - ByteBuffer bytes = source.getBytesUnsafe(name); - if (bytes == null) { - return null; - } + ByteBuffer bytes = source.getBytesUnsafe(name); + if (bytes == null) { + return null; + } - DataType fieldType = userType.getFieldType(name); - Object value = codecFor(fieldType).deserialize(bytes, ProtocolVersion.NEWEST_SUPPORTED); + DataType fieldType = userType.getFieldType(name); + Object value = codecFor(fieldType).deserialize(bytes, ProtocolVersion.NEWEST_SUPPORTED); - if (value != null) { + if (value != null) { - Optional> converter = property.getReadConverter(repository); + Optional> converter = property.getReadConverter(repository); - if (converter.isPresent()) { - value = converter.get().apply(value); - } - } + if (converter.isPresent()) { + value = converter.get().apply(value); + } + } - return (V) value; - } + return (V) value; + } } diff --git a/src/main/java/net/helenus/mapping/value/ValueProviderMap.java b/src/main/java/net/helenus/mapping/value/ValueProviderMap.java index 4a0cad2..562acca 100644 --- a/src/main/java/net/helenus/mapping/value/ValueProviderMap.java +++ b/src/main/java/net/helenus/mapping/value/ValueProviderMap.java @@ -19,6 +19,7 @@ import java.util.Collection; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; + import net.helenus.core.reflect.Drafted; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusProperty; @@ -26,120 +27,118 @@ import net.helenus.support.HelenusMappingException; public final class ValueProviderMap implements Map { - private final Object source; - private final ColumnValueProvider valueProvider; - private final HelenusEntity entity; - private final boolean immutable; + private final Object source; + private final ColumnValueProvider valueProvider; + private final HelenusEntity entity; + private final boolean immutable; - public ValueProviderMap(Object source, ColumnValueProvider valueProvider, HelenusEntity entity) { - this.source = source; - this.valueProvider = valueProvider; - this.entity = entity; - this.immutable = entity.getMappingInterface().isAssignableFrom(Drafted.class); - } + public ValueProviderMap(Object source, ColumnValueProvider valueProvider, HelenusEntity entity) { + this.source = source; + this.valueProvider = valueProvider; + this.entity = entity; + this.immutable = entity.getMappingInterface().isAssignableFrom(Drafted.class); + } - @Override - public Object get(Object key) { - if (key instanceof String) { - String name = (String) key; - HelenusProperty prop = entity.getProperty(name); - if (prop != null) { - return valueProvider.getColumnValue(source, -1, prop, immutable); - } - } - return null; - } + @Override + public Object get(Object key) { + if (key instanceof String) { + String name = (String) key; + HelenusProperty prop = entity.getProperty(name); + if (prop != null) { + return valueProvider.getColumnValue(source, -1, prop, immutable); + } + } + return null; + } - @Override - public Set keySet() { - return entity - .getOrderedProperties() - .stream() - .map(p -> p.getPropertyName()) - .collect(Collectors.toSet()); - } + @Override + public Set keySet() { + return entity.getOrderedProperties().stream().map(p -> p.getPropertyName()).collect(Collectors.toSet()); + } - @Override - public int size() { - return entity.getOrderedProperties().size(); - } + @Override + public int size() { + return entity.getOrderedProperties().size(); + } - @Override - public boolean isEmpty() { - return entity.getOrderedProperties().size() > 0; - } + @Override + public boolean isEmpty() { + return entity.getOrderedProperties().size() > 0; + } - @Override - public boolean containsKey(Object key) { - if (key instanceof Object) { - String s = (String) key; - return keySet().contains(s); - } - return false; - } + @Override + public boolean containsKey(Object key) { + if (key instanceof Object) { + String s = (String) key; + return keySet().contains(s); + } + return false; + } - @Override - public boolean containsValue(Object value) { - throwShouldNeverCall("containsValue()"); - return false; - } + @Override + public boolean containsValue(Object value) { + throwShouldNeverCall("containsValue()"); + return false; + } - @Override - public Object put(String key, Object value) { - throwShouldNeverCall("put()"); - return null; - } + @Override + public Object put(String key, Object value) { + throwShouldNeverCall("put()"); + return null; + } - @Override - public Object remove(Object key) { - throwShouldNeverCall("remove()"); - return null; - } + @Override + public Object remove(Object key) { + throwShouldNeverCall("remove()"); + return null; + } - @Override - public void putAll(Map m) { - throwShouldNeverCall("putAll()"); - } + @Override + public void putAll(Map m) { + throwShouldNeverCall("putAll()"); + } - @Override - public void clear() { - throwShouldNeverCall("clear()"); - } + @Override + public void clear() { + throwShouldNeverCall("clear()"); + } - @Override - public Collection values() { - throwShouldNeverCall("values()"); - return null; - } + @Override + public Collection values() { + throwShouldNeverCall("values()"); + return null; + } - @Override - public Set> entrySet() { - throwShouldNeverCall("entrySet()"); - return null; - } + @Override + public Set> entrySet() { + throwShouldNeverCall("entrySet()"); + return null; + } - private void throwShouldNeverCall(String methodName) { - throw new HelenusMappingException( - String.format( - "the method {} should never be called on an instance of a Helenus ValueProviderMap", - methodName)); - } + private void throwShouldNeverCall(String methodName) { + throw new HelenusMappingException(String.format( + "the method {} should never be called on an instance of a Helenus ValueProviderMap", methodName)); + } - @Override - public String toString() { - return source.toString(); - } + @Override + public String toString() { + return source.toString(); + } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || (!o.getClass().isAssignableFrom(Map.class) && getClass() != o.getClass())) - return false; + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || (!o.getClass().isAssignableFrom(Map.class) && getClass() != o.getClass())) + return false; - Map that = (Map) o; - if (this.size() != that.size()) return false; - for (String key : this.keySet()) if (!this.get(key).equals(that.get(key))) return false; + Map that = (Map) o; + if (this.size() != that.size()) + return false; + for (String key : this.keySet()) + if (!this.get(key).equals(that.get(key))) + return false; - return true; - } + return true; + } } diff --git a/src/main/java/net/helenus/support/CqlUtil.java b/src/main/java/net/helenus/support/CqlUtil.java index 5598af4..7de2dad 100644 --- a/src/main/java/net/helenus/support/CqlUtil.java +++ b/src/main/java/net/helenus/support/CqlUtil.java @@ -17,17 +17,18 @@ package net.helenus.support; public final class CqlUtil { - private CqlUtil() {} + private CqlUtil() { + } - public static String forceQuote(String identity) { + public static String forceQuote(String identity) { - if (identity == null) { - return null; - } + if (identity == null) { + return null; + } - if (identity.startsWith("\"")) { - return identity; - } - return "\"" + identity + "\""; - } + if (identity.startsWith("\"")) { + return identity; + } + return "\"" + identity + "\""; + } } diff --git a/src/main/java/net/helenus/support/DslPropertyException.java b/src/main/java/net/helenus/support/DslPropertyException.java index 91cce07..a62a831 100644 --- a/src/main/java/net/helenus/support/DslPropertyException.java +++ b/src/main/java/net/helenus/support/DslPropertyException.java @@ -19,16 +19,16 @@ import net.helenus.core.reflect.HelenusPropertyNode; public final class DslPropertyException extends HelenusException { - private static final long serialVersionUID = -2745598205929757758L; + private static final long serialVersionUID = -2745598205929757758L; - private final HelenusPropertyNode propertyNode; + private final HelenusPropertyNode propertyNode; - public DslPropertyException(HelenusPropertyNode propertyNode) { - super("DSL PropertyNode Exception"); - this.propertyNode = propertyNode; - } + public DslPropertyException(HelenusPropertyNode propertyNode) { + super("DSL PropertyNode Exception"); + this.propertyNode = propertyNode; + } - public HelenusPropertyNode getPropertyNode() { - return propertyNode; - } + public HelenusPropertyNode getPropertyNode() { + return propertyNode; + } } diff --git a/src/main/java/net/helenus/support/Either.java b/src/main/java/net/helenus/support/Either.java index 88d3dfc..853b82b 100644 --- a/src/main/java/net/helenus/support/Either.java +++ b/src/main/java/net/helenus/support/Either.java @@ -19,62 +19,62 @@ import java.util.function.Function; public final class Either { - private final L left; - private final R right; + private final L left; + private final R right; - private Either(L left, R right) { - this.left = left; - this.right = right; - } + private Either(L left, R right) { + this.left = left; + this.right = right; + } - public boolean isLeft() { - return left != null; - } + public boolean isLeft() { + return left != null; + } - public L getLeft() { - return left; - } + public L getLeft() { + return left; + } - public boolean isRight() { - return right != null; - } + public boolean isRight() { + return right != null; + } - public R getRight() { - return right; - } + public R getRight() { + return right; + } - public static Either left(L left) { - return new Either(left, null); - } + public static Either left(L left) { + return new Either(left, null); + } - public static Either right(R right) { - return new Either(null, right); - } + public static Either right(R right) { + return new Either(null, right); + } - public EitherCase getCase() { - if (left != null) { - return EitherCase.LEFT; - } else if (right != null) { - return EitherCase.RIGHT; - } - throw new IllegalStateException("unexpected state"); - } + public EitherCase getCase() { + if (left != null) { + return EitherCase.LEFT; + } else if (right != null) { + return EitherCase.RIGHT; + } + throw new IllegalStateException("unexpected state"); + } - public T fold(Function leftFunction, Function rightFunction) { - switch (getCase()) { - case LEFT: - return leftFunction.apply(left); - case RIGHT: - return rightFunction.apply(right); - } - throw new IllegalStateException("unexpected state"); - } + public T fold(Function leftFunction, Function rightFunction) { + switch (getCase()) { + case LEFT : + return leftFunction.apply(left); + case RIGHT : + return rightFunction.apply(right); + } + throw new IllegalStateException("unexpected state"); + } - @Override - public String toString() { - if (left != null) { - return "[" + left + ",]"; - } - return "[," + right + "]"; - } + @Override + public String toString() { + if (left != null) { + return "[" + left + ",]"; + } + return "[," + right + "]"; + } } diff --git a/src/main/java/net/helenus/support/EitherCase.java b/src/main/java/net/helenus/support/EitherCase.java index 19db08c..9ca0db1 100644 --- a/src/main/java/net/helenus/support/EitherCase.java +++ b/src/main/java/net/helenus/support/EitherCase.java @@ -16,6 +16,5 @@ package net.helenus.support; public enum EitherCase { - LEFT, - RIGHT; + LEFT, RIGHT; } diff --git a/src/main/java/net/helenus/support/Fun.java b/src/main/java/net/helenus/support/Fun.java index 722cca4..aa3c896 100644 --- a/src/main/java/net/helenus/support/Fun.java +++ b/src/main/java/net/helenus/support/Fun.java @@ -19,219 +19,193 @@ import java.util.Arrays; public final class Fun { - private Fun() {} + private Fun() { + } - public static final class ArrayTuple { + public static final class ArrayTuple { - public final Object[] _a; + public final Object[] _a; - public ArrayTuple(Object[] a) { - this._a = a; - } + public ArrayTuple(Object[] a) { + this._a = a; + } - public static ArrayTuple of(Object[] a) { - return new ArrayTuple(a); - } + public static ArrayTuple of(Object[] a) { + return new ArrayTuple(a); + } - @Override - public String toString() { - return "ArrayTuple " + Arrays.toString(_a); - } - } + @Override + public String toString() { + return "ArrayTuple " + Arrays.toString(_a); + } + } - public static final class Tuple1 { + public static final class Tuple1 { - public final A _1; + public final A _1; - public Tuple1(A v1) { - this._1 = v1; - } + public Tuple1(A v1) { + this._1 = v1; + } - public static Tuple1 of(A _1) { - return new Tuple1(_1); - } + public static Tuple1 of(A _1) { + return new Tuple1(_1); + } - @Override - public String toString() { - return "Tuple1 [_1=" + _1 + "]"; - } - } + @Override + public String toString() { + return "Tuple1 [_1=" + _1 + "]"; + } + } - public static final class Tuple2 { + public static final class Tuple2 { - public final A _1; - public final B _2; + public final A _1; + public final B _2; - public Tuple2(A v1, B v2) { - this._1 = v1; - this._2 = v2; - } + public Tuple2(A v1, B v2) { + this._1 = v1; + this._2 = v2; + } - public static Tuple2 of(A _1, B _2) { - return new Tuple2(_1, _2); - } + public static Tuple2 of(A _1, B _2) { + return new Tuple2(_1, _2); + } - @Override - public String toString() { - return "Tuple2 [_1=" + _1 + ", _2=" + _2 + "]"; - } - } + @Override + public String toString() { + return "Tuple2 [_1=" + _1 + ", _2=" + _2 + "]"; + } + } - public static final class Tuple3 { + public static final class Tuple3 { - public final A _1; - public final B _2; - public final C _3; + public final A _1; + public final B _2; + public final C _3; - public Tuple3(A v1, B v2, C v3) { - this._1 = v1; - this._2 = v2; - this._3 = v3; - } + public Tuple3(A v1, B v2, C v3) { + this._1 = v1; + this._2 = v2; + this._3 = v3; + } - public static Tuple3 of(A _1, B _2, C _3) { - return new Tuple3(_1, _2, _3); - } + public static Tuple3 of(A _1, B _2, C _3) { + return new Tuple3(_1, _2, _3); + } - @Override - public String toString() { - return "Tuple3 [_1=" + _1 + ", _2=" + _2 + ", _3=" + _3 + "]"; - } - } + @Override + public String toString() { + return "Tuple3 [_1=" + _1 + ", _2=" + _2 + ", _3=" + _3 + "]"; + } + } - public static final class Tuple4 { + public static final class Tuple4 { - public final A _1; - public final B _2; - public final C _3; - public final D _4; + public final A _1; + public final B _2; + public final C _3; + public final D _4; - public Tuple4(A v1, B v2, C v3, D v4) { - this._1 = v1; - this._2 = v2; - this._3 = v3; - this._4 = v4; - } + public Tuple4(A v1, B v2, C v3, D v4) { + this._1 = v1; + this._2 = v2; + this._3 = v3; + this._4 = v4; + } - public static Tuple4 of(A _1, B _2, C _3, D _4) { - return new Tuple4(_1, _2, _3, _4); - } + public static Tuple4 of(A _1, B _2, C _3, D _4) { + return new Tuple4(_1, _2, _3, _4); + } - @Override - public String toString() { - return "Tuple4 [_1=" + _1 + ", _2=" + _2 + ", _3=" + _3 + ", _4=" + _4 + "]"; - } - } + @Override + public String toString() { + return "Tuple4 [_1=" + _1 + ", _2=" + _2 + ", _3=" + _3 + ", _4=" + _4 + "]"; + } + } - public static final class Tuple5 { + public static final class Tuple5 { - public final A _1; - public final B _2; - public final C _3; - public final D _4; - public final E _5; + public final A _1; + public final B _2; + public final C _3; + public final D _4; + public final E _5; - public Tuple5(A v1, B v2, C v3, D v4, E v5) { - this._1 = v1; - this._2 = v2; - this._3 = v3; - this._4 = v4; - this._5 = v5; - } + public Tuple5(A v1, B v2, C v3, D v4, E v5) { + this._1 = v1; + this._2 = v2; + this._3 = v3; + this._4 = v4; + this._5 = v5; + } - public static Tuple5 of(A _1, B _2, C _3, D _4, E _5) { - return new Tuple5(_1, _2, _3, _4, _5); - } + public static Tuple5 of(A _1, B _2, C _3, D _4, E _5) { + return new Tuple5(_1, _2, _3, _4, _5); + } - @Override - public String toString() { - return "Tuple5 [_1=" + _1 + ", _2=" + _2 + ", _3=" + _3 + ", _4=" + _4 + ", _5=" + _5 + "]"; - } - } + @Override + public String toString() { + return "Tuple5 [_1=" + _1 + ", _2=" + _2 + ", _3=" + _3 + ", _4=" + _4 + ", _5=" + _5 + "]"; + } + } - public static final class Tuple6 { + public static final class Tuple6 { - public final A _1; - public final B _2; - public final C _3; - public final D _4; - public final E _5; - public final F _6; + public final A _1; + public final B _2; + public final C _3; + public final D _4; + public final E _5; + public final F _6; - public Tuple6(A v1, B v2, C v3, D v4, E v5, F v6) { - this._1 = v1; - this._2 = v2; - this._3 = v3; - this._4 = v4; - this._5 = v5; - this._6 = v6; - } + public Tuple6(A v1, B v2, C v3, D v4, E v5, F v6) { + this._1 = v1; + this._2 = v2; + this._3 = v3; + this._4 = v4; + this._5 = v5; + this._6 = v6; + } - public static Tuple6 of( - A _1, B _2, C _3, D _4, E _5, F _6) { - return new Tuple6(_1, _2, _3, _4, _5, _6); - } + public static Tuple6 of(A _1, B _2, C _3, D _4, E _5, F _6) { + return new Tuple6(_1, _2, _3, _4, _5, _6); + } - @Override - public String toString() { - return "Tuple6 [_1=" - + _1 - + ", _2=" - + _2 - + ", _3=" - + _3 - + ", _4=" - + _4 - + ", _5=" - + _5 - + ", _6=" - + _6 - + "]"; - } - } + @Override + public String toString() { + return "Tuple6 [_1=" + _1 + ", _2=" + _2 + ", _3=" + _3 + ", _4=" + _4 + ", _5=" + _5 + ", _6=" + _6 + "]"; + } + } - public static final class Tuple7 { + public static final class Tuple7 { - public final A _1; - public final B _2; - public final C _3; - public final D _4; - public final E _5; - public final F _6; - public final G _7; + public final A _1; + public final B _2; + public final C _3; + public final D _4; + public final E _5; + public final F _6; + public final G _7; - public Tuple7(A v1, B v2, C v3, D v4, E v5, F v6, G v7) { - this._1 = v1; - this._2 = v2; - this._3 = v3; - this._4 = v4; - this._5 = v5; - this._6 = v6; - this._7 = v7; - } + public Tuple7(A v1, B v2, C v3, D v4, E v5, F v6, G v7) { + this._1 = v1; + this._2 = v2; + this._3 = v3; + this._4 = v4; + this._5 = v5; + this._6 = v6; + this._7 = v7; + } - public static Tuple7 of( - A _1, B _2, C _3, D _4, E _5, F _6, G _7) { - return new Tuple7(_1, _2, _3, _4, _5, _6, _7); - } + public static Tuple7 of(A _1, B _2, C _3, D _4, E _5, F _6, G _7) { + return new Tuple7(_1, _2, _3, _4, _5, _6, _7); + } - @Override - public String toString() { - return "Tuple7 [_1=" - + _1 - + ", _2=" - + _2 - + ", _3=" - + _3 - + ", _4=" - + _4 - + ", _5=" - + _5 - + ", _6=" - + _6 - + ", _7=" - + _7 - + "]"; - } - } + @Override + public String toString() { + return "Tuple7 [_1=" + _1 + ", _2=" + _2 + ", _3=" + _3 + ", _4=" + _4 + ", _5=" + _5 + ", _6=" + _6 + + ", _7=" + _7 + "]"; + } + } } diff --git a/src/main/java/net/helenus/support/HelenusException.java b/src/main/java/net/helenus/support/HelenusException.java index 9fb613e..2777e8e 100644 --- a/src/main/java/net/helenus/support/HelenusException.java +++ b/src/main/java/net/helenus/support/HelenusException.java @@ -17,17 +17,17 @@ package net.helenus.support; public class HelenusException extends RuntimeException { - private static final long serialVersionUID = 7711799134283942588L; + private static final long serialVersionUID = 7711799134283942588L; - public HelenusException(String msg) { - super(msg); - } + public HelenusException(String msg) { + super(msg); + } - public HelenusException(Throwable t) { - super(t); - } + public HelenusException(Throwable t) { + super(t); + } - public HelenusException(String msg, Throwable t) { - super(msg, t); - } + public HelenusException(String msg, Throwable t) { + super(msg, t); + } } diff --git a/src/main/java/net/helenus/support/HelenusMappingException.java b/src/main/java/net/helenus/support/HelenusMappingException.java index 92d80e2..2284775 100644 --- a/src/main/java/net/helenus/support/HelenusMappingException.java +++ b/src/main/java/net/helenus/support/HelenusMappingException.java @@ -17,17 +17,17 @@ package net.helenus.support; public class HelenusMappingException extends HelenusException { - private static final long serialVersionUID = -4730562130753392363L; + private static final long serialVersionUID = -4730562130753392363L; - public HelenusMappingException(String msg) { - super(msg); - } + public HelenusMappingException(String msg) { + super(msg); + } - public HelenusMappingException(Throwable t) { - super(t); - } + public HelenusMappingException(Throwable t) { + super(t); + } - public HelenusMappingException(String msg, Throwable t) { - super(msg, t); - } + public HelenusMappingException(String msg, Throwable t) { + super(msg, t); + } } diff --git a/src/main/java/net/helenus/support/Immutables.java b/src/main/java/net/helenus/support/Immutables.java index d008b42..841d80a 100644 --- a/src/main/java/net/helenus/support/Immutables.java +++ b/src/main/java/net/helenus/support/Immutables.java @@ -19,349 +19,348 @@ import java.util.*; public final class Immutables { - private Immutables() {} - - public static Set setOf(T value) { - return new SingleEntrySet(value); - } - - public static List listOf(T value) { - return new SingleEntryList(value); - } - - public static Map mapOf(K key, V value) { - return new SingleEntryMap(key, value); - } - - static class SingleEntryIterator implements Iterator { - - T entry; - boolean processed = false; - - SingleEntryIterator(T entry) { - this.entry = entry; - } - - @Override - public boolean hasNext() { - return !processed; - } - - @Override - public T next() { - processed = true; - return entry; - } - } - - static class SingleEntryListIterator extends SingleEntryIterator - implements ListIterator { - - SingleEntryListIterator(T entry) { - super(entry); - } - - @Override - public boolean hasPrevious() { - return processed; - } - - @Override - public T previous() { - processed = false; - return entry; - } - - @Override - public int nextIndex() { - return processed ? 1 : 0; - } - - @Override - public int previousIndex() { - return processed ? 0 : -1; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public void set(T e) { - throw new UnsupportedOperationException(); - } - - @Override - public void add(T e) { - throw new UnsupportedOperationException(); - } - } - - static class SingleEntryCollection implements Collection { - - final T entry; - - SingleEntryCollection(T entry) { - this.entry = entry; - } - - @Override - public int size() { - return 1; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean contains(Object o) { - if (entry == null) { - return o == null; - } - return entry.equals(o); - } - - @Override - public Iterator iterator() { - return new SingleEntryIterator(entry); - } - - @Override - public Object[] toArray() { - return new Object[] {entry}; - } - - @Override - public V[] toArray(V[] a) { - if (a.length != 1) { - a = Arrays.copyOf(a, 1); - } - a[0] = (V) entry; - return a; - } - - @Override - public boolean add(T e) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean remove(Object o) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean containsAll(Collection c) { - int size = c.size(); - if (size != 1) { - return false; - } - for (Object o : c) { - return contains(o); - } - return false; - } - - @Override - public boolean addAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean removeAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean retainAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - } - - static final class SingleEntrySet extends SingleEntryCollection implements Set { - - SingleEntrySet(T entry) { - super(entry); - } - } - - static final class SingleEntryList extends SingleEntryCollection implements List { - - SingleEntryList(T entry) { - super(entry); - } - - @Override - public boolean addAll(int index, Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public T get(int index) { - if (index == 0) { - return entry; - } - throw new IndexOutOfBoundsException(); - } - - @Override - public T set(int index, T element) { - throw new UnsupportedOperationException(); - } - - @Override - public void add(int index, T element) { - throw new UnsupportedOperationException(); - } - - @Override - public T remove(int index) { - throw new UnsupportedOperationException(); - } - - @Override - public int indexOf(Object o) { - return contains(o) ? 0 : -1; - } - - @Override - public int lastIndexOf(Object o) { - return contains(o) ? 0 : -1; - } - - @Override - public ListIterator listIterator() { - return new SingleEntryListIterator(entry); - } - - @Override - public ListIterator listIterator(int index) { - if (index != 0) { - throw new IndexOutOfBoundsException(); - } - return listIterator(); - } - - @Override - public List subList(int fromIndex, int toIndex) { - if (fromIndex == 0) { - if (toIndex == 0) { - return Collections.emptyList(); - } else if (toIndex == 1) { - return this; - } else { - throw new IndexOutOfBoundsException(); - } - } else if (fromIndex == 1 && toIndex == 1) { - return Collections.emptyList(); - } else { - throw new IndexOutOfBoundsException(); - } - } - } - - static final class SingleEntryMap implements Map { - - final K key; - final V value; - - SingleEntryMap(K key, V value) { - this.key = key; - this.value = value; - } - - @Override - public int size() { - return 1; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean containsKey(Object key) { - if (this.key == null) { - return key == null; - } - return this.key.equals(key); - } - - @Override - public boolean containsValue(Object value) { - if (this.value == null) { - return value == null; - } - return this.value.equals(value); - } - - @Override - public V get(Object key) { - if (this.key == null) { - return key == null ? this.value : null; - } - return this.key.equals(key) ? this.value : null; - } - - @Override - public V put(K key, V value) { - throw new UnsupportedOperationException(); - } - - @Override - public V remove(Object key) { - throw new UnsupportedOperationException(); - } - - @Override - public void putAll(Map m) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - - @Override - public Set keySet() { - return new SingleEntrySet(this.key); - } - - @Override - public Collection values() { - return new SingleEntrySet(this.value); - } - - @Override - public Set> entrySet() { - return new SingleEntrySet>( - new Map.Entry() { - - @Override - public K getKey() { - return key; - } - - @Override - public V getValue() { - return value; - } - - @Override - public V setValue(V value) { - throw new UnsupportedOperationException(); - } - }); - } - } + private Immutables() { + } + + public static Set setOf(T value) { + return new SingleEntrySet(value); + } + + public static List listOf(T value) { + return new SingleEntryList(value); + } + + public static Map mapOf(K key, V value) { + return new SingleEntryMap(key, value); + } + + static class SingleEntryIterator implements Iterator { + + T entry; + boolean processed = false; + + SingleEntryIterator(T entry) { + this.entry = entry; + } + + @Override + public boolean hasNext() { + return !processed; + } + + @Override + public T next() { + processed = true; + return entry; + } + } + + static class SingleEntryListIterator extends SingleEntryIterator implements ListIterator { + + SingleEntryListIterator(T entry) { + super(entry); + } + + @Override + public boolean hasPrevious() { + return processed; + } + + @Override + public T previous() { + processed = false; + return entry; + } + + @Override + public int nextIndex() { + return processed ? 1 : 0; + } + + @Override + public int previousIndex() { + return processed ? 0 : -1; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public void set(T e) { + throw new UnsupportedOperationException(); + } + + @Override + public void add(T e) { + throw new UnsupportedOperationException(); + } + } + + static class SingleEntryCollection implements Collection { + + final T entry; + + SingleEntryCollection(T entry) { + this.entry = entry; + } + + @Override + public int size() { + return 1; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean contains(Object o) { + if (entry == null) { + return o == null; + } + return entry.equals(o); + } + + @Override + public Iterator iterator() { + return new SingleEntryIterator(entry); + } + + @Override + public Object[] toArray() { + return new Object[]{entry}; + } + + @Override + public V[] toArray(V[] a) { + if (a.length != 1) { + a = Arrays.copyOf(a, 1); + } + a[0] = (V) entry; + return a; + } + + @Override + public boolean add(T e) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean remove(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean containsAll(Collection c) { + int size = c.size(); + if (size != 1) { + return false; + } + for (Object o : c) { + return contains(o); + } + return false; + } + + @Override + public boolean addAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + } + + static final class SingleEntrySet extends SingleEntryCollection implements Set { + + SingleEntrySet(T entry) { + super(entry); + } + } + + static final class SingleEntryList extends SingleEntryCollection implements List { + + SingleEntryList(T entry) { + super(entry); + } + + @Override + public boolean addAll(int index, Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public T get(int index) { + if (index == 0) { + return entry; + } + throw new IndexOutOfBoundsException(); + } + + @Override + public T set(int index, T element) { + throw new UnsupportedOperationException(); + } + + @Override + public void add(int index, T element) { + throw new UnsupportedOperationException(); + } + + @Override + public T remove(int index) { + throw new UnsupportedOperationException(); + } + + @Override + public int indexOf(Object o) { + return contains(o) ? 0 : -1; + } + + @Override + public int lastIndexOf(Object o) { + return contains(o) ? 0 : -1; + } + + @Override + public ListIterator listIterator() { + return new SingleEntryListIterator(entry); + } + + @Override + public ListIterator listIterator(int index) { + if (index != 0) { + throw new IndexOutOfBoundsException(); + } + return listIterator(); + } + + @Override + public List subList(int fromIndex, int toIndex) { + if (fromIndex == 0) { + if (toIndex == 0) { + return Collections.emptyList(); + } else if (toIndex == 1) { + return this; + } else { + throw new IndexOutOfBoundsException(); + } + } else if (fromIndex == 1 && toIndex == 1) { + return Collections.emptyList(); + } else { + throw new IndexOutOfBoundsException(); + } + } + } + + static final class SingleEntryMap implements Map { + + final K key; + final V value; + + SingleEntryMap(K key, V value) { + this.key = key; + this.value = value; + } + + @Override + public int size() { + return 1; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean containsKey(Object key) { + if (this.key == null) { + return key == null; + } + return this.key.equals(key); + } + + @Override + public boolean containsValue(Object value) { + if (this.value == null) { + return value == null; + } + return this.value.equals(value); + } + + @Override + public V get(Object key) { + if (this.key == null) { + return key == null ? this.value : null; + } + return this.key.equals(key) ? this.value : null; + } + + @Override + public V put(K key, V value) { + throw new UnsupportedOperationException(); + } + + @Override + public V remove(Object key) { + throw new UnsupportedOperationException(); + } + + @Override + public void putAll(Map m) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + @Override + public Set keySet() { + return new SingleEntrySet(this.key); + } + + @Override + public Collection values() { + return new SingleEntrySet(this.value); + } + + @Override + public Set> entrySet() { + return new SingleEntrySet>(new Map.Entry() { + + @Override + public K getKey() { + return key; + } + + @Override + public V getValue() { + return value; + } + + @Override + public V setValue(V value) { + throw new UnsupportedOperationException(); + } + }); + } + } } diff --git a/src/main/java/net/helenus/support/Mutable.java b/src/main/java/net/helenus/support/Mutable.java index 622b1d3..9a44d99 100644 --- a/src/main/java/net/helenus/support/Mutable.java +++ b/src/main/java/net/helenus/support/Mutable.java @@ -17,17 +17,17 @@ package net.helenus.support; public final class Mutable { - private volatile T value; + private volatile T value; - public Mutable(T initialValue) { - this.value = initialValue; - } + public Mutable(T initialValue) { + this.value = initialValue; + } - public T get() { - return value; - } + public T get() { + return value; + } - public void set(T value) { - this.value = value; - } + public void set(T value) { + this.value = value; + } } diff --git a/src/main/java/net/helenus/support/PackageUtil.java b/src/main/java/net/helenus/support/PackageUtil.java index 83b4ffa..230058a 100644 --- a/src/main/java/net/helenus/support/PackageUtil.java +++ b/src/main/java/net/helenus/support/PackageUtil.java @@ -25,117 +25,115 @@ import java.util.HashSet; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PackageUtil { - private static final Logger log = LoggerFactory.getLogger(PackageUtil.class); + private static final Logger log = LoggerFactory.getLogger(PackageUtil.class); - public static final String JAR_URL_SEPARATOR = "!/"; + public static final String JAR_URL_SEPARATOR = "!/"; - private static void doFetchInPath( - Set> classes, File directory, String packageName, ClassLoader classLoader) - throws ClassNotFoundException { - File[] dirContents = directory.listFiles(); - if (dirContents == null) { - throw new ClassNotFoundException("invalid directory " + directory.getAbsolutePath()); - } - for (File file : dirContents) { - String fileName = file.getName(); - if (file.isDirectory()) { - doFetchInPath(classes, file, packageName + "." + fileName, classLoader); - } else if (fileName.endsWith(".class")) { - classes.add( - classLoader.loadClass( - packageName + '.' + fileName.substring(0, fileName.length() - 6))); - } - } - } + private static void doFetchInPath(Set> classes, File directory, String packageName, + ClassLoader classLoader) throws ClassNotFoundException { + File[] dirContents = directory.listFiles(); + if (dirContents == null) { + throw new ClassNotFoundException("invalid directory " + directory.getAbsolutePath()); + } + for (File file : dirContents) { + String fileName = file.getName(); + if (file.isDirectory()) { + doFetchInPath(classes, file, packageName + "." + fileName, classLoader); + } else if (fileName.endsWith(".class")) { + classes.add(classLoader.loadClass(packageName + '.' + fileName.substring(0, fileName.length() - 6))); + } + } + } - public static Set> getClasses(String packagePath) - throws ClassNotFoundException, IOException { - Set> classes = new HashSet>(); - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - if (classLoader == null) { - throw new ClassNotFoundException("class loader not found for current thread"); - } - Enumeration resources = null; - try { - resources = classLoader.getResources(packagePath.replace('.', '/')); - } catch (IOException e) { - throw new ClassNotFoundException("invalid package " + packagePath, e); - } - while (resources.hasMoreElements()) { - URL url = resources.nextElement(); - if (url == null) { - throw new ClassNotFoundException(packagePath + " - package not found"); - } - String dirPath = fastReplace(url.getFile(), "%20", " "); - int jarSeparator = dirPath.indexOf(JAR_URL_SEPARATOR); - if (jarSeparator == -1) { - File directory = new File(dirPath); - if (!directory.exists()) { - throw new ClassNotFoundException(packagePath + " - invalid package"); - } - doFetchInPath(classes, directory, packagePath, classLoader); - } else { - String rootEntry = dirPath.substring(jarSeparator + JAR_URL_SEPARATOR.length()); - if (!"".equals(rootEntry) && !rootEntry.endsWith("/")) { - rootEntry = rootEntry + "/"; - } - JarFile jarFile = null; - try { - URLConnection con = url.openConnection(); - if (con instanceof JarURLConnection) { - JarURLConnection jarCon = (JarURLConnection) con; - jarCon.setUseCaches(false); - jarFile = jarCon.getJarFile(); - } else { - String jarName = dirPath.substring(0, jarSeparator); - jarName = fastReplace(jarName, " ", "%20"); - jarFile = new JarFile(jarName); - } - for (Enumeration entries = jarFile.entries(); entries.hasMoreElements(); ) { - JarEntry entry = entries.nextElement(); - String fileName = entry.getName(); - if (fileName.startsWith(rootEntry) && fileName.endsWith(".class")) { - fileName = fileName.replace('/', '.'); - try { - classes.add(classLoader.loadClass(fileName.substring(0, fileName.length() - 6))); - } catch (ClassNotFoundException e) { - log.error("class load fail", e); - } - } - } - } catch (IOException e) { - throw new ClassNotFoundException("jar fail", e); - } finally { - if (jarFile != null) jarFile.close(); - } - } - } - return classes; - } + public static Set> getClasses(String packagePath) throws ClassNotFoundException, IOException { + Set> classes = new HashSet>(); + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + if (classLoader == null) { + throw new ClassNotFoundException("class loader not found for current thread"); + } + Enumeration resources = null; + try { + resources = classLoader.getResources(packagePath.replace('.', '/')); + } catch (IOException e) { + throw new ClassNotFoundException("invalid package " + packagePath, e); + } + while (resources.hasMoreElements()) { + URL url = resources.nextElement(); + if (url == null) { + throw new ClassNotFoundException(packagePath + " - package not found"); + } + String dirPath = fastReplace(url.getFile(), "%20", " "); + int jarSeparator = dirPath.indexOf(JAR_URL_SEPARATOR); + if (jarSeparator == -1) { + File directory = new File(dirPath); + if (!directory.exists()) { + throw new ClassNotFoundException(packagePath + " - invalid package"); + } + doFetchInPath(classes, directory, packagePath, classLoader); + } else { + String rootEntry = dirPath.substring(jarSeparator + JAR_URL_SEPARATOR.length()); + if (!"".equals(rootEntry) && !rootEntry.endsWith("/")) { + rootEntry = rootEntry + "/"; + } + JarFile jarFile = null; + try { + URLConnection con = url.openConnection(); + if (con instanceof JarURLConnection) { + JarURLConnection jarCon = (JarURLConnection) con; + jarCon.setUseCaches(false); + jarFile = jarCon.getJarFile(); + } else { + String jarName = dirPath.substring(0, jarSeparator); + jarName = fastReplace(jarName, " ", "%20"); + jarFile = new JarFile(jarName); + } + for (Enumeration entries = jarFile.entries(); entries.hasMoreElements();) { + JarEntry entry = entries.nextElement(); + String fileName = entry.getName(); + if (fileName.startsWith(rootEntry) && fileName.endsWith(".class")) { + fileName = fileName.replace('/', '.'); + try { + classes.add(classLoader.loadClass(fileName.substring(0, fileName.length() - 6))); + } catch (ClassNotFoundException e) { + log.error("class load fail", e); + } + } + } + } catch (IOException e) { + throw new ClassNotFoundException("jar fail", e); + } finally { + if (jarFile != null) + jarFile.close(); + } + } + } + return classes; + } - public static String fastReplace(String inString, String oldPattern, String newPattern) { - if (inString == null) { - return null; - } - if (oldPattern == null || newPattern == null) { - return inString; - } - StringBuilder sbuf = new StringBuilder(); - int pos = 0; - int index = inString.indexOf(oldPattern); - int patLen = oldPattern.length(); - while (index >= 0) { - sbuf.append(inString.substring(pos, index)); - sbuf.append(newPattern); - pos = index + patLen; - index = inString.indexOf(oldPattern, pos); - } - sbuf.append(inString.substring(pos)); - return sbuf.toString(); - } + public static String fastReplace(String inString, String oldPattern, String newPattern) { + if (inString == null) { + return null; + } + if (oldPattern == null || newPattern == null) { + return inString; + } + StringBuilder sbuf = new StringBuilder(); + int pos = 0; + int index = inString.indexOf(oldPattern); + int patLen = oldPattern.length(); + while (index >= 0) { + sbuf.append(inString.substring(pos, index)); + sbuf.append(newPattern); + pos = index + patLen; + index = inString.indexOf(oldPattern, pos); + } + sbuf.append(inString.substring(pos)); + return sbuf.toString(); + } } diff --git a/src/main/java/net/helenus/support/Requires.java b/src/main/java/net/helenus/support/Requires.java index 51543fa..cc8e4bf 100644 --- a/src/main/java/net/helenus/support/Requires.java +++ b/src/main/java/net/helenus/support/Requires.java @@ -20,13 +20,14 @@ import java.util.Objects; public final class Requires { - private Requires() {} + private Requires() { + } - public static void nonNullArray(T[] arr) { - Objects.requireNonNull(arr, "array is null"); - int len = Array.getLength(arr); - for (int i = 0; i != len; ++i) { - Objects.requireNonNull(Array.get(arr, i), "element " + i + " is empty in array"); - } - } + public static void nonNullArray(T[] arr) { + Objects.requireNonNull(arr, "array is null"); + int len = Array.getLength(arr); + for (int i = 0; i != len; ++i) { + Objects.requireNonNull(Array.get(arr, i), "element " + i + " is empty in array"); + } + } } diff --git a/src/main/java/net/helenus/support/Timeuuid.java b/src/main/java/net/helenus/support/Timeuuid.java index 45f9497..d417f10 100644 --- a/src/main/java/net/helenus/support/Timeuuid.java +++ b/src/main/java/net/helenus/support/Timeuuid.java @@ -21,66 +21,55 @@ import java.util.UUID; public final class Timeuuid { - private static class Holder { - static final SecureRandom numberGenerator = new SecureRandom(); - } + private static class Holder { + static final SecureRandom numberGenerator = new SecureRandom(); + } - private Timeuuid() {} + private Timeuuid() { + } - public static UUID of(long timestampMillis, int clockSequence, long node) { - return new UuidBuilder() - .addVersion(1) - .addTimestampMillis(timestampMillis) - .addClockSequence(clockSequence) - .addNode(node) - .build(); - } + public static UUID of(long timestampMillis, int clockSequence, long node) { + return new UuidBuilder().addVersion(1).addTimestampMillis(timestampMillis).addClockSequence(clockSequence) + .addNode(node).build(); + } - public static UUID of(Date date, int clockSequence, long node) { - return of(date.getTime(), clockSequence, node); - } + public static UUID of(Date date, int clockSequence, long node) { + return of(date.getTime(), clockSequence, node); + } - public static UUID of(long timestampMillis) { - return of(timestampMillis, randomClockSequence(), randomNode()); - } + public static UUID of(long timestampMillis) { + return of(timestampMillis, randomClockSequence(), randomNode()); + } - public static UUID of(Date date) { - return of(date.getTime()); - } + public static UUID of(Date date) { + return of(date.getTime()); + } - public static UUID minOf(long timestampMillis) { - return new UuidBuilder() - .addVersion(1) - .addTimestampMillis(timestampMillis) - .setMinClockSeqAndNode() - .build(); - } + public static UUID minOf(long timestampMillis) { + return new UuidBuilder().addVersion(1).addTimestampMillis(timestampMillis).setMinClockSeqAndNode().build(); + } - public static UUID minOf(Date date) { - return minOf(date.getTime()); - } + public static UUID minOf(Date date) { + return minOf(date.getTime()); + } - public static UUID maxOf(long timestampMillis) { - return new UuidBuilder() - .addVersion(1) - .addTimestampMillis(timestampMillis) - .setMaxClockSeqAndNode() - .build(); - } + public static UUID maxOf(long timestampMillis) { + return new UuidBuilder().addVersion(1).addTimestampMillis(timestampMillis).setMaxClockSeqAndNode().build(); + } - public static UUID maxOf(Date date) { - return maxOf(date.getTime()); - } + public static UUID maxOf(Date date) { + return maxOf(date.getTime()); + } - public static int randomClockSequence() { - return Holder.numberGenerator.nextInt(0x3fff); - } + public static int randomClockSequence() { + return Holder.numberGenerator.nextInt(0x3fff); + } - public static long randomNode() { - return Holder.numberGenerator.nextLong() & 0xFFFFFFFFFFFFL; - } + public static long randomNode() { + return Holder.numberGenerator.nextLong() & 0xFFFFFFFFFFFFL; + } - public static long getTimestampMillis(UUID uuid) { - return UuidBuilder.getTimestampMillis(uuid); - } + public static long getTimestampMillis(UUID uuid) { + return UuidBuilder.getTimestampMillis(uuid); + } } diff --git a/src/main/java/net/helenus/support/Transformers.java b/src/main/java/net/helenus/support/Transformers.java index dd62ddf..2b21ca3 100644 --- a/src/main/java/net/helenus/support/Transformers.java +++ b/src/main/java/net/helenus/support/Transformers.java @@ -15,66 +15,68 @@ */ package net.helenus.support; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import java.util.*; import java.util.function.Function; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + public final class Transformers { - private Transformers() {} + private Transformers() { + } - public static Set transformSet(Set inputSet, Function func) { - Set set = Sets.newHashSet(); - for (I in : inputSet) { - set.add(func.apply(in)); - } - return set; - } + public static Set transformSet(Set inputSet, Function func) { + Set set = Sets.newHashSet(); + for (I in : inputSet) { + set.add(func.apply(in)); + } + return set; + } - public static List transformList(List inputList, Function func) { - return new TransformedImmutableList(inputList, func); - } + public static List transformList(List inputList, Function func) { + return new TransformedImmutableList(inputList, func); + } - public static Map transformMapKey(Map inputMap, Function func) { - Map map = Maps.newHashMap(); - for (Map.Entry e : inputMap.entrySet()) { - map.put(func.apply(e.getKey()), e.getValue()); - } - return map; - } + public static Map transformMapKey(Map inputMap, Function func) { + Map map = Maps.newHashMap(); + for (Map.Entry e : inputMap.entrySet()) { + map.put(func.apply(e.getKey()), e.getValue()); + } + return map; + } - public static Map transformMapValue(Map inputMap, Function func) { - return Maps.transformValues(inputMap, func::apply); - } + public static Map transformMapValue(Map inputMap, Function func) { + return Maps.transformValues(inputMap, func::apply); + } - public static Map transformMap( - Map inputMap, Function funcKey, Function funcValue) { - Map map = Maps.newHashMap(); - for (Map.Entry e : inputMap.entrySet()) { - map.put(funcKey.apply(e.getKey()), funcValue.apply(e.getValue())); - } - return map; - } + public static Map transformMap(Map inputMap, Function funcKey, + Function funcValue) { + Map map = Maps.newHashMap(); + for (Map.Entry e : inputMap.entrySet()) { + map.put(funcKey.apply(e.getKey()), funcValue.apply(e.getValue())); + } + return map; + } - static final class TransformedImmutableList extends AbstractList implements List { + static final class TransformedImmutableList extends AbstractList implements List { - final List inputList; - final Function func; + final List inputList; + final Function func; - TransformedImmutableList(List inputList, Function func) { - this.inputList = Objects.requireNonNull(inputList, "inputList is null"); - this.func = Objects.requireNonNull(func, "func is null"); - } + TransformedImmutableList(List inputList, Function func) { + this.inputList = Objects.requireNonNull(inputList, "inputList is null"); + this.func = Objects.requireNonNull(func, "func is null"); + } - @Override - public O get(int index) { - return func.apply(inputList.get(index)); - } + @Override + public O get(int index) { + return func.apply(inputList.get(index)); + } - @Override - public int size() { - return inputList.size(); - } - } + @Override + public int size() { + return inputList.size(); + } + } } diff --git a/src/main/java/net/helenus/support/UuidBuilder.java b/src/main/java/net/helenus/support/UuidBuilder.java index 9bbabf5..d56050b 100644 --- a/src/main/java/net/helenus/support/UuidBuilder.java +++ b/src/main/java/net/helenus/support/UuidBuilder.java @@ -19,76 +19,76 @@ import java.util.UUID; public final class UuidBuilder { - public static final long NUM_100NS_IN_MILLISECOND = 10000L; + public static final long NUM_100NS_IN_MILLISECOND = 10000L; - public static final long NUM_100NS_SINCE_UUID_EPOCH = 0x01b21dd213814000L; + public static final long NUM_100NS_SINCE_UUID_EPOCH = 0x01b21dd213814000L; - private static final long MIN_CLOCK_SEQ_AND_NODE = 0x8080808080808080L; - private static final long MAX_CLOCK_SEQ_AND_NODE = 0x7f7f7f7f7f7f7f7fL; + private static final long MIN_CLOCK_SEQ_AND_NODE = 0x8080808080808080L; + private static final long MAX_CLOCK_SEQ_AND_NODE = 0x7f7f7f7f7f7f7f7fL; - private long leastSigBits = 0x8000000000000000L; + private long leastSigBits = 0x8000000000000000L; - private long mostSigBits = 0L; + private long mostSigBits = 0L; - public long getLeastSignificantBits() { - return leastSigBits; - } + public long getLeastSignificantBits() { + return leastSigBits; + } - public long getMostSignificantBits() { - return mostSigBits; - } + public long getMostSignificantBits() { + return mostSigBits; + } - public UUID build() { - return new UUID(mostSigBits, leastSigBits); - } + public UUID build() { + return new UUID(mostSigBits, leastSigBits); + } - public UuidBuilder addVersion(int version) { - if (version < 1 || version > 4) { - throw new IllegalArgumentException("unsupported version " + version); - } + public UuidBuilder addVersion(int version) { + if (version < 1 || version > 4) { + throw new IllegalArgumentException("unsupported version " + version); + } - mostSigBits |= ((long) (version & 0x0f)) << 12; + mostSigBits |= ((long) (version & 0x0f)) << 12; - return this; - } + return this; + } - public UuidBuilder addTimestamp100Nanos(long uuid100Nanos) { + public UuidBuilder addTimestamp100Nanos(long uuid100Nanos) { - long timeLow = uuid100Nanos & 0xffffffffL; - long timeMid = uuid100Nanos & 0xffff00000000L; - long timeHi = uuid100Nanos & 0xfff000000000000L; + long timeLow = uuid100Nanos & 0xffffffffL; + long timeMid = uuid100Nanos & 0xffff00000000L; + long timeHi = uuid100Nanos & 0xfff000000000000L; - mostSigBits |= (timeLow << 32) | (timeMid >> 16) | (timeHi >> 48); + mostSigBits |= (timeLow << 32) | (timeMid >> 16) | (timeHi >> 48); - return this; - } + return this; + } - public UuidBuilder addTimestampMillis(long milliseconds) { - long uuid100Nanos = milliseconds * NUM_100NS_IN_MILLISECOND + NUM_100NS_SINCE_UUID_EPOCH; - return addTimestamp100Nanos(uuid100Nanos); - } + public UuidBuilder addTimestampMillis(long milliseconds) { + long uuid100Nanos = milliseconds * NUM_100NS_IN_MILLISECOND + NUM_100NS_SINCE_UUID_EPOCH; + return addTimestamp100Nanos(uuid100Nanos); + } - public UuidBuilder addClockSequence(int clockSequence) { - leastSigBits |= ((long) (clockSequence & 0x3fff)) << 48; - return this; - } + public UuidBuilder addClockSequence(int clockSequence) { + leastSigBits |= ((long) (clockSequence & 0x3fff)) << 48; + return this; + } - public UuidBuilder addNode(long node) { - leastSigBits |= node & 0xffffffffffffL; - return this; - } + public UuidBuilder addNode(long node) { + leastSigBits |= node & 0xffffffffffffL; + return this; + } - public UuidBuilder setMinClockSeqAndNode() { - this.leastSigBits = MIN_CLOCK_SEQ_AND_NODE; - return this; - } + public UuidBuilder setMinClockSeqAndNode() { + this.leastSigBits = MIN_CLOCK_SEQ_AND_NODE; + return this; + } - public UuidBuilder setMaxClockSeqAndNode() { - this.leastSigBits = MAX_CLOCK_SEQ_AND_NODE; - return this; - } + public UuidBuilder setMaxClockSeqAndNode() { + this.leastSigBits = MAX_CLOCK_SEQ_AND_NODE; + return this; + } - public static long getTimestampMillis(UUID uuid) { - return (uuid.timestamp() - NUM_100NS_SINCE_UUID_EPOCH) / NUM_100NS_IN_MILLISECOND; - } + public static long getTimestampMillis(UUID uuid) { + return (uuid.timestamp() - NUM_100NS_SINCE_UUID_EPOCH) / NUM_100NS_IN_MILLISECOND; + } } diff --git a/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java b/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java index bf217c2..4efed56 100644 --- a/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java +++ b/src/test/java/net/helenus/test/integration/core/unitofwork/UnitOfWorkTest.java @@ -150,16 +150,21 @@ public class UnitOfWorkTest extends AbstractEmbeddedCassandraTest { UUID key = UUIDs.timeBased(); try (UnitOfWork uow = session.begin()) { - // This should inserted Widget, but not cache it. + // This should insert and cache Widget in the uow. session .insert(widget) .value(widget::id, key) .value(widget::name, RandomString.make(20)) - .sync(); + .sync(uow); // This should read from the database and return a Widget. w1 = - session.select(widget).where(widget::id, eq(key)).single().sync(uow).orElse(null); + session + .select(widget) + .where(widget::id, eq(key)) + .single() + .sync(uow) + .orElse(null); // This should read from the cache and get the same instance of a Widget. w2 = From 1746691826a81adb4558a5630cf25ac65f76761e Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Fri, 20 Oct 2017 12:33:42 -0400 Subject: [PATCH 9/9] Facet cache is working, able to fetch by non-primary key within UOW. --- helenus-core.iml | 1 - pom.xml | 6 - .../net/helenus/core/AbstractUnitOfWork.java | 128 ++++++------------ src/main/java/net/helenus/core/Filter.java | 4 + src/main/java/net/helenus/core/Postulate.java | 4 + .../java/net/helenus/core/SchemaUtil.java | 29 +++- .../java/net/helenus/core/UnitOfWork.java | 13 +- .../net/helenus/core/cache/BoundFacet.java | 16 ++- .../java/net/helenus/core/cache/Facet.java | 55 ++++++-- ...dentifyingFacet.java => UnboundFacet.java} | 39 +++--- .../operation/AbstractOptionalOperation.java | 9 +- .../operation/AbstractStatementOperation.java | 77 ++++------- .../operation/AbstractStreamOperation.java | 10 +- .../core/operation/BoundStreamOperation.java | 9 +- .../core/operation/InsertOperation.java | 19 +-- .../net/helenus/core/operation/Operation.java | 11 +- .../core/operation/SelectFirstOperation.java | 15 +- .../SelectFirstTransformingOperation.java | 9 +- .../core/operation/SelectOperation.java | 44 +++--- .../SelectTransformingOperation.java | 15 +- .../core/operation/UpdateOperation.java | 2 +- .../net/helenus/mapping/HelenusEntity.java | 6 +- .../helenus/mapping/HelenusMappingEntity.java | 41 +++--- 23 files changed, 248 insertions(+), 314 deletions(-) rename src/main/java/net/helenus/core/cache/{EntityIdentifyingFacet.java => UnboundFacet.java} (59%) diff --git a/helenus-core.iml b/helenus-core.iml index 1f3247f..be96637 100644 --- a/helenus-core.iml +++ b/helenus-core.iml @@ -35,7 +35,6 @@ - diff --git a/pom.xml b/pom.xml index 8e4391b..71feca8 100644 --- a/pom.xml +++ b/pom.xml @@ -148,12 +148,6 @@ 20.0 - - org.ahocorasick - ahocorasick - 0.4.0 - - io.zipkin.java diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index b689ab2..1bc6683 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -16,17 +16,13 @@ package net.helenus.core; import java.util.*; -import java.util.stream.Collectors; - -import org.ahocorasick.trie.Emit; -import org.ahocorasick.trie.Trie; import com.diffplug.common.base.Errors; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; import com.google.common.collect.TreeTraverser; -import net.helenus.core.cache.BoundFacet; import net.helenus.core.cache.Facet; -import net.helenus.support.Either; /** Encapsulates the concept of a "transaction" as a unit-of-work. */ public abstract class AbstractUnitOfWork implements UnitOfWork, AutoCloseable { @@ -34,11 +30,12 @@ public abstract class AbstractUnitOfWork implements UnitOfW private final HelenusSession session; private final AbstractUnitOfWork parent; private List postCommit = new ArrayList(); - private final Map>> cache = new HashMap>>(); - private Trie cacheIndex = Trie.builder().ignoreOverlaps().build(); private boolean aborted = false; private boolean committed = false; + // Cache: + private final Table cache = HashBasedTable.create(); + protected AbstractUnitOfWork(HelenusSession session, AbstractUnitOfWork parent) { Objects.requireNonNull(session, "containing session cannot be null"); @@ -68,62 +65,40 @@ public abstract class AbstractUnitOfWork implements UnitOfW } @Override - public Optional>> cacheLookupByFacet(Set facets) { - Optional>> result = Optional.empty(); - Collection emits = cacheIndex.parseText( - String.join(" ", facets.stream().map(facet -> facet.toString()).collect(Collectors.toList()))); - for (Emit emit : emits) { - // NOTE: rethink. should this match *all* facets? how do I know which emit - // keyword is the primary key? - String key = emit.getKeyword(); - result = cacheLookup(key); - if (result.isPresent()) { - return result; + public Optional cacheLookup(List facets) { + Facet table = facets.remove(0); + String tableName = table.value().toString(); + Optional result = Optional.empty(); + for (Facet facet : facets) { + String columnName = facet.name() + "==" + facet.value(); + Object value = cache.get(tableName, columnName); + if (value != null) { + if (result.isPresent() && result.get() != value) { + // One facet matched, but another did not. + result = Optional.empty(); + break; + } else { + result = Optional.of(value); + } } } if (!result.isPresent()) { // Be sure to check all enclosing UnitOfWork caches as well, we may be nested. if (parent != null) { - return parent.cacheLookupByFacet(facets); + return parent.cacheLookup(facets); } } return result; } @Override - public Optional>> cacheLookupByStatement(String[] statementKeys) { - String key = String.join(",", statementKeys); - return cacheLookup(key); - } - - @Override - public Optional>> cacheLookup(String key) { - Optional>> result = (cache.containsKey(key)) - ? Optional.of(cache.get(key)) - : Optional.empty(); - - if (!result.isPresent()) { - // Be sure to check all enclosing UnitOfWork caches as well, we may be nested. - if (parent != null) { - return parent.cacheLookup(key); - } + public void cacheUpdate(Object value, List facets) { + Facet table = facets.remove(0); + String tableName = table.value().toString(); + for (Facet facet : facets) { + String columnName = facet.name() + "==" + facet.value(); + cache.put(tableName, columnName, value); } - return result; - } - - @Override - public void cacheUpdate(Either> value, String[] statementKeys, - Map facetMap) { - String key = "CQL::" + String.join(",", statementKeys); - cache.put(key, value); - Trie.TrieBuilder builder = cacheIndex.builder().ignoreOverlaps(); - facetMap.forEach((facetName, facet) -> { - builder.addKeyword(facet.toString()); - if (facetName.equals("*")) { - cache.put(facet.toString(), value); - } - }); - cacheIndex = builder.build(); } private Iterator> getChildNodes() { @@ -161,15 +136,14 @@ public abstract class AbstractUnitOfWork implements UnitOfW committed = true; aborted = false; - // TODO(gburd): union this cache with parent's (if there is a parent) or with - // the session cache for all cacheable entities we currently hold - nested.forEach((uow) -> Errors.rethrow().wrap(uow::commit)); // Merge UOW cache into parent's cache. if (parent != null) { - parent.assumeCache(cache, cacheIndex); - } + parent.mergeCache(cache); + } // else { + // TODO... merge into session cache objects marked cacheable + // } // Apply all post-commit functions for if (parent == null) { @@ -197,35 +171,21 @@ public abstract class AbstractUnitOfWork implements UnitOfW // cache.invalidateSince(txn::start time) } - private void assumeCache(Map>> childCache, Trie childCacheIndex) { - for (String key : childCache.keySet()) { - if (cache.containsKey(key)) { - Either> value = cache.get(key); - if (value.isLeft()) { - Object obj = value.getLeft(); - // merge objects - Either> childValue = childCache.get(key); - if (childValue.isLeft()) { - Object childObj = childValue.getLeft(); - } else { - Set childSet = childValue.getRight(); - } + private void mergeCache(Table from) { + Table to = this.cache; + from.rowMap().forEach((rowKey, columnMap) -> { + columnMap.forEach((columnKey, value) -> { + if (to.contains(rowKey, columnKey)) { + to.put(rowKey, columnKey, merge(to.get(rowKey, columnKey), from.get(rowKey, columnKey))); } else { - // merge the sets - Set set = value.getRight(); - Either> childValue = childCache.get(key); - if (childValue.isLeft()) { - Object childObj = childValue.getLeft(); - set.add(childObj); - } else { - Set childSet = childValue.getRight(); - set.addAll(childSet); - } + to.put(rowKey, columnKey, from.get(rowKey, columnKey)); } - } else { - cache.put(key, childCache.get(key)); - } - } + }); + }); + } + + private Object merge(Object to, Object from) { + return to; // TODO(gburd): yeah... } public String describeConflicts() { diff --git a/src/main/java/net/helenus/core/Filter.java b/src/main/java/net/helenus/core/Filter.java index 3d6762f..79d9a34 100644 --- a/src/main/java/net/helenus/core/Filter.java +++ b/src/main/java/net/helenus/core/Filter.java @@ -105,6 +105,10 @@ public final class Filter { return new Filter(node, postulate); } + public V[] postulateValues() { + return postulate.values(); + } + @Override public String toString() { return node.getColumnName() + postulate.toString(); diff --git a/src/main/java/net/helenus/core/Postulate.java b/src/main/java/net/helenus/core/Postulate.java index a31d0a8..05e9f57 100644 --- a/src/main/java/net/helenus/core/Postulate.java +++ b/src/main/java/net/helenus/core/Postulate.java @@ -71,6 +71,10 @@ public final class Postulate { } } + public V[] values() { + return values; + } + @Override public String toString() { diff --git a/src/main/java/net/helenus/core/SchemaUtil.java b/src/main/java/net/helenus/core/SchemaUtil.java index 8e421c0..44ccae8 100644 --- a/src/main/java/net/helenus/core/SchemaUtil.java +++ b/src/main/java/net/helenus/core/SchemaUtil.java @@ -140,6 +140,28 @@ public final class SchemaUtil { return SchemaBuilder.dropType(type.getTypeName()).ifExists(); } + public static String createPrimaryKeyPhrase(Collection properties) { + List p = new ArrayList(properties.size()); + List c = new ArrayList(properties.size()); + + for (HelenusProperty prop : properties) { + String columnName = prop.getColumnName().toCql(); + switch (prop.getColumnType()) { + case PARTITION_KEY : + p.add(columnName); + break; + case CLUSTERING_COLUMN : + c.add(columnName); + break; + default : + break; + } + } + + return "(" + ((p.size() > 1) ? "(" + String.join(", ", p) + ")" : p.get(0)) + + ((c.size() > 0) ? ", " + ((c.size() > 1) ? "(" + String.join(", ", c) + ")" : c.get(0)) : "") + ")"; + } + public static SchemaStatement createMaterializedView(String keyspace, String viewName, HelenusEntity entity) { if (entity.getType() != HelenusEntityType.VIEW) { throw new HelenusMappingException("expected view entity " + entity); @@ -162,20 +184,16 @@ public final class SchemaUtil { Class iface = entity.getMappingInterface(); String tableName = Helenus.entity(iface.getInterfaces()[0]).getName().toCql(); Select.Where where = selection.from(tableName).where(); - List p = new ArrayList(props.size()); - List c = new ArrayList(props.size()); List o = new ArrayList(props.size()); for (HelenusPropertyNode prop : props) { String columnName = prop.getColumnName(); switch (prop.getProperty().getColumnType()) { case PARTITION_KEY : - p.add(columnName); where = where.and(new IsNotNullClause(columnName)); break; case CLUSTERING_COLUMN : - c.add(columnName); where = where.and(new IsNotNullClause(columnName)); ClusteringColumn clusteringColumn = prop.getProperty().getGetterMethod() @@ -189,8 +207,7 @@ public final class SchemaUtil { } } - String primaryKey = "PRIMARY KEY (" + ((p.size() > 1) ? "(" + String.join(", ", p) + ")" : p.get(0)) - + ((c.size() > 0) ? ", " + ((c.size() > 1) ? "(" + String.join(", ", c) + ")" : c.get(0)) : "") + ")"; + String primaryKey = "PRIMARY KEY " + createPrimaryKeyPhrase(entity.getOrderedProperties()); String clustering = ""; if (o.size() > 0) { diff --git a/src/main/java/net/helenus/core/UnitOfWork.java b/src/main/java/net/helenus/core/UnitOfWork.java index 36f1291..0242a00 100644 --- a/src/main/java/net/helenus/core/UnitOfWork.java +++ b/src/main/java/net/helenus/core/UnitOfWork.java @@ -15,13 +15,10 @@ */ package net.helenus.core; -import java.util.Map; +import java.util.List; import java.util.Optional; -import java.util.Set; -import net.helenus.core.cache.BoundFacet; import net.helenus.core.cache.Facet; -import net.helenus.support.Either; public interface UnitOfWork extends AutoCloseable { @@ -56,11 +53,7 @@ public interface UnitOfWork extends AutoCloseable { boolean hasCommitted(); - Optional>> cacheLookup(String key); + Optional cacheLookup(List facets); - Optional>> cacheLookupByFacet(Set facets); - - Optional>> cacheLookupByStatement(String[] statementKeys); - - void cacheUpdate(Either> pojo, String[] statementKeys, Map facets); + void cacheUpdate(Object pojo, List facets); } diff --git a/src/main/java/net/helenus/core/cache/BoundFacet.java b/src/main/java/net/helenus/core/cache/BoundFacet.java index d6bc7d1..905a67f 100644 --- a/src/main/java/net/helenus/core/cache/BoundFacet.java +++ b/src/main/java/net/helenus/core/cache/BoundFacet.java @@ -20,15 +20,19 @@ import java.util.stream.Collectors; import net.helenus.mapping.HelenusProperty; -public class BoundFacet extends Facet { +public class BoundFacet extends Facet { private final Map properties; - BoundFacet(Map properties) { + BoundFacet(String name, Map properties) { + super(name, + (properties.keySet().size() > 1) + ? "[" + String.join(", ", + properties.keySet().stream().map(key -> properties.get(key).toString()) + .collect(Collectors.toSet())) + + "]" + : String.join("", properties.keySet().stream().map(key -> properties.get(key).toString()) + .collect(Collectors.toSet()))); this.properties = properties; } - public String toString() { - return String.join(";", - properties.keySet().stream().map(key -> properties.get(key).toString()).collect(Collectors.toSet())); - } } diff --git a/src/main/java/net/helenus/core/cache/Facet.java b/src/main/java/net/helenus/core/cache/Facet.java index fd5eaa2..d0c3e30 100644 --- a/src/main/java/net/helenus/core/cache/Facet.java +++ b/src/main/java/net/helenus/core/cache/Facet.java @@ -1,23 +1,56 @@ +/* + * Copyright (C) 2015 The Helenus Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.helenus.core.cache; -public class Facet { -} -/* - * +/** * An Entity is identifiable via one or more Facets - * + * * A Facet is is a set of Properties and bound Facets - * + * * An Entity will have it's Keyspace, Table and Schema Version Facets bound. - * + * * A property may also have a TTL or write time bound. - * + * * The cache contains key->value mappings of merkel-hash -> Entity or * Set The only way a Set is put into the cache is with a key = * hash([Entity's bound Facets, hash(filter clause from SELECT)]) - * + * * REMEMBER to update the cache on build() for all impacted facets, delete * existing keys and add new keys - * - * */ +public class Facet { + private final String name; + private T value; + + public Facet(String name) { + this.name = name; + } + + public Facet(String name, T value) { + this.name = name; + this.value = value; + } + + public String name() { + return name; + } + + public T value() { + return value; + } + +} diff --git a/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java b/src/main/java/net/helenus/core/cache/UnboundFacet.java similarity index 59% rename from src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java rename to src/main/java/net/helenus/core/cache/UnboundFacet.java index fb28dc1..e2b618b 100644 --- a/src/main/java/net/helenus/core/cache/EntityIdentifyingFacet.java +++ b/src/main/java/net/helenus/core/cache/UnboundFacet.java @@ -15,44 +15,45 @@ */ package net.helenus.core.cache; +import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; +import java.util.List; import java.util.Map; -import java.util.Set; +import net.helenus.core.SchemaUtil; import net.helenus.mapping.HelenusProperty; -public class EntityIdentifyingFacet extends Facet { +public class UnboundFacet extends Facet { - private final Set properties; + private final List properties; - public EntityIdentifyingFacet(HelenusProperty prop) { - properties = new HashSet(); - properties.add(prop); + public UnboundFacet(List properties) { + super(SchemaUtil.createPrimaryKeyPhrase(properties)); + this.properties = properties; } - public EntityIdentifyingFacet(Set props) { - properties = props; + public UnboundFacet(HelenusProperty property) { + super(property.getPropertyName()); + properties = new ArrayList(); + properties.add(property); } - public boolean isFullyBound() { - return false; - } - - public Set getProperties() { + public List getProperties() { return properties; } public Binder binder() { - return new Binder(properties); + return new Binder(name(), properties); } public static class Binder { - private final Set properties = new HashSet(); + private final String name; + private final List properties = new ArrayList(); private Map boundProperties = new HashMap(); - Binder(Set properties) { + Binder(String name, List properties) { + this.name = name; this.properties.addAll(properties); } @@ -62,12 +63,12 @@ public class EntityIdentifyingFacet extends Facet { return this; } - public boolean isFullyBound() { + public boolean isBound() { return properties.isEmpty(); } public BoundFacet bind() { - return new BoundFacet(boundProperties); + return new BoundFacet(name, boundProperties); } } } diff --git a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java index f644c2e..d74b807 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java @@ -15,8 +15,8 @@ */ package net.helenus.core.operation; +import java.util.List; import java.util.Optional; -import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.TimeoutException; @@ -80,9 +80,8 @@ public abstract class AbstractOptionalOperation facets = bindFacetValues(); - statementKeys = getQueryKeys(); - cacheResult = checkCache(uow, facets, statementKeys); + List facets = bindFacetValues(); + cacheResult = checkCache(uow, facets); if (cacheResult != null) { result = Optional.of(cacheResult); } @@ -101,7 +100,7 @@ public abstract class AbstractOptionalOperation> extends Operation { @@ -320,42 +318,16 @@ public abstract class AbstractStatementOperation uow, Set facets, String[] statementKeys) { + protected E checkCache(UnitOfWork uow, List facets) { E result = null; - Optional>> optionalCachedResult = Optional.empty(); + Optional optionalCachedResult = Optional.empty(); if (!facets.isEmpty()) { - // TODO(gburd): what about select ResultSet, Tuple... etc.? - optionalCachedResult = uow.cacheLookupByFacet(facets); + optionalCachedResult = uow.cacheLookup(facets); if (optionalCachedResult.isPresent()) { - Either> eitherCachedResult = optionalCachedResult.get(); - if (eitherCachedResult.isLeft()) { - uowCacheHits.mark(); - logger.info("UnitOfWork({}) cache hit using facets", uow.hashCode()); - result = (E) eitherCachedResult.getLeft(); - } - } - } - - if (result == null && statementKeys != null) { - // Then check to see if this query happens to uniquely identify a single object - // in thecache. - optionalCachedResult = uow.cacheLookupByStatement(statementKeys); - if (optionalCachedResult.isPresent()) { - Either> eitherCachedResult = optionalCachedResult.get(); - // Statements always store Set as the value in the cache. - if (eitherCachedResult.isRight()) { - Set cachedResult = eitherCachedResult.getRight(); - if (cachedResult.size() == 1) { - Optional maybeResult = cachedResult.stream().findFirst(); - if (maybeResult.isPresent()) { - uowCacheHits.mark(); - logger.info("UnitOfWork({}) cache hit for stmt", uow.hashCode()); - } else { - result = null; - } - } - } + uowCacheHits.mark(); + logger.info("UnitOfWork({}) cache hit using facets", uow.hashCode()); + result = (E) optionalCachedResult.get(); } } @@ -367,30 +339,29 @@ public abstract class AbstractStatementOperation uow, E pojo, Map facetMap, - String[] statementKeys) { - - // Insert this entity into the cache for each facet for this entity that we can - // fully bind. - Map boundFacets = new HashMap(); + protected void updateCache(UnitOfWork uow, E pojo, List identifyingFacets) { + List facets = new ArrayList<>(); Map valueMap = pojo instanceof MapExportable ? ((MapExportable) pojo).toMap() : null; - facetMap.forEach((facetName, facet) -> { - if (!facet.isFullyBound()) { - EntityIdentifyingFacet.Binder binder = facet.binder(); - facet.getProperties().forEach(prop -> { + + for (Facet facet : identifyingFacets) { + 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, false); - binder.setValueForProperty(prop, prop.getColumnName().toCql() + "==" + value.toString()); + binder.setValueForProperty(prop, value.toString()); } else { - binder.setValueForProperty(prop, - prop.getColumnName().toCql() + "==" + valueMap.get(prop.getPropertyName()).toString()); + binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); } + facets.add(binder.bind()); }); - boundFacets.put(facetName, binder.bind()); + } else { + facets.add(facet); } - }); + } // Cache the value (pojo), the statement key, and the fully bound facets. - uow.cacheUpdate(Either.left(pojo), statementKeys, boundFacets); + uow.cacheUpdate(pojo, facets); } } diff --git a/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java b/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java index 4f349b9..0d3e1d8 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStreamOperation.java @@ -15,7 +15,7 @@ */ package net.helenus.core.operation; -import java.util.Set; +import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.TimeoutException; @@ -76,12 +76,10 @@ public abstract class AbstractStreamOperation result = null; E cachedResult = null; - String[] statementKeys = null; if (enableCache) { - Set facets = bindFacetValues(); - statementKeys = getQueryKeys(); - cachedResult = checkCache(uow, facets, statementKeys); + List facets = bindFacetValues(); + cachedResult = checkCache(uow, facets); if (cachedResult != null) { result = Stream.of(cachedResult); } @@ -96,7 +94,7 @@ public abstract class AbstractStreamOperation extends AbstractStreamOperation bindFacetValues() { + public List bindFacetValues() { return delegate.bindFacetValues(); } diff --git a/src/main/java/net/helenus/core/operation/InsertOperation.java b/src/main/java/net/helenus/core/operation/InsertOperation.java index 4812df3..c92dac4 100644 --- a/src/main/java/net/helenus/core/operation/InsertOperation.java +++ b/src/main/java/net/helenus/core/operation/InsertOperation.java @@ -236,23 +236,6 @@ public final class InsertOperation extends AbstractOperation keys = new ArrayList<>(values.size()); - values.forEach(t -> { - HelenusPropertyNode prop = t._1; - switch (prop.getProperty().getColumnType()) { - case PARTITION_KEY : - case CLUSTERING_COLUMN : - keys.add(entity.getName().toCql() + '.' + prop.getColumnName() + "==" + t._2.toString()); - break; - default : - break; - } - }); - return keys.toArray(new String[keys.size()]); - } - @Override public T sync(UnitOfWork uow) throws TimeoutException { if (uow == null) { @@ -261,7 +244,7 @@ public final class InsertOperation extends AbstractOperation iface = entity.getMappingInterface(); if (resultType == iface) { - updateCache(uow, result, entity.getIdentifyingFacets(), getQueryKeys()); + updateCache(uow, result, entity.getFacets()); } return result; } diff --git a/src/main/java/net/helenus/core/operation/Operation.java b/src/main/java/net/helenus/core/operation/Operation.java index 0953dc7..a9f1b51 100644 --- a/src/main/java/net/helenus/core/operation/Operation.java +++ b/src/main/java/net/helenus/core/operation/Operation.java @@ -15,8 +15,7 @@ */ package net.helenus.core.operation; -import java.util.Map; -import java.util.Set; +import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -32,7 +31,6 @@ import brave.Tracer; import brave.propagation.TraceContext; import net.helenus.core.AbstractSessionOperations; import net.helenus.core.UnitOfWork; -import net.helenus.core.cache.EntityIdentifyingFacet; import net.helenus.core.cache.Facet; public abstract class Operation { @@ -87,15 +85,12 @@ public abstract class Operation { return null; } - public String[] getQueryKeys() { + public List getFacets() { return null; } - public Map getIdentifyingFacets() { + public List bindFacetValues() { return null; } - public Set bindFacetValues() { - return null; - } } diff --git a/src/main/java/net/helenus/core/operation/SelectFirstOperation.java b/src/main/java/net/helenus/core/operation/SelectFirstOperation.java index e34d933..1419218 100644 --- a/src/main/java/net/helenus/core/operation/SelectFirstOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectFirstOperation.java @@ -15,15 +15,13 @@ */ package net.helenus.core.operation; -import java.util.Map; +import java.util.List; import java.util.Optional; -import java.util.Set; import java.util.function.Function; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.BuiltStatement; -import net.helenus.core.cache.EntityIdentifyingFacet; import net.helenus.core.cache.Facet; public final class SelectFirstOperation extends AbstractFilterOptionalOperation> { @@ -48,17 +46,12 @@ public final class SelectFirstOperation extends AbstractFilterOptionalOperati } @Override - public String[] getQueryKeys() { - return delegate.getQueryKeys(); + public List getFacets() { + return delegate.getFacets(); } @Override - public Map getIdentifyingFacets() { - return delegate.getIdentifyingFacets(); - } - - @Override - public Set bindFacetValues() { + public List bindFacetValues() { return delegate.bindFacetValues(); } diff --git a/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java b/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java index 15dfed5..038324a 100644 --- a/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectFirstTransformingOperation.java @@ -15,8 +15,8 @@ */ package net.helenus.core.operation; +import java.util.List; import java.util.Optional; -import java.util.Set; import java.util.function.Function; import com.datastax.driver.core.ResultSet; @@ -41,12 +41,7 @@ public final class SelectFirstTransformingOperation } @Override - public String[] getQueryKeys() { - return delegate.getQueryKeys(); - } - - @Override - public Set bindFacetValues() { + public List bindFacetValues() { return delegate.bindFacetValues(); } diff --git a/src/main/java/net/helenus/core/operation/SelectOperation.java b/src/main/java/net/helenus/core/operation/SelectOperation.java index 1a9908e..59709fe 100644 --- a/src/main/java/net/helenus/core/operation/SelectOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectOperation.java @@ -31,8 +31,8 @@ import com.datastax.driver.core.querybuilder.Select.Where; import com.google.common.collect.Iterables; import net.helenus.core.*; -import net.helenus.core.cache.EntityIdentifyingFacet; 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.MappingUtil; @@ -177,31 +177,37 @@ public final class SelectOperation extends AbstractFilterStreamOperation getIdentifyingFacets() { + public List getFacets() { HelenusEntity entity = props.get(0).getEntity(); - return entity.getIdentifyingFacets(); + return entity.getFacets(); } @Override - public Set bindFacetValues() { + public List bindFacetValues() { HelenusEntity entity = props.get(0).getEntity(); - Set boundFacets = new HashSet(); - // Check to see if this select statement has enough information to build one or - // more identifying facets. - entity.getIdentifyingFacets().forEach((facetName, facet) -> { - EntityIdentifyingFacet.Binder binder = facet.binder(); - facet.getProperties().forEach(prop -> { - Filter filter = filters.get(prop); - if (filter != null) { - binder.setValueForProperty(prop, filter.toString()); - } else if (facetName.equals("*")) { - binder.setValueForProperty(prop, ""); + 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 -> { + Filter filter = filters.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()); } - }); - if (binder.isFullyBound()) { - boundFacets.add(binder.bind()); + } else { + boundFacets.add(facet); } - }); + } return boundFacets; } diff --git a/src/main/java/net/helenus/core/operation/SelectTransformingOperation.java b/src/main/java/net/helenus/core/operation/SelectTransformingOperation.java index 1d43ae9..4a7720e 100644 --- a/src/main/java/net/helenus/core/operation/SelectTransformingOperation.java +++ b/src/main/java/net/helenus/core/operation/SelectTransformingOperation.java @@ -15,15 +15,13 @@ */ package net.helenus.core.operation; -import java.util.Map; -import java.util.Set; +import java.util.List; import java.util.function.Function; import java.util.stream.Stream; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.BuiltStatement; -import net.helenus.core.cache.EntityIdentifyingFacet; import net.helenus.core.cache.Facet; public final class SelectTransformingOperation @@ -43,18 +41,13 @@ public final class SelectTransformingOperation } @Override - public String[] getQueryKeys() { - return delegate.getQueryKeys(); - } - - @Override - public Set bindFacetValues() { + public List bindFacetValues() { return delegate.bindFacetValues(); } @Override - public Map getIdentifyingFacets() { - return delegate.getIdentifyingFacets(); + public List getFacets() { + return delegate.getFacets(); } @Override diff --git a/src/main/java/net/helenus/core/operation/UpdateOperation.java b/src/main/java/net/helenus/core/operation/UpdateOperation.java index 9237526..e7a2822 100644 --- a/src/main/java/net/helenus/core/operation/UpdateOperation.java +++ b/src/main/java/net/helenus/core/operation/UpdateOperation.java @@ -578,7 +578,7 @@ public final class UpdateOperation extends AbstractFilterOperation getIdentifyingFacets(); + List getFacets(); } diff --git a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java index 509cac2..87797f1 100644 --- a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java @@ -28,7 +28,8 @@ import com.google.common.collect.ImmutableMap; import net.helenus.config.HelenusSettings; import net.helenus.core.Helenus; import net.helenus.core.annotation.Cacheable; -import net.helenus.core.cache.EntityIdentifyingFacet; +import net.helenus.core.cache.Facet; +import net.helenus.core.cache.UnboundFacet; import net.helenus.mapping.annotation.*; import net.helenus.support.HelenusMappingException; @@ -41,9 +42,7 @@ public final class HelenusMappingEntity implements HelenusEntity { private final ImmutableMap methods; private final ImmutableMap props; private final ImmutableList orderedProps; - private final EntityIdentifyingFacet primaryIdentityFacet; - private final ImmutableMap allIdentityFacets; - private final ImmutableMap ancillaryIdentityFacets; + private final List facets; public HelenusMappingEntity(Class iface, Metadata metadata) { this(iface, autoDetectType(iface), metadata); @@ -112,33 +111,31 @@ public final class HelenusMappingEntity implements HelenusEntity { // Caching cacheable = (null != iface.getDeclaredAnnotation(Cacheable.class)); - ImmutableMap.Builder allFacetsBuilder = ImmutableMap.builder(); - ImmutableMap.Builder ancillaryFacetsBuilder = ImmutableMap.builder(); - EntityIdentifyingFacet primaryFacet = null; - List primaryProperties = new ArrayList(4); - for (HelenusProperty prop : propsLocal) { + List primaryKeyProperties = new ArrayList<>(); + ImmutableList.Builder facetsBuilder = ImmutableList.builder(); + facetsBuilder.add(new Facet("table", name.toCql())); + for (HelenusProperty prop : orderedProps) { switch (prop.getColumnType()) { case PARTITION_KEY : case CLUSTERING_COLUMN : - primaryProperties.add(prop); + primaryKeyProperties.add(prop); break; default : - if (primaryProperties != null) { - primaryFacet = new EntityIdentifyingFacet(new HashSet(primaryProperties)); - allFacetsBuilder.put("*", primaryFacet); - primaryProperties = null; + if (primaryKeyProperties != null && primaryKeyProperties.size() > 0) { + facetsBuilder.add(new UnboundFacet(primaryKeyProperties)); + primaryKeyProperties = null; } Optional optionalIndexName = prop.getIndexName(); if (optionalIndexName.isPresent()) { - EntityIdentifyingFacet facet = new EntityIdentifyingFacet(prop); - ancillaryFacetsBuilder.put(prop.getPropertyName(), facet); - allFacetsBuilder.put(prop.getPropertyName(), facet); + UnboundFacet facet = new UnboundFacet(prop); + facetsBuilder.add(facet); } } } - this.primaryIdentityFacet = primaryFacet; - this.ancillaryIdentityFacets = ancillaryFacetsBuilder.build(); - this.allIdentityFacets = allFacetsBuilder.build(); + if (primaryKeyProperties != null && primaryKeyProperties.size() > 0) { + facetsBuilder.add(new UnboundFacet(primaryKeyProperties)); + } + this.facets = facetsBuilder.build(); } @Override @@ -172,8 +169,8 @@ public final class HelenusMappingEntity implements HelenusEntity { } @Override - public Map getIdentifyingFacets() { - return allIdentityFacets; + public List getFacets() { + return facets; } @Override