Package com.eviware.soapui.impl.wsdl.panels.teststeps.support

Source Code of com.eviware.soapui.impl.wsdl.panels.teststeps.support.PropertyHolderTable$PropertiesTableCellRenderer

/*
*  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.panels.teststeps.support;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.ActionEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;

import com.eviware.soapui.SoapUI;
import com.eviware.soapui.impl.wsdl.MutableTestPropertyHolder;
import com.eviware.soapui.impl.wsdl.teststeps.AMFRequestTestStep;
import com.eviware.soapui.impl.wsdl.teststeps.JdbcRequestTestStep;
import com.eviware.soapui.model.TestPropertyHolder;
import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
import com.eviware.soapui.model.propertyexpansion.PropertyExpansionImpl;
import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
import com.eviware.soapui.model.support.TestPropertyUtils;
import com.eviware.soapui.model.testsuite.TestProperty;
import com.eviware.soapui.model.testsuite.TestPropertyListener;
import com.eviware.soapui.model.tree.nodes.PropertyTreeNode.PropertyModelItem;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.components.JXToolBar;
import com.eviware.soapui.support.xml.XmlUtils;
import com.eviware.x.form.XFormDialog;
import com.eviware.x.form.support.ADialogBuilder;
import com.eviware.x.form.support.AField;
import com.eviware.x.form.support.AForm;
import com.eviware.x.form.support.AField.AFieldType;

@SuppressWarnings( "serial" )
public class PropertyHolderTable extends JPanel
{
  protected final TestPropertyHolder holder;
  protected PropertyHolderTableModel propertiesModel;
  protected RemovePropertyAction removePropertyAction;
  protected AddPropertyAction addPropertyAction;
  protected InternalTestPropertyListener testPropertyListener;
  protected JTable propertiesTable;
  protected JXToolBar toolbar;
  protected LoadPropertiesAction loadPropertiesAction;
  protected MovePropertyUpAction movePropertyUpAction;
  protected MovePropertyDownAction movePropertyDownAction;

  public PropertyHolderTable( TestPropertyHolder holder )
  {
    super( new BorderLayout() );
    this.holder = holder;

    loadPropertiesAction = new LoadPropertiesAction();
    testPropertyListener = new InternalTestPropertyListener();
    holder.addTestPropertyListener( testPropertyListener );

    JScrollPane scrollPane = new JScrollPane( buildPropertiesTable() );

    if( getHolder().getModelItem() != null )
    {
      DropTarget dropTarget = new DropTarget( scrollPane, new PropertyHolderTablePropertyExpansionDropTarget() );
      dropTarget.setDefaultActions( DnDConstants.ACTION_COPY_OR_MOVE );
    }

    add( scrollPane, BorderLayout.CENTER );
    add( buildToolbar(), BorderLayout.NORTH );
  }

  protected JTable buildPropertiesTable()
  {
    propertiesModel = new DefaultPropertyTableHolderModel( holder );
    propertiesTable = new PropertiesHolderJTable();
    propertiesTable.setSurrendersFocusOnKeystroke( true );

    propertiesTable.putClientProperty( "terminateEditOnFocusLost", Boolean.TRUE );
    propertiesTable.getSelectionModel().addListSelectionListener( new ListSelectionListener()
    {
      public void valueChanged( ListSelectionEvent e )
      {
        int selectedRow = propertiesTable.getSelectedRow();
        if( removePropertyAction != null )
          removePropertyAction.setEnabled( selectedRow != -1 );

        if( movePropertyUpAction != null )
          movePropertyUpAction.setEnabled( selectedRow > 0 );

        if( movePropertyDownAction != null )
          movePropertyDownAction.setEnabled( selectedRow >= 0 && selectedRow < propertiesTable.getRowCount() - 1 );
      }
    } );

    propertiesTable.setDragEnabled( true );
    propertiesTable.setTransferHandler( new TransferHandler( "testProperty" ) );

    if( getHolder().getModelItem() != null )
    {
      DropTarget dropTarget = new DropTarget( propertiesTable, new PropertyHolderTablePropertyExpansionDropTarget() );
      dropTarget.setDefaultActions( DnDConstants.ACTION_COPY_OR_MOVE );
    }

    // Set render this only for value column. In this cell render we handle password shadowing.
    propertiesTable.getColumnModel().getColumn( 1 ).setCellRenderer( new PropertiesTableCellRenderer() );
    return propertiesTable;
  }

  public class PropertiesHolderJTable extends JTable
  {
    public PropertiesHolderJTable()
    {
      super( propertiesModel );
      setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
      // setAutoStartEditOnKeyStroke( true );
      setSurrendersFocusOnKeystroke( true );
      setRowHeight( 19 );
      // setHorizontalScrollEnabled(true);
    }

    public PropertyModelItem getTestProperty()
    {
      int index = getSelectedRow();
      if( index == -1 )
        return null;
      TestProperty property = propertiesModel.getPropertyAtRow( index );
      return new PropertyModelItem( property, true );
    }
  }

  private Component buildToolbar()
  {
    toolbar = UISupport.createSmallToolbar();

    if( holder instanceof MutableTestPropertyHolder )
    {
      removePropertyAction = new RemovePropertyAction();
      addPropertyAction = new AddPropertyAction();
      movePropertyUpAction = new MovePropertyUpAction();
      movePropertyDownAction = new MovePropertyDownAction();

      JButton addPropertyButton = UISupport.createToolbarButton( addPropertyAction );
      toolbar.add( addPropertyButton );
      JButton removePropertyButton = UISupport.createToolbarButton( removePropertyAction );
      toolbar.add( removePropertyButton );

      toolbar.addRelatedGap();
      JButton movePropertyUpButton = UISupport.createToolbarButton( movePropertyUpAction );
      toolbar.add( movePropertyUpButton );
      JButton movePropertyDownButton = UISupport.createToolbarButton( movePropertyDownAction );
      toolbar.add( movePropertyDownButton );

      if( !( holder instanceof AMFRequestTestStep || holder instanceof JdbcRequestTestStep ) )
      {
        toolbar.addRelatedGap();
        toolbar.add( UISupport.createToolbarButton( new SortPropertiesAction() ) );
        toolbar.addRelatedGap();
      }
    }

    JButton clearPropertiesButton = UISupport.createToolbarButton( new ClearPropertiesAction() );
    toolbar.add( clearPropertiesButton );
    JButton loadPropertiesButton = UISupport.createToolbarButton( loadPropertiesAction );
    toolbar.add( loadPropertiesButton );
    toolbar.add( UISupport.createToolbarButton( new SavePropertiesAction() ) );

    return toolbar;
  }

  public JXToolBar getToolbar()
  {
    return toolbar;
  }

  public JTable getPropertiesTable()
  {
    return propertiesTable;
  }

  public void release()
  {
    if( propertiesTable.isEditing() )
      propertiesTable.getCellEditor().stopCellEditing();

    holder.removeTestPropertyListener( testPropertyListener );
  }

  public void setEnabled( boolean enabled )
  {
    addPropertyAction.setEnabled( enabled );
    removePropertyAction.setEnabled( enabled );
    propertiesTable.setEnabled( enabled );
    loadPropertiesAction.setEnabled( enabled );

    super.setEnabled( enabled );
  }

  private final class InternalTestPropertyListener implements TestPropertyListener
  {
    private boolean enabled = true;

    @SuppressWarnings( "unused" )
    public boolean isEnabled()
    {
      return enabled;
    }

    @SuppressWarnings( "unused" )
    public void setEnabled( boolean enabled )
    {
      this.enabled = enabled;
    }

    public void propertyAdded( String name )
    {
      if( enabled )
        propertiesModel.fireTableDataChanged();
    }

    public void propertyRemoved( String name )
    {
      if( enabled )
        propertiesModel.fireTableDataChanged();
    }

    public void propertyRenamed( String oldName, String newName )
    {
      if( enabled )
        propertiesModel.fireTableDataChanged();
    }

    public void propertyValueChanged( String name, String oldValue, String newValue )
    {
      if( enabled )
        propertiesModel.fireTableDataChanged();
    }

    public void propertyMoved( String name, int oldIndex, int newIndex )
    {
      if( enabled )
        propertiesModel.fireTableDataChanged();
    }
  }

  private class AddPropertyAction extends AbstractAction
  {
    public AddPropertyAction()
    {
      putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/add_property.gif" ) );
      putValue( Action.SHORT_DESCRIPTION, "Adds a property to the property list" );
    }

    public void actionPerformed( ActionEvent e )
    {
      String name = UISupport.prompt( "Specify unique property name", "Add Property", "" );
      if( StringUtils.hasContent( name ) )
      {
        if( holder.hasProperty( name ) )
        {
          UISupport.showErrorMessage( "Property name [" + name + "] already exists.." );
          return;
        }

        ( ( MutableTestPropertyHolder )holder ).addProperty( name );
        final int row = holder.getPropertyNames().length - 1;
        propertiesModel.fireTableRowsInserted( row, row );
        SwingUtilities.invokeLater( new Runnable()
        {
          public void run()
          {
            requestFocusInWindow();
            scrollRectToVisible( propertiesTable.getCellRect( row, 1, true ) );
            SwingUtilities.invokeLater( new Runnable()
            {
              public void run()
              {
                propertiesTable.editCellAt( row, 1 );
                Component editorComponent = propertiesTable.getEditorComponent();
                if( editorComponent != null )
                  editorComponent.requestFocusInWindow();
              }
            } );
          }
        } );

      }
    }
  }

  protected class RemovePropertyAction extends AbstractAction
  {
    public RemovePropertyAction()
    {
      putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/remove_property.gif" ) );
      putValue( Action.SHORT_DESCRIPTION, "Removes the selected property from the property list" );
      setEnabled( false );
    }

    public void actionPerformed( ActionEvent e )
    {
      int row = propertiesTable.getSelectedRow();
      if( row == -1 )
        return;

      UISupport.stopCellEditing( propertiesTable );

      String propertyName = propertiesModel.getValueAt( row, 0 ).toString();
      if( UISupport.confirm( "Remove property [" + propertyName + "]?", "Remove Property" ) )
      {
        ( ( MutableTestPropertyHolder )holder ).removeProperty( propertyName );
        propertiesModel.fireTableRowsDeleted( row, row );
      }
    }
  }

  protected class ClearPropertiesAction extends AbstractAction
  {
    public ClearPropertiesAction()
    {
      putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/clear_properties.gif" ) );
      putValue( Action.SHORT_DESCRIPTION, "Clears all current property values" );
    }

    public void actionPerformed( ActionEvent e )
    {
      if( UISupport.confirm( "Clear all property values?", "Clear Properties" ) )
      {
        for( String name : holder.getPropertyNames() )
        {
          holder.getProperty( name ).setValue( null );
        }
      }
    }
  }

  protected class MovePropertyUpAction extends AbstractAction
  {
    public MovePropertyUpAction()
    {
      putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/up_arrow.gif" ) );
      putValue( Action.SHORT_DESCRIPTION, "Moves selected property up one row" );
      setEnabled( false );
    }

    public void actionPerformed( ActionEvent e )
    {
      int ix = propertiesTable.getSelectedRow();
      if( ix != -1 )
      {
        ( ( MutableTestPropertyHolder )holder ).moveProperty( holder.getPropertyAt( ix ).getName(), ix - 1 );
        propertiesTable.setRowSelectionInterval( ix - 1, ix - 1 );
      }
    }
  }

  protected class MovePropertyDownAction extends AbstractAction
  {
    public MovePropertyDownAction()
    {
      putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/down_arrow.gif" ) );
      putValue( Action.SHORT_DESCRIPTION, "Moves selected property down one row" );
      setEnabled( false );
    }

    public void actionPerformed( ActionEvent e )
    {
      int ix = propertiesTable.getSelectedRow();
      if( ix != -1 )
      {
        ( ( MutableTestPropertyHolder )holder ).moveProperty( holder.getPropertyAt( ix ).getName(), ix + 1 );

        propertiesTable.setRowSelectionInterval( ix + 1, ix + 1 );
      }
    }
  }

  protected class LoadPropertiesAction extends AbstractAction
  {
    private XFormDialog dialog;

    public LoadPropertiesAction()
    {
      putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/load_properties.gif" ) );
      putValue( Action.SHORT_DESCRIPTION, "Loads property values from an external file" );
    }

    public void actionPerformed( ActionEvent e )
    {
      if( dialog == null )
        dialog = ADialogBuilder.buildDialog( LoadOptionsForm.class );

      dialog.getFormField( LoadOptionsForm.DELETEREMAINING )
          .setEnabled( holder instanceof MutableTestPropertyHolder );
      dialog.getFormField( LoadOptionsForm.CREATEMISSING ).setEnabled( holder instanceof MutableTestPropertyHolder );

      if( dialog.show() )
      {
        try
        {
          BufferedReader reader = new BufferedReader( new FileReader( dialog.getValue( LoadOptionsForm.FILE ) ) );

          String line = reader.readLine();
          int count = 0;

          Set<String> names = new HashSet<String>( Arrays.asList( holder.getPropertyNames() ) );

          while( line != null )
          {
            if( line.trim().length() > 0 && !( line.charAt( 0 ) == '#' ) )
            {
              int ix = line.indexOf( '=' );
              if( ix > 0 )
              {
                String name = line.substring( 0, ix ).trim();
                String value = line.length() > ix ? line.substring( ix + 1 ) : "";

                // read multiline value
                if( value.endsWith( "\\" ) )
                {
                  value = value.substring( 0, value.length() - 1 );

                  String ln = reader.readLine();
                  while( ln != null && ln.endsWith( "\\" ) )
                  {
                    value += ln.substring( 0, ln.length() - 1 );
                    ln = reader.readLine();
                  }

                  if( ln != null )
                    value += ln;
                  if( ln == null )
                    break;
                }

                if( holder.hasProperty( name ) )
                {
                  count++ ;
                  holder.setPropertyValue( name, value );
                }
                else if( dialog.getBooleanValue( LoadOptionsForm.CREATEMISSING )
                    && holder instanceof MutableTestPropertyHolder )
                {
                  TestProperty prop = ( ( MutableTestPropertyHolder )holder ).addProperty( name );
                  if( !prop.isReadOnly() )
                    prop.setValue( value );
                  count++ ;
                }

                names.remove( name );
              }
            }

            line = reader.readLine();
          }

          if( dialog.getBooleanValue( LoadOptionsForm.DELETEREMAINING )
              && holder instanceof MutableTestPropertyHolder )
          {
            for( String name : names )
            {
              ( ( MutableTestPropertyHolder )holder ).removeProperty( name );
            }
          }

          reader.close();
          UISupport.showInfoMessage( "Added/Updated " + count + " properties from file" );
        }
        catch( Exception ex )
        {
          UISupport.showErrorMessage( ex );
        }
      }
    }
  }

  private class SavePropertiesAction extends AbstractAction
  {
    public SavePropertiesAction()
    {
      putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/set_properties_target.gif" ) );
      putValue( Action.SHORT_DESCRIPTION, "Saves current property-values to a file" );
    }

    public void actionPerformed( ActionEvent e )
    {
      if( holder.getPropertyCount() == 0 )
      {
        UISupport.showErrorMessage( "No properties to save!" );
        return;
      }

      File file = UISupport.getFileDialogs().saveAs( this, "Save Properties" );
      if( file != null )
      {
        try
        {
          int cnt = TestPropertyUtils.saveTo( holder, file.getAbsolutePath() );
          UISupport.showInfoMessage( "Saved " + cnt + " propert" + ( ( cnt == 1 ) ? "y" : "ies" ) + " to file" );
        }
        catch( IOException e1 )
        {
          UISupport.showErrorMessage( e1 );
        }
      }
    }
  }

  private class SortPropertiesAction extends AbstractAction
  {
    public SortPropertiesAction()
    {
      putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/arrow_down.png" ) );
      putValue( Action.SHORT_DESCRIPTION, "Sorts properties alphabetically" );
    }

    public void actionPerformed( ActionEvent e )
    {
      if( holder.getPropertyCount() == 0 )
      {
        UISupport.showErrorMessage( "No properties to sort!" );
        return;
      }

      try
      {
        UISupport.setHourglassCursor();
        TestPropertyUtils.sortProperties( ( MutableTestPropertyHolder )holder );
      }
      finally
      {
        UISupport.resetCursor();
      }

    }
  }

  @AForm( name = "Load Properties", description = "Set load options below" )
  private static interface LoadOptionsForm
  {
    @AField( name = "File", description = "The Properties file to load", type = AFieldType.FILE )
    public static final String FILE = "File";

    @AField( name = "Create Missing", description = "Creates Missing Properties", type = AFieldType.BOOLEAN )
    public static final String CREATEMISSING = "Create Missing";

    @AField( name = "Delete Remaining", description = "Deletes properties not in file", type = AFieldType.BOOLEAN )
    public static final String DELETEREMAINING = "Delete Remaining";
  }

  public TestPropertyHolder getHolder()
  {
    return holder;
  }

  public PropertyHolderTableModel getPropertiesModel()
  {
    return propertiesModel;
  }

  public final class PropertyHolderTablePropertyExpansionDropTarget implements DropTargetListener
  {
    public PropertyHolderTablePropertyExpansionDropTarget()
    {
    }

    public void dragEnter( DropTargetDragEvent dtde )
    {
      if( !isAcceptable( dtde.getTransferable(), dtde.getLocation() ) )
        dtde.rejectDrag();
    }

    public void dragExit( DropTargetEvent dtde )
    {
    }

    public void dragOver( DropTargetDragEvent dtde )
    {
      if( !isAcceptable( dtde.getTransferable(), dtde.getLocation() ) )
      {
        dtde.rejectDrag();
      }
      else
      {
        dtde.acceptDrag( dtde.getDropAction() );
      }
    }

    public void drop( DropTargetDropEvent dtde )
    {
      if( !isAcceptable( dtde.getTransferable(), dtde.getLocation() ) )
      {
        dtde.rejectDrop();
      }
      else
      {
        try
        {
          Transferable transferable = dtde.getTransferable();
          Object transferData = transferable.getTransferData( transferable.getTransferDataFlavors()[0] );
          if( transferData instanceof PropertyModelItem )
          {
            dtde.acceptDrop( dtde.getDropAction() );
            PropertyModelItem modelItem = ( PropertyModelItem )transferData;

            String xpath = modelItem.getXPath();
            if( xpath == null && XmlUtils.seemsToBeXml( modelItem.getProperty().getValue() ) )
            {
              xpath = UISupport.selectXPath( "Create PropertyExpansion", "Select XPath below", modelItem
                  .getProperty().getValue(), null );

              if( xpath != null )
                xpath = PropertyExpansionUtils.shortenXPathForPropertyExpansion( xpath, modelItem.getProperty()
                    .getValue() );
            }

            PropertyExpansion propertyExpansion = new PropertyExpansionImpl( modelItem.getProperty(), xpath );

            Point point = dtde.getLocation();
            int column = getPropertiesTable().columnAtPoint( point );
            int row = getPropertiesTable().rowAtPoint( point );

            if( row == -1 )
            {
              if( holder instanceof MutableTestPropertyHolder )
              {
                MutableTestPropertyHolder mtph = ( MutableTestPropertyHolder )holder;
                String name = UISupport.prompt( "Specify unique name of property", "Add Property", modelItem
                    .getProperty().getName() );
                while( name != null && mtph.hasProperty( name ) )
                {
                  name = UISupport.prompt( "Specify unique name of property", "Add Property", modelItem
                      .getProperty().getName() );
                }

                if( name != null )
                  mtph.addProperty( name ).setValue( propertyExpansion.toString() );
              }
            }
            else
            {
              getPropertiesTable().setValueAt( propertyExpansion.toString(), row, column );
            }

            dtde.dropComplete( true );
          }
        }
        catch( Exception e )
        {
          SoapUI.logError( e );
        }
      }
    }

    public void dropActionChanged( DropTargetDragEvent dtde )
    {
    }

    public boolean isAcceptable( Transferable transferable, Point point )
    {
      int row = getPropertiesTable().rowAtPoint( point );
      if( row >= 0 )
      {
        int column = getPropertiesTable().columnAtPoint( point );
        if( column != 1 )
          return false;

        if( !getPropertiesTable().isCellEditable( row, column ) )
          return false;
      }
      else if( !( getHolder() instanceof MutableTestPropertyHolder ) )
      {
        return false;
      }

      DataFlavor[] flavors = transferable.getTransferDataFlavors();
      for( int i = 0; i < flavors.length; i++ )
      {
        DataFlavor flavor = flavors[i];
        if( flavor.isMimeTypeEqual( DataFlavor.javaJVMLocalObjectMimeType ) )
        {
          try
          {
            Object modelItem = transferable.getTransferData( flavor );
            if( modelItem instanceof PropertyModelItem
                && ( ( PropertyModelItem )modelItem ).getProperty().getModelItem() != getHolder()
                    .getModelItem() )
            {
              return PropertyExpansionUtils.canExpandProperty( getHolder().getModelItem(),
                  ( ( PropertyModelItem )modelItem ).getProperty() );
            }
          }
          catch( Exception ex )
          {
            SoapUI.logError( ex );
          }
        }
      }

      return false;
    }
  }

  /**
   * Idea is that all values which property name starts or ends with 'password' case insesitive be
   * shadowed.
   *
   * This cell render in applied only on property value column.
   *
   * @author robert
   *
   */
  private static class PropertiesTableCellRenderer extends DefaultTableCellRenderer
  {
    public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus,
        int row, int column )
    {
      Component component = super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column );
      if( value instanceof String )
      {
        if( value != null && ( ( String )value ).length() > 0 )
        {
          String val = (( String )table.getValueAt( row, 0 )).toLowerCase();
          if( val.startsWith( "password" ) || val.endsWith( "password" ) )
            component = super.getTableCellRendererComponent( table, "**************", isSelected, hasFocus, row,
                column );
        }
      }

      return component;
    }
  }
}
TOP

Related Classes of com.eviware.soapui.impl.wsdl.panels.teststeps.support.PropertyHolderTable$PropertiesTableCellRenderer

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.