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