private static boolean typesEquals(DataType t1, DataType t2) { if (t1.isCollection() && t2.isCollection()) { final List<DataType> t1Args = t1.getTypeArguments(); final List<DataType> t2Args = t2.getTypeArguments(); if (t1Args.size() == t2Args.size()) { boolean eq = true; for (int i = 0; i < t1Args.size(); i++) { eq &= typesEquals(t1Args.get(i), t2Args.get(i)); } return eq; } } final Class<?> jTableCls = t1.asJavaClass(); final Class<?> jColumnCls = t2.asJavaClass(); return Objects.equals(jTableCls, jColumnCls); }
static boolean isBuildInType(DataType dataType) { if (dataType.isCollection()) { for (DataType type : dataType.getTypeArguments()) { if (!isBuildInType(type)) { return false; } } return true; } else { return DataType.allPrimitiveTypes().contains(dataType) || (TupleType.class.isAssignableFrom(dataType.getClass())); } }
@SuppressWarnings("unchecked") @Override public <P> Getter<GettableByIndexData, P> newGetter( Type target, DatastaxColumnKey key, ColumnDefinition<?, ?> columnDefinition) { Class<?> targetClass = TypeHelper.toClass(target); if (Date.class.equals(targetClass)) { return (Getter<GettableByIndexData, P>) new DatastaxDateGetter(key.getIndex()); } if (boolean.class.equals(targetClass) || Boolean.class.equals(targetClass)) { return (Getter<GettableByIndexData, P>) new DatastaxBooleanGetter(key.getIndex()); } if (InetAddress.class.equals(targetClass)) { return (Getter<GettableByIndexData, P>) new DatastaxInetAddressGetter(key.getIndex()); } if (TupleValue.class.equals(targetClass)) { return (Getter<GettableByIndexData, P>) new DatastaxTupleValueGetter(key.getIndex()); } if (Collection.class.isAssignableFrom(targetClass)) { Type elementType = TypeHelper.getComponentTypeOfListOrArray(target); Class<?> dataTypeClass = Object.class; Class<?> dataTypeElt = null; DataType dtElt = null; if (key.getDataType() != null) { DataType dataType = key.getDataType(); dataTypeClass = dataType.asJavaClass(); if (dataType.isCollection()) { dtElt = key.getDataType().getTypeArguments().get(0); dataTypeElt = dtElt.asJavaClass(); } } else { dataTypeElt = TypeHelper.toClass(elementType); } if (dataTypeElt != null) { if (TypeHelper.areEquals(elementType, dataTypeElt)) { if (Set.class.equals(dataTypeClass)) { if (targetClass.isAssignableFrom(dataTypeClass)) { return new DatastaxSetGetter(key.getIndex(), TypeHelper.toClass(elementType)); } } if (List.class.equals(dataTypeClass)) { if (targetClass.isAssignableFrom(dataTypeClass)) { return new DatastaxListGetter(key.getIndex(), TypeHelper.toClass(elementType)); } } } else { Converter<?, ?> converter = getConverter(elementType, dataTypeElt, dtElt); if (converter != null) { if (Set.class.equals(dataTypeClass)) { if (targetClass.isAssignableFrom(dataTypeClass)) { return new DatastaxSetWithConverterGetter(key.getIndex(), dataTypeElt, converter); } } if (List.class.equals(dataTypeClass)) { if (targetClass.isAssignableFrom(dataTypeClass)) { return new DatastaxListWithConverterGetter(key.getIndex(), dataTypeElt, converter); } } } } } } if (Map.class.equals(targetClass)) { Tuple2<Type, Type> keyValueTypeOfMap = TypeHelper.getKeyValueTypeOfMap(target); Class<?> dtKeyType = null; Class<?> dtValueType = null; DataType dtKey = null; DataType dtValue = null; if (key.getDataType() != null) { List<DataType> typeArguments = key.getDataType().getTypeArguments(); if (typeArguments.size() == 2) { dtKey = typeArguments.get(0); dtKeyType = dtKey.asJavaClass(); dtValue = typeArguments.get(1); dtValueType = dtValue.asJavaClass(); } } else { dtKeyType = TypeHelper.toClass(keyValueTypeOfMap.first()); dtValueType = TypeHelper.toClass(keyValueTypeOfMap.second()); } if (dtKeyType != null && dtValueType != null) { if (TypeHelper.areEquals(keyValueTypeOfMap.first(), dtKeyType) && TypeHelper.areEquals(keyValueTypeOfMap.second(), dtValueType)) { return new DatastaxMapGetter( key.getIndex(), TypeHelper.toClass(keyValueTypeOfMap.first()), TypeHelper.toClass(keyValueTypeOfMap.second())); } else { Converter<?, ?> keyConverter = getConverter(keyValueTypeOfMap.first(), dtKeyType, dtKey); Converter<?, ?> valueConverter = getConverter(keyValueTypeOfMap.second(), dtValueType, dtValue); if (keyConverter != null && valueConverter != null) { return new DatastaxMapWithConverterGetter( key.getIndex(), dtKeyType, dtValueType, keyConverter, valueConverter); } } } } if (Tuples.isTuple(target)) { if (key.getDataType() != null && key.getDataType() instanceof TupleType) { TupleType tt = (TupleType) key.getDataType(); List<DataType> typeArguments = tt.getTypeArguments(); TypeVariable<? extends Class<?>>[] typeParameters = targetClass.getTypeParameters(); if (typeArguments.size() <= typeParameters.length) { return (Getter<GettableByIndexData, P>) DatastaxTupleGetter.newInstance(datastaxMapperFactory, target, tt, key.getIndex()); } } } if (TypeHelper.isEnum(target)) { final Getter<GettableByIndexData, ? extends Enum> getter = enumGetter(key, TypeHelper.toClass(target)); if (getter != null) { return (Getter<GettableByIndexData, P>) getter; } } final GetterFactory<GettableByIndexData, DatastaxColumnKey> rowGetterFactory = getterFactories.get(targetClass); if (rowGetterFactory != null) { return rowGetterFactory.newGetter(target, key, columnDefinition); } final Getter<GettableByIndexData, P> getter = jodaTimeGetterFactory.newGetter(target, key, columnDefinition); if (getter != null) { return getter; } if (key.getDataType() != null && key.getDataType() instanceof UserType) { UserType ut = (UserType) key.getDataType(); return (Getter<GettableByIndexData, P>) DatastaxUDTGetter.newInstance(datastaxMapperFactory, target, ut, key.getIndex()); } return null; }
/** * @param datatype the db datatype * @param udtValue the udt value * @param fieldtype1 the field 1 type * @param fieldtype2 the field 2 type * @param fieldname the fieldname * @return the mapped value or <code>null</code> */ public <T> Object fromUdtValue( DataType datatype, UDTValue udtValue, Class<?> fieldtype1, Class<?> fieldtype2, String fieldname) { final CodecRegistry codecRegistry = getCodecRegistry(); // build-in type if (isBuildInType(datatype)) { final TypeCodec<T> typeCodec = codecRegistry.codecFor(datatype); try { if (udtValue.isNull(fieldname)) return null; return typeCodec.deserialize(udtValue.getBytesUnsafe(fieldname), protocolVersion); } catch (IllegalArgumentException ex) { return null; } // udt collection } else if (datatype.isCollection()) { // set if (DataType.Name.SET == datatype.getName()) { return fromUdtValues( datatype.getTypeArguments().get(0), ImmutableSet.copyOf(udtValue.getSet(fieldname, UDTValue.class)), fieldtype2); // list } else if (DataType.Name.LIST == datatype.getName()) { return fromUdtValues( datatype.getTypeArguments().get(0), ImmutableList.copyOf(udtValue.getList(fieldname, UDTValue.class)), fieldtype2); // map } else { if (isBuildInType(datatype.getTypeArguments().get(0))) { return fromUdtValues( datatype.getTypeArguments().get(0), datatype.getTypeArguments().get(1), ImmutableMap.<Object, Object>copyOf( udtValue.getMap(fieldname, fieldtype1, UDTValue.class)), fieldtype1, fieldtype2); } else if (isBuildInType(datatype.getTypeArguments().get(1))) { return fromUdtValues( datatype.getTypeArguments().get(0), datatype.getTypeArguments().get(1), ImmutableMap.<Object, Object>copyOf( udtValue.getMap(fieldname, UDTValue.class, fieldtype2)), fieldtype1, fieldtype2); } else { return fromUdtValues( datatype.getTypeArguments().get(0), datatype.getTypeArguments().get(1), ImmutableMap.<Object, Object>copyOf( udtValue.getMap(fieldname, UDTValue.class, UDTValue.class)), fieldtype1, fieldtype2); } } // udt } else { return fromUdtValue(datatype, udtValue, fieldtype1); } }
@SuppressWarnings("unchecked") public Object toUdtValue( Tablename tablename, MetadataCatalog catalog, DataType datatype, Object value) { // build-in type (will not be converted) if (isBuildInType(datatype)) { return value; // udt collection } else if (datatype.isCollection()) { // set if (DataType.Name.SET == datatype.getName()) { final DataType elementDataType = datatype.getTypeArguments().get(0); final Set<Object> udt = Sets.newHashSet(); if (value != null) { for (Object element : (Set<Object>) value) { udt.add(toUdtValue(tablename, catalog, elementDataType, element)); } } return ImmutableSet.copyOf(udt); // list } else if (DataType.Name.LIST == datatype.getName()) { final DataType elementDataType = datatype.getTypeArguments().get(0); final List<Object> udt = Lists.newArrayList(); if (value != null) { for (Object element : (List<Object>) value) { udt.add(toUdtValue(tablename, catalog, elementDataType, element)); } } return ImmutableList.copyOf(udt); // map } else { final DataType keyDataType = datatype.getTypeArguments().get(0); final DataType valueDataType = datatype.getTypeArguments().get(1); final Map<Object, Object> udt = Maps.newHashMap(); if (value != null) { for (Entry<Object, Object> entry : ((Map<Object, Object>) value).entrySet()) { udt.put( toUdtValue(tablename, catalog, keyDataType, entry.getKey()), toUdtValue(tablename, catalog, valueDataType, entry.getValue())); } } return ImmutableMap.copyOf(udt); } // udt } else { if (value == null) { return value; } else { final UserType usertype = catalog.getUserType(tablename, ((UserType) datatype).getTypeName()); final UDTValue udtValue = usertype.newValue(); for (Entry<String, Optional<Object>> entry : beanMapper.toValues(value, ImmutableSet.<String>of()).entrySet()) { if (!entry.getValue().isPresent()) { // return null; udtValue.setToNull(entry.getKey()); continue; } final DataType fieldType = usertype.getFieldType(entry.getKey()); Object vl = entry.getValue().get(); if (!isBuildInType(usertype.getFieldType(entry.getKey()))) { vl = toUdtValue(tablename, catalog, fieldType, vl); } final String key = entry.getKey(); udtValue.setBytesUnsafe(key, serialize(fieldType, vl)); } return udtValue; } } }