/*******************************************************************************
 * Copyright (c) 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.ws.internal.consumption.ui.widgets.runtime;

import java.util.Vector;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jst.ws.internal.common.J2EEUtils;
import org.eclipse.jst.ws.internal.common.ResourceUtils;
import org.eclipse.jst.ws.internal.common.ServerUtils;
import org.eclipse.jst.ws.internal.common.StringToIProjectTransformer;
import org.eclipse.jst.ws.internal.consumption.ui.common.ClientServerSelectionUtils;
import org.eclipse.jst.ws.internal.consumption.ui.common.ServerSelectionUtils;
import org.eclipse.jst.ws.internal.consumption.ui.wizard.ClientProjectTypeRegistry;
import org.eclipse.jst.ws.internal.consumption.ui.wsrt.WebServiceRuntimeExtensionUtils;
import org.eclipse.jst.ws.internal.data.TypeRuntimeServer;
import org.eclipse.wst.command.internal.provisional.env.core.SimpleCommand;
import org.eclipse.wst.command.internal.provisional.env.core.common.Environment;
import org.eclipse.wst.command.internal.provisional.env.core.common.MessageUtils;
import org.eclipse.wst.command.internal.provisional.env.core.common.SimpleStatus;
import org.eclipse.wst.command.internal.provisional.env.core.common.Status;
import org.eclipse.wst.command.internal.provisional.env.core.context.ResourceContext;
import org.eclipse.wst.command.internal.provisional.env.core.selection.SelectionList;
import org.eclipse.wst.command.internal.provisional.env.core.selection.SelectionListChoices;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.server.core.IRuntime;
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.IServerType;
import org.eclipse.wst.server.core.ServerCore;
import org.eclipse.wst.ws.internal.parser.wsil.WebServicesParser;
import org.eclipse.wst.ws.internal.provisional.wsrt.IContext;
import org.eclipse.wst.ws.internal.provisional.wsrt.ISelection;
import org.eclipse.wst.ws.internal.provisional.wsrt.IWebServiceClient;
import org.eclipse.wst.ws.internal.provisional.wsrt.IWebServiceRuntime;
import org.eclipse.wst.ws.internal.provisional.wsrt.WebServiceClientInfo;
import org.eclipse.wst.ws.internal.provisional.wsrt.WebServiceScenario;
import org.eclipse.wst.ws.internal.provisional.wsrt.WebServiceState;
import org.eclipse.wst.ws.internal.wsrt.SimpleContext;

public class ClientRuntimeSelectionWidgetDefaultingCommand extends SimpleCommand
{   
  protected MessageUtils msgUtils_;
  // clientRuntimeJ2EEType contains the default client runtime and J2EE level based on the initial selection.
  // If the initialSeleciton does not result in a valid client runtime and J2EE level, clientRuntimeJ2EEType
  // should remain null for the life of this instance.  
  private WSRuntimeJ2EEType    clientRuntimeJ2EEType_;
  
  private TypeRuntimeServer    clientIds_;
  private SelectionListChoices runtimeClientTypes_;
  private String clientComponentName_;
  private String clientEarComponentName_;
  
  private Environment       environment_;
  private IContext          context_;
  private ISelection        selection_;
  private IWebServiceClient webServiceClient_;
  private ResourceContext   resourceContext_;
  private boolean           test_;
  
  //A note on initialSelections ...
  //The difference between clientInitialSelection_ and initialInitialSelection is that
  //clientInitialSelection_ comes from the ObjectSelectionOutputCommand while initialInitialSelection
  //is the actual thing that was selected before the wizard was launched. In the runtime/j2ee/project 
  //defaulting algorithm, clientInitialSelection will be given first priority. If, however, it is 
  //deemed that clientInitialProject is not a valid initial selection, initialInitialSelection
  //will be given second priority. Things that could make an initialSelection invalid include
  //1. The containing project contains the Web service for which we are trying to create a client
  //2. The containing project has a J2EE level, server target, and project type combination which
  //   is not supported by any of the registered Web service runtimes.
  private IStructuredSelection clientInitialSelection_;
  private IProject clientInitialProject_;
  private String clientInitialComponentName_;
  private IStructuredSelection initialInitialSelection_;
  private IProject initialInitialProject_;

  private String clientJ2EEVersion_;
  protected boolean clientNeedEAR_ = true;
  
  private String wsdlURI_;
  private WebServicesParser parser_;


  public ClientRuntimeSelectionWidgetDefaultingCommand()
  {
    super();
    String  pluginId = "org.eclipse.jst.ws.consumption.ui";
    msgUtils_ = new MessageUtils( pluginId + ".plugin", this );
  }
  
  public void setClientTypeRuntimeServer( TypeRuntimeServer ids )
  {
    clientIds_ = ids;
  }
  
  public TypeRuntimeServer getClientTypeRuntimeServer()
  {
    return clientIds_; 
  }
  
  public SelectionListChoices getRuntime2ClientTypes()
  {
    return runtimeClientTypes_;
  }
  
  public String getClientProjectName()
  {
    return getRuntime2ClientTypes().getChoice().getChoice().getList().getSelection();
  }
  
  public String getClientEarProjectName()
  {
    return getRuntime2ClientTypes().getChoice().getChoice().getChoice().getList().getSelection();
  }
  
  public String getClientComponentName()
  {
    return clientComponentName_;
  }
  
  public String getClientEarComponentName()
  {
    return clientEarComponentName_;
  }
  
  public String getClientComponentType()
  {
    return  getRuntime2ClientTypes().getChoice().getList().getSelection();
  }
  
  public String getClientJ2EEVersion()
  {
    return clientJ2EEVersion_;
  }
  
  public IWebServiceClient getWebService()
  {
    return webServiceClient_;  
  }
  
  public Environment getEnvironment()
  {
    return environment_;
  }
  
  public IContext getContext()
  {
    return context_;
  }  
  
  public ISelection getSelection()
  {
    return selection_;    
  }
  
  /* (non-Javadoc)
   * @see org.eclipse.wst.command.env.core.Command#execute(org.eclipse.wst.command.internal.provisional.env.core.common.Environment)
   */
  public Status execute(Environment environment)
  {
    try
    {

	  String[] runtimeIds = WebServiceRuntimeExtensionUtils.getRuntimesByClientType(clientIds_.getTypeId()); 
      SelectionList list = new SelectionList(runtimeIds, 0);
      Vector choices = new Vector();
      for (int i = 0; i < runtimeIds.length; i++) {
        choices.add(getClientTypesChoice(runtimeIds[i]));
      }
      runtimeClientTypes_ = new SelectionListChoices(list, choices);
      //setClientDefaultRuntimeFromPreference();
      //setClientDefaultJ2EEVersionFromPreference();
      //clientRuntimeJ2EEType_ = getClientRuntimeAndJ2EEFromProject(clientInitialProject_);
      //if (clientRuntimeJ2EEType_ != null)
      //{
        //clientJ2EEVersion_ = clientRuntimeJ2EEType_.getJ2eeVersionId();
        //setClientRuntimeId(clientRuntimeJ2EEType_.getWsrId());
        //setClientProjectType(clientRuntimeJ2EEType_.getClientProjectTypeId());
      //}
	  setClientRuntimeId((WebServiceRuntimeExtensionUtils.getRuntimesByClientType(clientIds_.getTypeId()))[0]);
	  setClientComponentType();
	  clientJ2EEVersion_ = (WebServiceRuntimeExtensionUtils.getWebServiceRuntimeById(clientIds_.getRuntimeId()).getJ2eeLevels())[0];
	  
	  
      //If clientInitialProject is the service project, check the initialInitialProject
      //to see if it is valid.
	  /*
      ValidationUtils vu = new ValidationUtils();
      if (vu.isProjectServiceProject(clientInitialProject_, wsdlURI_, parser_))
      {            
        clientRuntimeJ2EEType_ = getClientRuntimeAndJ2EEFromProject(initialInitialProject_);
        if (clientRuntimeJ2EEType_ != null)
        {
          clientJ2EEVersion_ = clientRuntimeJ2EEType_.getJ2eeVersionId();
          setClientRuntimeId(clientRuntimeJ2EEType_.getWsrId());
          setClientProjectType(clientRuntimeJ2EEType_.getClientProjectTypeId());
          //Since the original clientIntialProject was invalid but initialInitialProject is valid,
          //reset clientInitalProject_ to be initialInitialProject for the benefit of
          //downstream project defaulting.
          clientInitialProject_ = initialInitialProject_;
        }
      }
      */
      setClientDefaultProject();
      setClientDefaultEAR();
      setClientDefaultServer();
      updateClientEARs();
      
      //Calculate default IWebServiceClient
      setDefaultsForExtension(environment);
      return new SimpleStatus("");
    } catch (Exception e)
    {
      //Catch all Exceptions in order to give some feedback to the user
      Status errorStatus = new SimpleStatus("", msgUtils_.getMessage("MSG_ERROR_TASK_EXCEPTED",new String[]{e.getMessage()}),Status.ERROR, e);
      environment.getStatusHandler().reportError(errorStatus);
      return errorStatus;
    }
    
  }
  

  /**
   * 
   * @param runtimeId
   * @return
   */
  private SelectionListChoices getClientTypesChoice(String runtimeId)
  {
    String[] clientComponentTypes;
	clientComponentTypes = WebServiceRuntimeExtensionUtils.getClientProjectTypes(clientIds_.getTypeId(), runtimeId);
    SelectionList list = new SelectionList(clientComponentTypes, 0);
    Vector choices = new Vector();
    for (int i = 0; i < clientComponentTypes.length; i++) {
      choices.add(getProjectChoice(clientComponentTypes[i]));
    }
    return new SelectionListChoices(list, choices);
  }
    
  /**
   * 
   * @param clientType
   * @return
   * 
   */
  private SelectionListChoices getProjectChoice(String clientType)
  {
    //IProject[] projects = ClientProjectTypeRegistry.getInstance().getProjects(clientType);	  
    //String[] projectNames = new String[projects.length];
	    //for (int i = 0; i < projectNames.length; i++)
		  //    projectNames[i] = projects[i].getName();	  
	String[] projectNames = J2EEUtils.getProjectsContainingComponentOfType(clientType);
    SelectionList list = new SelectionList(projectNames, 0);
    Vector choices = new Vector();
    for (int i = 0; i < projectNames.length; i++)
	{
	  IProject project = ProjectUtilities.getProject(projectNames[i]);
      choices.add(getProjectEARChoice(project));
	}
    return new SelectionListChoices(list, choices, getEARProjects());
  }
  
/**
 * 
 * @param project
 * @return
 */
  protected SelectionListChoices getProjectEARChoice(IProject project)
  {
    Vector v = new Vector();
    String[] flexProjects = getAllFlexibleProjects();
    SelectionList list = new SelectionList(flexProjects, 0);
    return new SelectionListChoices(list, null);
  }
  
  protected SelectionList getEARProjects()
  {
    /*
    IProject[] earProjects = J2EEUtils.getEARProjects();
    String[] earProjectNames = new String[earProjects.length];
    for (int i=0; i<earProjects.length; i++)
    {
      earProjectNames[i] = earProjects[i].getName();
    }
    */
    String[] flexProjects = getAllFlexibleProjects();
    return new SelectionList(flexProjects, 0);
  }

  // rskreg
  /*
  private String[] gatherAttributeValues(IConfigurationElement[] elements, String key)
  {
    Vector v = new Vector();
    for (int i = 0; i < elements.length; i++)
    {
      String value = elements[i].getAttribute(key);
      if (value != null && value.length() > 0)
      {
        if (!v.contains(value))
          v.add(value);
      }
    }
    return (String [])v.toArray(new String[0]);
  }
  */
  // rskreg
  
  // rskreg
  /*
  private void setClientDefaultRuntimeFromPreference()
  {
    PersistentServerRuntimeContext context = WebServiceConsumptionUIPlugin.getInstance().getServerRuntimeContext();
    String pRuntimeId = context.getRuntimeId();

    //set the client runtime to be the preferred runtime if the client type allows.
    setClientRuntimeId(pRuntimeId);
  }
  */
  // rskreg
  
  private void setClientRuntimeId(String id)
  {
    String[] clientRuntimeIds = getRuntime2ClientTypes().getList().getList();
    for (int i=0; i<clientRuntimeIds.length;i++)
    {
    	if(clientRuntimeIds[i].equals(id))
    	{
    	  getClientTypeRuntimeServer().setRuntimeId(id);
		  getRuntime2ClientTypes().getList().setIndex(i);
		  break;
   	    }
    }    
  }
  
  private void setClientProjectType(String id)
  {
    String[] clientProjectTypeIds = getRuntime2ClientTypes().getChoice().getList().getList();
    for (int i=0; i<clientProjectTypeIds.length;i++)
    {
    	if(clientProjectTypeIds[i].equals(id))
    	{
    	  getRuntime2ClientTypes().getChoice().getList().setIndex(i);
		  break;
   	    }
    }        
  }
  
  // rskreg
  /*
  protected void setClientDefaultJ2EEVersionFromPreference()
  {
    if (clientIds_ != null)
    {
      String runtimeId = clientIds_.getRuntimeId();
      if (runtimeId != null)
      {
        IWebServiceRuntime wsr = WebServiceServerRuntimeTypeRegistry.getInstance().getWebServiceRuntimeById(runtimeId);
        if (wsr != null)
        {
          String[] versions = wsr.getJ2EEVersions();
          if (versions != null && versions.length > 0)
          {
          	PersistentServerRuntimeContext context = WebServiceConsumptionUIPlugin.getInstance().getServerRuntimeContext();
          	String pJ2EE = context.getJ2EEVersion();
          	if (pJ2EE!=null && pJ2EE.length()>0)
          	{
              for (int i=0;i<versions.length;i++)
          	  {
          		if (versions[i].equals(pJ2EE))
          		{
          	      clientJ2EEVersion_ = versions[i];
          		  return;
          		}
          	  }
          	}
          	clientJ2EEVersion_ = versions[0];
          	return;          	
          }
        }
      }
    }  	
  }
  */
  // rskreg
  // rskreg
  /*
  private WSRuntimeJ2EEType getClientRuntimeAndJ2EEFromProject(IProject project)
  {
    WSRuntimeJ2EEType cRJ2EE = null;
    //If there is a valid initial selection, use it to determine
    //reasonable J2EE version and Web service runtime values

    if (project != null && project.exists())
    {
      if (ResourceUtils.isWebProject(project) || ResourceUtils.isEJBProject(project) || ResourceUtils.isAppClientProject(project) || ResourceUtils.isTrueJavaProject(project))
      {
        WebServiceClientTypeRegistry wsctReg = WebServiceClientTypeRegistry.getInstance();
        
        //Get the J2EE level
        String versionString = null;
        if (!ResourceUtils.isTrueJavaProject(project))
        {
	      int versionId = J2EEUtils.getJ2EEVersion(project);        
	      versionString = String.valueOf(versionId);
        }

        //Get the runtime target of the project
        IRuntime runtimeTarget = ServerSelectionUtils.getRuntimeTarget(project.getName());
        String runtimeTargetId = null;
        if (runtimeTarget != null) 
          runtimeTargetId = runtimeTarget.getRuntimeType().getId();
        
        //Get the client project type
        String clientProjectTypeId = getClientProjectTypeFromRuntimeId(project, clientIds_.getRuntimeId());
        
        //If the preferred runtime supports this J2EE level and server target, keep it
        if ((versionString == null || wsctReg.doesRuntimeSupportJ2EELevel(versionString, clientIds_.getRuntimeId())) &&
            ((runtimeTarget == null) ||
             ((runtimeTarget != null) && wsctReg.doesRuntimeSupportServerTarget(runtimeTargetId, clientIds_.getRuntimeId()))) &&
             (clientProjectTypeId != null)
           )
        {
          //Set the J2EE level and web service runtime to match the project
          cRJ2EE = new WSRuntimeJ2EEType();
          cRJ2EE.setJ2eeVersionId(versionString);
          cRJ2EE.setWsrId(clientIds_.getRuntimeId());
          cRJ2EE.setClientProjectTypeId(clientProjectTypeId);
          return cRJ2EE;
        } else
        {
          //Look for a runtime that matches
          String[] validRuntimes = wsctReg.getRuntimesByType(clientIds_.getTypeId());
          for (int i = 0; i < validRuntimes.length; i++)
          {
            String thisClientProjectTypeId = getClientProjectTypeFromRuntimeId(project, validRuntimes[i]); 
            if ((versionString == null || wsctReg.doesRuntimeSupportJ2EELevel(versionString, validRuntimes[i])) &&
                ((runtimeTarget == null) ||
                 ((runtimeTarget != null) && wsctReg.doesRuntimeSupportServerTarget(runtimeTargetId, validRuntimes[i]))) &&
                 (thisClientProjectTypeId != null)
                )
            {
              cRJ2EE = new WSRuntimeJ2EEType();
              cRJ2EE.setJ2eeVersionId(versionString);
              cRJ2EE.setWsrId(validRuntimes[i]);
              cRJ2EE.setClientProjectTypeId(thisClientProjectTypeId);
              return cRJ2EE;
            }
          }
        }
      }
    }    
    return cRJ2EE;
  }
  */
  // rskreg
  
  private void setClientComponentType()
  {
	  getRuntime2ClientTypes().getChoice().getList().setIndex(0);	  
  }

  private void setClientDefaultProject()
  {
    if (clientInitialProject_ != null)
    {
      getRuntime2ClientTypes().getChoice().getChoice().getList().setSelectionValue(clientInitialProject_.getName());
      String moduleName = null;
      if (clientInitialComponentName_!=null && clientInitialComponentName_.length()>0)
      {
        moduleName = clientInitialComponentName_;
      }
      else
      {
        moduleName = J2EEUtils.getFirstWebModuleName(clientInitialProject_);
      }
      clientComponentName_ = moduleName;
      String version = String.valueOf(J2EEUtils.getJ2EEVersion(clientInitialProject_, moduleName));
      String[] validVersions = WebServiceRuntimeExtensionUtils.getWebServiceRuntimeById(clientIds_.getRuntimeId()).getJ2eeLevels();
      for (int i=0; i< validVersions.length; i++)
      {
        if (validVersions[i].equals(version))
        {
          clientJ2EEVersion_ = validVersions[i];
        }
      }           
    }
    else
    {
      //Pick the first one
      IProject[] projects = WebServiceRuntimeExtensionUtils.getAllProjects();
      if (projects.length>0)
      {
        getRuntime2ClientTypes().getChoice().getChoice().getList().setSelectionValue(projects[0].getName());
        String moduleName = J2EEUtils.getFirstWebModuleName(projects[0]);
        clientComponentName_ = moduleName;
        String version = String.valueOf(J2EEUtils.getJ2EEVersion(projects[0], moduleName));
        String[] validVersions = WebServiceRuntimeExtensionUtils.getWebServiceRuntimeById(clientIds_.getRuntimeId()).getJ2eeLevels();
        for (int i=0; i< validVersions.length; i++)
        {
          if (validVersions[i].equals(version))
          {
            clientJ2EEVersion_ = validVersions[i];
          }
        }        
        
      }
      else
      {
        //there are no projects in the workspace. Pass the default names for new projects.
        getRuntime2ClientTypes().getChoice().getChoice().getList().setSelectionValue(ResourceUtils.getDefaultWebProjectName());
        clientComponentName_ = ResourceUtils.getDefaultWebComponentName();
      }      
    }
  }
  // rskreg
  /*
  private void setClientDefaultProject()
  {    
	//Handle the case where no valid initial selection exists
    if (clientInitialProject_ == null || (clientInitialProject_!=null && clientRuntimeJ2EEType_==null))
    {
      //Select the first existing project that is valid.
      setClientProjectToFirstValid();
      return;
    }    

    ValidationUtils vu = new ValidationUtils();
    if (!vu.isProjectServiceProject(clientInitialProject_, wsdlURI_, parser_))
    {
      getRuntime2ClientTypes().getChoice().getChoice().getList().setSelectionValue(clientInitialProject_.getName());
    }
    else
    {
      setClientProjectToFirstValid();
    }

  }
  */
  /*
  private void setClientProjectToFirstValid()
  {
    WebServiceClientTypeRegistry wsctReg = WebServiceClientTypeRegistry.getInstance();
    ValidationUtils vu = new ValidationUtils();
    String[] projectNames = getRuntime2ClientTypes().getChoice().getChoice().getList().getList();
    for (int i=0;i<projectNames.length; i++)
    {
      IProject project = (IProject)((new StringToIProjectTransformer().transform(projectNames[i])));
      if (project.isOpen() && (ResourceUtils.isWebProject(project) || ResourceUtils.isEJBProject(project) || ResourceUtils.isAppClientProject(project)))
      {
        //Get the J2EE level
        int versionId = J2EEUtils.getJ2EEVersion(project);
        String versionString = String.valueOf(versionId);
        
        //Get the runtime target of the project
        IRuntime runtimeTarget = ServerSelectionUtils.getRuntimeTarget(project.getName());
        String runtimeTargetId = null;
        if (runtimeTarget != null) 
          runtimeTargetId = runtimeTarget.getRuntimeType().getId();
        
        if (clientJ2EEVersion_ != null && clientJ2EEVersion_.length()>0 && clientJ2EEVersion_.equals(versionString))
        {
          if (wsctReg.doesRuntimeSupportJ2EELevel(versionString, clientIds_.getRuntimeId()) &&
             ((runtimeTarget == null) || 
             ((runtimeTarget!=null) && wsctReg.doesRuntimeSupportServerTarget(runtimeTargetId, clientIds_.getRuntimeId()))) 
             )
          {
            if (!vu.isProjectServiceProject(project, wsdlURI_, parser_))
            {        	
              getRuntime2ClientTypes().getChoice().getChoice().getList().setSelectionValue(projectNames[i]);
              return;
            }
          }
        }
      }
    }
    
    //No valid project was found. Enter a new project name.
    getRuntime2ClientTypes().getChoice().getChoice().getList().setSelectionValue(ResourceUtils.getDefaultWebProjectName());
  }
  */
  // rskreg
  
  protected IResource getResourceFromInitialSelection(IStructuredSelection selection)
  {
    if (selection != null && selection.size() == 1)
    {
      Object obj = selection.getFirstElement();
      if (obj != null) 
      {
        try
        { 
          IResource resource = ResourceUtils.getResourceFromSelection(obj);
          return resource;
        } catch(CoreException e)
        {
          return null;
        }        
      }
    }
    return null;
  }
  
  /*
  private void setClientDefaultEAR2()
  {
    //Client-side
    String initialClientProjectName = getRuntime2ClientTypes().getChoice().getChoice().getList().getSelection(); 
    IProject initialClientProject = (IProject)((new StringToIProjectTransformer()).transform(initialClientProjectName));    
    IProject defaultClientEAR = getDefaultEARFromClientProject(initialClientProject);
    getRuntime2ClientTypes().getChoice().getChoice().getChoice().getList().setSelectionValue(defaultClientEAR.getName());
  }
  */
  
  private void setClientDefaultEAR()
  {    
    String initialClientProjectName = getRuntime2ClientTypes().getChoice().getChoice().getList().getSelection(); 
    IProject initialClientProject =   (IProject)((new StringToIProjectTransformer()).transform(initialClientProjectName));
    IVirtualComponent[] earComps = J2EEUtils.getReferencingEARComponents(initialClientProject, clientComponentName_);
    if (earComps.length>0)
    {
      //Pick the first one
      IVirtualComponent earComp = earComps[0];
      String earProjectName = earComp.getProject().getName();
      String earComponentName = earComp.getName();
      getRuntime2ClientTypes().getChoice().getChoice().getChoice().getList().setSelectionValue(earProjectName);
      clientEarComponentName_ = earComponentName;      
    }
    else
    {
      //Component is not associated with any EARs, so pick the first EAR you see with the correct J2EE version.
      IVirtualComponent[] allEarComps = J2EEUtils.getAllEARComponents();
      if (allEarComps.length>0)
      {
        for (int i=0; i<allEarComps.length; i++)
        {
          if (clientJ2EEVersion_.equals(String.valueOf(J2EEUtils.getJ2EEVersion(allEarComps[i]))))
          {
            String earProjectName = allEarComps[i].getProject().getName();
            getRuntime2ClientTypes().getChoice().getChoice().getChoice().getList().setSelectionValue(earProjectName);
            clientEarComponentName_ = allEarComps[i].getName();
            
          }
            
        }
      }
      else
      {
        //there are no Ears.
        getRuntime2ClientTypes().getChoice().getChoice().getChoice().getList().setSelectionValue(ResourceUtils.getDefaultClientEARProjectName());
        clientEarComponentName_ = ResourceUtils.getDefaultClientEARComponentName();
      }
      
      
    }
  }
  
  /**
   * 
   * @param project
   * @return
   * 
   * @deprecated Needs to be re-written to deal with flexible project structure APIs 
   */
  /*
  protected IProject getDefaultEARFromClientProject(IProject project)
  {
    if (project!=null && project.exists()) 
    {
      IServer[] configuredServers = ServerUtil.getServersByModule(ResourceUtils.getModule(project), null);
      IServer firstSupportedServer = ClientServerSelectionUtils.getFirstSupportedServer(configuredServers, clientIds_.getTypeId() );
      
      EARNatureRuntime[] earProjects = J2EEUtils.getEARProjects(project, firstSupportedServer);
      if (earProjects!=null && earProjects[0] instanceof EARNatureRuntime) 
        return earProjects[0].getProject();
    }
    
    int versionId = -1;
    if (clientJ2EEVersion_ != null && clientJ2EEVersion_.length()>0)
    {
      versionId = Integer.parseInt(clientJ2EEVersion_);
    }
    EARNatureRuntime newEAR = J2EEUtils.getEAR(versionId);

    IProject earProject = ResourceUtils.getWorkspaceRoot().getProject(ResourceUtils.getDefaultClientEARProjectName());
      
    if (newEAR!=null)
      earProject = newEAR.getProject();

    return earProject;  	
  }
  */
  private void setClientDefaultServer()
  {
    String initialClientProjectName = runtimeClientTypes_.getChoice().getChoice().getList().getSelection();
    IRuntime runtimeTarget = ServerSelectionUtils.getRuntimeTarget(initialClientProjectName);
    String runtimeTargetId = null;
    if (runtimeTarget != null)
    {
      runtimeTargetId = runtimeTarget.getRuntimeType().getId();
      //Pick a compatible existing server if one exists.
      IServer[] servers = ServerSelectionUtils.getCompatibleExistingServers(runtimeTarget);
      if (servers!=null && servers.length>0)
      {
        for (int i=0; i<servers.length; i++)
        {
          String thisFactoryId = servers[0].getServerType().getId();
          //if (WebServiceRuntimeExtensionUtils.doesRuntimeSupportServer(clientIds_.getRuntimeId(), thisFactoryId))
          //{
            //Pick this server and return.
            clientIds_.setServerId(thisFactoryId);
            clientIds_.setServerInstanceId(servers[0].getId());
            return;
          //}
        }
      }
      
      //No compatible existing server, set the factory id to something the runtime supports
      String[] factoryIds = WebServiceRuntimeExtensionUtils.getWebServiceRuntimeById(clientIds_.getRuntimeId()).getServerFactoryIds();
      if (factoryIds!=null && factoryIds.length>0)
      {
        for (int i=0; i<factoryIds.length; i++)
        {
          IServerType serverType = ServerCore.findServerType(factoryIds[i]);
          if (serverType != null)
          {
            String serverRuntimeTypeId = serverType.getRuntimeType().getId();            
            if (serverRuntimeTypeId.equals(runtimeTargetId))
            {
              //Found a match
              clientIds_.setServerId(factoryIds[i]);
              return;
            }
          }
        }        
      }
      else
      {
        //Runtime does not specify any server factory ids
        IServerType[] serverTypes = ServerCore.getServerTypes();
        clientIds_.setServerId(serverTypes[0].getId());
      }
      
    }
    else
    {
      // The project has no server target so pick a server factory id that is supported by the runtime
      String[] fids = WebServiceRuntimeExtensionUtils.getWebServiceRuntimeById(clientIds_.getRuntimeId()).getServerFactoryIds();
      if (fids!=null && fids.length>0)
      {
        clientIds_.setServerId(fids[0]);  
      }
      else
      {
        //Runtime does not specify any server factory ids
        IServerType[] serverTypes = ServerCore.getServerTypes();
        clientIds_.setServerId(serverTypes[0].getId());        
      }
            
    }        
  }
  /*
  private void setClientDefaultServer()
  {
    //Calculate reasonable default server based on initial project selection. 
    String initialClientProjectName = runtimeClientTypes_.getChoice().getChoice().getList().getSelection(); 
    IProject initialClientProject = (IProject)((new StringToIProjectTransformer()).transform(initialClientProjectName));
    if (initialClientProject.exists())
    {
      String[] serverInfo = ClientServerSelectionUtils.getServerInfoFromExistingProject(initialClientProject, clientIds_.getTypeId(), clientIds_.getRuntimeId(), true);
      if (serverInfo!=null)
      {
        if (serverInfo[0]!=null && serverInfo[0].length()>0)
        {
          clientIds_.setServerId(serverInfo[0]);
        }
        if (serverInfo[1]!=null && serverInfo[1].length()>0)
        {
          clientIds_.setServerInstanceId(serverInfo[1]);
        }        
      }      
    }
    else //the project does not exist.
    {
      //Does the EAR exist?
      String initialClientEARProjectName = runtimeClientTypes_.getChoice().getChoice().getChoice().getList().getSelection();
      IProject initialClientEARProject = (IProject)((new StringToIProjectTransformer()).transform(initialClientEARProjectName));
      if (initialClientEARProject.exists())
      {
        String[] serverInfo = ClientServerSelectionUtils.getServerInfoFromExistingProject(initialClientEARProject, clientIds_.getTypeId(), clientIds_.getRuntimeId(), false);
        if (serverInfo!=null)
        {
          if (serverInfo[0]!=null && serverInfo[0].length()>0)
          {
            clientIds_.setServerId(serverInfo[0]);
          }
          if (serverInfo[1]!=null && serverInfo[1].length()>0)
          {
            clientIds_.setServerInstanceId(serverInfo[1]);
          }        
        }              
      }
      else
      {
        String[] serverInfo = ClientServerSelectionUtils.getServerFromClientRuntimeAndJ2EE(clientIds_.getRuntimeId(), clientJ2EEVersion_);
        if (serverInfo!=null)
        {
          if (serverInfo[0]!=null && serverInfo[0].length()>0)
          {
            clientIds_.setServerId(serverInfo[0]);
          }
          if (serverInfo[1]!=null && serverInfo[1].length()>0)
          {
            clientIds_.setServerInstanceId(serverInfo[1]);
          }        
        }        
      }
      
    }        
  }  
  */
  
  protected void updateClientProject(String projectName, String componentName, String serviceTypeId)
  {
    boolean isEJB = false;
    String implId = WebServiceRuntimeExtensionUtils.getImplIdFromTypeId(serviceTypeId);
    isEJB = (implId.equals("org.eclipse.jst.ws.wsImpl.ejb"));
    String[] updatedNames = ResourceUtils.getClientProjectComponentName(projectName, componentName, isEJB);
    getRuntime2ClientTypes().getChoice().getChoice().getList().setSelectionValue(updatedNames[0]);
    clientComponentName_ = updatedNames[1];
    
  }
  
  protected void updateClientEARs()
  {
  	//Set EAR selection to null if the project/server defaults imply an EAR should not be created
    String clientProjectName = getRuntime2ClientTypes().getChoice().getChoice().getList().getSelection();
  	IProject clientProject = (IProject)((new StringToIProjectTransformer()).transform(clientProjectName));
  	if (clientProject != null && clientProject.exists())
  	{
  	  //Get the runtime target on the serviceProject
  	  IRuntime clientTarget = ClientServerSelectionUtils.getRuntimeTarget(clientProjectName);
  	  String j2eeVersion = String.valueOf(J2EEUtils.getJ2EEVersion(clientProject, clientComponentName_));
  	  if (clientTarget != null)
  	  {
  	  	if (!ServerUtils.isTargetValidForEAR(clientTarget.getRuntimeType().getId(),j2eeVersion))
  	  	{
  	      //Default the EAR selection to be empty
  	  	  getRuntime2ClientTypes().getChoice().getChoice().getChoice().getList().setIndex(-1);
          clientEarComponentName_="";
  	  	  clientNeedEAR_ = false;
  	  	}  	  		
  	  }
  	  
  	}
  	else
  	{
  		//Use the server type
  		String clientServerTargetId = ServerUtils.getRuntimeTargetIdFromFactoryId(clientIds_.getServerId());
  		if (clientServerTargetId!=null && clientServerTargetId.length()>0)
  		{
  		  if (!ServerUtils.isTargetValidForEAR(clientServerTargetId,clientJ2EEVersion_))
  	  	  {
  	        //Default the EAR selection to be empty
  	  	    getRuntime2ClientTypes().getChoice().getChoice().getChoice().getList().setIndex(-1);
            clientEarComponentName_="";
  	  	    clientNeedEAR_ = false;
  	  	  }
  		}
  	}  	
  }  
  
  private void setDefaultsForExtension(Environment env)
  {
    IWebServiceRuntime wsrt = WebServiceRuntimeExtensionUtils.getWebServiceRuntime(clientIds_.getRuntimeId());
    if (wsrt != null)
    {
      WebServiceClientInfo wsInfo = new WebServiceClientInfo();

      wsInfo.setJ2eeLevel(clientJ2EEVersion_);
      wsInfo.setServerFactoryId(clientIds_.getServerId());
      wsInfo.setServerInstanceId(clientIds_.getServerInstanceId());
      wsInfo.setState(WebServiceState.UNKNOWN_LITERAL);
      wsInfo.setWebServiceRuntimeId(clientIds_.getRuntimeId());
      wsInfo.setWsdlURL(wsdlURI_);

      environment_ = env;
      webServiceClient_ = wsrt.getWebServiceClient(wsInfo);
      WebServiceScenario scenario = WebServiceScenario.CLIENT_LITERAL;
      if (resourceContext_ != null)
      {
        context_ = new SimpleContext(true, true, true, true, true, true, test_, false, scenario, resourceContext_.isOverwriteFilesEnabled(), resourceContext_
            .isCreateFoldersEnabled(), resourceContext_.isCheckoutFilesEnabled());
      }
    }
  
  }
  
  public void setClientInitialSelection(IStructuredSelection selection)
  {
    clientInitialSelection_ = selection;
    if (clientInitialProject_ == null)
    {
      clientInitialProject_ = getProjectFromInitialSelection(selection);
      clientInitialComponentName_ = getComponentNameFromInitialSelection(selection);
    }
  }

  public void setClientInitialProject(IProject clientInitialProject)
  {
    clientInitialProject_ = clientInitialProject;
  }
  
  public void setClientInitialComponentName(String name)
  {
    clientInitialComponentName_ = name;
  }  
  
  /**
   * @param initialInitialSelection_ The initialInitialSelection_ to set.
   */
  public void setInitialInitialSelection(IStructuredSelection initialInitialSelection)
  {
    initialInitialSelection_ = initialInitialSelection;
    initialInitialProject_ = getProjectFromInitialSelection(initialInitialSelection);
  }
  
  public boolean getClientNeedEAR()
  {
    return clientNeedEAR_;
  }

  /**
   * @param parser_ The parser_ to set.
   */
  public void setWebServicesParser(WebServicesParser parser) {
  	parser_ = parser;
  }
  
  public void setWsdlURI(String wsdlURI)
  {
    wsdlURI_ = wsdlURI;
  }
  
  public void setTestService(boolean testService)
  {
    test_ = testService;
  }   
  
  public void setResourceContext( ResourceContext resourceContext )
  {
    resourceContext_ = resourceContext;   
  }  
  
  private IProject getProjectFromInitialSelection(IStructuredSelection selection)
  {
    if (selection != null && selection.size() == 1)
    {
      Object obj = selection.getFirstElement();
      if (obj != null) 
      {
        try
        { 
          IResource resource = ResourceUtils.getResourceFromSelection(obj);
          if (resource==null) 
            return null;
          IProject p = ResourceUtils.getProjectOf(resource.getFullPath());
          return p;
        } catch(CoreException e)
        {
          return null;
        }        
      }
    }
    return null;
  }
  
  private String getComponentNameFromInitialSelection(IStructuredSelection selection)
  {
    if (selection != null && selection.size() == 1)
    {
      Object obj = selection.getFirstElement();
      if (obj != null) 
      {
        try
        { 
          IResource resource = ResourceUtils.getResourceFromSelection(obj);
          if (resource==null) 
            return null;
          
          IVirtualComponent comp = ResourceUtils.getComponentOf(resource.getFullPath());
          if (comp!=null)
          {
            return comp.getName();
          }
        } catch(CoreException e)
        {
          return null;
        }        
      }
    }
    return null;
  }
  
  private String getClientProjectTypeFromRuntimeId(IProject p, String runtimeId)
  {
    //Navigate the runtimeClientTypes to see if we can navigate from the provided
    //runtime to the provided project's name.
    String pName = p.getName();
    String[] runtimeIds = getRuntime2ClientTypes().getList().getList();
    int numberOfRuntimes = runtimeIds.length;
    //Get the index of the runtimeId we are interested in
    for (int i=0; i<numberOfRuntimes; i++)
    {
      if (runtimeIds[i].equals(runtimeId))
      {
        //Get the list of client project types for this runtimeId
        SelectionListChoices clientProjectTypesToProjects= getRuntime2ClientTypes().getChoice(i);
        String[] clientProjectTypes = clientProjectTypesToProjects.getList().getList();
        for (int j=0; j<clientProjectTypes.length; j++)
        {
          //Get the list of projects for this clientProjectType. If pName
          //is in this list, we know the runtimeId supports this project
          //and we know the client project type.
          String[] clientProjects = clientProjectTypesToProjects.getChoice(j).getList().getList();
          for (int k=0; k<clientProjects.length; k++)
          {
            if (clientProjects[k].equals(pName))
            {
              //Found the project!!
              return clientProjectTypes[j];
            }
          }
        }
        
      }
    }

    //We didn't find the project under any of this runtimes client project types.
    //This means that this runtime does not support that client type. Return null
    return null;
  }
  
  protected String[] getAllFlexibleProjects()
  {
    Vector v = new Vector();
    IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
    for (int i = 0; i < projects.length; i++)
    {
      if (!projects[i].getName().equals("Servers") && !projects[i].getName().startsWith("."))
      {
        v.add(projects[i].getName());
      }
    }    
    
    return (String[])v.toArray(new String[0]);
    
  }
  
  /**
   * This inner class is being used to pass around Web service runtime
   * and J2EE level information.
   * 
   */
  protected class WSRuntimeJ2EEType
  {
    private String wsrId_;
    private String j2eeVersionId_;
    private String clientProjectTypeId; //only used for client-side defaulting
    
    public WSRuntimeJ2EEType()
    {
     //making this ctor public so that subclasses can instantiate. 
    }    
    /**
     * @return Returns the j2eeVersionId_.
     */
    public String getJ2eeVersionId()
    {
      return j2eeVersionId_;
    }
    /**
     * @param versionId_ The j2eeVersionId_ to set.
     */
    public void setJ2eeVersionId(String versionId_)
    {
      j2eeVersionId_ = versionId_;
    }
    /**
     * @return Returns the wsrId_.
     */
    public String getWsrId()
    {
      return wsrId_;
    }
    /**
     * @param wsrId_ The wsrId_ to set.
     */
    public void setWsrId(String wsrId_)
    {
      this.wsrId_ = wsrId_;
    }    
    
    /**
     * @return Returns the clientProjectTypeId.
     */
    public String getClientProjectTypeId()
    {
      return clientProjectTypeId;
    }
    /**
     * @param clientProjectTypeId The clientProjectTypeId to set.
     */
    public void setClientProjectTypeId(String clientProjectTypeId)
    {
      this.clientProjectTypeId = clientProjectTypeId;
    }
  }
}