| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 org.apache.cassandra.cql3.functions.types; |
| |
| import java.math.BigDecimal; |
| import java.math.BigInteger; |
| import java.net.InetAddress; |
| import java.nio.ByteBuffer; |
| import java.util.*; |
| |
| import com.google.common.reflect.TypeToken; |
| |
| import org.apache.cassandra.transport.ProtocolVersion; |
| import org.apache.cassandra.cql3.functions.types.exceptions.InvalidTypeException; |
| |
| abstract class AbstractGettableByIndexData implements GettableByIndexData |
| { |
| |
| protected final ProtocolVersion protocolVersion; |
| |
| AbstractGettableByIndexData(ProtocolVersion protocolVersion) |
| { |
| this.protocolVersion = protocolVersion; |
| } |
| |
| /** |
| * Returns the type for the value at index {@code i}. |
| * |
| * @param i the index of the type to fetch. |
| * @return the type of the value at index {@code i}. |
| * @throws IndexOutOfBoundsException if {@code i} is not a valid index. |
| */ |
| protected abstract DataType getType(int i); |
| |
| /** |
| * Returns the name corresponding to the value at index {@code i}. |
| * |
| * @param i the index of the name to fetch. |
| * @return the name corresponding to the value at index {@code i}. |
| * @throws IndexOutOfBoundsException if {@code i} is not a valid index. |
| */ |
| protected abstract String getName(int i); |
| |
| /** |
| * Returns the value at index {@code i}. |
| * |
| * @param i the index to fetch. |
| * @return the value at index {@code i}. |
| * @throws IndexOutOfBoundsException if {@code i} is not a valid index. |
| */ |
| protected abstract ByteBuffer getValue(int i); |
| |
| protected abstract CodecRegistry getCodecRegistry(); |
| |
| protected <T> TypeCodec<T> codecFor(int i) |
| { |
| return getCodecRegistry().codecFor(getType(i)); |
| } |
| |
| protected <T> TypeCodec<T> codecFor(int i, Class<T> javaClass) |
| { |
| return getCodecRegistry().codecFor(getType(i), javaClass); |
| } |
| |
| protected <T> TypeCodec<T> codecFor(int i, TypeToken<T> javaType) |
| { |
| return getCodecRegistry().codecFor(getType(i), javaType); |
| } |
| |
| protected <T> TypeCodec<T> codecFor(int i, T value) |
| { |
| return getCodecRegistry().codecFor(getType(i), value); |
| } |
| |
| void checkType(int i, DataType.Name actual) |
| { |
| DataType.Name expected = getType(i).getName(); |
| if (!actual.isCompatibleWith(expected)) |
| throw new InvalidTypeException( |
| String.format("Value %s is of type %s, not %s", getName(i), expected, actual)); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public boolean isNull(int i) |
| { |
| return getValue(i) == null; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public boolean getBool(int i) |
| { |
| ByteBuffer value = getValue(i); |
| TypeCodec<Boolean> codec = codecFor(i, Boolean.class); |
| if (codec instanceof TypeCodec.PrimitiveBooleanCodec) |
| return ((TypeCodec.PrimitiveBooleanCodec) codec).deserializeNoBoxing(value, protocolVersion); |
| else return codec.deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public byte getByte(int i) |
| { |
| ByteBuffer value = getValue(i); |
| TypeCodec<Byte> codec = codecFor(i, Byte.class); |
| if (codec instanceof TypeCodec.PrimitiveByteCodec) |
| return ((TypeCodec.PrimitiveByteCodec) codec).deserializeNoBoxing(value, protocolVersion); |
| else return codec.deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public short getShort(int i) |
| { |
| ByteBuffer value = getValue(i); |
| TypeCodec<Short> codec = codecFor(i, Short.class); |
| if (codec instanceof TypeCodec.PrimitiveShortCodec) |
| return ((TypeCodec.PrimitiveShortCodec) codec).deserializeNoBoxing(value, protocolVersion); |
| else return codec.deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public int getInt(int i) |
| { |
| ByteBuffer value = getValue(i); |
| TypeCodec<Integer> codec = codecFor(i, Integer.class); |
| if (codec instanceof TypeCodec.PrimitiveIntCodec) |
| return ((TypeCodec.PrimitiveIntCodec) codec).deserializeNoBoxing(value, protocolVersion); |
| else return codec.deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public long getLong(int i) |
| { |
| ByteBuffer value = getValue(i); |
| TypeCodec<Long> codec = codecFor(i, Long.class); |
| if (codec instanceof TypeCodec.PrimitiveLongCodec) |
| return ((TypeCodec.PrimitiveLongCodec) codec).deserializeNoBoxing(value, protocolVersion); |
| else return codec.deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public Date getTimestamp(int i) |
| { |
| ByteBuffer value = getValue(i); |
| return codecFor(i, Date.class).deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public LocalDate getDate(int i) |
| { |
| ByteBuffer value = getValue(i); |
| return codecFor(i, LocalDate.class).deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public long getTime(int i) |
| { |
| ByteBuffer value = getValue(i); |
| TypeCodec<Long> codec = codecFor(i, Long.class); |
| if (codec instanceof TypeCodec.PrimitiveLongCodec) |
| return ((TypeCodec.PrimitiveLongCodec) codec).deserializeNoBoxing(value, protocolVersion); |
| else return codec.deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public float getFloat(int i) |
| { |
| ByteBuffer value = getValue(i); |
| TypeCodec<Float> codec = codecFor(i, Float.class); |
| if (codec instanceof TypeCodec.PrimitiveFloatCodec) |
| return ((TypeCodec.PrimitiveFloatCodec) codec).deserializeNoBoxing(value, protocolVersion); |
| else return codec.deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public double getDouble(int i) |
| { |
| ByteBuffer value = getValue(i); |
| TypeCodec<Double> codec = codecFor(i, Double.class); |
| if (codec instanceof TypeCodec.PrimitiveDoubleCodec) |
| return ((TypeCodec.PrimitiveDoubleCodec) codec).deserializeNoBoxing(value, protocolVersion); |
| else return codec.deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public ByteBuffer getBytesUnsafe(int i) |
| { |
| ByteBuffer value = getValue(i); |
| if (value == null) return null; |
| return value.duplicate(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public ByteBuffer getBytes(int i) |
| { |
| ByteBuffer value = getValue(i); |
| return codecFor(i, ByteBuffer.class).deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public String getString(int i) |
| { |
| ByteBuffer value = getValue(i); |
| return codecFor(i, String.class).deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public BigInteger getVarint(int i) |
| { |
| ByteBuffer value = getValue(i); |
| return codecFor(i, BigInteger.class).deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public BigDecimal getDecimal(int i) |
| { |
| ByteBuffer value = getValue(i); |
| return codecFor(i, BigDecimal.class).deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public UUID getUUID(int i) |
| { |
| ByteBuffer value = getValue(i); |
| return codecFor(i, UUID.class).deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public InetAddress getInet(int i) |
| { |
| ByteBuffer value = getValue(i); |
| return codecFor(i, InetAddress.class).deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> List<T> getList(int i, Class<T> elementsClass) |
| { |
| return getList(i, TypeToken.of(elementsClass)); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> List<T> getList(int i, TypeToken<T> elementsType) |
| { |
| ByteBuffer value = getValue(i); |
| TypeToken<List<T>> javaType = TypeTokens.listOf(elementsType); |
| return codecFor(i, javaType).deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> Set<T> getSet(int i, Class<T> elementsClass) |
| { |
| return getSet(i, TypeToken.of(elementsClass)); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> Set<T> getSet(int i, TypeToken<T> elementsType) |
| { |
| ByteBuffer value = getValue(i); |
| TypeToken<Set<T>> javaType = TypeTokens.setOf(elementsType); |
| return codecFor(i, javaType).deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| @SuppressWarnings("unchecked") |
| public <K, V> Map<K, V> getMap(int i, Class<K> keysClass, Class<V> valuesClass) |
| { |
| return getMap(i, TypeToken.of(keysClass), TypeToken.of(valuesClass)); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| @SuppressWarnings("unchecked") |
| public <K, V> Map<K, V> getMap(int i, TypeToken<K> keysType, TypeToken<V> valuesType) |
| { |
| ByteBuffer value = getValue(i); |
| TypeToken<Map<K, V>> javaType = TypeTokens.mapOf(keysType, valuesType); |
| return codecFor(i, javaType).deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| @SuppressWarnings("unchecked") |
| public UDTValue getUDTValue(int i) |
| { |
| ByteBuffer value = getValue(i); |
| return codecFor(i, UDTValue.class).deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| @SuppressWarnings("unchecked") |
| public TupleValue getTupleValue(int i) |
| { |
| ByteBuffer value = getValue(i); |
| return codecFor(i, TupleValue.class).deserialize(value, protocolVersion); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public Object getObject(int i) |
| { |
| return get(i, codecFor(i)); |
| } |
| |
| @Override |
| public <T> T get(int i, Class<T> targetClass) |
| { |
| return get(i, codecFor(i, targetClass)); |
| } |
| |
| @Override |
| public <T> T get(int i, TypeToken<T> targetType) |
| { |
| return get(i, codecFor(i, targetType)); |
| } |
| |
| @Override |
| public <T> T get(int i, TypeCodec<T> codec) |
| { |
| checkType(i, codec.getCqlType().getName()); |
| ByteBuffer value = getValue(i); |
| return codec.deserialize(value, protocolVersion); |
| } |
| } |