001/* 
002 * JKNIV, whinstone one contract to access your database.
003 * 
004 * Copyright (C) 2017, the original author or authors.
005 *
006 * This library is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 2.1 of the License.
010 * 
011 * This library is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 * Lesser General Public License for more details.
015 * 
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with this library; if not, write to the Free Software Foundation, Inc., 
018 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
019 */
020package net.sf.jkniv.whinstone.cassandra;
021
022import java.sql.SQLException;
023
024import com.datastax.driver.core.DataType;
025import com.datastax.driver.core.Row;
026
027import net.sf.jkniv.reflect.beans.ObjectProxy;
028import net.sf.jkniv.reflect.beans.ObjectProxyFactory;
029import net.sf.jkniv.reflect.beans.PropertyAccess;
030import net.sf.jkniv.whinstone.JdbcColumn;
031import net.sf.jkniv.whinstone.JdbcColumnMapper;
032import net.sf.jkniv.whinstone.UnderscoreToCamelCaseMapper;
033import net.sf.jkniv.whinstone.types.CassandraType;
034import net.sf.jkniv.whinstone.types.ColumnType;
035import net.sf.jkniv.whinstone.types.Convertible;
036import net.sf.jkniv.whinstone.types.RegisterType;
037
038/**
039 * 
040 * @author Alisson Gomes
041 * @since 0.6.0
042 */
043public class CassandraColumn implements JdbcColumn<Row>
044{
045    private final static JdbcColumnMapper JDBC_COLUMN_MAPPER = new UnderscoreToCamelCaseMapper();// TODO design property to config;
046    private final int                     columnIndex;
047    private final String                  columnName;
048    private final String                  methodName;
049    private final ColumnType              columnType;
050    private final boolean                 nestedAttribute;
051    private final PropertyAccess          propertyAccess;
052    private final RegisterType            registerType;
053    
054    public CassandraColumn(int columnIndex, String columnName, DataType.Name columnType, RegisterType registerType, Class<?> classTarget)
055    {
056        super();
057        this.columnIndex = columnIndex;
058        this.columnName = columnName;
059        this.propertyAccess = new PropertyAccess(JDBC_COLUMN_MAPPER.map(columnName), classTarget);
060        this.columnType = CassandraType.valueOf(columnType.name());
061        this.registerType = registerType;
062        if(columnName.indexOf(".") > 0)
063        {
064            this.nestedAttribute = true;
065            this.methodName = columnName;
066        }
067        else
068        {
069            this.nestedAttribute = false;
070            this.methodName = propertyAccess.getWriterMethodName();
071        }
072    }
073    
074    @Override
075    public PropertyAccess getPropertyAccess()
076    {
077        return this.propertyAccess;
078    }
079
080    @Override
081    public String getAttributeName()
082    {
083        return propertyAccess.getFieldName();
084    }
085    
086    @Override
087    public String getMethodName()
088    {
089        return methodName;
090    }
091    
092    @Override
093    public String getName()
094    {
095        return this.columnName;
096    }
097    
098    @Override
099    public int getIndex()
100    {
101        return this.columnIndex;
102    }
103    
104    @Override
105    public boolean isBinary()
106    {
107        return this.columnType.isBinary();
108    }
109    
110    @Override
111    public boolean isNestedAttribute()
112    {
113        return nestedAttribute;
114    }
115    
116    @Override
117    public Object getValue(Row row) throws SQLException
118    {
119        Object value = row.getObject(columnIndex);
120        ObjectProxy<?> proxy = ObjectProxyFactory.of(this.propertyAccess.getTargetClass());
121        Convertible<Object, Object> convertible = registerType.toAttribute(this, proxy);
122        if (!convertible.getType().isInstance(value))
123            value = convertible.toAttribute(value);
124        return value;
125    }
126    
127    @Override
128    public Object getBytes(Row row) throws SQLException
129    {
130        return row.getBytes(columnIndex);
131    }
132
133    @Override
134    public ColumnType getType()
135    {
136        return this.columnType;
137    }
138
139    @Override
140    public String toString()
141    {
142        return "CassandraColumn [index=" + columnIndex + ", columnName=" + columnName + ", jdbcType=" + columnType
143                + "]";
144    }
145}