content: /*
   * Copyright (c) 2013. wyouflf (wyouflf@gmail.com)
   *
   * 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.lidroid.xutils.db.table;
  
  import android.database.Cursor;
  import com.lidroid.xutils.db.converter.ColumnConverter;
  import com.lidroid.xutils.db.converter.ColumnConverterFactory;
  import com.lidroid.xutils.db.sqlite.ColumnDbType;
  import com.lidroid.xutils.util.LogUtils;
  
  import java.lang.reflect.Field;
  import java.lang.reflect.Method;
  
  public class Column {
  
      private Table table;
  
      private int index = -1;
  
      protected final String columnName;
      private final Object defaultValue;
  
      protected final Method getMethod;
      protected final Method setMethod;
  
      protected final Field columnField;
      protected final ColumnConverter columnConverter;
  
      /* package */ Column(Class<?> entityType, Field field) {
          this.columnField = field;
          this.columnConverter = ColumnConverterFactory.getColumnConverter(field.getType());
          this.columnName = ColumnUtils.getColumnNameByField(field);
          if (this.columnConverter != null) {
              this.defaultValue = this.columnConverter.getFieldValue(ColumnUtils.getColumnDefaultValue(field));
          } else {
              this.defaultValue = null;
          }
          this.getMethod = ColumnUtils.getColumnGetMethod(entityType, field);
          this.setMethod = ColumnUtils.getColumnSetMethod(entityType, field);
      }
  
      @SuppressWarnings("unchecked")
      public void setValue2Entity(Object entity, Cursor cursor, int index) {
          this.index = index;
          Object value = columnConverter.getFieldValue(cursor, index);
          if (value == null && defaultValue == null) return;
  
          if (setMethod != null) {
              try {
                  setMethod.invoke(entity, value == null ? defaultValue : value);
              } catch (Throwable e) {
                  LogUtils.e(e.getMessage(), e);
              }
          } else {
              try {
                  this.columnField.setAccessible(true);
                  this.columnField.set(entity, value == null ? defaultValue : value);
              } catch (Throwable e) {
                  LogUtils.e(e.getMessage(), e);
              }
          }
      }
  
      @SuppressWarnings("unchecked")
      public Object getColumnValue(Object entity) {
          Object fieldValue = getFieldValue(entity);
          return columnConverter.fieldValue2ColumnValue(fieldValue);
      }
  
      public Object getFieldValue(Object entity) {
          Object fieldValue = null;
          if (entity != null) {
              if (getMethod != null) {
                  try {
                      fieldValue = getMethod.invoke(entity);
                  } catch (Throwable e) {
                      LogUtils.e(e.getMessage(), e);
                  }
              } else {
                  try {
                      this.columnField.setAccessible(true);
                      fieldValue = this.columnField.get(entity);
                  } catch (Throwable e) {
                      LogUtils.e(e.getMessage(), e);
                  }
              }
          }
          return fieldValue;
      }
  
      public Table getTable() {
          return table;
      }
  
      /* package */ void setTable(Table table) {
          this.table = table;
      }
  
      /**
       * The value set in setValue2Entity(...)
       *
       * @return -1 or the index of this column.
       */
      public int getIndex() {
          return index;
      }
  
      public String getColumnName() {
          return columnName;
      }
  
      public Object getDefaultValue() {
          return defaultValue;
      }
  
      public Field getColumnField() {
          return columnField;
      }
  
      public ColumnConverter getColumnConverter() {
          return columnConverter;
      }
  
      public ColumnDbType getColumnDbType() {
          return columnConverter.getColumnDbType();
      }
  }
  