1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.panels.teststeps.support;
14
15 import java.awt.BorderLayout;
16 import java.awt.Component;
17 import java.awt.Point;
18 import java.awt.datatransfer.DataFlavor;
19 import java.awt.datatransfer.Transferable;
20 import java.awt.dnd.DnDConstants;
21 import java.awt.dnd.DropTarget;
22 import java.awt.dnd.DropTargetDragEvent;
23 import java.awt.dnd.DropTargetDropEvent;
24 import java.awt.dnd.DropTargetEvent;
25 import java.awt.dnd.DropTargetListener;
26 import java.awt.event.ActionEvent;
27 import java.io.BufferedReader;
28 import java.io.File;
29 import java.io.FileReader;
30 import java.io.IOException;
31 import java.util.Arrays;
32 import java.util.HashSet;
33 import java.util.Set;
34
35 import javax.swing.AbstractAction;
36 import javax.swing.Action;
37 import javax.swing.JButton;
38 import javax.swing.JPanel;
39 import javax.swing.JScrollPane;
40 import javax.swing.JTable;
41 import javax.swing.ListSelectionModel;
42 import javax.swing.SwingUtilities;
43 import javax.swing.TransferHandler;
44 import javax.swing.event.ListSelectionEvent;
45 import javax.swing.event.ListSelectionListener;
46 import javax.swing.table.AbstractTableModel;
47
48 import com.eviware.soapui.SoapUI;
49 import com.eviware.soapui.impl.wsdl.MutableTestPropertyHolder;
50 import com.eviware.soapui.model.TestPropertyHolder;
51 import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
52 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionImpl;
53 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
54 import com.eviware.soapui.model.support.TestPropertyUtils;
55 import com.eviware.soapui.model.testsuite.TestProperty;
56 import com.eviware.soapui.model.testsuite.TestPropertyListener;
57 import com.eviware.soapui.model.tree.nodes.PropertyTreeNode.PropertyModelItem;
58 import com.eviware.soapui.support.StringUtils;
59 import com.eviware.soapui.support.UISupport;
60 import com.eviware.soapui.support.components.JXToolBar;
61 import com.eviware.soapui.support.types.StringList;
62 import com.eviware.soapui.support.xml.XmlUtils;
63 import com.eviware.x.form.XFormDialog;
64 import com.eviware.x.form.support.ADialogBuilder;
65 import com.eviware.x.form.support.AField;
66 import com.eviware.x.form.support.AForm;
67 import com.eviware.x.form.support.AField.AFieldType;
68
69 public class PropertyHolderTable extends JPanel
70 {
71 private final TestPropertyHolder holder;
72 private PropertiesModel propertiesModel;
73 private RemovePropertyAction removePropertyAction;
74 private AddPropertyAction addPropertyAction;
75 private InternalTestPropertyListener testPropertyListener;
76 private JTable propertiesTable;
77 private JXToolBar toolbar;
78 private LoadPropertiesAction loadPropertiesAction;
79 private MovePropertyUpAction movePropertyUpAction;
80 private MovePropertyDownAction movePropertyDownAction;
81
82 public PropertyHolderTable( TestPropertyHolder holder )
83 {
84 super( new BorderLayout() );
85 this.holder = holder;
86
87 loadPropertiesAction = new LoadPropertiesAction();
88 testPropertyListener = new InternalTestPropertyListener();
89 holder.addTestPropertyListener( testPropertyListener );
90
91 JScrollPane scrollPane = new JScrollPane( buildPropertiesTable() );
92
93 if( getHolder().getModelItem() != null )
94 {
95 DropTarget dropTarget = new DropTarget( scrollPane, new PropertyHolderTablePropertyExpansionDropTarget() );
96 dropTarget.setDefaultActions( DnDConstants.ACTION_COPY_OR_MOVE );
97 }
98
99 add( scrollPane, BorderLayout.CENTER );
100 add( buildToolbar(), BorderLayout.NORTH );
101 }
102
103 protected JTable buildPropertiesTable()
104 {
105 propertiesModel = new PropertiesModel();
106 propertiesTable = new PropertiesHolderJTable();
107 propertiesTable.setSurrendersFocusOnKeystroke( true );
108
109 propertiesTable.putClientProperty( "terminateEditOnFocusLost", Boolean.TRUE );
110 propertiesTable.getSelectionModel().addListSelectionListener( new ListSelectionListener()
111 {
112 public void valueChanged( ListSelectionEvent e )
113 {
114 int selectedRow = propertiesTable.getSelectedRow();
115 if( removePropertyAction != null )
116 removePropertyAction.setEnabled( selectedRow != -1 );
117
118 if( movePropertyUpAction != null )
119 movePropertyUpAction.setEnabled( selectedRow > 0 );
120
121 if( movePropertyDownAction != null )
122 movePropertyDownAction.setEnabled( selectedRow >= 0 && selectedRow < propertiesTable.getRowCount() - 1 );
123 }
124 } );
125
126 propertiesTable.setDragEnabled( true );
127 propertiesTable.setTransferHandler( new TransferHandler( "testProperty" ) );
128
129 if( getHolder().getModelItem() != null )
130 {
131 DropTarget dropTarget = new DropTarget( propertiesTable, new PropertyHolderTablePropertyExpansionDropTarget() );
132 dropTarget.setDefaultActions( DnDConstants.ACTION_COPY_OR_MOVE );
133 }
134
135 return propertiesTable;
136 }
137
138 public class PropertiesHolderJTable extends JTable
139 {
140 public PropertiesHolderJTable()
141 {
142 super( propertiesModel );
143 setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
144
145 setSurrendersFocusOnKeystroke( true );
146 setRowHeight( 19 );
147
148 }
149
150 public PropertyModelItem getTestProperty()
151 {
152 int index = getSelectedRow();
153 if( index == -1 )
154 return null;
155 TestProperty property = propertiesModel.getPropertyAtRow( index );
156 return new PropertyModelItem( property, true );
157 }
158 }
159
160 private Component buildToolbar()
161 {
162 toolbar = UISupport.createSmallToolbar();
163
164 if( holder instanceof MutableTestPropertyHolder )
165 {
166 removePropertyAction = new RemovePropertyAction();
167 addPropertyAction = new AddPropertyAction();
168 movePropertyUpAction = new MovePropertyUpAction();
169 movePropertyDownAction = new MovePropertyDownAction();
170
171 JButton addPropertyButton = UISupport.createToolbarButton( addPropertyAction );
172 toolbar.add( addPropertyButton );
173 JButton removePropertyButton = UISupport.createToolbarButton( removePropertyAction );
174 toolbar.add( removePropertyButton );
175
176 JButton movePropertyUpButton = UISupport.createToolbarButton( movePropertyUpAction );
177 toolbar.add( movePropertyUpButton );
178 JButton movePropertyDownButton = UISupport.createToolbarButton( movePropertyDownAction );
179 toolbar.add( movePropertyDownButton );
180 }
181
182 JButton clearPropertiesButton = UISupport.createToolbarButton( new ClearPropertiesAction() );
183 toolbar.add( clearPropertiesButton );
184 JButton loadPropertiesButton = UISupport.createToolbarButton( loadPropertiesAction );
185 toolbar.add( loadPropertiesButton );
186 toolbar.add( UISupport.createToolbarButton( new SavePropertiesAction() ) );
187
188 return toolbar;
189 }
190
191 public JXToolBar getToolbar()
192 {
193 return toolbar;
194 }
195
196 public JTable getPropertiesTable()
197 {
198 return propertiesTable;
199 }
200
201 public void release()
202 {
203 if( propertiesTable.isEditing() )
204 propertiesTable.getCellEditor().stopCellEditing();
205
206 holder.removeTestPropertyListener( testPropertyListener );
207 }
208
209 public void setEnabled( boolean enabled )
210 {
211 addPropertyAction.setEnabled( enabled );
212 removePropertyAction.setEnabled( enabled );
213 propertiesTable.setEnabled( enabled );
214 loadPropertiesAction.setEnabled( enabled );
215
216 super.setEnabled( enabled );
217 }
218
219 private final class InternalTestPropertyListener implements TestPropertyListener
220 {
221 private boolean enabled = true;
222
223 public boolean isEnabled()
224 {
225 return enabled;
226 }
227
228 public void setEnabled( boolean enabled )
229 {
230 this.enabled = enabled;
231 }
232
233 public void propertyAdded( String name )
234 {
235 if( enabled )
236 propertiesModel.fireTableDataChanged();
237 }
238
239 public void propertyRemoved( String name )
240 {
241 if( enabled )
242 propertiesModel.fireTableDataChanged();
243 }
244
245 public void propertyRenamed( String oldName, String newName )
246 {
247 if( enabled )
248 propertiesModel.fireTableDataChanged();
249 }
250
251 public void propertyValueChanged( String name, String oldValue, String newValue )
252 {
253 if( enabled )
254 propertiesModel.fireTableDataChanged();
255 }
256
257 public void propertyMoved( String name, int oldIndex, int newIndex )
258 {
259 if( enabled )
260 propertiesModel.fireTableDataChanged();
261 }
262 }
263
264 private class PropertiesModel extends AbstractTableModel
265 {
266 private StringList names = new StringList();
267
268 public PropertiesModel()
269 {
270 names = new StringList( holder.getPropertyNames() );
271 }
272
273 public int getRowCount()
274 {
275 return names.size();
276 }
277
278 public int getColumnCount()
279 {
280 return 2;
281 }
282
283 @Override
284 public void fireTableDataChanged()
285 {
286 names = new StringList( holder.getPropertyNames() );
287 super.fireTableDataChanged();
288 }
289
290 public String getColumnName( int columnIndex )
291 {
292 switch( columnIndex )
293 {
294 case 0 :
295 return "Name";
296 case 1 :
297 return "Value";
298 }
299
300 return null;
301 }
302
303 public boolean isCellEditable( int rowIndex, int columnIndex )
304 {
305 if( columnIndex == 0 )
306 {
307 return holder instanceof MutableTestPropertyHolder;
308 }
309
310 return !holder.getProperty( names.get( rowIndex ) ).isReadOnly();
311 }
312
313 public void setValueAt( Object aValue, int rowIndex, int columnIndex )
314 {
315 TestProperty property = holder.getProperty( names.get( rowIndex ) );
316 switch( columnIndex )
317 {
318 case 0 :
319 {
320 if( holder instanceof MutableTestPropertyHolder )
321 {
322 TestProperty prop = holder.getProperty( aValue.toString() );
323 if( prop != null && prop != property )
324 {
325 UISupport.showErrorMessage( "Property name exists!" );
326 return;
327 }
328 ( ( MutableTestPropertyHolder )holder ).renameProperty( property.getName(), aValue.toString() );
329 }
330 break;
331 }
332 case 1 :
333 {
334 property.setValue( aValue.toString() );
335 break;
336 }
337 }
338 }
339
340 @Override
341 public Class<?> getColumnClass( int columnIndex )
342 {
343 return String.class;
344 }
345
346 public TestProperty getPropertyAtRow( int rowIndex )
347 {
348 return holder.getProperty( names.get( rowIndex ) );
349 }
350
351 public Object getValueAt( int rowIndex, int columnIndex )
352 {
353 TestProperty property = holder.getProperty( names.get( rowIndex ) );
354 if( property == null )
355 return null;
356
357 switch( columnIndex )
358 {
359 case 0 :
360 return property.getName();
361 case 1 :
362 return property.getValue();
363 }
364
365 return null;
366 }
367 }
368
369 private class AddPropertyAction extends AbstractAction
370 {
371 public AddPropertyAction()
372 {
373 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/add_property.gif" ) );
374 putValue( Action.SHORT_DESCRIPTION, "Adds a property to the property list" );
375 }
376
377 public void actionPerformed( ActionEvent e )
378 {
379 String name = UISupport.prompt( "Specify unique property name", "Add Property", "" );
380 if( StringUtils.hasContent( name ) )
381 {
382 if( holder.hasProperty( name ) )
383 {
384 UISupport.showErrorMessage( "Property name [" + name + "] already exists.." );
385 return;
386 }
387
388 ( ( MutableTestPropertyHolder )holder ).addProperty( name );
389 final int row = holder.getPropertyNames().length - 1;
390 propertiesModel.fireTableRowsInserted( row, row );
391 SwingUtilities.invokeLater( new Runnable()
392 {
393 public void run()
394 {
395 requestFocusInWindow();
396 scrollRectToVisible( propertiesTable.getCellRect( row, 1, true ) );
397 SwingUtilities.invokeLater( new Runnable()
398 {
399 public void run()
400 {
401 propertiesTable.editCellAt( row, 1 );
402 Component editorComponent = propertiesTable.getEditorComponent();
403 if( editorComponent != null )
404 editorComponent.requestFocusInWindow();
405 }
406 } );
407 }
408 } );
409
410 }
411 }
412 }
413
414 private class RemovePropertyAction extends AbstractAction
415 {
416 public RemovePropertyAction()
417 {
418 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/remove_property.gif" ) );
419 putValue( Action.SHORT_DESCRIPTION, "Removes the selected property from the property list" );
420 setEnabled( false );
421 }
422
423 public void actionPerformed( ActionEvent e )
424 {
425 int row = propertiesTable.getSelectedRow();
426 if( row == -1 )
427 return;
428
429 UISupport.stopCellEditing( propertiesTable );
430
431 String propertyName = propertiesModel.getValueAt( row, 0 ).toString();
432 if( UISupport.confirm( "Remove property [" + propertyName + "]?", "Remove Property" ) )
433 {
434 ( ( MutableTestPropertyHolder )holder ).removeProperty( propertyName );
435 propertiesModel.fireTableRowsDeleted( row, row );
436 }
437 }
438 }
439
440 private class ClearPropertiesAction extends AbstractAction
441 {
442 public ClearPropertiesAction()
443 {
444 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/clear_properties.gif" ) );
445 putValue( Action.SHORT_DESCRIPTION, "Clears all current property values" );
446 }
447
448 public void actionPerformed( ActionEvent e )
449 {
450 if( UISupport.confirm( "Clear all property values?", "Clear Properties" ) )
451 {
452 for( String name : holder.getPropertyNames() )
453 {
454 holder.getProperty( name ).setValue( null );
455 }
456 }
457 }
458 }
459
460 private class MovePropertyUpAction extends AbstractAction
461 {
462 public MovePropertyUpAction()
463 {
464 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/up_arrow.gif" ) );
465 putValue( Action.SHORT_DESCRIPTION, "Moves selected property up one row" );
466 setEnabled( false );
467 }
468
469 public void actionPerformed( ActionEvent e )
470 {
471 int ix = propertiesTable.getSelectedRow();
472 if( ix != -1 )
473 {
474 ( ( MutableTestPropertyHolder )holder ).moveProperty( holder.getPropertyAt( ix ).getName(), ix - 1 );
475 propertiesTable.setRowSelectionInterval( ix - 1, ix - 1 );
476 }
477 }
478 }
479
480 private class MovePropertyDownAction extends AbstractAction
481 {
482 public MovePropertyDownAction()
483 {
484 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/down_arrow.gif" ) );
485 putValue( Action.SHORT_DESCRIPTION, "Moves selected property down one row" );
486 setEnabled( false );
487 }
488
489 public void actionPerformed( ActionEvent e )
490 {
491 int ix = propertiesTable.getSelectedRow();
492 if( ix != -1 )
493 {
494 ( ( MutableTestPropertyHolder )holder ).moveProperty( holder.getPropertyAt( ix ).getName(), ix + 1 );
495
496 propertiesTable.setRowSelectionInterval( ix + 1, ix + 1 );
497 }
498 }
499 }
500
501 private class LoadPropertiesAction extends AbstractAction
502 {
503 private XFormDialog dialog;
504
505 public LoadPropertiesAction()
506 {
507 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/load_properties.gif" ) );
508 putValue( Action.SHORT_DESCRIPTION, "Loads property values from an external file" );
509 }
510
511 public void actionPerformed( ActionEvent e )
512 {
513 if( dialog == null )
514 dialog = ADialogBuilder.buildDialog( LoadOptionsForm.class );
515
516 dialog.getFormField( LoadOptionsForm.DELETEREMAINING )
517 .setEnabled( holder instanceof MutableTestPropertyHolder );
518 dialog.getFormField( LoadOptionsForm.CREATEMISSING ).setEnabled( holder instanceof MutableTestPropertyHolder );
519
520 if( dialog.show() )
521 {
522 try
523 {
524 BufferedReader reader = new BufferedReader( new FileReader( dialog.getValue( LoadOptionsForm.FILE ) ) );
525
526 String line = reader.readLine();
527 int count = 0;
528
529 Set<String> names = new HashSet<String>( Arrays.asList( holder.getPropertyNames() ) );
530
531 while( line != null )
532 {
533 if( line.trim().length() > 0 && !( line.charAt( 0 ) == '#' ) )
534 {
535 int ix = line.indexOf( '=' );
536 if( ix > 0 )
537 {
538 String name = line.substring( 0, ix ).trim();
539 String value = line.length() > ix ? line.substring( ix + 1 ) : "";
540
541
542 if( value.endsWith( "//" ) )
543 {
544 value = value.substring( 0, value.length() - 1 );
545
546 String ln = reader.readLine();
547 while( ln != null && ln.endsWith( "//" ) )
548 {
549 value += ln.substring( 0, ln.length() - 1 );
550 }
551
552 if( ln != null )
553 value += ln;
554 if( ln == null )
555 break;
556 }
557
558 if( holder.hasProperty( name ) )
559 {
560 count++ ;
561 holder.setPropertyValue( name, value );
562 }
563 else if( dialog.getBooleanValue( LoadOptionsForm.CREATEMISSING )
564 && holder instanceof MutableTestPropertyHolder )
565 {
566 ( ( MutableTestPropertyHolder )holder ).addProperty( name ).setValue( value );
567 count++ ;
568 }
569
570 names.remove( name );
571 }
572 }
573
574 line = reader.readLine();
575 }
576
577 if( dialog.getBooleanValue( LoadOptionsForm.DELETEREMAINING )
578 && holder instanceof MutableTestPropertyHolder )
579 {
580 for( String name : names )
581 {
582 ( ( MutableTestPropertyHolder )holder ).removeProperty( name );
583 }
584 }
585
586 reader.close();
587 UISupport.showInfoMessage( "Added/Updated " + count + " properties from file" );
588 }
589 catch( Exception ex )
590 {
591 UISupport.showErrorMessage( ex );
592 }
593 }
594 }
595 }
596
597 private class SavePropertiesAction extends AbstractAction
598 {
599 public SavePropertiesAction()
600 {
601 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/set_properties_target.gif" ) );
602 putValue( Action.SHORT_DESCRIPTION, "Saves current property-values to a file" );
603 }
604
605 public void actionPerformed( ActionEvent e )
606 {
607 if( holder.getPropertyCount() == 0 )
608 {
609 UISupport.showErrorMessage( "No properties to save!" );
610 return;
611 }
612
613 File file = UISupport.getFileDialogs().saveAs( this, "Save Properties" );
614 if( file != null )
615 {
616 try
617 {
618 TestPropertyUtils.saveTo( holder, file.getAbsolutePath() );
619 }
620 catch( IOException e1 )
621 {
622 UISupport.showErrorMessage( e1 );
623 }
624 }
625 }
626 }
627
628 @AForm( name = "Load Properties", description = "Set load options below" )
629 private static interface LoadOptionsForm
630 {
631 @AField( name = "File", description = "The Properties file to load", type = AFieldType.FILE )
632 public static final String FILE = "File";
633
634 @AField( name = "Create Missing", description = "Creates Missing Properties", type = AFieldType.BOOLEAN )
635 public static final String CREATEMISSING = "Create Missing";
636
637 @AField( name = "Delete Remaining", description = "Deletes properties not in file", type = AFieldType.BOOLEAN )
638 public static final String DELETEREMAINING = "Delete Remaining";
639 }
640
641 public TestPropertyHolder getHolder()
642 {
643 return holder;
644 }
645
646 public PropertiesModel getPropertiesModel()
647 {
648 return propertiesModel;
649 }
650
651 public final class PropertyHolderTablePropertyExpansionDropTarget implements DropTargetListener
652 {
653 public PropertyHolderTablePropertyExpansionDropTarget()
654 {
655 }
656
657 public void dragEnter( DropTargetDragEvent dtde )
658 {
659 if( !isAcceptable( dtde.getTransferable(), dtde.getLocation() ) )
660 dtde.rejectDrag();
661 }
662
663 public void dragExit( DropTargetEvent dtde )
664 {
665 }
666
667 public void dragOver( DropTargetDragEvent dtde )
668 {
669 if( !isAcceptable( dtde.getTransferable(), dtde.getLocation() ) )
670 {
671 dtde.rejectDrag();
672 }
673 else
674 {
675 dtde.acceptDrag( dtde.getDropAction() );
676 }
677 }
678
679 public void drop( DropTargetDropEvent dtde )
680 {
681 if( !isAcceptable( dtde.getTransferable(), dtde.getLocation() ) )
682 {
683 dtde.rejectDrop();
684 }
685 else
686 {
687 try
688 {
689 Transferable transferable = dtde.getTransferable();
690 Object transferData = transferable.getTransferData( transferable.getTransferDataFlavors()[0] );
691 if( transferData instanceof PropertyModelItem )
692 {
693 dtde.acceptDrop( dtde.getDropAction() );
694 PropertyModelItem modelItem = ( PropertyModelItem )transferData;
695
696 String xpath = modelItem.getXPath();
697 if( xpath == null && XmlUtils.seemsToBeXml( modelItem.getProperty().getValue() ) )
698 {
699 xpath = UISupport.selectXPath( "Create PropertyExpansion", "Select XPath below", modelItem
700 .getProperty().getValue(), null );
701
702 if( xpath != null )
703 xpath = XmlUtils.removeXPathNamespaceDeclarations( xpath );
704 }
705
706 PropertyExpansion propertyExpansion = new PropertyExpansionImpl( modelItem.getProperty(), xpath );
707
708 Point point = dtde.getLocation();
709 int column = getPropertiesTable().columnAtPoint( point );
710 int row = getPropertiesTable().rowAtPoint( point );
711
712 if( row == -1 )
713 {
714 if( holder instanceof MutableTestPropertyHolder )
715 {
716 MutableTestPropertyHolder mtph = ( MutableTestPropertyHolder )holder;
717 String name = UISupport.prompt( "Specify unique name of property", "Add Property", modelItem
718 .getProperty().getName() );
719 while( name != null && mtph.hasProperty( name ) )
720 {
721 name = UISupport.prompt( "Specify unique name of property", "Add Property", modelItem
722 .getProperty().getName() );
723 }
724
725 if( name != null )
726 mtph.addProperty( name ).setValue( propertyExpansion.toString() );
727 }
728 }
729 else
730 {
731 getPropertiesTable().setValueAt( propertyExpansion.toString(), row, column );
732 }
733
734 dtde.dropComplete( true );
735 }
736 }
737 catch( Exception e )
738 {
739 SoapUI.logError( e );
740 }
741 }
742 }
743
744 public void dropActionChanged( DropTargetDragEvent dtde )
745 {
746 }
747
748 public boolean isAcceptable( Transferable transferable, Point point )
749 {
750 int row = getPropertiesTable().rowAtPoint( point );
751 if( row >= 0 )
752 {
753 int column = getPropertiesTable().columnAtPoint( point );
754 if( column != 1 )
755 return false;
756
757 if( !getPropertiesTable().isCellEditable( row, column ) )
758 return false;
759 }
760 else if( !( getHolder() instanceof MutableTestPropertyHolder ) )
761 {
762 return false;
763 }
764
765 DataFlavor[] flavors = transferable.getTransferDataFlavors();
766 for( int i = 0; i < flavors.length; i++ )
767 {
768 DataFlavor flavor = flavors[i];
769 if( flavor.isMimeTypeEqual( DataFlavor.javaJVMLocalObjectMimeType ) )
770 {
771 try
772 {
773 Object modelItem = transferable.getTransferData( flavor );
774 if( modelItem instanceof PropertyModelItem
775 && ( ( PropertyModelItem )modelItem ).getProperty().getModelItem() != getHolder()
776 .getModelItem() )
777 {
778 return PropertyExpansionUtils.canExpandProperty( getHolder().getModelItem(),
779 ( ( PropertyModelItem )modelItem ).getProperty() );
780 }
781 }
782 catch( Exception ex )
783 {
784 SoapUI.logError( ex );
785 }
786 }
787 }
788
789 return false;
790 }
791 }
792 }