All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.datastax.driver.mapping.DefaultMappedProperty Maven / Gradle / Ivy

The newest version!
/*
 * Copyright DataStax, Inc.
 *
 * 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 com.datastax.driver.mapping;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

import com.datastax.driver.core.TypeCodec;
import com.datastax.driver.mapping.annotations.ClusteringColumn;
import com.datastax.driver.mapping.annotations.Column;
import com.datastax.driver.mapping.annotations.Computed;
import com.datastax.driver.mapping.annotations.Defaults;
import com.datastax.driver.mapping.annotations.PartitionKey;
import com.google.common.reflect.TypeToken;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;

/** Default implementation of {@link MappedProperty}. */
class DefaultMappedProperty implements MappedProperty {

  static  DefaultMappedProperty create(
      Class mappedClass,
      String propertyName,
      String mappedName,
      Field field,
      Method getter,
      Method setter,
      Map, Annotation> annotations) {
    @SuppressWarnings("unchecked")
    TypeToken propertyType = (TypeToken) inferType(field, getter);
    boolean partitionKey = annotations.containsKey(PartitionKey.class);
    boolean clusteringColumn = annotations.containsKey(ClusteringColumn.class);
    boolean computed = annotations.containsKey(Computed.class);
    int position = inferPosition(annotations);
    @SuppressWarnings("unchecked")
    Class> codecClass =
        (Class>) getCustomCodecClass(annotations);
    return new DefaultMappedProperty(
        mappedClass,
        propertyName,
        mappedName,
        propertyType,
        partitionKey,
        clusteringColumn,
        computed,
        position,
        codecClass,
        field,
        getter,
        setter);
  }

  private final Class mappedClass;
  private final String propertyName;
  private final TypeToken propertyType;
  private final String mappedName;
  private final boolean partitionKey;
  private final boolean clusteringColumn;
  private final boolean computed;
  private final int position;
  private final TypeCodec customCodec;
  private final Field field;
  private final Method getter;
  private final Method setter;

  private DefaultMappedProperty(
      Class mappedClass,
      String propertyName,
      String mappedName,
      TypeToken propertyType,
      boolean partitionKey,
      boolean clusteringColumn,
      boolean computed,
      int position,
      Class> codecClass,
      Field field,
      Method getter,
      Method setter) {
    checkArgument(propertyName != null && !propertyName.isEmpty());
    checkArgument(mappedName != null && !mappedName.isEmpty());
    checkNotNull(propertyType);
    this.mappedClass = mappedClass;
    this.propertyName = propertyName;
    this.mappedName = mappedName;
    this.propertyType = propertyType;
    this.partitionKey = partitionKey;
    this.clusteringColumn = clusteringColumn;
    this.computed = computed;
    this.position = position;
    this.customCodec =
        codecClass == null || codecClass.equals(Defaults.NoCodec.class)
            ? null
            : ReflectionUtils.newInstance(codecClass);
    this.field = field;
    this.getter = getter;
    this.setter = setter;
  }

  @Override
  public String getPropertyName() {
    return propertyName;
  }

  @Override
  public TypeToken getPropertyType() {
    return propertyType;
  }

  @Override
  public String getMappedName() {
    return mappedName;
  }

  @Override
  public int getPosition() {
    return position;
  }

  @Override
  public TypeCodec getCustomCodec() {
    return customCodec;
  }

  @Override
  public boolean isComputed() {
    return computed;
  }

  @Override
  public boolean isPartitionKey() {
    return partitionKey;
  }

  @Override
  public boolean isClusteringColumn() {
    return clusteringColumn;
  }

  @SuppressWarnings("unchecked")
  @Override
  public T getValue(Object entity) {
    try {
      // try getter first, if available, otherwise direct field access
      if (getter != null && getter.isAccessible()) return (T) getter.invoke(entity);
      else return (T) checkNotNull(field).get(entity);
    } catch (Exception e) {
      throw new IllegalArgumentException(
          "Unable to read property '" + getPropertyName() + "' in " + entity.getClass(), e);
    }
  }

  @Override
  public void setValue(Object entity, T value) {
    try {
      // try setter first, if available, otherwise direct field access
      if (setter != null && setter.isAccessible()) setter.invoke(entity, value);
      else checkNotNull(field).set(entity, value);
    } catch (Exception e) {
      throw new IllegalArgumentException(
          "Unable to write property '" + getPropertyName() + "' in " + entity.getClass(), e);
    }
  }

  @Override
  public String toString() {
    return mappedClass.getSimpleName() + "." + getPropertyName();
  }

  private static TypeToken inferType(Field field, Method getter) {
    if (getter != null) return TypeToken.of(getter.getGenericReturnType());
    else return TypeToken.of(checkNotNull(field).getGenericType());
  }

  private static int inferPosition(Map, Annotation> annotations) {
    if (annotations.containsKey(PartitionKey.class)) {
      return ((PartitionKey) annotations.get(PartitionKey.class)).value();
    }
    if (annotations.containsKey(ClusteringColumn.class)) {
      return ((ClusteringColumn) annotations.get(ClusteringColumn.class)).value();
    }
    return -1;
  }

  private static Class> getCustomCodecClass(
      Map, Annotation> annotations) {
    Column column = (Column) annotations.get(Column.class);
    if (column != null) return column.codec();
    com.datastax.driver.mapping.annotations.Field udtField =
        (com.datastax.driver.mapping.annotations.Field)
            annotations.get(com.datastax.driver.mapping.annotations.Field.class);
    if (udtField != null) return udtField.codec();
    return null;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy