package org.apache.torque.templates.typemapping;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

import org.apache.commons.lang.StringUtils;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */


/**
 * The SQL type data for a column. Can contain additional information such as
 * default size, scale and defaultValue.
 * This class is immutable.
 *
 * @version $Id: SqlTypeWithJdbcType.java 1402632 2012-10-26 19:40:58Z tfischer $
 */
public class SqlTypeWithJdbcType
{
    /**
     * The default size for the columns with this type
     * (can be overridden in the column definition).
     */
    private String size;

    /**
     * The default scale for the columns with this type
     * (can be overridden in the column definition).
     */
    private String scale;

    /**
     * The default "default value" for the columns with this type
     * (can be overridden in the column definition).
     */
    private String defaultValue;

    /**
     * The SQL expression for the type name, not null.
     */
    private String sqlTypeName;

    /**
     * The jdbc type as in <code>java.sql.types</code>
     */
    private int jdbcType;

    /**
     * Creates a new SqlType with the given SQL Type.
     * Size, scale and defaultValue are set to null.
     *
     * @param sqlType the SQL name of the SQL type, not null.
     * @param jdbcType the jdbc type as in <code>java.sql.types</code>.
     *
     * @throws NullPointerException if sqlTypeName is null.
     */
    public SqlTypeWithJdbcType(String sqlTypeName, int jdbcType)
    {
        if (sqlTypeName == null)
        {
            throw new NullPointerException("sqlTypeName must not be null");
        }
        this.sqlTypeName = sqlTypeName;
        this.jdbcType = jdbcType;
    }

    /**
     * Creates a new SqlType with null scale and null default value.
     *
     * @param sqlTypeName the SQL name of the SQL type, not null.
     * @param jdbcType the jdbc type as in <code>java.sql.types</code>.
     * @param size the default size of the columns with this SQL type.
     *        Can be overridden in the column definition.
     *
     * @throws NullPointerException if sqlTypeName is null.
     */
    public SqlTypeWithJdbcType(
            String sqlTypeName,
            int jdbcType,
            String size)
    {
        this(sqlTypeName, jdbcType);
        this.size = size;
    }

    /**
     * Creates a new SqlType with null default value.
     *
     * @param sqlTypeName the SQL name of the SQL type, not null.
     * @param jdbcType the jdbc type as in <code>java.sql.types</code>.
     * @param size the default size of the columns with this SQL type.
     *        Can be overridden in the column definition.
     * @param scale the default scale of the columns with this SQL type.
     *        Can be overridden in the column definition.
     *
     * @throws NullPointerException if sqlTypeName is null.
     */
    public SqlTypeWithJdbcType(
            String sqlTypeName,
            int jdbcType,
            String size,
            String scale)
    {
        this(sqlTypeName, jdbcType, size);
        this.scale = scale;
    }

    /**
     * Creates a new SqlType.
     *
     * @param sqlTypeName the SQL name of the SQL type, not null.
     * @param jdbcType the jdbc type as in <code>java.sql.types</code>.
     * @param size the default size of the columns with this SQL type.
     *        Can be overridden in the column definition.
     * @param scale the default scale of the columns with this SQL type.
     *        Can be overridden in the column definition.
     * @param defaultValue the default "default value" of the columns with this
     *        SQL type. Can be overridden in the column definition.
     *
     * @throws NullPointerException if sqlTypeName is null.
     */
    public SqlTypeWithJdbcType(
            String sqlTypeName,
            int jdbcType,
            String size,
            String scale,
            String defaultValue)
    {
        this(sqlTypeName, jdbcType, size, scale);
        this.defaultValue = defaultValue;
    }

    /**
     * Creates a new SqlType by copying another sql type.
     *
     * @param sqlType the SQL type, to copy, not null.
     * @param size the default size of the columns with this SQL type.
     *        Can be overridden in the column definition.
     *        If null, the size from sqlType is used.
     * @param scale the default scale of the columns with this SQL type.
     *        Can be overridden in the column definition.
     *        If null, the scale from sqlType is used.
     * @param defaultValue the default "default value" of the columns with this
     *        SQL type. Can be overridden in the column definition.
     *        If null, the defaultValue from sqlType is used.
     *
     * @throws NullPointerException if sqlType is null.
     */
    public SqlTypeWithJdbcType(
            SqlTypeWithJdbcType sqlType,
            String size,
            String scale,
            String defaultValue)
    {
        this(sqlType.getSqlTypeName(), sqlType.getJdbcType());
        if (size != null)
        {
            this.size = size;
        }
        else
        {
            this.size = sqlType.getSize();
        }
        if (scale != null)
        {
            this.scale = scale;
        }
        else
        {
            this.scale = sqlType.getScale();
        }
        if (defaultValue != null)
        {
            this.defaultValue = defaultValue;
        }
        else
        {
            this.defaultValue = sqlType.getDefaultValue();
        }
    }

    /**
     * @return Returns the scale.
     */
    public String getScale()
    {
        return scale;
    }

    /**
     * @return Returns the size.
     */
    public String getSize()
    {
        return size;
    }

    /**
     * @return Returns the defaultValue.
     */
    public String getDefaultValue()
    {
        return defaultValue;
    }

    /**
     * @return Returns the SQL type name for this column type.
     */
    public String getSqlTypeName()
    {
        return sqlTypeName;
    }

    /**
     * @return Returns the jdbc type tas in <code>java.sql.types</code>.
     */
    public int getJdbcType()
    {
        return jdbcType;
    }

    /**
     * Return the size and scale in brackets for use in an SQL script.
     *
     * @return size and scale or an empty String if there are no values
     *         available.
     */
    public String printSize()
    {
        if (StringUtils.isNotBlank(size) && StringUtils.isNotBlank(scale))
        {
            return '(' + size + ',' + scale + ')';
        }
        else if (StringUtils.isNotBlank(size))
        {
            return '(' + size + ')';
        }
        else
        {
            return "";
        }
    }
}
