org.batoo.jpa.core.impl.jdbc.BasicColumn.java Source code

Java tutorial

Introduction

Here is the source code for org.batoo.jpa.core.impl.jdbc.BasicColumn.java

Source

/*
 * Copyright (c) 2012 - Batoo Software ve Consultancy Ltd.
 * 
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.batoo.jpa.core.impl.jdbc;

import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.Date;

import javax.persistence.EnumType;
import javax.persistence.TemporalType;

import org.apache.commons.lang.StringUtils;
import org.batoo.jpa.common.reflect.ReflectHelper;
import org.batoo.jpa.core.impl.model.mapping.BasicMapping;
import org.batoo.jpa.core.jdbc.adapter.JdbcAdaptor;
import org.batoo.jpa.parser.MappingException;
import org.batoo.jpa.parser.impl.AbstractLocator;
import org.batoo.jpa.parser.metadata.ColumnMetadata;

/**
 * BasicColumn to persist basic attributes of the entity.
 * 
 * @author hceylan
 * @since $version
 */
public class BasicColumn extends AbstractColumn {

    private AbstractTable table;
    private final int sqlType;
    private final String name;
    private final String columnDefinition;
    private final int length;
    private final AbstractLocator locator;
    private final int precision;
    private final int scale;
    private final String tableName;
    private final boolean nullable;
    private final boolean insertable;
    private final boolean unique;
    private final boolean updatable;
    private final String mappingName;
    private final BasicMapping<?, ?> mapping;
    private final JdbcAdaptor jdbcAdaptor;
    private final EnumType enumType;
    private final Enum<?>[] values;
    private final Method method;
    private final TemporalType temporalType;
    private final Class<?> numberType;

    /**
     * @param jdbcAdaptor
     *            the jdbc adaptor
     * @param mapping
     *            the mapping
     * @param sqlType
     *            the SQL type
     * @param metadata
     *            the metadata
     * 
     * @since $version
     * @author hceylan
     */
    @SuppressWarnings("unchecked")
    public BasicColumn(JdbcAdaptor jdbcAdaptor, BasicMapping<?, ?> mapping, int sqlType, ColumnMetadata metadata) {
        super();

        this.jdbcAdaptor = jdbcAdaptor;
        this.mapping = mapping;
        this.locator = metadata != null ? metadata.getLocator() : null;
        this.sqlType = sqlType;

        this.mappingName = (metadata != null) && StringUtils.isNotBlank(metadata.getName()) ? metadata.getName()
                : this.mapping.getAttribute().getName();
        this.name = this.jdbcAdaptor.escape(this.mappingName);

        this.tableName = metadata != null ? metadata.getTable() : "";
        this.columnDefinition = metadata != null ? metadata.getColumnDefinition() : "";
        this.length = metadata != null ? metadata.getLength() : 255;
        this.precision = metadata != null ? metadata.getPrecision() : 0;
        this.scale = metadata != null ? metadata.getScale() : 0;
        this.insertable = metadata != null ? metadata.isInsertable() : true;
        this.nullable = metadata != null ? metadata.isNullable() : true;
        this.unique = metadata != null ? metadata.isUnique() : false;
        this.updatable = metadata != null ? metadata.isUpdatable() : true;

        this.numberType = Number.class.isAssignableFrom(mapping.getAttribute().getJavaType())
                ? mapping.getAttribute().getJavaType()
                : null;
        this.temporalType = mapping.getAttribute().getTemporalType();
        this.enumType = mapping.getAttribute().getEnumType();
        if (this.enumType != null) {
            Class<Enum<?>> enumJavaType;
            enumJavaType = (Class<Enum<?>>) mapping.getAttribute().getJavaType();
            try {
                if (this.enumType == EnumType.ORDINAL) {
                    this.values = (Enum<?>[]) enumJavaType.getMethod("values").invoke(null);
                    this.method = null;
                } else {
                    this.values = null;
                    this.method = enumJavaType.getMethod("valueOf", String.class);
                }
            } catch (final Exception e) {
                throw new MappingException("Unable to map enum type", this.mapping.getAttribute().getLocator());
            }
        } else {
            this.values = null;
            this.method = null;
        }
    }

    /**
     * Converts the value corresponding to enum or temporal type
     * 
     * @param value
     *            the raw value
     * @return the converted value
     * 
     * @since $version
     * @author hceylan
     */
    public Object convertValue(final Object value) {
        if (value == null) {
            return null;
        }

        if (this.temporalType != null) {
            switch (this.temporalType) {
            case DATE:
                if (value instanceof java.sql.Date) {
                    return value;
                }

                if (value instanceof Date) {
                    return new java.sql.Date(((Date) value).getTime());
                }

                return new java.sql.Date(((Calendar) value).getTimeInMillis());
            case TIME:
                if (value instanceof java.sql.Time) {
                    return value;
                }

                if (value instanceof Date) {
                    return new java.sql.Time(((Date) value).getTime());
                }

                return new java.sql.Time(((Calendar) value).getTimeInMillis());
            case TIMESTAMP:
                if (value instanceof java.sql.Timestamp) {
                    return value;
                }

                if (value instanceof Date) {
                    return new java.sql.Timestamp(((Date) value).getTime());
                }

                return new java.sql.Timestamp(((Calendar) value).getTimeInMillis());
            }
        }

        if (this.numberType != null) {
            return ReflectHelper.convertNumber((Number) value, this.numberType);
        }

        if (this.enumType == null) {
            return value;
        }

        final Enum<?> enumValue = (Enum<?>) value;
        if (this.enumType == EnumType.ORDINAL) {
            return enumValue.ordinal();
        }

        return enumValue.name();
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public String getColumnDefinition() {
        return this.columnDefinition;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public int getLength() {
        return this.length;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public AbstractLocator getLocator() {
        return this.locator;
    }

    /**
     * Returns the mapping of the BasicColumn.
     * 
     * @return the mapping of the BasicColumn
     * 
     * @since $version
     * @author hceylan
     */
    @Override
    public BasicMapping<?, ?> getMapping() {
        return this.mapping;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public String getMappingName() {
        return this.mappingName;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public String getName() {
        return this.name;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public int getPrecision() {
        return this.precision;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public int getScale() {
        return this.scale;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public int getSqlType() {
        return this.sqlType;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public AbstractTable getTable() {
        return this.table;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public String getTableName() {
        return this.tableName;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public Object getValue(Object instance) {
        final Object value = this.mapping.get(instance);

        return this.convertValue(value);
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public boolean isInsertable() {
        return this.insertable;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public boolean isNullable() {
        return this.nullable;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public boolean isUnique() {
        return this.unique;
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public boolean isUpdatable() {
        return this.updatable;
    }

    /**
     * Sets the table of the column.
     * 
     * @param table
     *            the owning table
     * 
     * @since $version
     * @author hceylan
     */
    @Override
    public void setTable(AbstractTable table) {
        this.table = table;

        this.table.addColumn(this);
    }

    /**
     * Sets the value for the instance
     * 
     * @param instance
     *            the instance of which to set value
     * @param value
     *            the value to set
     * 
     * @since $version
     * @author hceylan
     */
    @Override
    public void setValue(Object instance, Object value) {
        if ((value != null) && (this.enumType != null)) {
            if (this.enumType == EnumType.ORDINAL) {
                value = this.values[((Number) value).shortValue()];
            } else {
                try {
                    value = this.method.invoke(null, value);
                } catch (final Exception e) {
                }
            }
        }

        this.mapping.set(instance, value);
    }
}