/*
 * MiningMart Version 1.0
 * 
 * Copyright (C) 2006 Martin Scholz, Timm Euler, 
 *                    Daniel Hakenjos, Katharina Morik
 *
 * Contact: miningmart@ls8.cs.uni-dortmund.de
 *
 * A list of contributing developers (other than the copyright 
 * holders) can be found at
 * http://mmart.cs.uni-dortmund.de/downloads/download.html
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program, see the file MM_HOME/LICENSE; if not, write
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
 * Floor, Boston, MA 02110-1301, USA.
 */
package edu.udo.cs.miningmart.m4.core;

import java.util.Collection;

import edu.udo.cs.miningmart.db.DB;
import edu.udo.cs.miningmart.exception.DbConnectionClosed;
import edu.udo.cs.miningmart.exception.M4Exception;
import edu.udo.cs.miningmart.m4.utils.M4Info;
import edu.udo.cs.miningmart.m4.utils.M4InfoEntry;
import edu.udo.cs.miningmart.m4.utils.Print;
import edu.udo.cs.miningmart.m4.utils.XmlInfo;

/**
 * This class represents an M4 Value.
 * 
 * @author Timm Euler
 * @version $Id: Value.java,v 1.3 2006/04/11 14:10:14 euler Exp $
 */
public class Value extends ParameterObject implements XmlInfo, edu.udo.cs.miningmart.m4.Value {

	// ***** Database constants for the M4 value table *****
	public static final String M4_TABLE_NAME ="value_t";
	public static final String ATTRIB_VALUE_ID = "v_id"; // NOT NULL NUMBER
	public static final String ATTRIB_DATATYPE = "v_condtid"; // NOT NULL NUMBER
	public static final String ATTRIB_VALUE_NAME = "v_name"; // VARCHAR2(100)
	public static final String ATTRIB_THE_VALUE  = "v_value"; // NOT NULL VARCHAR2(4000)


	/** Cache for getM4Info() */
	public static M4Info m4Info = null;

	/** @see M4Table.getM4TableName() */
	public String getM4TableName() {
		return M4_TABLE_NAME;	
	}

	/** @see M4Table.getIdAttributeName() */
	public String getIdAttributeName() {
		return ATTRIB_VALUE_ID;
	}

	/** @see M4Table.getM4Info() */
	public M4Info getM4Info() {
		if (m4Info == null) {
			M4InfoEntry[] m4i = {
				new M4InfoEntry(ATTRIB_VALUE_ID,   "getId",    "setId",         long.class,  NOT_NULL),
				new M4InfoEntry(ATTRIB_VALUE_NAME, "getName",  "setName",     String.class),
				new M4InfoEntry(ATTRIB_DATATYPE,   "getTypeL",  "setTypeL",     Long.class,  NOT_NULL),
				new M4InfoEntry(ATTRIB_THE_VALUE,  "getValue", "setRawValue", String.class,  NOT_NULL)
			};
			m4Info = new M4Info(m4i);
		}
		return m4Info;
	}


	/** Cache for getXmlInfo() */
	private static M4Info xmlInfo = null;

	/** @see XmlInfo.getXmlInfo() */
	public M4Info getXmlInfo() {
		if (xmlInfo == null) {
			M4InfoEntry[] m4i = {				
				new M4InfoEntry("Name",  "getName",          "setName",          String.class),
				new M4InfoEntry("Type",  "getType",          "setType",          long.class),
				new M4InfoEntry("Val",   "getValue",         "setValue",         String.class),
				new M4InfoEntry("Docu",  "getDocumentation", "setDocumentation", String.class)
			};
			xmlInfo = new M4Info(m4i);
		}
		return xmlInfo;
	}


    // ***** Value Variables from M4-DB *****
    private Long   myType;
    private String myValue;


	/**
	 * Constructor for Value.
	 * 
	 * @param m4Db
	 * 
	 * @see edu.udo.cs.miningmart.m4.core.M4Data#Constructor
	 */
	public Value(DB m4Db) {
		super(m4Db);
	}
	
	/**
	 * @see edu.udo.cs.miningmart.m4.core.Parameter#print
	 */
    public void print(){
		this.doPrint(Print.M4_OBJECT,
					 "Value (Id = " + myId + ";"
					 + " Type = " + myType + ") = "
					 + myValue);
    }
	
	/**
	 * @see edu.udo.cs.miningmart.m4.core.M4Data#getObjectsInNamespace(Class)
	 */
	protected Collection getObjectsInNamespace(Class typeOfObjects) throws M4Exception {
		return null;
	}

	/**
	 * Setter method.
	 * 
	 * @param t the new type
	 */
    public void setType(long t)
    {   
		this.setDirty();
    	this.myType = new Long(t);
    }

	/**
	 * Setter method.
	 * 
	 * @param t the new type
	 */
    public void setTypeL(Long t)
    {   
		this.setDirty();
    	this.myType = t;
    }
    
    public void setType(String conceptualDatatypeName) throws M4Exception {
    	ConceptualDatatypes cd;
    	try {
    		cd = new ConceptualDatatypes(this.getM4Db());
    	}
    	catch (DbConnectionClosed c) {
    		throw new M4Exception (c.getMessage());
    	}
    	this.setType(cd.getIdForName(conceptualDatatypeName));
    }

    public String getTypeName() throws M4Exception {
    	ConceptualDatatypes cd;
    	try {
    		cd = new ConceptualDatatypes(this.getM4Db());    		
    	}
    	catch (DbConnectionClosed c) {
    		throw new M4Exception (c.getMessage());
    	}
    	return cd.getNameForId(this.getType());
    }
    
	/**
	 * Getter method.
	 * 
	 * @return the type
	 */
    public long getType()
    {   return (myType == null ? 0 : myType.longValue()); }

	/**
	 * Getter method.
	 * 
	 * @return the type
	 */
    public Long getTypeL()
    {   return this.myType;   }

	/**
	 * Setter method.
	 * 
	 * @param v the new value
	 */
    public void setValue(String v)
    {   
		this.setDirty();
    	this.myValue = v;
    }

	/**
	 * This setter method cares about conversion from database <code>String</code>
	 * formats and should only be used during load. The value type needs to be set
	 * already!
	 * 
	 * @param value the value in database <code>String</code> representation
	 */
	public void setRawValue(String value) {
		long t = this.getType();
		if (t == 7 || t == 9) {
			try {
				value = DB.checkDouble(value);
			}
			catch (M4Exception e) {
				// ignore errors in DB.checkDouble(String) !
			}
	    }
	    this.setValue(value);
	}

	/**
	 * Getter method.
	 * 
	 * @return the value
	 */
    public String getValue()
    {   return myValue;   }

    /** 
     * @return <i>true</i> iff the value can be parsed to <i>Long</i>. 
     */
	public boolean isLong()
	{
		String value = getValue();
		if (value == null)
			return (false);
		try
		{
			Long.valueOf(value.trim());
		}
		catch (NumberFormatException e)
		{
			return (false);
		}
		return (true);
	}

    /** 
     * @return <i>true</i> iff the value can be parsed to <i>Double</i>. 
     */
	public boolean isDouble()
	{
		String value = getValue();
		if (value == null)
			return (false);
		try
		{
			Double.valueOf(value.trim());
		}
		catch (NumberFormatException e)
		{
			return (false);
		}
		return (true);
	}

    /** 
     * @return a <i>Long</i> object if the value <i>isLong()</i>, <i>null</i> otherwise. 
     */
    public Long getLong() {
	if (this.isLong())
	    return Long.valueOf(getValue().trim());
	else return null;
    }

    /** 
     * @return a <i>Double</i> object if the value <i>isDouble()</i>, <i>null</i> otherwise. 
     */
    public Double getDouble() {
		if (this.isDouble())
	    	return Double.valueOf(getValue().trim());
		else return null;
    }

 	/** <code>Value</code>s do not have coordinates. */
	protected boolean hasCoordinates() {
		return false;
	}
    
   	/** @see M4Data#removeAllM4References() */
	protected void removeAllM4References() throws M4Exception {
		super.removeAllM4References();
		this.removeDocObject();
	}

}
/*
 * Historie
 * --------
 * 
 * $Log: Value.java,v $
 * Revision 1.3  2006/04/11 14:10:14  euler
 * Updated license text.
 *
 * Revision 1.2  2006/04/06 16:31:13  euler
 * Prepended license remark.
 *
 * Revision 1.1  2006/01/03 09:54:17  hakenjos
 * Initial version!
 *
 */
