/*
 * 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.M4Exception;
import edu.udo.cs.miningmart.exception.ParameterError;
import edu.udo.cs.miningmart.exception.ParameterNotFoundException;
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;
import edu.udo.cs.miningmart.m4.ParameterObject;

/**
 * @author Timm Euler, Martin Scholz
 * @version $Id: Parameter.java,v 1.5 2006/04/11 14:10:13 euler Exp $
 */
public class Parameter extends M4Data implements XmlInfo, edu.udo.cs.miningmart.m4.Parameter {

	/** name of the corresponding m4 table */
	public static final String M4_TABLE_NAME = "parameter_t";
	
	/** db level tuple id of this parameter tuple */
	public static final String ATTRIB_PARAMETER_ID = "par_id";
	
	/** db level name of this parameter tuple */
	public static final String ATTRIB_PARAMETER_NAME = "par_name";

	/** db level tuple id of the corresponding object tuple */
	public static final String ATTRIB_OBJECT_ID = "par_objid";

	/** db level type (table) of the corresponding object tuple */
	public static final String ATTRIB_OBJECT_TYPE = "par_objtype";

	/** db level type of parameter: input or output */
	public static final String ATTRIB_PAR_IO_TYPE = "par_type";

	/** db level: loop number this parameter belongs to */
	public static final String ATTRIB_PAR_LOOP_NR = "par_stloopnr";
	
	/** db level: id of the corresponding operator */
	public static final String ATTRIB_PAR_OPERATOR_ID = "par_opid";

	/** db level: id of the corresponding step */
	public static final String ATTRIB_PAR_STEP_ID = "par_stid";
	
	/** db level: number of this parameter within its embedding array */
	public static final String ATTRIB_PARAMETER_NR = "par_nr";



	/** 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_PARAMETER_ID;
	}

	/** @see M4Table.getM4Info() */
	public M4Info getM4Info() {
		if (m4Info == null) {
			M4InfoEntry[] m4i = {
				new M4InfoEntry(ATTRIB_PARAMETER_ID,    "getId",            "setId",             long.class,   NOT_NULL),
				new M4InfoEntry(ATTRIB_PARAMETER_NAME,  "getName",          "setName",           String.class, NOT_NULL),
				new M4InfoEntry(ATTRIB_PAR_IO_TYPE ,    "getInputParam",    "setInputParam",     String.class, NOT_NULL),
				new M4InfoEntry(ATTRIB_PAR_LOOP_NR,     "getLoopNr",        "setLoopNr",         int.class),
				new M4InfoEntry(ATTRIB_PARAMETER_NR,    "getParamNr",       "setParamNr",        long.class,   NOT_NULL),
				new M4InfoEntry(ATTRIB_PAR_STEP_ID,     "getTheStep",       "primitiveSetStep",  edu.udo.cs.miningmart.m4.Step.class,   NOT_NULL),

				// The parameter object type needs to be set before the parameter ID, because setting the
				// parameter ID does it by loading and storing the parameter object!
				new M4InfoEntry(ATTRIB_OBJECT_TYPE,     "getParObjectType", "privateSetParType", String.class, NOT_NULL),
				new M4InfoEntry(ATTRIB_OBJECT_ID,       "getParObjectId",   "readParObjFromDb",  Long.class),

				// This setter is a dummy, because the Operator is stored redundantly in this Parameter's Step!
				new M4InfoEntry(ATTRIB_PAR_OPERATOR_ID, "getTheOperator",   "setTheOperator",    edu.udo.cs.miningmart.m4.Operator.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("InOut",           "getInputParam",         "setInputParam",          String.class),
				new M4InfoEntry("LoopNumber",      "getLoopNr",             "setLoopNr",              int.class),
				new M4InfoEntry("ParameterNumber", "getParamNr",            "setParamNr",             long.class),
				new M4InfoEntry("Step",            "getTheStep",            "setTheStep",             edu.udo.cs.miningmart.m4.Step.class),
				new M4InfoEntry("ParameterObject", "getTheParameterObject", "setTheParameterObject",  edu.udo.cs.miningmart.m4.ParameterObject.class),
				new M4InfoEntry("Docu",            "getDocumentation",      "setDocumentation",       String.class)
			};
			xmlInfo = new M4Info(m4i);
		}
		return xmlInfo;
	}
	
	/**
	 * Maps the parameter type constants in <code>DB</code> to the ones used here.
	 * <code>typeMapping[TYPE_X]</code> is the <code>String</code> in <code>DB</code>
	 * for <code>TYPE_X</code>.
	 */
	private static final String[] typeMapping =
		{DB.C_VAL, DB.C_CONC, DB.C_REL, DB.C_BA, DB.C_MCF, DB.C_FEA, "*invalid*"};

	/**
	 * Maps the parameter type constants in <code>DB</code> to the <code>Class</code> objects.
	 * <code>typeMapping[TYPE_X]</code> is the <code>Class</code> representing <code>TYPE_X</code>.
	 */
	private static final Class[] classForType =
		  { Value.class, 
	    	Concept.class, 
			Relation.class, 
			BaseAttribute.class,
			MultiColumnFeature.class, 
			Feature.class, 
			ParameterObject.class};

	/**
	 * @param a <code>DB</code> constant for a parameter type
	 * @return a short representing the parameter
	 */
	public static short typeConstForTypeString(String parameterType) 
		throws ParameterError
	{
		short type = -1;
		if (parameterType != null) {
			parameterType = parameterType.trim();
			for (short i=0; i<Parameter.typeMapping.length && type == -1; i++) {
				if (Parameter.typeMapping[i].equalsIgnoreCase(parameterType)) {
			  		type = i;
			   	}
		    }
		}
		if (type == -1) {
			throw new ParameterError(
				"Parameter.typeConstForTypeString(String):\n"
				+ " Unsupported parameter type found: "
				+ parameterType);			
		}
		return type;		
	}

	/**
	 * @param a <code>DB</code> constant for a parameter type
	 * @return a short representing the parameter
	 */
	public static String typeStringForTypeConst(short parameterType) 
		throws ParameterError
	{
		if (parameterType < 0 || parameterType >= Parameter.typeMapping.length) {
			throw new ParameterError(
				"Parameter.typeStringForTypeConst(short):\n"
				+ " Unsupported parameter type found: "
				+ parameterType);
		}
		return Parameter.typeMapping[parameterType];
	}

	
	/**
	 * @param a <code>short</code> constant for a parameter type
	 * @return the <code>Class</code> (subclass of <code>ParameterObject</code>)
	 * representing the parameter
	 * @throws <code>ParameterError</code> if the parameter is out of bounds.
	 */
	public static Class getClassForParameterType(short parameterType) 
			throws ParameterError
	{
		if (parameterType < 0 || parameterType >= Parameter.classForType.length) {
			throw new ParameterError(
				"Parameter.getClassForParameterType(short):\n"
				+ " Unsupported parameter type found: "
				+ parameterType);
		}
		return Parameter.classForType[parameterType];
	}

	/**
	 * @param  parameterObject a <code>ParameterObject</code>
	 * @return the <code>String</code> representing parameter objects of this type
	 *         in the database, or <code>null</code> if the <code>parameterObject</code>
	 *         is <code>null</code>
	 * 
	 * @throws <code>ParameterError</code> if the parameter type is unknown
	 */
	public static String getTypeStringForParObject(ParameterObject parameterObject)
		throws ParameterError
	{
		if (parameterObject != null) {
			for (short i=0; i<classForType.length; i++) {
				if (classForType[i].isInstance(parameterObject)) {
					return typeStringForTypeConst(i);
				}				
			}
			throw new ParameterError(
				"Unknown type of ParameterObject: "
				+ parameterObject.getClass().getName());
		}
		else return null;
	}


	// ***** Parameter Variables from M4-DB *****

	/**
	 * A pointer to the step this parameter belongs to.
	 * It is set after the first request. As long as the value is
	 * <code>null</code> the object has not been loaded.
	 */
	private Step myStep;

	/* Is it an input parameter? */
	private boolean isInputParam;

	/* The loop nr of this parameter. Loop Parameters in the DB must go from
	 * 1 to "myStep.getLoopCount()". Non-Looped Parameters (valid for all loops)
	 * must be 0 or (SQL-) NULL */
	private int loopNr;

	/* 
	 * This is a reference to the M4 object constituting the parameter.
	 * It is loaded on the first request.
	 */	
	private ParameterObject parameterObject;
	
	/* The number of the parameter within the array formed by the OP_PARAM_T specification. */
	private long myParameterNr;

	/* The ParameterArray this Parameter belongs to. */
	// private ParameterArray paramArray;

	/* This field is just used to store the parameter object's type during autoload. */
	private String parTypeDuringLoad;
	
	// ***** Constructor *****

	public Parameter(DB db) {
		super(db);
	}

	// ***** Getter and setter methods *****
	
	/**
	 * @see edu.udo.cs.miningmart.m4.core.M4Data#getObjectsInNamespace(Class)
	 */
	protected Collection getObjectsInNamespace(Class typeOfObjects) throws M4Exception {
		return null;
	}
	
	/**
	 * This method is based on a <b>redundant</b> attribute in
	 * the database! The operator of this parameter is defined
	 * by its <code>Step</code>. Thus the getter method for the
	 * <code>Operator</code> and its ID will return the result
	 * based on the <code>Operator</code> of the associated
	 * <code>Step</code> object.
	 * 
	 * As a result of being redundant this method does not do
	 * anything!
	 * 
	 * @param op The new operator.
	 */
	public void setTheOperator(edu.udo.cs.miningmart.m4.Operator op) {}

	/**
	 * Getter method for this <code>Parameter</code>'s <code>Operator</code>
	 * 
	 * @return the <code>Operator</code> this parameter belongs to.
	 * If no embedding <code>Step</code> can be found or the <code>Step</code>
	 * does not return its <code>Operator</code> then <code>null</code> is
	 * returned.
	 */
	public edu.udo.cs.miningmart.m4.Operator getTheOperator() throws M4Exception
	{
		edu.udo.cs.miningmart.m4.Step step = this.getTheStep();
		if (step != null) {
			return step.getTheOperator();
		}
		else return null;
	}

	/**
	 * @param step The new <code>Step</code> for this <code>Parameter</code>
	 */
	public void setTheStep(edu.udo.cs.miningmart.m4.Step step) throws M4Exception {
		edu.udo.cs.miningmart.m4.core.Step.step2par.checkNameExists(this, step);
		edu.udo.cs.miningmart.m4.core.Step.step2par.updateReferenceTo(this, step);
	}

	/**
	 * Primitive setter, do not use it!
	 * @param step the <code>Step</code> to be set
	 */
	public void primitiveSetStep(edu.udo.cs.miningmart.m4.Step step) {
		this.setDirty();
		this.myStep = (Step) step;	
	}

	/**
	 * @return The step this parameter belongs to.
	 */
	public edu.udo.cs.miningmart.m4.Step getTheStep() throws M4Exception {
		return myStep;
	}

	/**
	 * @return TRUE if this parameter is an Input Parameter, FALSE otherwise.
	 */
	public boolean isInputParam() {
		return isInputParam;
	}

	/**
	 * Same as <code>isInputParam</code>, but returns the database <code>String</code>
	 * representation for the flag.
	 * 
	 * @return the value of the input parameter flag as a <code>String</code>
	 * @see DB.c_yes
	 */
	public String getInputParam() {
		return (this.isInputParam ? DB.c_input : DB.c_output);
	}

	/**
	 * @param is Set to TRUE if this parameter is an Input parameter, FALSE otherwise.
	 */
	public void setIsInputParam(boolean is) {
		this.setDirty();
		isInputParam = is;
	}

	/**
	 * Each parameter is an input or an output parameter.
	 * This method expects the database <code>String</code> representation of
	 * this flag.
	 * 
	 * @param The value of the flag in database representation.
	 * @see DB.c_yes
	 */
	public void setInputParam(String inputString) {
		this.setIsInputParam(!DB.c_output.equals(inputString));
	}
	
	/**
	 * @param nr the number of the loop for which this parameter is to be used
	 */
	public void setLoopNr(int nr) {
		this.setDirty();
		loopNr = nr;
	}

	/**
	 * @return the number of the loop for which this parameter is to be used.
	 */
	public int getLoopNr() {
		return loopNr;
	}

	/**
	 * @return the type of this parameter object ("CON", "BA" etc),
	 * or <code>null</code> if the <code>ParameterObject</code> is
	 * not set.
	 */
	public String getParObjectType() throws ParameterError, M4Exception {
		return Parameter.getTypeStringForParObject(this.getTheParameterObject());
	}
	
	/**
	 * @return the Id of the <code>ParameterObject</code> as a <code>Long</code>
	 * object, or <code>null</code> if there is no <code>ParameterObject</code>
	 * stored.
	 */
	public Long getParObjectId() throws M4Exception {
		edu.udo.cs.miningmart.m4.ParameterObject parObj = this.getTheParameterObject();
		return (parObj == null ? null : new Long(parObj.getId()));
	}
	
	/**
	 * @return the parameterObject, the <code>M4Data</code> object
	 * constituting the parameter. A value of <code>null</code>
	 * indicates an error.
	 */
	public edu.udo.cs.miningmart.m4.ParameterObject getTheParameterObject() throws M4Exception {
		return this.parameterObject;
	}

	/**
	 * Sets the parameterObject.
	 * @param parameterObject The parameterObject to set
	 */
	public void setTheParameterObject(edu.udo.cs.miningmart.m4.ParameterObject parameterObject)
		throws M4Exception {
		// special case:
		if (parameterObject == null) {
			ParameterObject old = this.getTheParameterObject();
			if (old != null && (old instanceof Value)) {
				// Value objects should be deleted if they are not a parameter object
				// any longer (no other M4 object refers to Values). 
				old.deleteSoon();
			}
		}
		edu.udo.cs.miningmart.m4.core.ParameterObject.parObj2par.updateReferenceTo(this, parameterObject);
	}
	
	/**
	 * Returns the parameter number.
	 * @return long
	 */
	public long getParamNr() {
		return this.myParameterNr;
	}

	/**
	 * Sets the number of this parameter within its embedding parameter array
	 * @param paramNr The parameter number to set
	 */
	public void setParamNr(long paramNr) {
		this.setDirty();
		this.myParameterNr = paramNr;
	}
	

	/*
	 * Gets the paramArray this <code>Parameter</code> belongs to or <code>null</code>.
	 * @return Returns a ParameterArray
	 *
	public edu.udo.cs.miningmart.m4.ParameterArray getParamArray() {
		return this.paramArray;
	}
	*/
	/*
	 * Sets the paramArray this <code>Parameter</code> belongs to.
	 * @param paramArray The paramArray to set. <code>null</code> indicates,
	 * that there is no corresponding <code>OpParam</code> object, so this
	 * parameter would not be loaded by the compiler.
	 *
	public void setParamArray(edu.udo.cs.miningmart.m4.ParameterArray paramArray) throws M4Exception {
		ParameterArray.parArr2par.updateReferenceTo(this, paramArray);
	}
	*/
	
	/*
	 * Primitive setter method for internal <code>ParameterArray</code> field.
	 * Do not use it!
	 * 
	 * @param paramArray the <code>ParameterArray</code> to be set
	 * 
	public void primitiveSetParamArray(ParameterArray paramArray) {
		this.paramArray = paramArray;
	}
	*/

	/** 
	 * Primitive setter method for internal <code>ParameterObject</code> field.
	 * Do not use it!
	 * 
	 * @param paramObj the <code>ParameterObject</code> to be set
	 */
	public void primitiveSetParameterObject(edu.udo.cs.miningmart.m4.ParameterObject paramObj) {
    	this.setDirty();
		this.parameterObject = paramObj;	
	}

	/**
	 * This method is just used when a <code>Parameter</code> object is
	 * loaded from the database and it needs to store the type information
	 * for loading the <code>ParameterObject</code>. Using this setter does
	 * not have any effect in any other case!
	 * 
	 * @param parType the type of the <code>ParameterObject</code> in the
	 *        database <code>String</code> representation.
	 */
	protected void privateSetParType(String parType) {
		this.parTypeDuringLoad = parType;		
	}
	
	// ***** inherited methods *****

	/**
	 * Method to be used and extended by subclasses. Prints the parameter information
	 * and certain information about referenced M4 objects.
	 * @see edu.udo.cs.miningmart.m4.core.M4Object#print()
	 */
	public void print() {
		try {
			if (this.getName() != null) {
				String objectType = this.getParObjectType();
				this.doPrint(Print.PARAM,
					"Parameter " + this.getName()
				    + "(Id = " + this.getId() + ";"
					+ " Type = " + (objectType == null ? "<null>" : objectType)
					+ "): "
				);
			}
			((edu.udo.cs.miningmart.m4.core.ParameterObject) this.getTheParameterObject()).print();
		}
		catch (M4Exception e) {
			this.doPrint(Print.MAX, "Warning: Exception caught when trying to"
						+" print a ParameterObject in Parameter.print():");
			this.doPrint(e);
		}
	}



	// ***** subroutines for loading M4 objects from the database *****

	/**
	 * This method is just used during autoLoad!
	 * 
	 * @param idL the id of the <code>ParameterObject</code> or <code>null</code>
	 */
	protected void readParObjFromDb(Long idL) throws M4Exception {
		// The parameter object's type needs to be set before by
		// privateSetParType during autoload:
		String parType = this.parTypeDuringLoad;

		ParameterObject parObject =	null;
		if (idL != null && parType != null) {
			try {
				parObject = this.readParameterObjectFromDb(parType, idL.longValue());
			}
			catch (ParameterNotFoundException e) {
				// In this case we do not throw an exception, but we store <null>
				// as the ParameterObject and continue. The next store() should
				// remove this object, because the type of the ParameterObject is
				// a NOT NULL entry in the database, but the type of <null> is
				// defined as <null> in the methods getParObjectType() and
				// getTypeStringForParObject().
				// Note that if this should change in the future then an
				// explicit delete on this Parameter could be useful!
				String name = this.getName();
				this.doPrint(Print.M4_OBJECT,
					"Invalid ParameterObject-reference detected while loading parameter (Name: "
					+ (name == null ? "<null>" : name) + ", ID: " + this.getId() + ")");
				this.doPrint(Print.M4_OBJECT,
					"Exception when trying to load was " + e.getMessage());
			}
		}
		this.primitiveSetParameterObject(parObject);
		
		this.parTypeDuringLoad = null; // no longer needed
	}
		
	/**
	 * @return the parameter object referenced by PAR_OBJID from the table
	 * specified by PAR_OBJTYPE.
	 * 
	 * @throws ParameterNotFoundException if the parameter cannot be found.
	 * @throws M4Exception if an SQLException occurs.
	 * */
	private ParameterObject readParameterObjectFromDb(String parObjType, long parObjId)
		throws M4Exception
	{
		final DB db = this.getM4Db();
		ParameterObject parObject = null;
		
		short type = Parameter.typeConstForTypeString(parObjType);
		Class c = Parameter.getClassForParameterType(type);
		if (ParameterObject.class.isAssignableFrom(c)) {
			parObject = (ParameterObject) db.getM4Object(parObjId, c);
		}
		else {
			throw new M4Exception(
				"Internal Compiler Error in Parameter.readParameterObjectFromDb():\n"
				+ "Class provided (" + c.getName() + ") is no subclass of ParameterObject!");	
		}

		if (parObject == null) {
			edu.udo.cs.miningmart.m4.Step s = this.getTheStep();
			throw new ParameterNotFoundException(
				"M4 Database: Parameter " + this.getName()
				+ " for Step " + (s == null ? "<null>" :
				"(Name: "  + s.getName() + ", ID: " +s.getId())
				+ " not found");
		}
		else {
			return parObject;	
		}
	}

   	/** @see M4Data#removeAllM4References() */
	protected void removeAllM4References() throws M4Exception {
		this.setTheStep(null);
		this.setTheParameterObject(null);
		// this.setParamArray(null);
		this.removeDocObject();
	}
	

	/**
	 * @see Parameter#getParameterName()
	 */
	public String getParameterName() {
		return this.getName();
	}
	
	/**
	 * @see Parameter#setParameterName(String)
	 */
	public void setParameterName(String parameterName) throws M4Exception {
		// Does not yet check whether the name exists: Where mustn't it exist?
		
		// new version: DOES check the name!:
		String validName = parameterName;
		if (this.getTheStep() != null) {
		    validName = this.getTheStep().getValidName(parameterName, Parameter.class);
		}
		
		this.setName(validName);
	}
	
	/**
	 * This is the IO_TYPE !!
	 * Possible values are "IN" and "OUT".
	 * 
	 * @see Parameter#getParameterType()
	 */
	public String getParameterType() {
		return (this.isInputParam() ? Parameter.TYPE_INPUT : Parameter.TYPE_OUTPUT);
	}

	/**
	 * @see Parameter#setParameterType(String)
	 */
	public void setParameterType(String parameterType) throws M4Exception {
		if (parameterType.equals(edu.udo.cs.miningmart.m4.Parameter.TYPE_INPUT))
		{   this.setIsInputParam(true);  }
		else if (parameterType.equals(edu.udo.cs.miningmart.m4.Parameter.TYPE_OUTPUT))
		     {   this.setIsInputParam(false);   }
			 else throw new M4Exception("Parameter.setParameterType: Expected " +
			                            Parameter.TYPE_INPUT + " or " +
			                            Parameter.TYPE_OUTPUT + ", but got " +
			                            parameterType + "!");
	}


	/**
	 * @see Parameter#removeParameterObject()
	 */
	public void removeParameterObject() throws M4Exception {
		this.setTheParameterObject(null);
	}
	
	/**
	 * @see Parameter#copy(Step)
	 */
	public edu.udo.cs.miningmart.m4.Parameter copy(edu.udo.cs.miningmart.m4.Step newStep)
		throws M4Exception {
		
		Parameter theCopy = new Parameter(this.getM4Db());
		
		theCopy.setTheStep(newStep);
		
		theCopy.setParameterName(this.getParameterName());
		theCopy.setParamNr(this.getParamNr());
		theCopy.setTheParameterObject(this.getTheParameterObject());
		theCopy.setParameterType(this.getParameterType());
		theCopy.setDocumentation(this.getDocumentation());

		// Setting the operator: please refer to comment in setOperator(Operator) !
		if (newStep != null) {
			theCopy.setTheOperator(newStep.getTheOperator());
		}
		else {
			theCopy.setTheOperator(null);
		}
		
		return theCopy;
	}
	
	/**
	 * @see Parameter#getValue()
	 */
	public edu.udo.cs.miningmart.m4.Value getValue() throws M4Exception {
		edu.udo.cs.miningmart.m4.M4Object parObj = this.getTheParameterObject();
		if (parObj == null)
			return null;
		
		if (! (parObj instanceof Value)) {
			super.doPrint(Print.MAX,
				"Warning: ParameterImpl.getValue() called on non-value class " +
				parObj.getClass().getName() + "!");
			return null;
		}
		else {
			return (edu.udo.cs.miningmart.m4.Value) parObj;
		}
	}

	/**
	 * @see Parameter#removeValue()
	 */
	public void removeValue() throws M4Exception {
		this.removeParameterObject();
	}

}
/*
 * Historie
 * --------
 * 
 * $Log: Parameter.java,v $
 * Revision 1.5  2006/04/11 14:10:13  euler
 * Updated license text.
 *
 * Revision 1.4  2006/04/06 16:31:13  euler
 * Prepended license remark.
 *
 * Revision 1.3  2006/03/30 16:07:14  scholz
 * fixed author tags for release
 *
 * Revision 1.2  2006/01/06 16:25:04  euler
 * Updates and bugfixes in the delete-Mechanism for M4Data objects.
 *
 * Revision 1.1  2006/01/03 09:54:17  hakenjos
 * Initial version!
 *
 */
