/** * Returns a {@link String} representation of the given {@link Map} key * * @param key * @return */ private String potentiallyConvertMapKey(Object key) { if (key instanceof String) { return (String) key; } return conversions.hasCustomWriteTarget(key.getClass(), String.class) ? (String) getPotentiallyConvertedSimpleWrite(key) : key.toString(); }
/** * Check if a given type requires a type hint (aka {@literal _class} attribute) when writing to the document. * * @param type must not be {@literal null}. * @return {@literal true} if not a simple type, {@link Collection} or type with custom write target. */ private boolean requiresTypeHint(Class<?> type) { return !conversions.isSimpleType(type) && !ClassUtils.isAssignable(Collection.class, type) && !conversions.hasCustomWriteTarget(type, Document.class); }
/** * @param keyspace * @param path * @param mapValueType * @param source * @param sink */ private void writeMap(String keyspace, String path, Class<?> mapValueType, Map<?, ?> source, RedisData sink) { if (CollectionUtils.isEmpty(source)) { return; } for (Map.Entry<?, ?> entry : source.entrySet()) { if (entry.getValue() == null || entry.getKey() == null) { continue; } String currentPath = path + ".[" + mapMapKey(entry.getKey()) + "]"; if (!ClassUtils.isAssignable(mapValueType, entry.getValue().getClass())) { throw new MappingException( String.format(INVALID_TYPE_ASSIGNMENT, entry.getValue().getClass(), currentPath, mapValueType)); } if (customConversions.hasCustomWriteTarget(entry.getValue().getClass())) { writeToBucket(currentPath, entry.getValue(), sink, mapValueType); } else { writeInternal(keyspace, currentPath, entry.getValue(), ClassTypeInformation.from(mapValueType), sink); } } }
private void writeToBucket(String path, @Nullable Object value, RedisData sink, Class<?> propertyType) { if (value == null || (value instanceof Optional && !((Optional<?>) value).isPresent())) { return; } if (customConversions.hasCustomWriteTarget(value.getClass())) { Optional<Class<?>> targetType = customConversions.getCustomWriteTarget(value.getClass()); if (!propertyType.isPrimitive() && !targetType.filter(it -> ClassUtils.isAssignable(Map.class, it)).isPresent() && customConversions.isSimpleType(value.getClass()) && value.getClass() != propertyType) { typeMapper.writeType(value.getClass(), sink.getBucket().getPropertyPath(path)); } if (targetType.filter(it -> ClassUtils.isAssignable(Map.class, it)).isPresent()) { Map<?, ?> map = (Map<?, ?>) conversionService.convert(value, targetType.get()); for (Map.Entry<?, ?> entry : map.entrySet()) { sink.getBucket().put(path + (StringUtils.hasText(path) ? "." : "") + entry.getKey(), toBytes(entry.getValue())); } } else if (targetType.filter(it -> ClassUtils.isAssignable(byte[].class, it)).isPresent()) { sink.getBucket().put(path, toBytes(value)); } else { throw new IllegalArgumentException( String.format("Cannot convert value '%s' of type %s to bytes.", value, value.getClass())); } } }
/** * @param keyspace * @param path * @param values * @param typeHint * @param sink */ private void writeCollection(String keyspace, String path, @Nullable Iterable<?> values, TypeInformation<?> typeHint, RedisData sink) { if (values == null) { return; } int i = 0; for (Object value : values) { if (value == null) { break; } String currentPath = path + ".[" + i + "]"; if (!ClassUtils.isAssignable(typeHint.getType(), value.getClass())) { throw new MappingException( String.format(INVALID_TYPE_ASSIGNMENT, value.getClass(), currentPath, typeHint.getType())); } if (customConversions.hasCustomWriteTarget(value.getClass())) { writeToBucket(currentPath, value, sink, typeHint.getType()); } else { writeInternal(keyspace, currentPath, value, typeHint, sink); } i++; } }
if (customConversions.hasCustomWriteTarget(value.getClass())) {
/** * Returns a {@link String} representation of the given {@link Map} key * * @param key * @return */ private String potentiallyConvertMapKey(Object key) { if (key instanceof String) { return (String) key; } return conversions.hasCustomWriteTarget(key.getClass(), String.class) ? (String) getPotentiallyConvertedSimpleWrite(key) : key.toString(); }
if (!customConversions.hasCustomWriteTarget(source.getClass())) { typeMapper.writeType(ClassUtils.getUserClass(source), sink.getBucket().getPath());
/** * Check if a given type requires a type hint (aka {@literal _class} attribute) when writing to the document. * * @param type must not be {@literal null}. * @return {@literal true} if not a simple type, {@link Collection} or type with custom write target. */ private boolean requiresTypeHint(Class<?> type) { return !conversions.isSimpleType(type) && !ClassUtils.isAssignable(Collection.class, type) && !conversions.hasCustomWriteTarget(type, Document.class); }
/** * @param sourceType * @return true if custom write target defined in {@link #customConversions} */ protected boolean hasCustomWriteTarget(Class<?> sourceType) { return this.customConversions.hasCustomWriteTarget(sourceType); }
/** * @param sourceType * @param targetType * @return true if custom write target defined in {@link #customConversions} */ protected boolean hasCustomWriteTarget(Class<?> sourceType, Class<?> targetType) { return this.customConversions.hasCustomWriteTarget(sourceType, targetType); }
private boolean isValidId(final Object key) { if (key == null) { return false; } final Class<?> type = key.getClass(); if (DBDocumentEntity.class.isAssignableFrom(type)) { return false; } else if (VPackSlice.class.isAssignableFrom(type)) { return false; } else if (type.isArray() && type.getComponentType() != byte.class) { return false; } else if (isSimpleType(type)) { return true; } else { return conversions.hasCustomWriteTarget(key.getClass(), String.class); } }
private boolean isValidId(final Object key) { if (key == null) { return false; } final Class<?> type = key.getClass(); if (DBDocumentEntity.class.isAssignableFrom(type)) { return false; } else if (VPackSlice.class.isAssignableFrom(type)) { return false; } else if (type.isArray() && type.getComponentType() != byte.class) { return false; } else if (isSimpleType(type)) { return true; } else { return conversions.hasCustomWriteTarget(key.getClass(), String.class); } }
@Override public String convertId(final Object id) { if (!isValidId(id)) { throw new MappingException( String.format("Type %s is not a valid id type!", id != null ? id.getClass() : "null")); } if (id instanceof String) { return id.toString(); } final boolean hasCustomConverter = conversions.hasCustomWriteTarget(id.getClass(), String.class); return hasCustomConverter ? conversionService.convert(id, String.class) : id.toString(); }
@Override public String convertId(final Object id) { if (!isValidId(id)) { throw new MappingException( String.format("Type %s is not a valid id type!", id != null ? id.getClass() : "null")); } if (id instanceof String) { return id.toString(); } final boolean hasCustomConverter = conversions.hasCustomWriteTarget(id.getClass(), String.class); return hasCustomConverter ? conversionService.convert(id, String.class) : id.toString(); }
@Override protected boolean shouldCreatePersistentEntityFor(TypeInformation<?> typeInfo) { return !this.customConversions.hasCustomWriteTarget(typeInfo.getType()) && super.shouldCreatePersistentEntityFor(typeInfo); }
/** * @param keyspace * @param path * @param mapValueType * @param source * @param sink */ private void writeMap(String keyspace, String path, Class<?> mapValueType, Map<?, ?> source, RedisData sink) { if (CollectionUtils.isEmpty(source)) { return; } for (Map.Entry<?, ?> entry : source.entrySet()) { if (entry.getValue() == null || entry.getKey() == null) { continue; } String currentPath = path + ".[" + mapMapKey(entry.getKey()) + "]"; if (!ClassUtils.isAssignable(mapValueType, entry.getValue().getClass())) { throw new MappingException( String.format(INVALID_TYPE_ASSIGNMENT, entry.getValue().getClass(), currentPath, mapValueType)); } if (customConversions.hasCustomWriteTarget(entry.getValue().getClass())) { writeToBucket(currentPath, entry.getValue(), sink, mapValueType); } else { writeInternal(keyspace, currentPath, entry.getValue(), ClassTypeInformation.from(mapValueType), sink); } } }
@Override public void write(Object source, SecretDocument sink) { Class<?> entityType = ClassUtils.getUserClass(source.getClass()); TypeInformation<? extends Object> type = ClassTypeInformation.from(entityType); SecretDocumentAccessor documentAccessor = new SecretDocumentAccessor(sink); writeInternal(source, documentAccessor, type); boolean handledByCustomConverter = conversions.hasCustomWriteTarget(entityType, SecretDocument.class); if (!handledByCustomConverter) { typeMapper.writeType(type, sink.getBody()); } }
boolean isProjecting() { if (!this.returnedType.isProjecting()) { return false; } // Spring Data Cassandra allows List<Map<String, Object> and Map<String, Object> declarations // on query methods so we don't want to let projection kick in if (ClassUtils.isAssignable(Map.class, this.returnedType.getReturnedType())) { return false; } // Type conversion using registered conversions is handled on template level if (this.customConversions.hasCustomWriteTarget(this.returnedType.getReturnedType())) { return false; } // Don't apply projection on Cassandra simple types return !this.customConversions.isSimpleType(this.returnedType.getReturnedType()); }
boolean isProjecting() { if (!returnedType.isProjecting()) { return false; } // Spring Data Cassandra allows List<Map<String, Object> and Map<String, Object> declarations // on query methods so we don't want to let projection kick in if (ClassUtils.isAssignable(Map.class, returnedType.getReturnedType())) { return false; } // Type conversion using registered conversions is handled on template level if (customConversions.hasCustomWriteTarget(returnedType.getReturnedType())) { return false; } // Don't apply projection on Cassandra simple types return !customConversions.isSimpleType(returnedType.getReturnedType()); }