1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.teststeps;
14
15 import com.eviware.soapui.config.PropertyTransferConfig;
16 import com.eviware.soapui.model.TestModelItem;
17 import com.eviware.soapui.model.TestPropertyHolder;
18 import com.eviware.soapui.model.iface.SubmitContext;
19 import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
20 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
21 import com.eviware.soapui.model.support.TestPropertyListenerAdapter;
22 import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
23 import com.eviware.soapui.model.testsuite.TestCase;
24 import com.eviware.soapui.model.testsuite.TestProperty;
25 import com.eviware.soapui.model.testsuite.TestStep;
26 import com.eviware.soapui.support.PropertyChangeNotifier;
27 import com.eviware.soapui.support.resolver.*;
28 import com.eviware.soapui.support.resolver.ResolveContext.PathToResolve;
29 import com.eviware.soapui.support.xml.XmlUtils;
30 import org.apache.log4j.Logger;
31 import org.apache.xmlbeans.XmlCursor;
32 import org.apache.xmlbeans.XmlCursor.TokenType;
33 import org.apache.xmlbeans.XmlException;
34 import org.apache.xmlbeans.XmlObject;
35 import org.apache.xmlbeans.XmlOptions;
36 import org.w3c.dom.Element;
37 import org.w3c.dom.Node;
38 import org.w3c.dom.NodeList;
39
40 import java.beans.PropertyChangeEvent;
41 import java.beans.PropertyChangeListener;
42 import java.beans.PropertyChangeSupport;
43 import java.util.ArrayList;
44 import java.util.List;
45
46 /***
47 * Class for transferring a property value between 2 test steps. This class is
48 * relatively complex due to backwards compatibility issues and to gracefull
49 * handling of references test steps and properties.
50 *
51 * @author Ole.Matzura
52 */
53
54 public class PropertyTransfer implements PropertyChangeNotifier
55 {
56 private final static Logger log = Logger.getLogger( PropertyTransfer.class );
57
58 public final static String SOURCE_PATH_PROPERTY = PropertyTransfer.class.getName() + "@sourcePath";
59 public final static String SOURCE_TYPE_PROPERTY = PropertyTransfer.class.getName() + "@sourceProperty";
60 public final static String SOURCE_STEP_PROPERTY = PropertyTransfer.class.getName() + "@sourceStep";
61 public final static String TARGET_PATH_PROPERTY = PropertyTransfer.class.getName() + "@targetPath";
62 public final static String TARGET_TYPE_PROPERTY = PropertyTransfer.class.getName() + "@targetProperty";
63 public final static String TARGET_STEP_PROPERTY = PropertyTransfer.class.getName() + "@targetStep";
64 public final static String NAME_PROPERTY = PropertyTransfer.class.getName() + "@name";
65 public final static String DISABLED_PROPERTY = PropertyTransfer.class.getName() + "@disabled";
66 public final static String CONFIG_PROPERTY = PropertyTransfer.class.getName() + "@config";
67
68 private TestStep testStep;
69
70
71
72 private PropertyTransferConfig config;
73 private String sourcePath;
74 private String sourceType;
75 private String targetPath;
76 private String name;
77 private String targetType;
78 private String sourceStep;
79 private String targetStep;
80
81 private TestPropertyHolder currentTargetStep;
82 private TestPropertyHolder currentSourceStep;
83 private TestProperty currentTargetProperty;
84 private TestProperty currentSourceProperty;
85
86 private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport( this );
87 private StepNameChangeListener stepNameChangeListener = new StepNameChangeListener();
88 private InternalTestPropertyListener propertyNameChangeListener = new InternalTestPropertyListener();
89 private TestCase testCase;
90
91 private InternalTestSuiteListener testSuiteListener = new InternalTestSuiteListener();
92
93 public PropertyTransfer( TestStep testStep )
94 {
95 this( testStep, PropertyTransferConfig.Factory.newInstance() );
96 }
97
98 public PropertyTransfer( TestStep testStep, PropertyTransferConfig config )
99 {
100 this.testStep = testStep;
101
102 if( testStep != null )
103 {
104 this.testCase = testStep.getTestCase();
105 testCase.getTestSuite().addTestSuiteListener( testSuiteListener );
106 }
107
108 setConfig( config );
109 }
110
111 void setConfigOnMove( PropertyTransferConfig config )
112 {
113 this.config = config;
114 }
115
116 void setConfig( PropertyTransferConfig config )
117 {
118 releaseListeners();
119
120 this.config = config;
121
122 if( !config.isSetSetNullOnMissingSource() )
123 {
124 config.setSetNullOnMissingSource( true );
125 }
126
127 if( !config.isSetTransferTextContent() )
128 {
129 config.setTransferTextContent( true );
130 }
131
132 sourceStep = config.getSourceStep();
133 if( sourceStep == null )
134 {
135 sourceStep = getSourceStepName();
136 if( sourceStep != null )
137 config.setSourceStep( sourceStep );
138 }
139
140 currentSourceStep = getPropertyHolder( sourceStep );
141
142 sourceType = config.getSourceType();
143 currentSourceProperty = currentSourceStep == null || sourceType == null ? null : currentSourceStep
144 .getProperty( sourceType );
145
146 sourcePath = config.getSourcePath();
147
148 targetStep = config.getTargetStep();
149 if( targetStep == null )
150 {
151 targetStep = getTargetStepName();
152 if( targetStep != null )
153 config.setTargetStep( targetStep );
154 }
155
156 currentTargetStep = getPropertyHolder( targetStep );
157
158 targetType = config.getTargetType();
159 currentTargetProperty = currentTargetStep == null || targetType == null ? null : currentTargetStep
160 .getProperty( targetType );
161
162 targetPath = config.getTargetPath();
163
164 name = config.getName();
165 initListeners();
166
167 propertyChangeSupport.firePropertyChange( CONFIG_PROPERTY, null, null );
168 }
169
170 private void initListeners()
171 {
172 if( currentSourceStep != null )
173 {
174 if( currentSourceStep instanceof TestStep )
175 ( (TestStep) currentSourceStep ).addPropertyChangeListener( TestStep.NAME_PROPERTY, stepNameChangeListener );
176
177 currentSourceStep.addTestPropertyListener( propertyNameChangeListener );
178 }
179
180 if( currentTargetStep != null )
181 {
182 if( currentTargetStep instanceof TestStep )
183 ( (TestStep) currentTargetStep ).addPropertyChangeListener( TestStep.NAME_PROPERTY, stepNameChangeListener );
184
185 currentTargetStep.addTestPropertyListener( propertyNameChangeListener );
186 }
187 }
188
189 public void releaseListeners()
190 {
191 if( currentSourceStep != null )
192 {
193 if( currentSourceStep instanceof TestStep )
194 ( (TestStep) currentSourceStep ).removePropertyChangeListener( TestStep.NAME_PROPERTY, stepNameChangeListener );
195
196 currentSourceStep.removeTestPropertyListener( propertyNameChangeListener );
197 }
198
199 if( currentTargetStep != null )
200 {
201 if( currentTargetStep instanceof TestStep )
202 ( (TestStep) currentTargetStep ).removePropertyChangeListener( TestStep.NAME_PROPERTY, stepNameChangeListener );
203
204 currentTargetStep.removeTestPropertyListener( propertyNameChangeListener );
205 }
206
207 PropertyChangeListener[] listeners = propertyChangeSupport.getPropertyChangeListeners();
208 for( PropertyChangeListener listener : listeners )
209 propertyChangeSupport.removePropertyChangeListener( listener );
210 }
211
212 public void release()
213 {
214 releaseListeners();
215 testCase.getTestSuite().removeTestSuiteListener( testSuiteListener );
216 }
217
218 public PropertyTransferConfig getConfig()
219 {
220 return config;
221 }
222
223 public String getSourcePath()
224 {
225 return sourcePath;
226 }
227
228 public String getTargetPath()
229 {
230 return targetPath;
231 }
232
233 public TestProperty getSourceProperty()
234 {
235 if( sourceType == null )
236 return null;
237
238 if( currentSourceProperty != null )
239 return currentSourceProperty;
240
241 TestPropertyHolder actualSourceStep = getSourceStep();
242 return actualSourceStep == null ? null : actualSourceStep.getProperty( sourceType );
243 }
244
245 public String[] transferProperties( SubmitContext context ) throws PropertyTransferException
246 {
247 TestProperty sourceProperty = getSourceProperty();
248 TestProperty targetProperty = getTargetProperty();
249
250 try
251 {
252 if( sourceProperty == null )
253 throw new Exception( "Missing source property" );
254 if( targetProperty == null )
255 throw new Exception( "Missing target property" );
256 if( sourceProperty.getValue() == null && !getSetNullOnMissingSource() && !getIgnoreEmpty() )
257 throw new Exception( "Source property is null" );
258
259 if( !hasSourcePath() && !hasTargetPath() )
260 {
261 if( !getIgnoreEmpty() || ( sourceProperty.getValue() != null && sourceProperty.getValue().length() > 0 ) )
262 return transferStringToString( sourceProperty, targetProperty );
263 }
264 else if( hasSourcePath() && hasTargetPath() )
265 {
266 return transferXPathToXml( sourceProperty, targetProperty, context );
267 }
268 else if( hasSourcePath() && !hasTargetPath() )
269 {
270 return new String[]{transferXPathToString( sourceProperty, targetProperty, context )};
271 }
272 else if( !hasSourcePath() && hasTargetPath() )
273 {
274 if( !getIgnoreEmpty() || ( sourceProperty.getValue() != null && sourceProperty.getValue().length() > 0 ) )
275 return transferStringToXml( sourceProperty, targetProperty, context );
276 }
277 }
278 catch( Exception e )
279 {
280 throw new PropertyTransferException( e.getMessage(), getSourceStepName(), sourceProperty, getTargetStepName(),
281 targetProperty );
282 }
283
284 return new String[0];
285 }
286
287 private boolean hasTargetPath()
288 {
289 String path = getTargetPath();
290 return path != null && path.trim().length() > 0;
291 }
292
293 private boolean hasSourcePath()
294 {
295 String path = getSourcePath();
296 return path != null && path.trim().length() > 0;
297 }
298
299 protected String[] transferStringToString( TestProperty sourceProperty, TestProperty targetProperty )
300 {
301 String value = sourceProperty.getValue();
302
303 if( getEntitize() )
304 value = XmlUtils.entitize( value );
305
306 targetProperty.setValue( value );
307 return new String[]{value};
308 }
309
310 protected String[] transferXPathToXml( TestProperty sourceProperty, TestProperty targetProperty, SubmitContext context )
311 throws Exception
312 {
313 String sourcePropertyValue = sourceProperty.getValue();
314 XmlObject sourceXmlObject = sourcePropertyValue == null ? null : XmlObject.Factory.parse( sourcePropertyValue );
315 XmlCursor sourceXml = sourceXmlObject == null ? null : sourceXmlObject.newCursor();
316
317 String targetPropertyValue = targetProperty.getValue();
318 XmlObject targetXmlObject = XmlObject.Factory.parse( targetPropertyValue );
319 XmlCursor targetXml = targetXmlObject.newCursor();
320
321 XmlCursor lastSource = null;
322
323 try
324 {
325 List<String> result = new ArrayList<String>();
326
327 String tp = PropertyExpansionUtils.expandProperties( context, getTargetPath() );
328 targetXml.selectPath( tp );
329
330 if( !targetXml.hasNextSelection() )
331 throw new Exception( "Missing match for Target XPath [" + tp + "]" );
332
333 if( sourceXml == null )
334 {
335 if( getSetNullOnMissingSource() )
336 {
337 while( targetXml.toNextSelection() )
338 {
339 result.add( setNodeValue( null, targetXml.getDomNode() ) );
340 if( !getTransferToAll() )
341 break;
342 }
343 }
344 }
345 else if( getUseXQuery() )
346 {
347 String sp = PropertyExpansionUtils.expandProperties( context, getSourcePath() );
348 XmlCursor resultCursor = sourceXml.execQuery( sp );
349 sourceXml.dispose();
350 sourceXml = resultCursor;
351
352 if( sourceXml.toNextToken() != TokenType.START )
353 {
354 if( getSetNullOnMissingSource() )
355 {
356 while( targetXml.toNextSelection() )
357 {
358 result.add( setNodeValue( null, targetXml.getDomNode() ) );
359 if( !getTransferToAll() )
360 break;
361 }
362 }
363 else if( !getIgnoreEmpty() )
364 throw new Exception( "Missing match for Source XQuery [" + sp + "]" );
365 }
366
367 boolean hasTarget = targetXml.toNextSelection();
368
369 if( hasTarget )
370 {
371 lastSource = sourceXml.newCursor();
372 result.add( transferXmlValue( sourceXml, targetXml ) );
373 }
374 }
375 else
376 {
377 String sp = PropertyExpansionUtils.expandProperties( context, getSourcePath() );
378 sourceXml.selectPath( sp );
379
380 if( !sourceXml.hasNextSelection() )
381 {
382 if( getSetNullOnMissingSource() )
383 {
384 while( targetXml.toNextSelection() )
385 {
386 result.add( setNodeValue( null, targetXml.getDomNode() ) );
387 if( !getTransferToAll() )
388 break;
389 }
390 }
391 else if( !getIgnoreEmpty() )
392 throw new Exception( "Missing match for Source XPath [" + sp + "]" );
393 }
394 else
395 {
396 boolean hasSource = sourceXml.toNextSelection();
397 boolean hasTarget = targetXml.toNextSelection();
398
399 while( hasSource && hasTarget )
400 {
401 if( lastSource != null )
402 lastSource.dispose();
403
404 lastSource = sourceXml.newCursor();
405 result.add( transferXmlValue( sourceXml, targetXml ) );
406
407 hasSource = sourceXml.toNextSelection();
408 hasTarget = targetXml.toNextSelection();
409 }
410
411 if( getTransferToAll() && !hasSource && hasTarget && lastSource != null )
412 {
413 while( hasTarget )
414 {
415 result.add( transferXmlValue( lastSource, targetXml ) );
416 hasTarget = targetXml.toNextSelection();
417 }
418 }
419 }
420 }
421
422 if( result.size() > 0 )
423 {
424 String value = targetXmlObject.xmlText( new XmlOptions().setSaveAggressiveNamespaces() );
425 if( getEntitize() )
426 value = XmlUtils.entitize( value );
427
428 targetProperty.setValue( value );
429 }
430
431 return result.toArray( new String[result.size()] );
432 }
433 finally
434 {
435 sourceXml.dispose();
436 targetXml.dispose();
437
438 if( lastSource != null )
439 lastSource.dispose();
440 }
441 }
442
443 protected String[] transferStringToXml(
444 TestProperty sourceProperty, TestProperty targetProperty,
445 SubmitContext context
446 ) throws XmlException, Exception
447 {
448 XmlObject targetXml = XmlObject.Factory.parse( targetProperty.getValue() );
449 XmlCursor targetCursor = targetXml.newCursor();
450
451 try
452 {
453 List<String> result = new ArrayList<String>();
454
455 String tp = PropertyExpansionUtils.expandProperties( context, getTargetPath() );
456 targetCursor.selectPath( tp );
457
458 if( !targetCursor.toNextSelection() )
459 throw new Exception( "Missing match for Target XPath [" + tp + "]" );
460
461 String value = sourceProperty.getValue();
462
463 Node targetNode = targetCursor.getDomNode();
464 setNodeValue( value, targetNode );
465
466 result.add( value );
467
468 if( getTransferToAll() )
469 {
470 while( targetCursor.toNextSelection() )
471 {
472 targetNode = targetCursor.getDomNode();
473 setNodeValue( value, targetNode );
474
475 result.add( value );
476 }
477 }
478
479 targetProperty.setValue( targetXml.xmlText( new XmlOptions().setSaveAggressiveNamespaces() ) );
480
481 return result.toArray( new String[result.size()] );
482 }
483 finally
484 {
485 targetCursor.dispose();
486 }
487 }
488
489 private String setNodeValue( String value, Node node ) throws Exception
490 {
491 short targetNodeType = node.getNodeType();
492
493 if( targetNodeType == Node.DOCUMENT_FRAGMENT_NODE )
494 {
495 node = node.getFirstChild();
496 if( node != null )
497 targetNodeType = node.getNodeType();
498 else
499 throw new Exception( "Missing source value for " + getSourcePropertyName() );
500 }
501
502 if( !XmlUtils.setNodeValue( node, value ) )
503
504
505
506
507
508
509
510
511
512 {
513 throw new Exception( "Failed to set value to node [" + node.toString() + "] of type [" + targetNodeType + "]" );
514 }
515
516 return value;
517 }
518
519 protected String transferXPathToString(
520 TestProperty sourceProperty, TestProperty targetProperty,
521 SubmitContext context
522 ) throws Exception
523 {
524 String sourceValue = sourceProperty.getValue();
525
526 if( sourceValue == null )
527 {
528 if( !getIgnoreEmpty() )
529 throw new Exception( "Missing source value" );
530
531 if( getSetNullOnMissingSource() )
532 targetProperty.setValue( null );
533 }
534
535 XmlObject sourceXml = sourceValue == null ? null : XmlObject.Factory.parse( sourceValue );
536 XmlCursor sourceCursor = sourceValue == null ? null : sourceXml.newCursor();
537
538 try
539 {
540 String value = null;
541
542 String xquery = PropertyExpansionUtils.expandProperties( context, getSourcePath() );
543 if( getUseXQuery() )
544 {
545 XmlCursor resultCursor = sourceCursor.execQuery( xquery );
546 sourceCursor.dispose();
547 sourceCursor = resultCursor;
548 }
549 else
550 {
551 sourceCursor.selectPath( xquery );
552 }
553
554 if( !getUseXQuery() && !sourceCursor.toNextSelection() )
555 {
556 if( !getSetNullOnMissingSource() && !getIgnoreEmpty() )
557 throw new Exception( "Missing match for Source XPath [" + xquery + "]" );
558 }
559 else if( getUseXQuery() && sourceCursor.toNextToken() != TokenType.START )
560 {
561 if( !getSetNullOnMissingSource() && !getIgnoreEmpty() )
562 throw new Exception( "Missing match for Source XQuery [" + xquery + "]" );
563 }
564 else
565 {
566 Node sourceNode = sourceCursor.getDomNode();
567 short sourceNodeType = sourceNode.getNodeType();
568
569 if( sourceNodeType == Node.DOCUMENT_FRAGMENT_NODE )
570 {
571 sourceNode = sourceNode.getFirstChild();
572 if( sourceNode != null )
573 sourceNodeType = sourceNode.getNodeType();
574 else
575 throw new Exception( "Missing source value for " + getSourcePropertyName() );
576 }
577
578 if( sourceNodeType == Node.TEXT_NODE || sourceNodeType == Node.ATTRIBUTE_NODE )
579 {
580 value = sourceNode.getNodeValue();
581 }
582 else if( sourceNodeType == Node.ELEMENT_NODE )
583 {
584 if( getTransferTextContent() )
585 {
586 value = XmlUtils.getElementText( (Element) sourceNode );
587 }
588
589 if( value == null || !getTransferTextContent() )
590 {
591 value = sourceCursor.getObject().xmlText(
592 new XmlOptions().setSaveOuter().setSaveAggressiveNamespaces() );
593 }
594 }
595 }
596
597 if( !getIgnoreEmpty() || ( value != null && value.length() > 0 ) )
598 {
599 if( getEntitize() )
600 value = XmlUtils.entitize( value );
601
602 targetProperty.setValue( value );
603 }
604 else
605 value = "";
606
607 return value;
608 }
609 finally
610 {
611 sourceCursor.dispose();
612 }
613 }
614
615 /***
616 * Method called for transferring between 2 xml properties..
617 */
618
619 private String transferXmlValue( XmlCursor source, XmlCursor dest ) throws Exception
620 {
621
622 Node destNode = dest.getDomNode();
623 Node sourceNode = source.getDomNode();
624 short destNodeType = destNode.getNodeType();
625 short sourceNodeType = sourceNode.getNodeType();
626 String value = null;
627
628 if( getTransferChildNodes() )
629 {
630 while( destNode.hasChildNodes() )
631 {
632 destNode.removeChild( destNode.getFirstChild() );
633 }
634
635 NodeList childNodes = sourceNode.getChildNodes();
636 for( int c = 0; c < childNodes.getLength(); c++ )
637 {
638 destNode.appendChild( destNode.getOwnerDocument().importNode( childNodes.item( c ), true ) );
639 }
640
641 return XmlUtils.serialize( destNode, false );
642 }
643
644 if( sourceNodeType == Node.DOCUMENT_FRAGMENT_NODE )
645 {
646 sourceNode = sourceNode.getFirstChild();
647 if( sourceNode != null )
648 sourceNodeType = sourceNode.getNodeType();
649 else
650 throw new Exception( "Missing source value for " + source );
651 }
652
653
654 if( destNodeType == sourceNodeType )
655 {
656 if( destNodeType == Node.TEXT_NODE || destNodeType == Node.ATTRIBUTE_NODE )
657 {
658 value = sourceNode.getNodeValue();
659 if( !getIgnoreEmpty() || ( value != null && value.length() > 0 ) )
660 {
661 if( getEntitize() )
662 value = XmlUtils.entitize( value );
663
664 destNode.setNodeValue( value );
665 }
666 }
667 else if( config.getTransferTextContent() && destNodeType == Node.ELEMENT_NODE )
668 {
669 value = XmlUtils.getElementText( (Element) sourceNode );
670 if( value == null && sourceNode.getFirstChild() != null )
671 {
672 value = source.getObject().xmlText( new XmlOptions().setSaveOuter().setSaveAggressiveNamespaces() );
673
674 if( getEntitize() )
675 value = XmlUtils.entitize( value );
676
677 destNode.getParentNode()
678 .replaceChild( destNode.getOwnerDocument().importNode( sourceNode, true ), destNode );
679 }
680 else if( !getIgnoreEmpty() || ( value != null && value.length() > 0 ) )
681 {
682 if( getEntitize() )
683 value = XmlUtils.entitize( value );
684
685 XmlUtils.setElementText( (Element) destNode, value );
686 }
687 }
688 else
689 {
690 destNode = destNode.getParentNode().replaceChild( destNode.getOwnerDocument().importNode( sourceNode, true ),
691 destNode );
692
693 value = dest.xmlText();
694 }
695 }
696
697 else if( ( sourceNodeType == Node.TEXT_NODE && destNodeType == Node.ATTRIBUTE_NODE )
698 || ( sourceNodeType == Node.ATTRIBUTE_NODE && destNodeType == Node.TEXT_NODE ) )
699 {
700 value = sourceNode.getNodeValue();
701 if( !getIgnoreEmpty() || ( value != null && value.length() > 0 ) )
702 {
703 if( getEntitize() )
704 value = XmlUtils.entitize( value );
705
706 destNode.setNodeValue( value );
707 }
708 }
709 else if( sourceNodeType == Node.ELEMENT_NODE && destNodeType == Node.ATTRIBUTE_NODE
710 || destNodeType == Node.TEXT_NODE )
711 {
712 value = XmlUtils.getElementText( (Element) sourceNode );
713 if( !getIgnoreEmpty() || ( value != null && value.length() > 0 ) )
714 {
715 if( getEntitize() )
716 value = XmlUtils.entitize( value );
717
718 destNode.setNodeValue( value );
719 }
720 }
721 else if( destNodeType == Node.ELEMENT_NODE && sourceNodeType == Node.ATTRIBUTE_NODE
722 || sourceNodeType == Node.TEXT_NODE )
723 {
724
725 value = sourceNode.getNodeValue();
726 if( !getIgnoreEmpty() || ( value != null && value.length() > 0 ) )
727 {
728 if( getEntitize() )
729 value = XmlUtils.entitize( value );
730
731 XmlUtils.setElementText( (Element) destNode, value );
732 }
733 }
734
735 return value;
736 }
737
738 /***
739 * Returns the name of the source property.
740 */
741
742 public String getSourcePropertyName()
743 {
744 if( sourceType == null )
745 return null;
746
747 if( currentSourceProperty != null )
748 return currentSourceProperty.getName();
749
750 TestPropertyHolder actualSourceStep = getSourceStep();
751 if( actualSourceStep == null )
752 return sourceType;
753
754 TestProperty property = actualSourceStep.getProperty( sourceType );
755 return property == null ? sourceType : property.getName();
756 }
757
758 public void setSourcePropertyName( String name )
759 {
760 String old = getSourcePropertyName();
761
762
763 if( ( name == null && old == null ) || ( name != null && old != null && name.equals( old ) ) )
764 return;
765
766
767 sourceType = name;
768 config.setSourceType( name );
769
770
771 TestPropertyHolder sourceStep2 = getSourceStep();
772 currentSourceProperty = sourceStep2 != null && sourceType != null ? sourceStep2.getProperty( sourceType ) : null;
773
774
775 propertyChangeSupport.firePropertyChange( SOURCE_TYPE_PROPERTY, old, name );
776 }
777
778 public TestProperty getTargetProperty()
779 {
780 if( targetType == null )
781 return null;
782
783 if( currentTargetProperty != null )
784 return currentTargetProperty;
785
786 TestPropertyHolder actualTargetStep = getTargetStep();
787 return actualTargetStep == null ? null : actualTargetStep.getProperty( targetType );
788 }
789
790 public String getTargetPropertyName()
791 {
792 if( targetType == null )
793 return null;
794
795 if( currentTargetProperty != null )
796 return currentTargetProperty.getName();
797
798 TestPropertyHolder actualTargetStep = getTargetStep();
799 TestProperty property = actualTargetStep == null ? null : actualTargetStep.getProperty( targetType );
800 return actualTargetStep == null || property == null ? targetType : property.getName();
801 }
802
803 public void setTargetPropertyName( String name )
804 {
805 String old = getTargetPropertyName();
806
807
808 if( ( name == null && old == null ) || ( name != null && old != null && name.equals( old ) ) )
809 return;
810
811
812 targetType = name;
813 config.setTargetType( name );
814
815
816 TestPropertyHolder targetStep2 = getTargetStep();
817
818 currentTargetProperty = targetStep2 != null && targetType != null ? targetStep2.getProperty( targetType ) : null;
819
820
821 propertyChangeSupport.firePropertyChange( TARGET_TYPE_PROPERTY, old, name );
822 }
823
824 public String getName()
825 {
826 return config.getName();
827 }
828
829 public void setSourcePath( String path )
830 {
831 String old = sourcePath;
832 sourcePath = path;
833 config.setSourcePath( path );
834 propertyChangeSupport.firePropertyChange( SOURCE_PATH_PROPERTY, old, path );
835 }
836
837 public void setTargetPath( String path )
838 {
839 String old = targetPath;
840 targetPath = path;
841 config.setTargetPath( path );
842 propertyChangeSupport.firePropertyChange( TARGET_PATH_PROPERTY, old, path );
843 }
844
845 public void setName( String name )
846 {
847 String old = this.name;
848 this.name = name;
849 config.setName( name );
850 propertyChangeSupport.firePropertyChange( NAME_PROPERTY, old, name );
851 }
852
853 public TestPropertyHolder getSourceStep()
854 {
855 return getPropertyHolder( getSourceStepName() );
856 }
857
858 public String getSourceStepName()
859 {
860 if( sourceStep != null )
861 return sourceStep;
862
863 if( testCase == null )
864 return null;
865
866 TestModelItem step = testCase.findPreviousStepOfType( this.testStep, WsdlTestRequestStep.class );
867 return step == null ? null : step.getName();
868 }
869
870 public void setSourceStepName( String sourceStep )
871 {
872 String old = getSourceStepName();
873
874
875 if( ( sourceStep == null && old == null ) || ( sourceStep != null && old != null && sourceStep.equals( old ) ) )
876 return;
877
878 if( sourceStep == null )
879 log.debug( "Setting sourceStep for transfer [" + getName() + "] to null" );
880
881 this.sourceStep = sourceStep;
882 config.setSourceStep( sourceStep );
883
884 if( currentSourceStep != null )
885 {
886 if( currentSourceStep instanceof TestStep )
887 ( (TestStep) currentSourceStep ).removePropertyChangeListener( TestStep.NAME_PROPERTY, stepNameChangeListener );
888
889 currentSourceStep.removeTestPropertyListener( propertyNameChangeListener );
890 }
891
892 currentSourceStep = getPropertyHolder( sourceStep );
893 if( currentSourceStep != null )
894 {
895 if( currentSourceStep instanceof TestStep )
896 ( (TestStep) currentSourceStep ).addPropertyChangeListener( TestStep.NAME_PROPERTY, stepNameChangeListener );
897
898 currentSourceStep.addTestPropertyListener( propertyNameChangeListener );
899 }
900 else
901 log.warn( "Failed to get sourceStep [" + sourceStep + "]" );
902
903 propertyChangeSupport.firePropertyChange( SOURCE_STEP_PROPERTY, old, sourceStep );
904 setSourcePropertyName( null );
905 }
906
907 public TestPropertyHolder getTargetStep()
908 {
909 return getPropertyHolder( getTargetStepName() );
910 }
911
912 public String getTargetStepName()
913 {
914 if( targetStep != null )
915 return targetStep;
916
917 if( testCase == null )
918 return null;
919
920 TestModelItem step = testCase.findNextStepOfType( this.testStep, WsdlTestRequestStep.class );
921 return step == null ? null : step.getName();
922 }
923
924 public void setTargetStepName( String targetStep )
925 {
926 String old = getTargetStepName();
927
928
929 if( ( targetStep == null && old == null ) || ( targetStep != null && old != null && targetStep.equals( old ) ) )
930 return;
931
932 if( targetStep == null )
933 log.debug( "Setting targetStep for transfer [" + getName() + "] to null" );
934
935 this.targetStep = targetStep;
936 config.setTargetStep( targetStep );
937
938 if( currentTargetStep != null )
939 {
940 if( currentTargetStep instanceof TestStep )
941 ( (TestStep) currentTargetStep ).removePropertyChangeListener( TestStep.NAME_PROPERTY, stepNameChangeListener );
942
943 currentTargetStep.removeTestPropertyListener( propertyNameChangeListener );
944 }
945
946 currentTargetStep = getPropertyHolder( targetStep );
947 if( currentTargetStep != null )
948 {
949 if( currentTargetStep instanceof TestStep )
950 ( (TestStep) currentTargetStep ).addPropertyChangeListener( TestStep.NAME_PROPERTY, stepNameChangeListener );
951
952 currentTargetStep.addTestPropertyListener( propertyNameChangeListener );
953 }
954 else
955 log.warn( "Failed to get targetStep [" + targetStep + "]" );
956
957 propertyChangeSupport.firePropertyChange( TARGET_STEP_PROPERTY, old, targetStep );
958 setTargetPropertyName( null );
959 }
960
961 private TestPropertyHolder getPropertyHolder( String name )
962 {
963 if( name == null || testCase == null )
964 return null;
965
966 if( name.charAt( 0 ) == PropertyExpansion.SCOPE_PREFIX )
967 {
968 if( name.equals( PropertyExpansion.GLOBAL_REFERENCE ) )
969 return PropertyExpansionUtils.getGlobalProperties();
970
971 if( name.equals( PropertyExpansion.PROJECT_REFERENCE ) )
972 return testCase.getTestSuite().getProject();
973
974 if( name.equals( PropertyExpansion.TESTSUITE_REFERENCE ) )
975 return testCase.getTestSuite();
976
977 if( name.equals( PropertyExpansion.TESTCASE_REFERENCE ) )
978 return testCase;
979 }
980
981 return testStep.getTestCase().getTestStepByName( name );
982 }
983
984 public void addPropertyChangeListener( String propertyName, PropertyChangeListener listener )
985 {
986 propertyChangeSupport.addPropertyChangeListener( propertyName, listener );
987 }
988
989 public void addPropertyChangeListener( PropertyChangeListener listener )
990 {
991 propertyChangeSupport.addPropertyChangeListener( listener );
992 }
993
994 public void removePropertyChangeListener( PropertyChangeListener listener )
995 {
996 propertyChangeSupport.removePropertyChangeListener( listener );
997 }
998
999 public void removePropertyChangeListener( String propertyName, PropertyChangeListener listener )
1000 {
1001 propertyChangeSupport.removePropertyChangeListener( propertyName, listener );
1002 }
1003
1004 public boolean getFailOnError()
1005 {
1006 return config.getFailOnError();
1007 }
1008
1009 public void setFailOnError( boolean failOnError )
1010 {
1011 config.setFailOnError( failOnError );
1012 }
1013
1014 public boolean getTransferToAll()
1015 {
1016 return config.getTransferToAll();
1017 }
1018
1019 public void setTransferToAll( boolean transferToAll )
1020 {
1021 config.setTransferToAll( transferToAll );
1022 }
1023
1024 public boolean getUseXQuery()
1025 {
1026 return config.getUseXQuery();
1027 }
1028
1029 public void setUseXQuery( boolean useXQuery )
1030 {
1031 config.setUseXQuery( useXQuery );
1032 }
1033
1034 public boolean getEntitize()
1035 {
1036 return config.getEntitize();
1037 }
1038
1039 public void setEntitize( boolean entitize )
1040 {
1041 config.setEntitize( entitize );
1042 }
1043
1044 public boolean getIgnoreEmpty()
1045 {
1046 return config.getIgnoreEmpty();
1047 }
1048
1049 public void setIgnoreEmpty( boolean ignoreEmpty )
1050 {
1051 config.setIgnoreEmpty( ignoreEmpty );
1052 }
1053
1054 public boolean getSetNullOnMissingSource()
1055 {
1056 return config.getSetNullOnMissingSource();
1057 }
1058
1059 public void setSetNullOnMissingSource( boolean setNullOnMissingSource )
1060 {
1061 config.setSetNullOnMissingSource( setNullOnMissingSource );
1062 }
1063
1064 public boolean getTransferTextContent()
1065 {
1066 return config.getTransferTextContent();
1067 }
1068
1069 public void setTransferTextContent( boolean transferTextContent )
1070 {
1071 config.setTransferTextContent( transferTextContent );
1072 }
1073
1074 public boolean isDisabled()
1075 {
1076 return config.getDisabled();
1077 }
1078
1079 public void setDisabled( boolean disabled )
1080 {
1081 config.setDisabled( disabled );
1082 }
1083
1084 public boolean getTransferChildNodes()
1085 {
1086 return config.getTransferChildNodes();
1087 }
1088
1089 public void setTransferChildNodes( boolean b )
1090 {
1091 config.setTransferChildNodes( b );
1092 }
1093
1094 private final class InternalTestSuiteListener extends TestSuiteListenerAdapter
1095 {
1096 public void testStepRemoved( TestStep testStep, int index )
1097 {
1098 if( testStep.getTestCase() == testCase )
1099 {
1100 String stepName = testStep.getName();
1101 if( stepName.equals( sourceStep ) )
1102 {
1103 setSourceStepName( null );
1104 }
1105
1106 if( stepName.equals( targetStep ) )
1107 {
1108 setTargetStepName( null );
1109 }
1110 }
1111 }
1112 }
1113
1114 /***
1115 * Handle changes to source/target testStep names
1116 *
1117 * @author Ole.Matzura
1118 */
1119
1120 private class StepNameChangeListener implements PropertyChangeListener
1121 {
1122 public void propertyChange( PropertyChangeEvent evt )
1123 {
1124 String oldName = (String) evt.getOldValue();
1125 String newValue = (String) evt.getNewValue();
1126
1127 if( newValue == null )
1128 {
1129 log.error( "Tried to change stepname to null!" );
1130 Thread.dumpStack();
1131 return;
1132 }
1133
1134 if( oldName.equals( sourceStep ) && currentSourceStep instanceof TestStep )
1135 {
1136 sourceStep = newValue;
1137 config.setSourceStep( sourceStep );
1138 propertyChangeSupport.firePropertyChange( SOURCE_STEP_PROPERTY, oldName, sourceStep );
1139 }
1140
1141 if( oldName.equals( targetStep ) && currentTargetStep instanceof TestStep )
1142 {
1143 targetStep = newValue;
1144 config.setTargetStep( targetStep );
1145 propertyChangeSupport.firePropertyChange( TARGET_STEP_PROPERTY, oldName, targetStep );
1146 }
1147 }
1148 }
1149
1150 /***
1151 * Handle changes to source/target property names
1152 *
1153 * @author Ole.Matzura
1154 */
1155
1156 private class InternalTestPropertyListener extends TestPropertyListenerAdapter
1157 {
1158 public void propertyRenamed( String oldName, String newName )
1159 {
1160 if( oldName.equals( sourceType ) )
1161 {
1162 sourceType = newName;
1163 config.setSourceType( sourceType );
1164 propertyChangeSupport.firePropertyChange( SOURCE_TYPE_PROPERTY, oldName, sourceType );
1165 }
1166
1167 if( oldName.equals( targetType ) )
1168 {
1169 targetType = newName;
1170 config.setTargetType( targetType );
1171 propertyChangeSupport.firePropertyChange( TARGET_TYPE_PROPERTY, oldName, targetType );
1172 }
1173 }
1174
1175 public void propertyRemoved( String name )
1176 {
1177 if( name.equals( sourceType ) )
1178 {
1179 log.warn( "source property for transfer [" + getName() + "] in teststep [" + testStep.getName() + "/"
1180 + testStep.getTestCase().getName() + "/" + testStep.getTestCase().getTestSuite().getName()
1181 + "] set to null, was [" + name + "]" );
1182
1183 currentSourceProperty = null;
1184 setSourcePropertyName( null );
1185 }
1186
1187 if( name.equals( targetType ) )
1188 {
1189 log.warn( "target property for transfer [" + getName() + "] in teststep [" + testStep.getName() + "/"
1190 + testStep.getTestCase().getName() + "/" + testStep.getTestCase().getTestSuite().getName()
1191 + "] set to null, was [" + name + "]" );
1192
1193 currentTargetProperty = null;
1194 setTargetPropertyName( null );
1195 }
1196 }
1197 }
1198
1199 @SuppressWarnings( "unchecked" )
1200 public void resolver( ResolveContext context, PropertyTransfersTestStep parent )
1201 {
1202 if( isDisabled() )
1203 return;
1204
1205 if( getSourceProperty() == null )
1206 {
1207 if( context.hasThisModelItem( parent, "Resolve source property", getConfig().getSourceStep() ) )
1208 return;
1209 context.addPathToResolve( parent, "Resolve source property", getConfig().getSourceStep() ).addResolvers(
1210 new DisablePropertyTransferResolver( this ), new CreateMissingPropertyResolver( this, parent ),
1211 new ChooseAnotherPropertySourceResolver( this, parent ) );
1212 }
1213 else
1214 {
1215 if( context.hasThisModelItem( parent, "Resolve source property", getConfig().getSourceStep() ) )
1216 {
1217 PathToResolve path = context.getPath( parent, "Resolve source property", getConfig().getSourceStep() );
1218 path.setSolved( true );
1219 }
1220 }
1221
1222 if( getTargetProperty() == null )
1223 {
1224 if( context.hasThisModelItem( parent, "Resolve target property", getConfig().getTargetStep() ) )
1225 return;
1226 context.addPathToResolve( parent, "Resolve target property", getConfig().getTargetStep() ).addResolvers(
1227 new DisablePropertyTransferResolver( this ), new CreateMissingPropertyResolver( this, parent ),
1228 new ChooseAnotherPropertyTargetResolver( this, parent ) );
1229 }
1230 else
1231 {
1232 if( context.hasThisModelItem( parent, "Resolve target property", getConfig().getTargetStep() ) )
1233 {
1234 PathToResolve path = context.getPath( parent, "Resolve target property", getConfig().getTargetStep() );
1235 path.setSolved( true );
1236 }
1237 }
1238
1239 }
1240 }