/*
 * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.ejte.ccl.reporter;

/**
	@Class: TestSuite
	@Description: Class holding One TestSuite info.
	@Author : Ramesh Mandava
	@Last Modified : By Ramesh on 10/24/2001
	@Last Modified : By Ramesh on 1/20/2002 , For preserving order of entry of tests 		used a separate testIdVector
*/


import java.util.Hashtable;
import java.util.Vector;

public class TestSuite 
{
	private String id;
	private String name;
	private String description;

	Hashtable testHash;
	Vector testIdVector;

	public TestSuite( String id, String name, String description )
	{
		this.id = id;
		this.name= name;
		this.description = description;
		testHash = new Hashtable();
		testIdVector = new Vector();
	}

	public TestSuite (String id, String name )
	{
		this.id = id;
		this.name = name;
		this.description=ReporterConstants.NA;
		testHash = new Hashtable();
		testIdVector = new Vector();
	}

	public TestSuite (String id )
	{
		this.id = id;
		this.name = ReporterConstants.NA;
		this.description=ReporterConstants.NA;
		testHash = new Hashtable();
		testIdVector = new Vector();
	}

	public String getId( )
	{
		return id;
	}

	public String getName( )
	{
		return name;
	}

	public String getDescription( )
	{
		return description;
	}

	public Vector getTestIdVector( )
	{
		return testIdVector;
	}
	public void setTestIdVector( Vector tidVector)
	{
		testIdVector= tidVector;
	}

	public Hashtable getTestHash( )
	{
		return testHash;
	}
	public void setTestHash( Hashtable testHash )
	{
		this.testHash= testHash;
	}

	public void addTest( Test myTest )
	{
		if ( testHash.put( myTest.getId().trim(), myTest) != null ) 
		{
			System.err.println("Error : Test was added before only. Still allowing. Old value of the test will be overridden" );
		}
			
		testIdVector.addElement( myTest.getId().trim() );
	}	

}
