package edu.uprm.admg.nettraveler.schema;

// JDK imports
import java.io.IOException;
import java.io.ObjectInputStream;

import edu.uprm.admg.util.DataVerify;

/**
 * 
 * <code>BaseAttribute</code> represents an attribute in a tuple 
 * to be read from an underlying data source. Each attribute 
 * instance consists of: a name, a class implementing 
 * the base type, and the name of the native type for the attribute 
 * at the data source level. This class should be used in the 
 * implementation of the physical operators for the plan of a query.
 * <p/>
 * Example: A base attribute for a polygon defined in a relational table
 * named <code>Polygons</code>, with attribute name <code>location</code> 
 * and native type <code>polygonImp</code> can be specified as follows:
 * 
 * <PRE>
 * . . .
 * BaseAttribute base_attr; 
 * . . .
 * base_attr = new BaseAttribute("location", "Object", 
 *                                Class.forName("MIPolygon").getName());
 * </PRE>
 * 
 * This code will create the object with the basic information needed
 * to to read and translate the <code>location</code> attribute 
 * from each tuple being fetched from the data source.
 * <br>
 * Universidad de Puerto Rico@Mayaguez.
 * <br>
 * <code>NetTraveler</code>
 */
 /*
  * @author Manuel Rodriguez-Martinez
 * @author Elliot A. Vargas-Figueroa - M.S. Thesis Project.
 * P.I. Manuel Rodriguez-Martinez
 */
public class BaseAttribute extends Attribute implements RelationAttribute{
    /**
	 * Serial Version
	 */
	private static final long serialVersionUID = -1754439402707799626L;
	/**
     * The name of the native type for this attribute at the data source 
     * level.
     */
    private String nativeTypeName = null;
    /** Relation name **/
    private String relationName = null;
    /** Relation alias **/
    private String relationAlias = null;
    /** Relation schema **/
    private String relationSchema = null;
    /**
     * Creates a new base attribute based on: a name, 
     * a class implementing the base type, and the name of the native 
     * type for this attribute at the  data source level.
     * @param name the name of the attribute.
     * @param srcType the name of the native type for this attribute at the data source level
     * @param className Name of the base class.
     * 
     */
    public BaseAttribute(String name,  String srcType, String className) {
	    	super(name, className);
	    	DataVerify.VerifyObjectParam("srcType", srcType);
	    	nativeTypeName = srcType;
    }

    /**
     * Returns the name of the native type for this attribute at the 
     * data source level.
     * @return the name of the native type for this attribute.
     */
    public String getNativeTypeName(){
    	return nativeTypeName;
    }
    /**
     * 
     */
	public String getSchemaName() {
		return relationSchema;
	}
	/**
	 * 
	 */
	public void setSchemaName(String name) {
		DataVerify.VerifyObjectParam("name", name);
		this.relationSchema = name;
	}
	/**
	 * 
	 */
	public String getRelationAlias() {
		return relationAlias;
	}
	/**
	 * 
	 */
	public void setRelationAlias(String name) {
		DataVerify.VerifyObjectParam("name", name);
		this.relationAlias = name;
	}
	/**
	 * 
	 */
	public String getRelationName() {
		return relationName;
	}
	/**
	 * 
	 */
	public void setRelationName(String name) {
		DataVerify.VerifyObjectParam("name", name);
		this.relationName =  name;
		
	}
    /**
     * @see edu.uprm.admg.nettraveler.schema.Attribute#localEquals(edu.uprm.admg.nettraveler.schema.Attribute)
     */
	protected boolean localEquals(Attribute attr) {
		if(!(attr instanceof BaseAttribute))
			return false;
		BaseAttribute o = (BaseAttribute) attr;		
		return nativeTypeName.equals(o.nativeTypeName);
	}
	/**
	 * @see edu.uprm.admg.nettraveler.schema.Attribute#localHashCode()
	 */
	protected int localHashCode() {
		int result = 17;
		result += result * 37 + nativeTypeName.hashCode();
		return result;
	}
	/**
	 * 
	 * @param in
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
		in.defaultReadObject();
		try{
			DataVerify.VerifyObjectParam("Native type", nativeTypeName);
		}catch(Exception e){
			throw new IOException(e.toString());
		}
	}
}
