package org.eclipse.jst.j2ee.ejb.test;

import java.util.List;

import junit.framework.TestSuite;

import org.eclipse.jst.j2ee.ejb.AssemblyDescriptor;
import org.eclipse.jst.j2ee.ejb.ContainerManagedEntity;
import org.eclipse.jst.j2ee.ejb.EJBResource;
import org.eclipse.jst.j2ee.ejb.EjbFactory;
import org.eclipse.jst.j2ee.ejb.EnterpriseBean;
import org.eclipse.jst.j2ee.ejb.Entity;

public class EntityTest extends EjbEMFTestBase{

	/**
	 * @param name
	 */
	public EntityTest(String name) {
		super(name);
	}
	
	private Entity getInstance() {
		return EjbFactory.eINSTANCE.createEntity();
	}
    public void test_Entity() {
        Entity tmpEntity = getInstance();
        assertNotNull(tmpEntity);
    }
    
    /* (non-Javadoc)
	 * @see junit.framework.TestCase#setUp()
	 */
	protected void setUp() throws Exception {
		super.setUp();
	}

    public void test_getPrimaryKeyName() throws Exception{
    	init();
    	EJBResource DD = (EJBResource) ejbFile.getDeploymentDescriptorResource();
    	
    	AssemblyDescriptor assemblyDescriptor = DD.getEJBJar().getAssemblyDescriptor();
		List enterpriseBeans = DD.getEJBJar().getEnterpriseBeans();
		ContainerManagedEntity entityBean = null;
		EnterpriseBean bean = null;
		for (int x=0; x< enterpriseBeans.size(); ++x) {
			bean = (EnterpriseBean) enterpriseBeans.get(x);
			if (bean.isEntity() && bean.isContainerManagedEntity()) {
				entityBean = (ContainerManagedEntity) bean;
				break;
			}
		}
		if (entityBean != null) {
			String name = entityBean.getPrimaryKeyName();
			String primKeyName = entityBean.getPrimaryKey().getQualifiedName();
			assertEquals(name,primKeyName);
			
		}
    }

    
   /* public void test_isContainerManagedEntity() {
        Entity objEntity = getInstance();
        boolean retValue = false;
        retValue = objEntity.isContainerManagedEntity();
    }*/

    public void test_setPrimaryKeyName() throws Exception {
    	init();
    	EJBResource DD = (EJBResource) ejbFile.getDeploymentDescriptorResource();
    	
    	AssemblyDescriptor assemblyDescriptor = DD.getEJBJar().getAssemblyDescriptor();
		List enterpriseBeans = DD.getEJBJar().getEnterpriseBeans();
		ContainerManagedEntity entityBean = null;
		EnterpriseBean bean = null;
		for (int x=0; x< enterpriseBeans.size(); ++x) {
			bean = (EnterpriseBean) enterpriseBeans.get(x);
			if (bean.isEntity() && bean.isContainerManagedEntity()) {
				entityBean = (ContainerManagedEntity) bean;
				break;
			}
		}
		if (entityBean != null) {
			String name = entityBean.getPrimaryKeyName();
			String newName = "NewName" ;
			entityBean.setPrimaryKeyName(newName);
			assertEquals(newName,entityBean.getPrimaryKeyName());
		}    
    }

  /* public void test_isReentrant() {

        Entity objEntity = getInstance();
        boolean retValue = false;
        retValue = objEntity.isReentrant();
    }

    public void test_setReentrant() {

        Entity objEntity = getInstance();
        boolean newReentrant = false;
        objEntity.setReentrant(newReentrant);
    }*/

  /*  public void test_unsetReentrant() {

        Entity objEntity = getInstance();
        objEntity.unsetReentrant();
    } */

   /* public void test_isSetReentrant() {

        Entity objEntity = getInstance();
        boolean retValue = false;
        retValue = objEntity.isSetReentrant();
    } */

  /*  public void test_getPrimaryKey() {

        Entity objEntity = getInstance();
        JavaClass retValue = null;
        retValue = objEntity.getPrimaryKey();
    }

    public void test_setPrimaryKey() {

        Entity objEntity = getInstance();
        JavaClass newPrimaryKey = null;
        objEntity.setPrimaryKey(newPrimaryKey);
    } */
    
    public static junit.framework.Test suite() {
		TestSuite suite = new TestSuite();
		suite.addTest(new EntityTest("test_setPrimaryKeyName"));
		suite.addTest(new EntityTest("test_getPrimaryKeyName"));
		return suite;
	}



}
