Package com.eviware.soapui.impl.wsdl

Source Code of com.eviware.soapui.impl.wsdl.WsdlProject

/*
*  soapUI, copyright (C) 2004-2011 eviware.com
*
*  soapUI is free software; you can redistribute it and/or modify it under the
*  terms of version 2.1 of the GNU Lesser General Public License as published by
*  the Free Software Foundation.
*
*  soapUI 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 Lesser General Public License for more details at gnu.org.
*/

package com.eviware.soapui.impl.wsdl;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.ImageIcon;
import javax.xml.namespace.QName;

import org.apache.commons.ssl.OpenSSL;
import org.apache.log4j.Logger;
import org.apache.xmlbeans.XmlError;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;

import com.eviware.soapui.SoapUI;
import com.eviware.soapui.config.CrossSiteScriptingScanConfig;
import com.eviware.soapui.config.GroovySecurityCheckConfig;
import com.eviware.soapui.config.GroovySecurityScanConfig;
import com.eviware.soapui.config.InterfaceConfig;
import com.eviware.soapui.config.InvalidSecurityCheckConfig;
import com.eviware.soapui.config.InvalidSecurityScanConfig;
import com.eviware.soapui.config.MaliciousAttachmentConfig;
import com.eviware.soapui.config.MaliciousAttachmentElementConfig;
import com.eviware.soapui.config.MaliciousAttachmentSecurityCheckConfig;
import com.eviware.soapui.config.MaliciousAttachmentSecurityScanConfig;
import com.eviware.soapui.config.MockServiceConfig;
import com.eviware.soapui.config.MockServiceDocumentConfig;
import com.eviware.soapui.config.ParameterExposureCheckConfig;
import com.eviware.soapui.config.ProjectConfig;
import com.eviware.soapui.config.SQLInjectionCheckConfig;
import com.eviware.soapui.config.SQLInjectionScanConfig;
import com.eviware.soapui.config.SchemaTypeForSecurityCheckConfig;
import com.eviware.soapui.config.SchemaTypeForSecurityScanConfig;
import com.eviware.soapui.config.SecurityCheckConfig;
import com.eviware.soapui.config.SecurityScanConfig;
import com.eviware.soapui.config.SecurityTestConfig;
import com.eviware.soapui.config.SoapuiProjectDocumentConfig;
import com.eviware.soapui.config.TestAssertionConfig;
import com.eviware.soapui.config.TestCaseConfig;
import com.eviware.soapui.config.TestStepSecurityTestConfig;
import com.eviware.soapui.config.TestSuiteConfig;
import com.eviware.soapui.config.TestSuiteDocumentConfig;
import com.eviware.soapui.config.TestSuiteRunTypesConfig;
import com.eviware.soapui.config.TestSuiteRunTypesConfig.Enum;
import com.eviware.soapui.config.XmlBombSecurityCheckConfig;
import com.eviware.soapui.config.XmlBombSecurityScanConfig;
import com.eviware.soapui.impl.WorkspaceImpl;
import com.eviware.soapui.impl.WsdlInterfaceFactory;
import com.eviware.soapui.impl.rest.support.RestRequestConverter.RestConversionException;
import com.eviware.soapui.impl.settings.XmlBeansSettingsImpl;
import com.eviware.soapui.impl.support.AbstractInterface;
import com.eviware.soapui.impl.wsdl.endpoint.DefaultEndpointStrategy;
import com.eviware.soapui.impl.wsdl.mock.WsdlMockService;
import com.eviware.soapui.impl.wsdl.support.ExternalDependency;
import com.eviware.soapui.impl.wsdl.support.PathUtils;
import com.eviware.soapui.impl.wsdl.support.wsdl.UrlWsdlLoader;
import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlLoader;
import com.eviware.soapui.impl.wsdl.support.wss.DefaultWssContainer;
import com.eviware.soapui.impl.wsdl.testcase.WsdlProjectRunner;
import com.eviware.soapui.model.ModelItem;
import com.eviware.soapui.model.iface.Interface;
import com.eviware.soapui.model.mock.MockService;
import com.eviware.soapui.model.project.EndpointStrategy;
import com.eviware.soapui.model.project.Project;
import com.eviware.soapui.model.project.ProjectListener;
import com.eviware.soapui.model.propertyexpansion.DefaultPropertyExpansionContext;
import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContainer;
import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContext;
import com.eviware.soapui.model.settings.Settings;
import com.eviware.soapui.model.support.ModelSupport;
import com.eviware.soapui.model.testsuite.ProjectRunContext;
import com.eviware.soapui.model.testsuite.ProjectRunListener;
import com.eviware.soapui.model.testsuite.ProjectRunner;
import com.eviware.soapui.model.testsuite.TestRunnable;
import com.eviware.soapui.model.testsuite.TestSuite;
import com.eviware.soapui.model.testsuite.TestSuite.TestSuiteRunType;
import com.eviware.soapui.settings.ProjectSettings;
import com.eviware.soapui.settings.UISettings;
import com.eviware.soapui.settings.WsdlSettings;
import com.eviware.soapui.support.SoapUIException;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.Tools;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.resolver.ResolveContext;
import com.eviware.soapui.support.resolver.ResolveDialog;
import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
import com.eviware.soapui.support.scripting.SoapUIScriptEngineRegistry;
import com.eviware.soapui.support.types.StringToObjectMap;
import com.eviware.soapui.support.xml.XmlUtils;

/**
* WSDL project implementation
*
* @author Ole.Matzura
*/

public class WsdlProject extends AbstractTestPropertyHolderWsdlModelItem<ProjectConfig> implements Project,
    PropertyExpansionContainer, PropertyChangeListener, TestRunnable
{
  public final static String AFTER_LOAD_SCRIPT_PROPERTY = WsdlProject.class.getName() + "@setupScript";
  public final static String BEFORE_SAVE_SCRIPT_PROPERTY = WsdlProject.class.getName() + "@tearDownScript";
  public final static String RESOURCE_ROOT_PROPERTY = WsdlProject.class.getName() + "@resourceRoot";

  private WorkspaceImpl workspace;
  protected String path;
  protected List<AbstractInterface<?>> interfaces = new ArrayList<AbstractInterface<?>>();
  protected List<WsdlTestSuite> testSuites = new ArrayList<WsdlTestSuite>();
  protected List<WsdlMockService> mockServices = new ArrayList<WsdlMockService>();
  private Set<ProjectListener> projectListeners = new HashSet<ProjectListener>();
  protected SoapuiProjectDocumentConfig projectDocument;
  private ImageIcon disabledIcon;
  private ImageIcon closedIcon;
  private ImageIcon remoteIcon;
  private ImageIcon openEncyptedIcon;
  protected EndpointStrategy endpointStrategy = new DefaultEndpointStrategy();
  protected long lastModified;
  private boolean remote;
  private boolean open = true;
  private boolean disabled;

  private SoapUIScriptEngine afterLoadScriptEngine;
  private SoapUIScriptEngine beforeSaveScriptEngine;
  private PropertyExpansionContext context = new DefaultPropertyExpansionContext( this );
  protected DefaultWssContainer wssContainer;
  private String projectPassword = null;
  private String hermesConfig;
  private boolean wrongPasswordSupplied;

  /*
   * 3 state flag: 1. 0 - project not encrypted 2. 1 - encrypted , good
   * password, means that it could be successfully decrypted 3. -1 - encrypted,
   * but with bad password or no password.
   */

  protected int encrypted;
  private ImageIcon closedEncyptedIcon;
  private SoapUIScriptEngine afterRunScriptEngine;
  private SoapUIScriptEngine beforeRunScriptEngine;
  private Set<ProjectRunListener> runListeners = new HashSet<ProjectRunListener>();

  protected final static Logger log = Logger.getLogger( WsdlProject.class );

  public WsdlProject() throws XmlException, IOException, SoapUIException
  {
    this( ( WorkspaceImpl )null );
  }

  public WsdlProject( String path ) throws XmlException, IOException, SoapUIException
  {
    this( path, ( WorkspaceImpl )null );
  }

  public WsdlProject( String projectFile, String projectPassword )
  {
    this( projectFile, null, true, true, null, projectPassword );
  }

  public WsdlProject( WorkspaceImpl workspace )
  {
    this( null, workspace, true );
  }

  public WsdlProject( String path, WorkspaceImpl workspace )
  {
    this( path, workspace, true );
  }

  public WsdlProject( String path, WorkspaceImpl workspace, boolean create )
  {
    this( path, workspace, create, true, null, null );
  }

  public WsdlProject( String path, WorkspaceImpl workspace, boolean create, boolean open, String tempName,
      String projectPassword )
  {
    super( null, workspace, "/project.gif" );

    this.workspace = workspace;
    this.path = path;
    this.projectPassword = projectPassword;

    for( ProjectListener listener : SoapUI.getListenerRegistry().getListeners( ProjectListener.class ) )
    {
      addProjectListener( listener );
    }

    for( ProjectRunListener listener : SoapUI.getListenerRegistry().getListeners( ProjectRunListener.class ) )
    {
      addProjectRunListener( listener );
    }

    try
    {
      if( path != null && open )
      {
        File file = new File( path.trim() );
        if( file.exists() )
        {
          try
          {
            loadProject( file.toURI().toURL() );
            lastModified = file.lastModified();
          }
          catch( MalformedURLException e )
          {
            SoapUI.logError( e );
            disabled = true;
          }
        }
        else
        {
          try
          {
            if( !PathUtils.isHttpPath( path ) )
              SoapUI.log.info( "File [" + file.getAbsolutePath() + "] does not exist, trying URL instead" );

            remote = true;
            loadProject( new URL( path ) );
          }
          catch( MalformedURLException e )
          {
            SoapUI.logError( e );
            disabled = true;
          }
        }
      }
    }
    catch( SoapUIException e )
    {
      SoapUI.logError( e );
      disabled = true;
    }
    finally
    {
      closedIcon = UISupport.createImageIcon( "/closedProject.gif" );
      remoteIcon = UISupport.createImageIcon( "/remoteProject.gif" );
      disabledIcon = UISupport.createImageIcon( "/disabledProject.gif" );
      openEncyptedIcon = UISupport.createImageIcon( "/openEncryptedProject.gif" );
      closedEncyptedIcon = UISupport.createImageIcon( "/closedEncryptedProject.gif" );

      this.open = open && !disabled && ( this.encrypted != -1 );

      if( projectDocument == null )
      {
        projectDocument = SoapuiProjectDocumentConfig.Factory.newInstance();
        setConfig( projectDocument.addNewSoapuiProject() );
        if( tempName != null || path != null )
          getConfig().setName( StringUtils.isNullOrEmpty( tempName ) ? getNameFromPath() : tempName );

        setPropertiesConfig( getConfig().addNewProperties() );
        wssContainer = new DefaultWssContainer( this, getConfig().addNewWssContainer() );
        // setResourceRoot("${projectDir}");
      }

      if( getConfig() != null )
      {
        endpointStrategy.init( this );
      }
      if( getSettings() != null )
      {
        setProjectRoot( path );
      }

      addPropertyChangeListener( this );
    }
  }

  public boolean isRemote()
  {
    return remote;
  }

  public void loadProject( URL file ) throws SoapUIException
  {
    try
    {
      UISupport.setHourglassCursor();

      UrlWsdlLoader loader = new UrlWsdlLoader( file.toString(), this );
      loader.setUseWorker( false );
      projectDocument = SoapuiProjectDocumentConfig.Factory.parse( loader.load() );

      // see if there is encoded data
      this.encrypted = checkForEncodedData( projectDocument.getSoapuiProject() );

      setConfig( projectDocument.getSoapuiProject() );

      // removed cached definitions if caching is disabled
      if( !getSettings().getBoolean( WsdlSettings.CACHE_WSDLS ) )
      {
        removeDefinitionCaches( projectDocument );
      }

      log.info( "Loaded project from [" + file.toString() + "]" );

      // TODO remove this after beta2
      updateChecksToScans( getConfig() );

      try
      {
        int majorVersion = Integer
            .parseInt( projectDocument.getSoapuiProject().getSoapuiVersion().split( "\\." )[0] );
        if( majorVersion > Integer.parseInt( SoapUI.SOAPUI_VERSION.split( "\\." )[0] ) )
          log.warn( "Project '" + projectDocument.getSoapuiProject().getName() + "' is from a newer version ("
              + projectDocument.getSoapuiProject().getSoapuiVersion() + ") of soapUI than this ("
              + SoapUI.SOAPUI_VERSION + ") and parts of it may be incompatible or incorrect. "
              + "Saving this project with this version of soapUI may cause it to function differently." );
      }
      catch( Exception e )
      {
      }

      List<InterfaceConfig> interfaceConfigs = getConfig().getInterfaceList();
      for( InterfaceConfig config : interfaceConfigs )
      {
        AbstractInterface<?> iface = InterfaceFactoryRegistry.build( this, config );
        interfaces.add( iface );
      }

      List<TestSuiteConfig> testSuiteConfigs = getConfig().getTestSuiteList();
      for( TestSuiteConfig config : testSuiteConfigs )
      {
        testSuites.add( buildTestSuite( config ) );
      }

      List<MockServiceConfig> mockServiceConfigs = getConfig().getMockServiceList();
      for( MockServiceConfig config : mockServiceConfigs )
      {
        mockServices.add( new WsdlMockService( this, config ) );
      }

      if( !getConfig().isSetWssContainer() )
        getConfig().addNewWssContainer();

      wssContainer = new DefaultWssContainer( this, getConfig().getWssContainer() );

      endpointStrategy.init( this );

      if( !getConfig().isSetProperties() )
        getConfig().addNewProperties();

      if( !getConfig().isSetAbortOnError() )
        getConfig().setAbortOnError( false );

      // if( !getConfig().isSetFailOnErrors() )
      // getConfig().setFailOnErrors( true );

      if( !getConfig().isSetRunType() )
        getConfig().setRunType( TestSuiteRunTypesConfig.SEQUENTIAL );

      setPropertiesConfig( getConfig().getProperties() );
      afterLoad();
    }
    catch( Exception e )
    {
      if( e instanceof XmlException )
      {
        XmlException xe = ( XmlException )e;
        XmlError error = xe.getError();
        if( error != null )
          System.err.println( "Error at line " + error.getLine() + ", column " + error.getColumn() );
      }

      if( e instanceof RestConversionException )
      {
        log.error( "Project file needs to be updated manually, please reload the project." );
        throw new SoapUIException( "Failed to load project from file [" + file.toString() + "]", e );
      }

      e.printStackTrace();
      throw new SoapUIException( "Failed to load project from file [" + file.toString() + "]", e );
    }
    finally
    {
      UISupport.resetCursor();
    }
  }

  protected WsdlTestSuite buildTestSuite( TestSuiteConfig config )
  {
    return new WsdlTestSuite( this, config );
  }

  public boolean isWrongPasswordSupplied()
  {
    return wrongPasswordSupplied;
  }

  /**
   * Decode encrypted data and restore user/pass
   *
   * @param soapuiProject
   * @return 0 - not encrypted, 1 - successfull decryption , -1 error while
   *         decrypting, bad password, no password.
   * @throws IOException
   * @throws GeneralSecurityException
   * @author robert nemet
   */
  protected int checkForEncodedData( ProjectConfig soapuiProject ) throws IOException, GeneralSecurityException
  {

    byte[] encryptedContent = soapuiProject.getEncryptedContent();
    char[] password = null;

    // no encrypted data then go back
    if( encryptedContent == null || encryptedContent.length == 0 )
      return 0;

    String projectPassword = null;
    if( workspace != null )
    {
      projectPassword = workspace.getProjectPassword( soapuiProject.getName() );
    }
    else
    {
      projectPassword = this.projectPassword;
    }
    if( projectPassword == null )
    {
      password = UISupport.promptPassword( "Enter Password:", soapuiProject.getName() );
    }
    else
    {
      password = projectPassword.toCharArray();
    }
    byte[] data = null;
    // no pass go back.
    if( password == null )
    {
      return -1;
    }

    try
    {
      data = OpenSSL.decrypt( "des3", password, encryptedContent );
    }
    catch( Exception e )
    {
      e.printStackTrace();
      return -1;
    }

    String decryptedData = new String( data, "UTF-8" );

    if( decryptedData != null )
    {
      if( decryptedData.length() > 0 )
      {
        try
        {
          // projectDocument.getSoapuiProject().set(
          // XmlObject.Factory.parse( decryptedData ) );
          projectDocument.getSoapuiProject().set( XmlUtils.createXmlObject( decryptedData ) );
          wrongPasswordSupplied = false;
        }
        catch( XmlException e )
        {
          UISupport.showErrorMessage( "Wrong password. Project needs to be reloaded." );
          wrongPasswordSupplied = true;
          getWorkspace().clearProjectPassword( soapuiProject.getName() );
          return -1;
        }
      }
    }
    else
    {
      UISupport.showErrorMessage( "Wrong project password" );
      wrongPasswordSupplied = true;
      getWorkspace().clearProjectPassword( soapuiProject.getName() );
      return -1;
    }
    projectDocument.getSoapuiProject().setEncryptedContent( null );
    return 1;
  }

  @Override
  public void afterLoad()
  {
    super.afterLoad();

    try
    {
      ProjectListener[] a = projectListeners.toArray( new ProjectListener[projectListeners.size()] );

      for( int c = 0; c < a.length; c++ )
      {
        a[c].afterLoad( this );
      }

      runAfterLoadScript();
    }
    catch( Exception e )
    {
      SoapUI.logError( e );
    }
  }

  protected void setProjectRoot( String path )
  {
    if( path != null && projectDocument != null )
    {
      int ix = path.lastIndexOf( File.separatorChar );
      if( ix > 0 )
        getSettings().setString( ProjectSettings.PROJECT_ROOT, path.substring( 0, ix ) );
    }
  }

  public void setResourceRoot( String resourceRoot )
  {
    String old = getResourceRoot();

    getConfig().setResourceRoot( resourceRoot );
    notifyPropertyChanged( RESOURCE_ROOT_PROPERTY, old, resourceRoot );
  }

  public String getResourceRoot()
  {
    if( !getConfig().isSetResourceRoot() )
      getConfig().setResourceRoot( "" );

    return getConfig().getResourceRoot();
  }

  @Override
  public ImageIcon getIcon()
  {
    if( isDisabled() )
      return disabledIcon;
    else if( getEncrypted() != 0 )
    {
      if( isOpen() )
      {
        return openEncyptedIcon;
      }
      else
      {
        return closedEncyptedIcon;
      }
    }
    else if( !isOpen() )
      return closedIcon;
    else if( isRemote() )
      return remoteIcon;
    else
      return super.getIcon();
  }

  private String getNameFromPath()
  {
    int ix = path.lastIndexOf( isRemote() ? '/' : File.separatorChar );
    String name = ix == -1 ? path : path.substring( ix + 1 );
    return name;
  }

  @Override
  public String getDescription()
  {
    if( isOpen() )
      return super.getDescription();

    String name = getName();

    if( isDisabled() )
      name += " - disabled [" + getPath() + "]";
    else
      name += " - closed [" + getPath() + "]";

    return name;
  }

  public WorkspaceImpl getWorkspace()
  {
    return workspace;
  }

  public AbstractInterface<?> getInterfaceAt( int index )
  {
    return interfaces.get( index );
  }

  public AbstractInterface<?> getInterfaceByName( String interfaceName )
  {
    return ( AbstractInterface<?> )getWsdlModelItemByName( interfaces, interfaceName );
  }

  public AbstractInterface<?> getInterfaceByTechnicalId( String technicalId )
  {
    for( int c = 0; c < getInterfaceCount(); c++ )
    {
      if( getInterfaceAt( c ).getTechnicalId().equals( technicalId ) )
        return getInterfaceAt( c );
    }

    return null;
  }

  public int getInterfaceCount()
  {
    return interfaces.size();
  }

  public String getPath()
  {
    return path;
  }

  public boolean save() throws IOException
  {
    return save( null );
  }

  public boolean save( String folder ) throws IOException
  {
    if( !isOpen() || isDisabled() || isRemote() )
      return true;

    if( path == null || isRemote() )
    {
      path = StringUtils.createFileName2( getName(), '-' ) + "-soapui-project.xml";
      if( folder != null )
      {
        path = folder + File.separatorChar + path;
      }

      File file = null;

      while( file == null
          || ( file.exists() && !UISupport.confirm( "File [" + file.getName() + "] exists, overwrite?",
              "Overwrite File?" ) ) )
      {
        file = UISupport.getFileDialogs().saveAs( this, "Save project " + getName(), ".xml", "XML Files (*.xml)",
            new File( path ) );
        if( file == null )
          return false;
      }

      path = file.getAbsolutePath();
    }

    File projectFile = new File( path );

    while( projectFile.exists() && !projectFile.canWrite() )
    {
      if( UISupport.confirm( "Project file [" + path + "] can not be written to, save to new file?", "Save Project" ) )
      {
        projectFile = UISupport.getFileDialogs().saveAs( this, "Save project " + getName(), ".xml",
            "XML Files (*.xml)", projectFile );

        if( projectFile == null )
          return false;

        path = projectFile.getAbsolutePath();
      }
      else
        return false;
    }

    // check modified
    if( projectFile.exists() && lastModified != 0 && lastModified < projectFile.lastModified() )
    {
      if( !UISupport.confirm( "Project file for [" + getName() + "] has been modified externally, overwrite?",
          "Save Project" ) )
        return false;
    }

    if( projectFile.exists() && getSettings().getBoolean( UISettings.CREATE_BACKUP ) )
    {
      createBackup( projectFile );
    }

    return saveIn( projectFile );
  }

  public boolean saveBackup() throws IOException
  {
    File projectFile;
    if( path == null || isRemote() )
    {
      projectFile = new File( StringUtils.createFileName2( getName(), '-' ) + "-soapui-project.xml" );
    }
    else
    {
      projectFile = new File( path );
    }
    File backupFile = getBackupFile( projectFile );
    return saveIn( backupFile );
  }

  public boolean saveIn( File projectFile ) throws IOException
  {
    long size = 0;

    beforeSave();
    // work with copy beacuse we do not want to change working project while
    // working with it
    // if user choose save project, save all etc.
    SoapuiProjectDocumentConfig projectDocument = ( SoapuiProjectDocumentConfig )this.projectDocument.copy();

    // check for caching
    if( !getSettings().getBoolean( WsdlSettings.CACHE_WSDLS ) )
    {
      // no caching -> create copy and remove definition cachings
      removeDefinitionCaches( projectDocument );
    }

    // remove project root
    XmlBeansSettingsImpl tempSettings = new XmlBeansSettingsImpl( this, null, projectDocument.getSoapuiProject()
        .getSettings() );
    tempSettings.clearSetting( ProjectSettings.PROJECT_ROOT );

    // check for encryption
    String passwordForEncryption = getSettings().getString( ProjectSettings.SHADOW_PASSWORD, null );

    // if it has encryptedContend that means it is not decrypted corectly( bad
    // password, etc ), so do not encrypt it again.
    if( projectDocument.getSoapuiProject().getEncryptedContent() == null )
    {
      if( passwordForEncryption != null )
      {
        if( passwordForEncryption.length() > 1 )
        {
          // we have password so do encryption
          try
          {
            String data = getConfig().xmlText();
            byte[] encrypted = OpenSSL.encrypt( "des3", passwordForEncryption.toCharArray(), data.getBytes() );
            projectDocument.getSoapuiProject().setEncryptedContent( encrypted );
            projectDocument.getSoapuiProject().setInterfaceArray( null );
            projectDocument.getSoapuiProject().setTestSuiteArray( null );
            projectDocument.getSoapuiProject().setMockServiceArray( null );
            projectDocument.getSoapuiProject().unsetWssContainer();
            projectDocument.getSoapuiProject().unsetSettings();
            projectDocument.getSoapuiProject().unsetProperties();

          }
          catch( GeneralSecurityException e )
          {
            UISupport.showErrorMessage( "Encryption Error" );
          }
        }
        else
        {
          // no password no encryption.
          projectDocument.getSoapuiProject().setEncryptedContent( null );
        }
      }
    }
    // end of encryption.

    XmlOptions options = new XmlOptions();
    if( SoapUI.getSettings().getBoolean( WsdlSettings.PRETTY_PRINT_PROJECT_FILES ) )
      options.setSavePrettyPrint();

    projectDocument.getSoapuiProject().setSoapuiVersion( SoapUI.SOAPUI_VERSION );

    try
    {
      File tempFile = File.createTempFile( "project-temp-", ".xml", projectFile.getParentFile() );

      // save once to make sure it can be saved
      FileOutputStream tempOut = new FileOutputStream( tempFile );
      projectDocument.save( tempOut, options );
      tempOut.close();

      if( getSettings().getBoolean( UISettings.LINEBREAK ) )
      {
        normalizeLineBreak( projectFile, tempFile );
      }
      else
      {
        // now save it for real
        FileOutputStream projectOut = new FileOutputStream( projectFile );
        projectDocument.save( projectOut, options );
        projectOut.close();
        // delete tempFile here so we have it as backup in case second save
        // fails
        if( !tempFile.delete() )
        {
          SoapUI.getErrorLog().warn( "Failed to delete temporary project file; " + tempFile.getAbsolutePath() );
          tempFile.deleteOnExit();
        }
      }
      size = projectFile.length();
    }
    catch( Throwable t )
    {
      SoapUI.logError( t );
      UISupport.showErrorMessage( "Failed to save project [" + getName() + "]: " + t.toString() );
      return false;
    }

    lastModified = projectFile.lastModified();
    log.info( "Saved project [" + getName() + "] to [" + projectFile.getAbsolutePath() + " - " + size + " bytes" );
    setProjectRoot( getPath() );
    return true;
  }

  private static void normalizeLineBreak( File target, File tmpFile )
  {
    try
    {
      FileReader fr = new FileReader( tmpFile );
      BufferedReader in = new BufferedReader( fr );
      FileWriter fw = new FileWriter( target );
      BufferedWriter out = new BufferedWriter( fw );
      String line = "";
      while( ( line = in.readLine() ) != null )
      {
        out.write( line );
        out.newLine();
        out.flush();
      }
      out.close();
      fw.close();
      in.close();
      fr.close();
    }
    catch( FileNotFoundException e )
    {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    catch( IOException e )
    {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    if( !tmpFile.delete() )
    {
      SoapUI.getErrorLog().warn( "Failed to delete temporary file: " + tmpFile.getAbsolutePath() );
      tmpFile.deleteOnExit();
    }
  }

  public void beforeSave()
  {
    try
    {
      ProjectListener[] a = projectListeners.toArray( new ProjectListener[projectListeners.size()] );

      for( int c = 0; c < a.length; c++ )
      {
        a[c].beforeSave( this );
      }

      runBeforeSaveScript();
    }
    catch( Exception e )
    {
      SoapUI.logError( e );
    }

    // notify
    for( AbstractInterface<?> iface : interfaces )
      iface.beforeSave();

    for( WsdlTestSuite testSuite : testSuites )
      testSuite.beforeSave();

    for( WsdlMockService mockService : mockServices )
      mockService.beforeSave();

    endpointStrategy.onSave();
  }

  protected void createBackup( File projectFile ) throws IOException
  {
    File backupFile = getBackupFile( projectFile );
    log.info( "Backing up [" + projectFile + "] to [" + backupFile + "]" );
    Tools.copyFile( projectFile, backupFile, true );
  }

  protected File getBackupFile( File projectFile )
  {
    String backupFolderName = getSettings().getString( UISettings.BACKUP_FOLDER, "" );

    File backupFolder = new File( backupFolderName );
    if( !backupFolder.isAbsolute() )
    {
      backupFolder = new File( projectFile.getParentFile(), backupFolderName );
    }

    if( !backupFolder.exists() )
      backupFolder.mkdirs();

    File backupFile = new File( backupFolder, projectFile.getName() + ".backup" );
    return backupFile;
  }

  protected void removeDefinitionCaches( SoapuiProjectDocumentConfig config )
  {
    for( InterfaceConfig ifaceConfig : config.getSoapuiProject().getInterfaceList() )
    {
      if( ifaceConfig.isSetDefinitionCache() )
      {
        log.info( "Removing definition cache from interface [" + ifaceConfig.getName() + "]" );
        ifaceConfig.unsetDefinitionCache();
      }
    }
  }

  public AbstractInterface<?> addNewInterface( String name, String type )
  {
    AbstractInterface<?> iface = ( AbstractInterface<?> )InterfaceFactoryRegistry.createNew( this, type, name );
    if( iface != null )
    {
      iface.getConfig().setType( type );

      interfaces.add( iface );
      fireInterfaceAdded( iface );
    }

    return iface;
  }

  public void addProjectListener( ProjectListener listener )
  {
    projectListeners.add( listener );
  }

  public void removeProjectListener( ProjectListener listener )
  {
    projectListeners.remove( listener );
  }

  public void fireInterfaceAdded( AbstractInterface<?> iface )
  {
    ProjectListener[] a = projectListeners.toArray( new ProjectListener[projectListeners.size()] );

    for( int c = 0; c < a.length; c++ )
    {
      a[c].interfaceAdded( iface );
    }
  }

  public void fireInterfaceRemoved( AbstractInterface<?> iface )
  {
    ProjectListener[] a = projectListeners.toArray( new ProjectListener[projectListeners.size()] );

    for( int c = 0; c < a.length; c++ )
    {
      a[c].interfaceRemoved( iface );
    }
  }

  public void fireInterfaceUpdated( AbstractInterface<?> iface )
  {
    ProjectListener[] a = projectListeners.toArray( new ProjectListener[projectListeners.size()] );

    for( int c = 0; c < a.length; c++ )
    {
      a[c].interfaceUpdated( iface );
    }
  }

  public void fireTestSuiteAdded( WsdlTestSuite testSuite )
  {
    ProjectListener[] a = projectListeners.toArray( new ProjectListener[projectListeners.size()] );

    for( int c = 0; c < a.length; c++ )
    {
      a[c].testSuiteAdded( testSuite );
    }
  }

  private void fireTestSuiteMoved( WsdlTestSuite testCase, int ix, int offset )
  {
    ProjectListener[] a = projectListeners.toArray( new ProjectListener[projectListeners.size()] );

    for( int c = 0; c < a.length; c++ )
    {
      a[c].testSuiteMoved( testCase, ix, offset );
    }
  }

  public void fireTestSuiteRemoved( WsdlTestSuite testSuite )
  {
    ProjectListener[] a = projectListeners.toArray( new ProjectListener[projectListeners.size()] );

    for( int c = 0; c < a.length; c++ )
    {
      a[c].testSuiteRemoved( testSuite );
    }
  }

  public void fireMockServiceAdded( WsdlMockService mockService )
  {
    ProjectListener[] a = projectListeners.toArray( new ProjectListener[projectListeners.size()] );

    for( int c = 0; c < a.length; c++ )
    {
      a[c].mockServiceAdded( mockService );
    }
  }

  public void fireMockServiceRemoved( WsdlMockService mockService )
  {
    ProjectListener[] a = projectListeners.toArray( new ProjectListener[projectListeners.size()] );

    for( int c = 0; c < a.length; c++ )
    {
      a[c].mockServiceRemoved( mockService );
    }
  }

  public void removeInterface( AbstractInterface<?> iface )
  {
    int ix = interfaces.indexOf( iface );
    interfaces.remove( ix );
    try
    {
      fireInterfaceRemoved( iface );
    }
    finally
    {
      iface.release();
      getConfig().removeInterface( ix );
    }
  }

  public void removeTestSuite( WsdlTestSuite testSuite )
  {
    int ix = testSuites.indexOf( testSuite );
    testSuites.remove( ix );

    try
    {
      fireTestSuiteRemoved( testSuite );
    }
    finally
    {
      testSuite.release();
      getConfig().removeTestSuite( ix );
    }
  }

  public boolean isDisabled()
  {
    return disabled;
  }

  public int getTestSuiteCount()
  {
    return testSuites.size();
  }

  public WsdlTestSuite getTestSuiteAt( int index )
  {
    return testSuites.get( index );
  }

  public WsdlTestSuite getTestSuiteByName( String testSuiteName )
  {
    return ( WsdlTestSuite )getWsdlModelItemByName( testSuites, testSuiteName );
  }

  public WsdlTestSuite addNewTestSuite( String name )
  {
    WsdlTestSuite testSuite = buildTestSuite( getConfig().addNewTestSuite() );
    testSuite.setName( name );
    testSuites.add( testSuite );
    fireTestSuiteAdded( testSuite );

    return testSuite;
  }

  public boolean isCacheDefinitions()
  {
    return getSettings().getBoolean( WsdlSettings.CACHE_WSDLS );
  }

  public void setCacheDefinitions( boolean cacheDefinitions )
  {
    getSettings().setBoolean( WsdlSettings.CACHE_WSDLS, cacheDefinitions );
  }

  public boolean saveAs( String fileName ) throws IOException
  {
    if( !isOpen() || isDisabled() )
      return false;

    String oldPath = path;
    path = fileName;
    boolean result = save();
    if( !result )
      path = oldPath;
    else
      remote = false;

    setProjectRoot( path );

    return result;
  }

  @Override
  public void release()
  {
    super.release();

    if( isOpen() )
    {
      endpointStrategy.release();

      for( WsdlTestSuite testSuite : testSuites )
        testSuite.release();

      for( WsdlMockService mockService : mockServices )
        mockService.release();

      for( AbstractInterface<?> iface : interfaces )
        iface.release();

      if( wssContainer != null )
      {
        wssContainer.release();
        wssContainer = null;
      }
    }

    projectListeners.clear();

    if( afterLoadScriptEngine != null )
      afterLoadScriptEngine.release();

    if( beforeSaveScriptEngine != null )
      beforeSaveScriptEngine.release();
  }

  public WsdlMockService addNewMockService( String name )
  {
    WsdlMockService mockService = new WsdlMockService( this, getConfig().addNewMockService() );
    mockService.setName( name );
    mockServices.add( mockService );
    fireMockServiceAdded( mockService );

    return mockService;
  }

  public WsdlMockService getMockServiceAt( int index )
  {
    return mockServices.get( index );
  }

  public WsdlMockService getMockServiceByName( String mockServiceName )
  {
    return ( WsdlMockService )getWsdlModelItemByName( mockServices, mockServiceName );
  }

  public int getMockServiceCount()
  {
    return mockServices.size();
  }

  public void removeMockService( WsdlMockService mockService )
  {
    int ix = mockServices.indexOf( mockService );
    mockServices.remove( ix );

    try
    {
      fireMockServiceRemoved( mockService );
    }
    finally
    {
      mockService.release();
      getConfig().removeMockService( ix );
    }
  }

  public List<TestSuite> getTestSuiteList()
  {
    return new ArrayList<TestSuite>( testSuites );
  }

  public List<MockService> getMockServiceList()
  {
    return new ArrayList<MockService>( mockServices );
  }

  public List<Interface> getInterfaceList()
  {
    return new ArrayList<Interface>( interfaces );
  }

  public Map<String, Interface> getInterfaces()
  {
    Map<String, Interface> result = new HashMap<String, Interface>();
    for( Interface iface : interfaces )
      result.put( iface.getName(), iface );

    return result;
  }

  public Map<String, TestSuite> getTestSuites()
  {
    Map<String, TestSuite> result = new HashMap<String, TestSuite>();
    for( TestSuite iface : testSuites )
      result.put( iface.getName(), iface );

    return result;
  }

  public Map<String, MockService> getMockServices()
  {
    Map<String, MockService> result = new HashMap<String, MockService>();
    for( MockService mockService : mockServices )
      result.put( mockService.getName(), mockService );

    return result;
  }

  public void reload() throws SoapUIException
  {
    reload( path );
  }

  public void reload( String path ) throws SoapUIException
  {
    this.path = path;
    getWorkspace().reloadProject( this );
  }

  public boolean hasNature( String natureId )
  {
    Settings projectSettings = getSettings();
    String projectNature = projectSettings.getString( ProjectSettings.PROJECT_NATURE, null );
    return natureId.equals( projectNature );
  }

  public AbstractInterface<?> importInterface( AbstractInterface<?> iface, boolean importEndpoints, boolean createCopy )
  {
    iface.beforeSave();

    InterfaceConfig ifaceConfig = ( InterfaceConfig )iface.getConfig().copy();
    ifaceConfig = ( InterfaceConfig )getConfig().addNewInterface().set( ifaceConfig );

    AbstractInterface<?> imported = InterfaceFactoryRegistry.build( this, ifaceConfig );
    interfaces.add( imported );

    if( iface.getProject() != this && importEndpoints )
    {
      endpointStrategy.importEndpoints( iface );
    }

    if( createCopy )
      ModelSupport.unsetIds( imported );

    imported.afterLoad();
    fireInterfaceAdded( imported );

    return imported;
  }

  public WsdlTestSuite importTestSuite( WsdlTestSuite testSuite, String name, int index, boolean createCopy,
      String description )
  {
    testSuite.beforeSave();
    TestSuiteConfig testSuiteConfig = index == -1 ? ( TestSuiteConfig )getConfig().addNewTestSuite().set(
        testSuite.getConfig().copy() ) : ( TestSuiteConfig )getConfig().insertNewTestSuite( index ).set(
        testSuite.getConfig().copy() );

    testSuiteConfig.setName( name );

    if( createCopy )
    {
      for( TestCaseConfig testCaseConfig : testSuiteConfig.getTestCaseList() )
      {
        testCaseConfig.setSecurityTestArray( new SecurityTestConfig[0] );
      }
    }

    WsdlTestSuite oldTestSuite = testSuite;
    testSuite = buildTestSuite( testSuiteConfig );

    if( description != null )
      testSuite.setDescription( description );

    if( index == -1 )
      testSuites.add( testSuite );
    else
      testSuites.add( index, testSuite );

    if( createCopy )
      ModelSupport.unsetIds( testSuite );

    testSuite.afterLoad();

    if( createCopy )
    {
      testSuite.afterCopy( oldTestSuite );
    }

    fireTestSuiteAdded( testSuite );

    resolveImportedTestSuite( testSuite );

    return testSuite;
  }

  public WsdlMockService importMockService( WsdlMockService mockService, String name, boolean createCopy,
      String description )
  {
    mockService.beforeSave();
    MockServiceConfig mockServiceConfig = ( MockServiceConfig )getConfig().addNewMockService().set(
        mockService.getConfig().copy() );
    mockServiceConfig.setName( name );
    if( mockServiceConfig.isSetId() && createCopy )
      mockServiceConfig.unsetId();
    mockService = new WsdlMockService( this, mockServiceConfig );
    mockService.setDescription( description );
    mockServices.add( mockService );
    if( createCopy )
      ModelSupport.unsetIds( mockService );

    mockService.afterLoad();

    fireMockServiceAdded( mockService );

    return mockService;
  }

  public EndpointStrategy getEndpointStrategy()
  {
    return endpointStrategy;
  }

  public boolean isOpen()
  {
    return open;
  }

  public List<? extends ModelItem> getChildren()
  {
    ArrayList<ModelItem> list = new ArrayList<ModelItem>();
    list.addAll( getInterfaceList() );
    list.addAll( getTestSuiteList() );
    list.addAll( getMockServiceList() );
    return list;
  }

  public void setAfterLoadScript( String script )
  {
    String oldScript = getAfterLoadScript();

    if( !getConfig().isSetAfterLoadScript() )
      getConfig().addNewAfterLoadScript();

    getConfig().getAfterLoadScript().setStringValue( script );
    if( afterLoadScriptEngine != null )
      afterLoadScriptEngine.setScript( script );

    notifyPropertyChanged( AFTER_LOAD_SCRIPT_PROPERTY, oldScript, script );
  }

  public String getAfterLoadScript()
  {
    return getConfig().isSetAfterLoadScript() ? getConfig().getAfterLoadScript().getStringValue() : null;
  }

  public void setBeforeSaveScript( String script )
  {
    String oldScript = getBeforeSaveScript();

    if( !getConfig().isSetBeforeSaveScript() )
      getConfig().addNewBeforeSaveScript();

    getConfig().getBeforeSaveScript().setStringValue( script );
    if( beforeSaveScriptEngine != null )
      beforeSaveScriptEngine.setScript( script );

    notifyPropertyChanged( BEFORE_SAVE_SCRIPT_PROPERTY, oldScript, script );
  }

  public String getBeforeSaveScript()
  {
    return getConfig().isSetBeforeSaveScript() ? getConfig().getBeforeSaveScript().getStringValue() : null;
  }

  public Object runAfterLoadScript() throws Exception
  {
    String script = getAfterLoadScript();
    if( StringUtils.isNullOrEmpty( script ) )
      return null;

    if( afterLoadScriptEngine == null )
    {
      afterLoadScriptEngine = SoapUIScriptEngineRegistry.create( this );
      afterLoadScriptEngine.setScript( script );
    }

    afterLoadScriptEngine.setVariable( "context", context );
    afterLoadScriptEngine.setVariable( "project", this );
    afterLoadScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
    return afterLoadScriptEngine.run();
  }

  public Object runBeforeSaveScript() throws Exception
  {
    String script = getBeforeSaveScript();
    if( StringUtils.isNullOrEmpty( script ) )
      return null;

    if( beforeSaveScriptEngine == null )
    {
      beforeSaveScriptEngine = SoapUIScriptEngineRegistry.create( this );
      beforeSaveScriptEngine.setScript( script );
    }

    beforeSaveScriptEngine.setVariable( "context", context );
    beforeSaveScriptEngine.setVariable( "project", this );
    beforeSaveScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
    return beforeSaveScriptEngine.run();
  }

  public PropertyExpansionContext getContext()
  {
    return context;
  }

  public DefaultWssContainer getWssContainer()
  {
    return wssContainer;
  }

  @Override
  public void resolve( ResolveContext<?> context )
  {
    super.resolve( context );

    wssContainer.resolve( context );
  }

  public PropertyExpansion[] getPropertyExpansions()
  {
    List<PropertyExpansion> result = new ArrayList<PropertyExpansion>();

    result.addAll( Arrays.asList( wssContainer.getPropertyExpansions() ) );
    // result.addAll(Arrays.asList(databaseConnectionContainer.
    // getPropertyExpansions()));

    return result.toArray( new PropertyExpansion[result.size()] );

  }
  @Override
  protected void addExternalDependencies( List<ExternalDependency> dependencies )
  {
    super.addExternalDependencies( dependencies );
    wssContainer.addExternalDependency( dependencies );
  }

  public String getPropertiesLabel()
  {
    return "Custom Properties";
  }

  public String getShadowPassword()
  {
    projectPassword = getSettings() == null ? projectPassword : getSettings().getString(
        ProjectSettings.SHADOW_PASSWORD, null );
    return projectPassword;
  }

  public void setShadowPassword( String password )
  {
    String oldPassword = getSettings().getString( ProjectSettings.SHADOW_PASSWORD, null );
    getSettings().setString( ProjectSettings.SHADOW_PASSWORD, password );
    notifyPropertyChanged( "projectPassword", oldPassword, password );
  }

  public String getHermesConfig()
  {
    hermesConfig = getSettings() == null ? hermesConfig : resolveHermesConfig();
    return hermesConfig;
  }

  private String resolveHermesConfig()
  {
    String hermesConfigProperty = getSettings().getString( ProjectSettings.HERMES_CONFIG, null );
    if( hermesConfigProperty != null && !hermesConfigProperty.equals( "" ) )
    {
      return hermesConfigProperty;
    }
    else if( System.getenv( "HERMES_CONFIG" ) != null )
    {
      return System.getenv( "HERMES_CONFIG" );
    }
    else
    {
      return "${#System#user.home}\\.hermes";
    }

  }

  public void setHermesConfig( String hermesConfigPath )
  {
    String oldHermesConfigPath = getSettings().getString( ProjectSettings.HERMES_CONFIG, null );
    getSettings().setString( ProjectSettings.HERMES_CONFIG, hermesConfigPath );
    notifyPropertyChanged( "hermesConfig", oldHermesConfigPath, hermesConfigPath );

  }

  public void inspect()
  {

    if( !isOpen() )
      return;

    byte data[] = projectDocument.getSoapuiProject().getEncryptedContent();
    if( data != null && data.length > 0 )
    {
      try
      {
        reload();
      }
      catch( SoapUIException e )
      {
        e.printStackTrace();
      }
    }
  }

  public int getEncrypted()
  {
    return this.encrypted;
  }

  public int setEncrypted( int code )
  {
    return this.encrypted = code;
  }

  public void propertyChange( PropertyChangeEvent evt )
  {
    if( "projectPassword".equals( evt.getPropertyName() ) )
    {
      if( encrypted == 0 & ( evt.getOldValue() == null || ( ( String )evt.getOldValue() ).length() == 0 ) )
      {
        encrypted = 1;
      }
      if( encrypted == 1 & ( evt.getNewValue() == null || ( ( String )evt.getNewValue() ).length() == 0 ) )
      {
        encrypted = 0;
      }

      if( SoapUI.getNavigator() != null )
        SoapUI.getNavigator().repaint();
    }
  }

  public SoapuiProjectDocumentConfig getProjectDocument()
  {
    return projectDocument;
  }

  public int getInterfaceCount( String type )
  {
    int result = 0;

    for( AbstractInterface<?> iface : interfaces )
    {
      if( iface.getType().equals( type ) )
        result++ ;
    }

    return result;
  }

  public List<AbstractInterface<?>> getInterfaces( String type )
  {
    ArrayList<AbstractInterface<?>> result = new ArrayList<AbstractInterface<?>>();

    for( AbstractInterface<?> iface : interfaces )
    {
      if( iface.getType().equals( type ) )
        result.add( iface );
    }

    return result;
  }

  public void importTestSuite( File file )
  {
    if( !file.exists() )
    {
      UISupport.showErrorMessage( "Error loading test case " );
      return;
    }

    TestSuiteDocumentConfig newTestSuiteConfig = null;

    try
    {
      newTestSuiteConfig = TestSuiteDocumentConfig.Factory.parse( file );
    }
    catch( Exception e )
    {
      SoapUI.logError( e );
    }

    if( newTestSuiteConfig == null )
    {
      UISupport.showErrorMessage( "Not valild test case xml" );
    }
    else
    {
      TestSuiteConfig config = ( TestSuiteConfig )projectDocument.getSoapuiProject().addNewTestSuite()
          .set( newTestSuiteConfig.getTestSuite() );
      WsdlTestSuite testSuite = buildTestSuite( config );

      ModelSupport.unsetIds( testSuite );
      testSuite.afterLoad();

      /*
       * security test keeps reference to test step by id, which gets changed
       * during importing, so old values needs to be rewritten to new ones.
       *
       * Create tarnsition table ( old id , new id ) and use it to replace
       * all old ids in new imported test case.
       *
       * Here needs to be done for all test cases separatly.
       */
      for( int cnt2 = 0; cnt2 < config.getTestCaseList().size(); cnt2++ )
      {
        TestCaseConfig newTestCase = config.getTestCaseList().get( cnt2 );
        TestCaseConfig importTestCaseConfig = newTestSuiteConfig.getTestSuite().getTestCaseList().get( cnt2 );
        LinkedHashMap<String, String> oldNewIds = new LinkedHashMap<String, String>();
        for( int cnt = 0; cnt < importTestCaseConfig.getTestStepList().size(); cnt++ )
          oldNewIds.put( importTestCaseConfig.getTestStepList().get( cnt ).getId(), newTestCase.getTestStepList()
              .get( cnt ).getId() );

        for( SecurityTestConfig scan : newTestCase.getSecurityTestList() )
          for( TestStepSecurityTestConfig secStepConfig : scan.getTestStepSecurityTestList() )
            if( oldNewIds.containsKey( secStepConfig.getTestStepId() ) )
              secStepConfig.setTestStepId( oldNewIds.get( secStepConfig.getTestStepId() ) );

      }
      testSuites.add( testSuite );
      fireTestSuiteAdded( testSuite );

      resolveImportedTestSuite( testSuite );
    }
  }

  private void resolveImportedTestSuite( WsdlTestSuite testSuite )
  {
    ResolveDialog resolver = new ResolveDialog( "Validate TestSuite", "Checks TestSuite for inconsistencies", null );
    resolver.setShowOkMessage( false );
    resolver.resolve( testSuite );
  }

  /**
   * @see com.eviware.soapui.impl.WsdlInterfaceFactory.importWsdl
   * @deprecated
   */

  public WsdlInterface[] importWsdl( String url, boolean createRequests ) throws SoapUIException
  {
    return WsdlInterfaceFactory.importWsdl( this, url, createRequests );
  }

  /**
   * @see com.eviware.soapui.impl.WsdlInterfaceFactory.importWsdl
   * @deprecated see WsdlInterfaceFactory
   */

  public WsdlInterface[] importWsdl( String url, boolean createRequests, WsdlLoader wsdlLoader )
      throws SoapUIException
  {
    return WsdlInterfaceFactory.importWsdl( this, url, createRequests, null, wsdlLoader );
  }

  /**
   * @see com.eviware.soapui.impl.WsdlInterfaceFactory.importWsdl
   * @deprecated see WsdlInterfaceFactory
   */

  public WsdlInterface[] importWsdl( String url, boolean createRequests, QName bindingName, WsdlLoader wsdlLoader )
      throws SoapUIException
  {
    return WsdlInterfaceFactory.importWsdl( this, url, createRequests, bindingName, wsdlLoader );
  }

  public void setDefaultScriptLanguage( String id )
  {
    getConfig().setDefaultScriptLanguage( id );
  }

  public String getDefaultScriptLanguage()
  {
    if( getConfig().isSetDefaultScriptLanguage() )
      return getConfig().getDefaultScriptLanguage();
    else
      return SoapUIScriptEngineRegistry.DEFAULT_SCRIPT_ENGINE_ID;
  }

  public int getIndexOfTestSuite( TestSuite testSuite )
  {
    return testSuites.indexOf( testSuite );
  }

  public String getBeforeRunScript()
  {
    return getConfig().isSetBeforeRunScript() ? getConfig().getBeforeRunScript().getStringValue() : null;
  }

  public void setBeforeRunScript( String script )
  {
    String oldScript = getBeforeRunScript();

    if( !getConfig().isSetBeforeRunScript() )
      getConfig().addNewBeforeRunScript();

    getConfig().getBeforeRunScript().setStringValue( script );
    if( beforeRunScriptEngine != null )
      beforeRunScriptEngine.setScript( script );

    notifyPropertyChanged( "beforeRunScript", oldScript, script );
  }

  public Object runBeforeRunScript( ProjectRunContext context, ProjectRunner runner ) throws Exception
  {
    String script = getBeforeRunScript();
    if( StringUtils.isNullOrEmpty( script ) )
      return null;

    if( beforeRunScriptEngine == null )
    {
      beforeRunScriptEngine = SoapUIScriptEngineRegistry.create( this );
      beforeRunScriptEngine.setScript( script );
    }

    beforeRunScriptEngine.setVariable( "runner", runner );
    beforeRunScriptEngine.setVariable( "context", context );
    beforeRunScriptEngine.setVariable( "project", this );
    beforeRunScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
    return beforeRunScriptEngine.run();
  }

  public String getAfterRunScript()
  {
    return getConfig().isSetAfterRunScript() ? getConfig().getAfterRunScript().getStringValue() : null;
  }

  public void setAfterRunScript( String script )
  {
    String oldScript = getAfterRunScript();

    if( !getConfig().isSetAfterRunScript() )
      getConfig().addNewAfterRunScript();

    getConfig().getAfterRunScript().setStringValue( script );
    if( afterRunScriptEngine != null )
      afterRunScriptEngine.setScript( script );

    notifyPropertyChanged( "afterRunScript", oldScript, script );
  }

  public Object runAfterRunScript( ProjectRunContext context, ProjectRunner runner ) throws Exception
  {
    String script = getAfterRunScript();
    if( StringUtils.isNullOrEmpty( script ) )
      return null;

    if( afterRunScriptEngine == null )
    {
      afterRunScriptEngine = SoapUIScriptEngineRegistry.create( this );
      afterRunScriptEngine.setScript( script );
    }

    afterRunScriptEngine.setVariable( "runner", runner );
    afterRunScriptEngine.setVariable( "context", context );
    afterRunScriptEngine.setVariable( "project", this );
    afterRunScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
    return afterRunScriptEngine.run();
  }

  public void addProjectRunListener( ProjectRunListener projectRunListener )
  {
    runListeners.add( projectRunListener );
  }

  public void removeProjectRunListener( ProjectRunListener projectRunListener )
  {
    runListeners.remove( projectRunListener );
  }

  public WsdlProjectRunner run( StringToObjectMap context, boolean async )
  {
    WsdlProjectRunner runner = new WsdlProjectRunner( this, context );
    runner.start( async );
    return runner;
  }

  public boolean isAbortOnError()
  {
    return getConfig().getAbortOnError();
  }

  // public boolean isFailOnErrors()
  // {
  // return getConfig().getFailOnErrors();
  // }
  //
  // public void setFailOnErrors( boolean arg0 )
  // {
  // getConfig().setFailOnErrors( arg0 );
  // }

  public void setAbortOnError( boolean arg0 )
  {
    getConfig().setAbortOnError( arg0 );
  }

  public long getTimeout()
  {
    return getConfig().getTimeout();
  }

  public void setTimeout( long timeout )
  {
    getConfig().setTimeout( timeout );
  }

  public ProjectRunListener[] getProjectRunListeners()
  {
    return runListeners.toArray( new ProjectRunListener[runListeners.size()] );
  }

  public TestSuiteRunType getRunType()
  {
    Enum runType = getConfig().getRunType();

    if( TestSuiteRunTypesConfig.PARALLELL.equals( runType ) )
      return TestSuiteRunType.PARALLEL;
    else
      return TestSuiteRunType.SEQUENTIAL;
  }

  public void setRunType( TestSuiteRunType runType )
  {
    TestSuiteRunType oldRunType = getRunType();

    if( runType == TestSuiteRunType.PARALLEL && oldRunType != TestSuiteRunType.PARALLEL )
    {
      getConfig().setRunType( TestSuiteRunTypesConfig.PARALLELL );
      notifyPropertyChanged( "runType", oldRunType, runType );
    }
    else if( runType == TestSuiteRunType.SEQUENTIAL && oldRunType != TestSuiteRunType.SEQUENTIAL )
    {
      getConfig().setRunType( TestSuiteRunTypesConfig.SEQUENTIAL );
      notifyPropertyChanged( "runType", oldRunType, runType );
    }
  }

  public WsdlTestSuite moveTestSuite( int ix, int offset )
  {
    WsdlTestSuite testSuite = testSuites.get( ix );

    if( offset == 0 )
      return testSuite;

    testSuites.remove( ix );
    testSuites.add( ix + offset, testSuite );

    TestSuiteConfig[] configs = new TestSuiteConfig[testSuites.size()];

    for( int c = 0; c < testSuites.size(); c++ )
    {
      if( offset > 0 )
      {
        if( c < ix )
          configs[c] = ( TestSuiteConfig )getConfig().getTestSuiteArray( c ).copy();
        else if( c < ( ix + offset ) )
          configs[c] = ( TestSuiteConfig )getConfig().getTestSuiteArray( c + 1 ).copy();
        else if( c == ix + offset )
          configs[c] = ( TestSuiteConfig )getConfig().getTestSuiteArray( ix ).copy();
        else
          configs[c] = ( TestSuiteConfig )getConfig().getTestSuiteArray( c ).copy();
      }
      else
      {
        if( c < ix + offset )
          configs[c] = ( TestSuiteConfig )getConfig().getTestSuiteArray( c ).copy();
        else if( c == ix + offset )
          configs[c] = ( TestSuiteConfig )getConfig().getTestSuiteArray( ix ).copy();
        else if( c <= ix )
          configs[c] = ( TestSuiteConfig )getConfig().getTestSuiteArray( c - 1 ).copy();
        else
          configs[c] = ( TestSuiteConfig )getConfig().getTestSuiteArray( c ).copy();
      }
    }

    getConfig().setTestSuiteArray( configs );
    for( int c = 0; c < configs.length; c++ )
    {
      testSuites.get( c ).resetConfigOnMove( getConfig().getTestSuiteArray( c ) );
    }

    fireTestSuiteMoved( testSuite, ix, offset );
    return testSuite;

  }

  public void importMockService( File file )
  {
    if( !file.exists() )
    {
      UISupport.showErrorMessage( "Error loading test case " );
      return;
    }

    MockServiceDocumentConfig newMockServiceConfig = null;

    try
    {
      newMockServiceConfig = MockServiceDocumentConfig.Factory.parse( file );
    }
    catch( Exception e )
    {
      SoapUI.logError( e );
    }

    if( newMockServiceConfig == null )
    {
      UISupport.showErrorMessage( "Not valid mock service xml" );
    }
    else
    {
      MockServiceConfig config = ( MockServiceConfig )projectDocument.getSoapuiProject().addNewMockService()
          .set( newMockServiceConfig.getMockService() );
      WsdlMockService mockService = new WsdlMockService( this, config );

      ModelSupport.unsetIds( mockService );
      mockService.afterLoad();

      mockServices.add( mockService );
      fireMockServiceAdded( mockService );

      resolveImportedMockService( mockService );
    }
  }

  private void resolveImportedMockService( WsdlMockService mockService )
  {
    ResolveDialog resolver = new ResolveDialog( "Validate MockService", "Checks MockService for inconsistencies",
        null );
    resolver.setShowOkMessage( false );
    resolver.resolve( mockService );
  }

  // we switch from check to scan, and then we work with scans only
  // quick and dirty way to get this done
  private static Map<String, String> checkToScanMap = initCheckToScanMap();

  private static Map<String, String> initCheckToScanMap()
  {
    Map<String, String> map = new HashMap<String, String>();
    map.put( "BoundaryCheck", "BoundaryScan" );
    map.put( "ParameterExposureCheck", "CrossSiteScriptingScan" );
    map.put( "FuzzingScan", "FuzzingScan" );
    map.put( "GroovySecurityCheck", "GroovySecurityScan" );
    map.put( "InvalidTypesSecurityCheck", "InvalidTypesSecurityScan" );
    map.put( "MalformedXmlSecurityCheck", "MalformedXmlSecurityScan" );
    map.put( "MaliciousAttachmentSecurityCheck", "MaliciousAttachmentSecurityScan" );
    map.put( "SQLInjectionCheck", "SQLInjectionScan" );
    map.put( "XmlBombSecurityCheck", "XmlBombSecurityScan" );
    map.put( "XPathInjectionSecurityCheck", "XPathInjectionSecurityScan" );
    return map;
  }

  protected void updateChecksToScans( ProjectConfig config )
  {
    for( TestSuiteConfig testSuite : config.getTestSuiteList() )
    {
      for( TestCaseConfig testCase : testSuite.getTestCaseList() )
      {
        for( SecurityTestConfig securityTest : testCase.getSecurityTestList() )
        {
          if( securityTest.getFailSecurityTestOnCheckErrors() )
          {
            securityTest.setFailSecurityTestOnScanErrors( securityTest.getFailSecurityTestOnCheckErrors() );
          }

          for( TestStepSecurityTestConfig testStep : securityTest.getTestStepSecurityTestList() )
          {
            // get all checks
            List<SecurityCheckConfig> checkList = testStep.getTestStepSecurityCheckList();

            // transform to scans
            for( SecurityCheckConfig check : checkList )
            {
              SecurityScanConfig scan = testStep.addNewTestStepSecurityScan();

              scan.setName( check.getName() );
              scan.setTestStep( check.getTestStep() );
              scan.setExecutionStrategy( check.getExecutionStrategy() );
              scan.setType( checkToScanMap.get( check.getType() ) );

              for( TestAssertionConfig assertion : check.getAssertionList() )
              {
                TestAssertionConfig assertion2 = scan.addNewAssertion();

                assertion2.setConfiguration( assertion.getConfiguration() );
                assertion2.setType( assertion.getType() );
                assertion2.setName( assertion.getName() );
                if( assertion.isSetDescription() )
                {
                  assertion2.setDescription( assertion.getDescription() );
                }
                if( assertion.isSetDisabled() )
                {
                  assertion2.setDisabled( assertion.getDisabled() );
                }
                if( assertion.isSetId() )
                {
                  assertion2.setId( assertion.getId() );
                }
                if( assertion.isSetTimestamp() )
                {
                  assertion2.setTimestamp( assertion.getTimestamp() );
                }
              }

              scan.setCheckedParameters( check.getCheckedPameters() );

              XmlObject obj = check.getConfig();

              if( obj instanceof InvalidSecurityCheckConfig )
              {
                InvalidSecurityScanConfig obj2 = InvalidSecurityScanConfig.Factory.newInstance();
                for( SchemaTypeForSecurityCheckConfig el : ( ( InvalidSecurityCheckConfig )obj )
                    .getTypesListList() )
                {
                  SchemaTypeForSecurityScanConfig type = obj2.addNewTypesList();
                  type.setType( el.getType() );
                  type.setValue( el.getValue() );
                }
              }
              else if( obj instanceof GroovySecurityCheckConfig )
              {
                GroovySecurityScanConfig obj2 = GroovySecurityScanConfig.Factory.newInstance();
                obj2.setExecuteScript( ( ( GroovySecurityCheckConfig )obj ).getExecuteScript() );
              }
              else if( obj instanceof ParameterExposureCheckConfig )
              {
                CrossSiteScriptingScanConfig obj2 = CrossSiteScriptingScanConfig.Factory.newInstance();
                for( String el : ( ( ParameterExposureCheckConfig )obj ).getParameterExposureStringsList() )
                {
                  obj2.addParameterExposureStrings( el );
                }
              }
              else if( obj instanceof MaliciousAttachmentSecurityCheckConfig )
              {
                MaliciousAttachmentSecurityScanConfig obj2 = MaliciousAttachmentSecurityScanConfig.Factory
                    .newInstance();
                obj2.setRequestTimeout( ( ( MaliciousAttachmentSecurityCheckConfig )obj ).getRequestTimeout() );
                for( MaliciousAttachmentElementConfig el : ( ( MaliciousAttachmentSecurityCheckConfig )obj )
                    .getElementList() )
                {
                  MaliciousAttachmentElementConfig el2 = obj2.addNewElement();
                  el2.setKey( el.getKey() );
                  el2.setRemove( el.getRemove() );
                  for( MaliciousAttachmentConfig gen : el.getGenerateAttachmentList() )
                  {
                    MaliciousAttachmentConfig gen2 = el2.addNewGenerateAttachment();
                    gen2.setCached( gen.getCached() );
                    gen2.setContentType( gen.getContentType() );
                    gen2.setEnabled( gen.getEnabled() );
                    gen2.setFilename( gen.getFilename() );
                    gen2.setSize( gen.getSize() );
                  }
                  for( MaliciousAttachmentConfig repl : el.getReplaceAttachmentList() )
                  {
                    MaliciousAttachmentConfig repl2 = el2.addNewReplaceAttachment();
                    repl2.setCached( repl.getCached() );
                    repl2.setContentType( repl.getContentType() );
                    repl2.setEnabled( repl.getEnabled() );
                    repl2.setFilename( repl.getFilename() );
                    repl2.setSize( repl.getSize() );
                  }
                }
              }
              else if( obj instanceof SQLInjectionCheckConfig )
              {
                SQLInjectionScanConfig obj2 = SQLInjectionScanConfig.Factory.newInstance();
                for( String el : ( ( SQLInjectionCheckConfig )obj ).getSqlInjectionStringsList() )
                {
                  obj2.addSqlInjectionStrings( el );
                }
              }
              else if( obj instanceof XmlBombSecurityCheckConfig )
              {
                XmlBombSecurityScanConfig obj2 = XmlBombSecurityScanConfig.Factory.newInstance();
                obj2.setAttachXmlBomb( ( ( XmlBombSecurityCheckConfig )obj ).getAttachXmlBomb() );
                obj2.setXmlAttachmentPrefix( ( ( XmlBombSecurityCheckConfig )obj ).getXmlAttachmentPrefix() );
                for( String el : ( ( XmlBombSecurityCheckConfig )obj ).getXmlBombsList() )
                {
                  obj2.addXmlBombs( el );
                }
              }
              else
              {
                // boundary scan, malformed xml, xpath
                scan.setConfig( obj );
              }
            }

            // finally, remove checks
            testStep.setTestStepSecurityCheckArray( new SecurityCheckConfig[0] );
          }
        }
      }
    }
  }
}
TOP

Related Classes of com.eviware.soapui.impl.wsdl.WsdlProject

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.