/*******************************************************************************
 * Copyright (c) 2004, 2010 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
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20060131 121071   rsinha@ca.ibm.com - Rupam Kuehner     
 * 20060221   119111 rsinha@ca.ibm.com - Rupam Kuehner
 * 20060227   124392 rsinha@ca.ibm.com - Rupam Kuehner
 * 20060315   131963 rsinha@ca.ibm.com - Rupam Kuehner
 * 20060418   129688 rsinha@ca.ibm.com - Rupam Kuehner
 * 20060427   126780 rsinha@ca.ibm.com - Rupam Kuehner
 * 20060427   138058 joan@ca.ibm.com - Joan Haggarty
 * 20060523   133714 joan@ca.ibm.com - Joan Haggarty
 * 20060525   143843 joan@ca.ibm.com - Joan Haggarty
 * 20060905   156230 kathy@ca.ibm.com - Kathy Chan, Handling projects with no target runtime
 * 20070319	  159458 mahutch@ca.ibm.com - Mark Hutchinson added in some null checks
 * 20071212	  200193 gilberta@ca.ibm.com - Gilbert Andrews
 * 20080326   171705 trungha@ca.ibm.com - Trung, improve AntTask errors report
 * 20080326   221364 kathy@ca.ibm.com - Kathy Chan
 * 20080402   225032 makandre@ca.ibm.com - Andrew Mak
 * 20080527   234226 kathy@ca.ibm.com - Kathy Chan
 * 20080730   242611 zhang@ca.ibm.com - Peter Moogk
 * 20080925   242312 ericdp@ca.ibm.com - Eric D. Peters, Cannot create BUJB WS from Bean in Java project using ANT tasks
 * 20100929   326549 mahutch@ca.ibm.com - Mark Hutchinson, Web Service Wizard Can Default to invalid project type
 *******************************************************************************/
package org.eclipse.jst.ws.internal.creation.ui.widgets.runtime;

import java.util.ArrayList;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jst.ws.internal.common.ResourceUtils;
import org.eclipse.jst.ws.internal.common.ServerUtils;
import org.eclipse.jst.ws.internal.consumption.common.FacetMatcher;
import org.eclipse.jst.ws.internal.consumption.common.FacetUtils;
import org.eclipse.jst.ws.internal.consumption.common.RequiredFacetVersion;
import org.eclipse.jst.ws.internal.consumption.ui.ConsumptionUIMessages;
import org.eclipse.jst.ws.internal.consumption.ui.common.DefaultingUtils;
import org.eclipse.jst.ws.internal.consumption.ui.plugin.WebServiceConsumptionUIPlugin;
import org.eclipse.jst.ws.internal.consumption.ui.preferences.PersistentServerRuntimeContext;
import org.eclipse.jst.ws.internal.consumption.ui.preferences.ProjectTopologyContext;
import org.eclipse.jst.ws.internal.consumption.ui.widgets.runtime.ClientRuntimeSelectionWidgetDefaultingCommand;
import org.eclipse.jst.ws.internal.consumption.ui.wsrt.FacetMatchCache;
import org.eclipse.jst.ws.internal.consumption.ui.wsrt.RuntimeDescriptor;
import org.eclipse.jst.ws.internal.consumption.ui.wsrt.ServiceRuntimeDescriptor;
import org.eclipse.jst.ws.internal.consumption.ui.wsrt.WebServiceRuntimeExtensionUtils2;
import org.eclipse.jst.ws.internal.data.TypeRuntimeServer;
import org.eclipse.jst.ws.internal.ui.WSUIPluginMessages;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.command.internal.env.core.common.StatusUtils;
import org.eclipse.wst.common.environment.IEnvironment;
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.server.core.ServerUtil;
import org.eclipse.wst.ws.internal.wsrt.WebServiceScenario;

public class ServerRuntimeSelectionWidgetDefaultingCommand extends ClientRuntimeSelectionWidgetDefaultingCommand
{	
  private boolean           generateProxy_=true; //jvh
  
  private TypeRuntimeServer serviceIds_;
  private boolean serviceIdsFixed_ = false;
  private String serviceRuntimeId_;
  private String serviceProjectName_;
  private String serviceEarProjectName_;
  private String serviceComponentType_;
  private IProject initialProject_;
  private boolean serviceNeedEAR_ = true;
  private FacetMatcher serviceFacetMatcher_;

  public ServerRuntimeSelectionWidgetDefaultingCommand()
  {
    super();
  }
  
  
  /**
   * Defaults the following bits of information in the following order:
   * serviceRuntimeId_ : the serviceRuntimeId. Must be defaulted to non-empty String.
   * serviceIds_.runtimeId_: the Web service runtime id. Must be defaulted to non-empty String.
   * serviceProjectName_ : the name of the service project. Must be non-empty. May or may not exist.
   * serviceComponentType_: the id of the service project template. Must be empty if the service
   *                        project exists. Must be non-empty of the service project does not exist.
   * serviceIds_.serverId_: the server type id. May be an empty String if the defaulted Web service runtime
   *                        does not require a server.
   * serviceIds_.serverInstanceId_: the server id. May be null or an empty String.
   * serviceNeedEAR_: true if an EAR is needed. False otherwise.
   * serviceEarProjectName_: the service EAR project. Must be empty if the serviceNeedEAR_ is false.
   *                         Must be non-empty if the serviceNeedEAR_ is true.
   * Defaults the parallel information on the client-side if needed 
   * (@see ClientRuntimeSelectionWidgetDefaultingCommand#execute).                                                 
   */
  public IStatus execute( IProgressMonitor monitor, IAdaptable adaptable )
  {    
    IEnvironment env = getEnvironment();
    
    try
    {    	
     
     //**Step 1** Default the serviceRuntime and the Web service runtime.
     //serviceIdsFixed_ is set to true for the Ant scenario. It's always false for the wizard
     //scenarios.    	
     if (serviceIdsFixed_)
     {
       //Set the serviceRuntime based on the runtime and server.
       //If user set a service project use that as initial project otherwise default from initial selection.
       //(above is true for all scenarios except BUJ from Java Project- for BUJ from Java Project need to create a dependancy in downstream commands
       //between the initial project and the service project so don't use as the initial selection        
    	 if (serviceProjectName_ != null) 
    	 {
    	 	 IProject serviceProject = ResourcesPlugin.getWorkspace().getRoot().getProject(serviceProjectName_);
    	 	 //use the user provided service project to define the runtime triplet (if user provided service project is not valid for
    	 	 //the web service type, the runtime triplet will contain a suitable project if one exists)
    	 	 DefaultRuntimeTriplet drt = getDefaultRuntime(serviceProject, serviceIds_.getTypeId(), false, serviceIds_.getServerId());
    		 if (!(WebServiceRuntimeExtensionUtils2.getScenarioFromTypeId(serviceIds_.getTypeId()) == WebServiceScenario.BOTTOMUP &&
    		    		FacetUtils.isJavaProject(initialProject_))){
    		     //user set a service project, use as initial project
    			 //initialProject_ is the project where the selected object resides, set to be the service project for now for all scenarios except BUJ from Java Project (for 
    			 //BUJ from Java Project need to create a dependancy in downstream commands between the initial project and the service project)
    			 initialProject_ = serviceProject;
    		 }
    		 serviceFacetMatcher_ = drt.getFacetMatcher();
   			 serviceProjectName_ = drt.getProjectName(); //a suitable service project for the web service type, or null if a suitable project does not exist
    	     serviceRuntimeId_ = drt.getRuntimeId();       

    	       if (serviceRuntimeId_ != null)
    	       {
    	    	   serviceIds_.setRuntimeId(WebServiceRuntimeExtensionUtils2.getServiceRuntimeDescriptorById(serviceRuntimeId_).getRuntime()
    	      	         .getId());
    	       }
    	 }
    	 else
    	 {
    		 DefaultRuntimeTriplet drt = getDefaultServiceRuntimeForFixedRuntimeAndServer(initialProject_, serviceIds_.getServerId());  
    	     serviceFacetMatcher_ = drt.getFacetMatcher();
    	     serviceProjectName_ = drt.getProjectName();
    	     serviceRuntimeId_ = drt.getRuntimeId();	 
    	 }   
     }
     else
     {
       // Set the runtime based on the initial selection
       DefaultRuntimeTriplet drt = getDefaultRuntime(initialProject_, serviceIds_.getTypeId(), false, serviceIds_.getServerId());
       if (drt.getProjectName() == null && initialProject_ != null
    	   && WebServiceRuntimeExtensionUtils2.getScenarioFromTypeId(serviceIds_.getTypeId()) == WebServiceScenario.BOTTOMUP
    	   && WebServiceRuntimeExtensionUtils2.getWebServiceImplIdFromTypeId(serviceIds_.getTypeId()).equals("org.eclipse.jst.ws.wsImpl.ejb") )
       {
    	   drt.setProjectName(initialProject_.getName());
       }
       serviceFacetMatcher_ = drt.getFacetMatcher();
       serviceProjectName_ = drt.getProjectName();
       serviceRuntimeId_ = drt.getRuntimeId();       

       if (serviceRuntimeId_ != null)
       {
    	   serviceIds_.setRuntimeId(WebServiceRuntimeExtensionUtils2.getServiceRuntimeDescriptorById(serviceRuntimeId_).getRuntime()
    		         .getId()); 
       } 
     }
     
     //**Step 2** Default the service project if it was not already defaulted 
     //as part of defaulting the Web service runtime.
     if (serviceProjectName_ == null)
     {
       // Project name did not get set when the runtime was set, so set it now
       serviceProjectName_ = getDefaultServiceProjectName();
     }

     //**Step 3** Default the service project type.
     IProject serviceProject = ResourcesPlugin.getWorkspace().getRoot().getProject(serviceProjectName_); 
     if (!serviceProject.exists())
     {
       // Set the project template
       serviceComponentType_ = getDefaultServiceProjectTemplate();
     }
     else
     {
       //Set it to an empty String
       serviceComponentType_ = "";
     }
     //**Step 4** Default the server if this is not an Ant scenario.
     if (!serviceIdsFixed_)
     {
       // Set the server
       IStatus serverStatus = setServiceDefaultServer();
       if (serverStatus.getSeverity() == Status.ERROR)
       {
         env.getStatusHandler().reportError(serverStatus);
         return serverStatus;
       }
     }
     
     //**Step 5** Default clientNeedEAR and client EAR if an EAR is needed
     setDefaultServiceEarProject();
     
     // jvh - for now comment out generate proxy
     //   need to look at defaulting based on an event
     //    on page 1 - when client generation goes from none
     //    to develop...
     /*if (generateProxy_)
     {*/
    	 //Default the client-side.
    	 IStatus clientSideStatus = defaultClientSide(monitor);
         if (clientSideStatus.getSeverity() == Status.ERROR)
         {
           return clientSideStatus;
         }                  
    // }
          
     return Status.OK_STATUS;
     
    } catch (Exception e)
    {
      // Catch all Exceptions in order to give some feedback to the user
      IStatus errorStatus = StatusUtils.errorStatus(NLS.bind(ConsumptionUIMessages.MSG_ERROR_TASK_EXCEPTED,
          new String[] { e.getMessage() }), e);
      
      // If the exception has no error msg, it's kind of useless to the user so let's log it
      if ( e.getMessage() == null){
      	ILog pluginlog = WebServiceConsumptionUIPlugin.getInstance().getLog();
      	pluginlog.log(errorStatus);
      	  
      	// create a new IStatus which has a non-null msg, this is to be thrown to the user.
      	errorStatus = StatusUtils.errorStatus(NLS.bind(ConsumptionUIMessages.MSG_ERROR_TASK_EXCEPTED,
    	          new String[] { WSUIPluginMessages.MSG_SEE_ERROR_LOG }), e);  
      }
        
      env.getStatusHandler().reportError(errorStatus);
      return errorStatus;
    }
  }

  private IStatus defaultClientSide(IProgressMonitor monitor)
  {
    IStatus clientDefaultFromServiceStatus = defaultClientSideFromServiceSide(serviceProjectName_, serviceIds_, serviceNeedEAR_, serviceEarProjectName_);

    // If an error status is returned, the only property that was set on 
    // ClientRuntimeSelectionWidgetDefaultingCommand is clientProjectName_. 
    // The rest of the properties including clientRuntimeId_, clientComponentType_, 
    // all the values in clientIds_, clientNeedEAR_, and clientEarProjectName_ 
    // have not been set because the service side server and
    // web service runtime could not be used on the client side. Run the entire
    // client-side defaulting algorithm using clientProjectName_ as the 
    // clientInitialProject_. Then update the clientEarProjectName_ based on the
    // service side EAR.
    if (clientDefaultFromServiceStatus.getSeverity() == IStatus.ERROR)
    {
      // 1. Run client side defaulting from scratch with clientInitialProject_
      // set to the new clientProjectName_.
      IProject clientProject = ResourcesPlugin.getWorkspace().getRoot().getProject(getClientProjectName());
      setClientInitialProject(clientProject);
      IStatus clientExecuteStatus = super.execute(monitor, null);
      if (clientExecuteStatus.getSeverity() == Status.ERROR)
      {
        return clientExecuteStatus;
      }

      // 2. Update the client-side EAR if serviceNeedEAR_ is true;
      if (serviceNeedEAR_)
      {
        defaultClientEarFromServiceEar(serviceProjectName_, serviceEarProjectName_);
      }
    }
    
    return Status.OK_STATUS;
	  
  }
  
  private void setDefaultServiceEarProject()
  {
    //Don't need an ear if this is a Java project, or if the selected template is jst.utility
    IProject serviceProject = ResourcesPlugin.getWorkspace().getRoot().getProject(serviceProjectName_);
    if (serviceProject.exists())
    {
      serviceNeedEAR_ = !(FacetUtils.isJavaProject(serviceProject));
    }
    else
    {
      serviceNeedEAR_ = !(FacetUtils.isUtilityTemplate(serviceComponentType_));  
    }    
    
    //If serviceNeedEAR_ is still true, it means that we're not dealing with a Java project
    //or Java project type. Check the server.
    
    
    if (serviceNeedEAR_)
    {
      
      // Determine if an ear selection is needed based on the server type.      
      String serverId = serviceIds_.getServerId();
      if (serverId != null)
      {
        // Use the server type
        String serverTargetId = ServerUtils.getRuntimeTargetIdFromFactoryId(serverId);
        if (serverTargetId != null && serverTargetId.length() > 0)
        {
          if (!ServerUtils.isTargetValidForEAR(serverTargetId, "13"))
          {
            // Default the EAR selection to be empty
            serviceNeedEAR_ = false;
          }
        }
      } else { // serverId == null, assume that it does not need EAR
    	  serviceNeedEAR_ = false;
      }
    }
    
    if (serviceNeedEAR_)
    {
      serviceEarProjectName_ = DefaultingUtils.getDefaultEARProjectName(serviceProjectName_);
    }
    else
    {
      serviceEarProjectName_ = "";
    }   
  }
  
  private IStatus setServiceDefaultServer()
  {
    //Choose an existing server the module is already associated with if possible
    IProject serviceProject = ResourcesPlugin.getWorkspace().getRoot().getProject(serviceProjectName_);
    IServer[] configuredServers = null;
    if(serviceProject.exists())
    	configuredServers = ServerUtil.getServersByModule(ServerUtils.getModule(serviceProject), null);
    
    if (configuredServers!=null && configuredServers.length>0)
    {
      serviceIds_.setServerId(configuredServers[0].getServerType().getId());
      serviceIds_.setServerInstanceId(configuredServers[0].getId());
      return Status.OK_STATUS;              
    }
    
    //If the project exists, choose a suitable server or server type based on the existing project's runtime or facets
    if (serviceProject.exists())
    {
      IServer server = getServerFromProject(serviceProjectName_, serviceFacetMatcher_);
      if (server != null)
      {
        serviceIds_.setServerId(server.getServerType().getId());
        serviceIds_.setServerInstanceId(server.getId());
        return Status.OK_STATUS;
      }
      else
      {
        IServerType serverType = getServerTypeFromProject(serviceProjectName_, serviceFacetMatcher_);
        if (serverType != null)
        {
          serviceIds_.setServerId(serverType.getId());
          return Status.OK_STATUS;
        }
      }
    }
    
    //Haven't picked a server/server type on the basis of the project. Pick a server/server type
    //that is compatible with the serviceRuntimeId.
    IServer server = getServerFromServiceRuntimeId();
    if (server!=null)
    {
      serviceIds_.setServerId(server.getServerType().getId());
      serviceIds_.setServerInstanceId(server.getId());
      return Status.OK_STATUS;
    }
    
    IServerType serverType = getServerTypeFromServiceRuntimeId();
    if (serverType != null)
    {
      serviceIds_.setServerId(serverType.getId());
      return Status.OK_STATUS;
    }    

    //No suitable server was found. Popup an error.
    RuntimeDescriptor runtimeDescriptor = WebServiceRuntimeExtensionUtils2.getRuntimeById(serviceIds_.getRuntimeId());
    if (runtimeDescriptor.getServerRequired())
    {    
      String runtimeLabel = WebServiceRuntimeExtensionUtils2.getRuntimeLabelById(serviceIds_.getRuntimeId());    
      IStatus status = StatusUtils.errorStatus(NLS.bind(ConsumptionUIMessages.MSG_ERROR_NO_SERVER_RUNTIME, new String[]{runtimeLabel}) );
      return status;
    }
    
    return Status.OK_STATUS;
  }  
  
  private IServer getServerFromServiceRuntimeId()
  {
    IServer[] servers = ServerCore.getServers();
    if (servers != null && servers.length > 0) 
    {
      PersistentServerRuntimeContext context = WebServiceConsumptionUIPlugin.getInstance().getServerRuntimeContext();
      String preferredServerFactoryId = context.getServerFactoryId();

      //If a server of the preferred server type is present, check that one first
      for (int j = 0; j < servers.length; j++)
      {
    	if (servers[j] != null && servers[j].getServerType() != null)
    	{
	        String serverFactoryId = servers[j].getServerType().getId();
	        if (serverFactoryId.equals(preferredServerFactoryId))
	        {
	          if (WebServiceRuntimeExtensionUtils2.doesServiceRuntimeSupportServer(serviceRuntimeId_, serverFactoryId))
	          {
	            return servers[j];
	          }
	        }  
    	}
      }
      
      //A server of the preferred server type could not be found or did not match. Check all the existing servers.    
      for (int i = 0; i < servers.length; i++)
      {
    	if (servers[i] != null && servers[i].getServerType() != null)
    	{
	        String serverFactoryId = servers[i].getServerType().getId();
	        if (WebServiceRuntimeExtensionUtils2.doesServiceRuntimeSupportServer(serviceRuntimeId_, serverFactoryId))
	        {
	          return servers[i];
	        }
    	}
      }
    }
    return null;    
  }
  
  private IServerType getServerTypeFromServiceRuntimeId()
  {
    String[] serverTypes = WebServiceRuntimeExtensionUtils2.getServerFactoryIdsByServiceRuntime(serviceRuntimeId_);
    if (serverTypes!=null && serverTypes.length>0)
    {
      //Return the preferred one if it is in the list
      PersistentServerRuntimeContext context = WebServiceConsumptionUIPlugin.getInstance().getServerRuntimeContext();
      String preferredServerFactoryId = context.getServerFactoryId();
      for (int i=0; i<serverTypes.length; i++)
      {
        if (serverTypes[i].equals(preferredServerFactoryId))
        {
          return ServerCore.findServerType(serverTypes[i]);
        }
      }
      
      return ServerCore.findServerType(serverTypes[0]);
    }    
    
    return null;
  }  
  
  
  private String getDefaultServiceProjectTemplate()
  {
    String[] templates = WebServiceRuntimeExtensionUtils2.getServiceProjectTemplates(serviceIds_.getTypeId(), serviceIds_.getRuntimeId(), serviceIds_.getServerId());
    
    //Walk the list of service project types in the project topology preference
    ProjectTopologyContext ptc= WebServiceConsumptionUIPlugin.getInstance().getProjectTopologyContext();
    String[] preferredTemplateIds = ptc.getServiceTypes();
    for (int j = 0; j < preferredTemplateIds.length; j++)
    {
      for (int i = 0; i < templates.length; i++)
      {
        String templateId = templates[i];
        if (templateId.equals(preferredTemplateIds[j]))
        {
          boolean matches = WebServiceRuntimeExtensionUtils2.doesServiceRuntimeSupportTemplate(serviceRuntimeId_, templateId);
          if (matches)
          {
            return templates[i];
          }
        }
      }
    }
    
    //Since the preferredTemplateIds contains the union of all project types for all service runtimes, we are
    //guaranteed to have returned by now, so the code below will never be executed under normal
    //circumstances. Just return something to satisfy the compiler.
    if (templates.length > 0)
      return templates[0];
    
    return "";    
    
  }  
  
  private String getDefaultServiceProjectName()
  {
    IProject[] projects = FacetUtils.getAllProjects();
    ServiceRuntimeDescriptor desc = WebServiceRuntimeExtensionUtils2.getServiceRuntimeDescriptorById(serviceRuntimeId_);
    RequiredFacetVersion[] rfvs = desc.getRequiredFacetVersions();
    
    //Check each project for compatibility with the serviceRuntime
    for (int i=0; i<projects.length; i++)
    {
      Set facetVersions = FacetUtils.getFacetsForProject(projects[i].getName());
      org.eclipse.wst.common.project.facet.core.runtime.IRuntime fRuntime = null;
      String fRuntimeName = null;
      fRuntime = FacetUtils.getFacetRuntimeForProject(projects[i].getName());
      if (fRuntime != null)
      {
        fRuntimeName = fRuntime.getName();        
      }              
      
      if (facetVersions != null)
      {
        FacetMatcher fm = FacetMatchCache.getInstance().getMatchForProject(false, serviceRuntimeId_, projects[i].getName());
        boolean facetRuntimeMatches = true;
        if (fRuntimeName != null)
        {
          facetRuntimeMatches = FacetUtils.isFacetRuntimeSupported(rfvs, fRuntimeName);  
        }
        
        if (fm.isMatch() && facetRuntimeMatches)
        {
          serviceFacetMatcher_ = fm;
          return projects[i].getName();
        }                    
      }
    }
    
    //No project was suitable, return a new project name
    return ResourceUtils.getDefaultWebProjectName();
    
  }  
  
  private DefaultRuntimeTriplet getDefaultServiceRuntimeForFixedRuntimeAndServer(IProject project, String runtimePreferredServer)
  {
    String[] serviceRuntimes = WebServiceRuntimeExtensionUtils2.getServiceRuntimesByServiceType(serviceIds_.getTypeId(), runtimePreferredServer);
    ArrayList<String> validServiceRuntimes = new ArrayList<String>();
    for (int i=0; i<serviceRuntimes.length; i++ )
    {
      ServiceRuntimeDescriptor desc = WebServiceRuntimeExtensionUtils2.getServiceRuntimeDescriptorById(serviceRuntimes[i]);
      if (desc.getRuntime().getId().equals(serviceIds_.getRuntimeId()))
      {
        //Check if this service runtime supports the server
        if (WebServiceRuntimeExtensionUtils2.doesServiceRuntimeSupportServer(desc.getId(), serviceIds_.getServerId()))
        {
          validServiceRuntimes.add(desc.getId());
          if (project != null && project.exists())  
          {
            Set facetVersions = FacetUtils.getFacetsForProject(project.getName());
            if (facetVersions != null)
            {
              FacetMatcher fm = FacetMatchCache.getInstance().getMatchForProject(false, serviceRuntimes[i], project.getName());
              if (fm.isMatch())
              {
                DefaultRuntimeTriplet drt = new DefaultRuntimeTriplet();
                drt.setFacetMatcher(fm);
                drt.setProjectName(project.getName());
                drt.setRuntimeId(desc.getId());
                return drt;
              }                      
            }
          }
          
        }
      }
      
    }
    
    if (validServiceRuntimes.size() > 0)
    {
      //We couldn't match to the initially selected project so return the first valid runtime.
      DefaultRuntimeTriplet drt = new DefaultRuntimeTriplet();
      drt.setFacetMatcher(null);
      drt.setProjectName(null);
      drt.setRuntimeId(((String[])validServiceRuntimes.toArray(new String[0]))[0]);
      return drt;      
    }
    else
    {
      //There are no service runtimes that match the fixed runtime and server. Fall back to original algorithm.
      serviceIdsFixed_ = false;
      return getDefaultRuntime(project, serviceIds_.getTypeId(), false, serviceIds_.getServerId());
    }
  }
  

  
  public void setInitialSelection(IStructuredSelection selection)
  {
  }
  
  public void setInitialProject(IProject initialProject)
  {
    initialProject_ = initialProject;
  }
  
  public IProject getInitialProject()
  {
    return initialProject_;  
  }
  
  public void setInitialComponentName(String name)
  {
    //TODO This method and any mappings to it
	// should be removed if no longer needed.
  }
  
  public void setServiceTypeRuntimeServer( TypeRuntimeServer ids )
  {
    serviceIds_ = ids;
  }
  
  public void setServiceIdsFixed(boolean b)
  {
    serviceIdsFixed_ = b;  
  }
  
  public TypeRuntimeServer getServiceTypeRuntimeServer()
  {
    return serviceIds_; 
  }

  public String getServiceRuntimeId()
  {
    return serviceRuntimeId_;
  }
  /**
   * @return Returns the generateProxy_.
   */
  public boolean getGenerateProxy()
  {
    return generateProxy_;
  }
  /**
   * @param generateProxy_ The generateProxy_ to set.
   */
  public void setGenerateProxy(boolean generateProxy_)
  {
    this.generateProxy_ = generateProxy_;
  }
  
  public String getServiceProjectName()
  {
    return serviceProjectName_;  
  }
  
  public String getServiceEarProjectName()
  {
    return serviceEarProjectName_;
  }
  
  public String getServiceComponentType()
  {
    return serviceComponentType_;
  }
  
  public boolean getServiceNeedEAR()
  {
    return serviceNeedEAR_;
  }
  
  // This is for the Ant scenario where the service project name can be set in the property file.
  // If the user has set the ServiceProjectName use it for defaulting purposes
  public void setServiceProjectName(String name)
  {
	  serviceProjectName_ = name;
  }
  
}
