1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.support;
14
15 import java.io.File;
16 import java.io.FileInputStream;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Collection;
22 import java.util.HashMap;
23 import java.util.HashSet;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Properties;
27 import java.util.Set;
28
29 import javax.xml.namespace.QName;
30
31 import org.apache.xmlbeans.XmlString;
32
33 import com.eviware.soapui.SoapUI;
34 import com.eviware.soapui.config.PropertiesTypeConfig;
35 import com.eviware.soapui.config.PropertyConfig;
36 import com.eviware.soapui.impl.wsdl.MutableTestPropertyHolder;
37 import com.eviware.soapui.impl.wsdl.support.wsdl.UrlWsdlLoader;
38 import com.eviware.soapui.model.ModelItem;
39 import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
40 import com.eviware.soapui.model.support.TestPropertyUtils;
41 import com.eviware.soapui.model.testsuite.RenameableTestProperty;
42 import com.eviware.soapui.model.testsuite.TestProperty;
43 import com.eviware.soapui.model.testsuite.TestPropertyListener;
44 import com.eviware.soapui.support.StringUtils;
45
46 public class XmlBeansPropertiesTestPropertyHolder implements MutableTestPropertyHolder, Map<String, TestProperty>
47 {
48 private PropertiesTypeConfig config;
49 private List<PropertiesStepProperty> properties = new ArrayList<PropertiesStepProperty>();
50 private Map<String, PropertiesStepProperty> propertyMap = new HashMap<String, PropertiesStepProperty>();
51 private Set<TestPropertyListener> listeners = new HashSet<TestPropertyListener>();
52 private ModelItem modelItem;
53 private Properties overrideProperties;
54 private String propertiesLabel = "Test Properties";
55
56 public XmlBeansPropertiesTestPropertyHolder( ModelItem modelItem, PropertiesTypeConfig config )
57 {
58 this.modelItem = modelItem;
59 this.config = config;
60
61 for( int c = 0; c < config.sizeOfPropertyArray(); c++ )
62 {
63 PropertyConfig propertyConfig = config.getPropertyArray( c );
64 if( StringUtils.hasContent( propertyConfig.getName() ) )
65 {
66 addProperty( propertyConfig, false, null );
67 }
68 else
69 {
70 config.removeProperty( c );
71 c-- ;
72 }
73 }
74 }
75
76 protected PropertiesStepProperty addProperty( PropertyConfig propertyConfig, boolean notify,
77 TestProperty virtualProperty )
78 {
79 PropertiesStepProperty propertiesStepProperty = new PropertiesStepProperty( propertyConfig, virtualProperty );
80
81 properties.add( propertiesStepProperty );
82
83 sortVirtualLast();
84
85 propertyMap.put( propertiesStepProperty.getName().toUpperCase(), propertiesStepProperty );
86
87 if( notify )
88 {
89 firePropertyAdded( propertiesStepProperty.getName() );
90 }
91
92 return propertiesStepProperty;
93 }
94
95 /***
96 * sort properties list and make sure that virtualproperties are always
97 * placed after properties
98 */
99 private void sortVirtualLast()
100 {
101 List<PropertiesStepProperty> virtualProperties = new ArrayList<PropertiesStepProperty>();
102 List<PropertiesStepProperty> nonVirtualProperties = new ArrayList<PropertiesStepProperty>();
103
104 for( PropertiesStepProperty psp : properties )
105 {
106 if( psp.isVirtualProperty() )
107 {
108 if( !virtualProperties.contains( psp ) )
109 virtualProperties.add( psp );
110 }
111 else
112 {
113 nonVirtualProperties.add( psp );
114 }
115 }
116 properties.clear();
117 properties.addAll( nonVirtualProperties );
118 properties.addAll( virtualProperties );
119 }
120
121 private void firePropertyAdded( String name )
122 {
123 TestPropertyListener[] listenersArray = listeners.toArray( new TestPropertyListener[listeners.size()] );
124 for( TestPropertyListener listener : listenersArray )
125 {
126 listener.propertyAdded( name );
127 }
128 }
129
130 private void firePropertyRemoved( String name )
131 {
132 TestPropertyListener[] listenersArray = listeners.toArray( new TestPropertyListener[listeners.size()] );
133 for( TestPropertyListener listener : listenersArray )
134 {
135 listener.propertyRemoved( name );
136 }
137 }
138
139 private void firePropertyMoved( String name, int oldIndex, int newIndex )
140 {
141 TestPropertyListener[] listenersArray = listeners.toArray( new TestPropertyListener[listeners.size()] );
142 for( TestPropertyListener listener : listenersArray )
143 {
144 listener.propertyMoved( name, oldIndex, newIndex );
145 }
146 }
147
148 private void firePropertyRenamed( String oldName, String newName )
149 {
150 TestPropertyListener[] listenersArray = listeners.toArray( new TestPropertyListener[listeners.size()] );
151 for( TestPropertyListener listener : listenersArray )
152 {
153 listener.propertyRenamed( oldName, newName );
154 }
155 }
156
157 private void firePropertyValueChanged( String name, String oldValue, String newValue )
158 {
159 TestPropertyListener[] listenersArray = listeners.toArray( new TestPropertyListener[listeners.size()] );
160 for( TestPropertyListener listener : listenersArray )
161 {
162 listener.propertyValueChanged( name, oldValue, newValue );
163 }
164 }
165
166 public TestProperty addProperty( String name )
167 {
168 PropertyConfig propertyConfig = config.addNewProperty();
169 propertyConfig.setName( name );
170 return addProperty( propertyConfig, true, null );
171 }
172
173 public TestProperty addVirtualProperty( String key, TestProperty virtualProperty )
174 {
175 PropertyConfig propertyConfig = PropertyConfig.Factory.newInstance();
176 propertyConfig.setName( key );
177 return addProperty( propertyConfig, true, virtualProperty );
178 }
179
180 public void addTestPropertyListener( TestPropertyListener listener )
181 {
182 listeners.add( listener );
183 }
184
185 public PropertiesStepProperty getProperty( String name )
186 {
187 return propertyMap.get( name.toUpperCase() );
188 }
189
190 public String[] getPropertyNames()
191 {
192 String[] result = new String[properties.size()];
193 for( int c = 0; c < properties.size(); c++ )
194 result[c] = properties.get( c ).getName();
195
196 return result;
197 }
198
199 public List<TestProperty> getPropertyList()
200 {
201 List<TestProperty> result = new ArrayList<TestProperty>();
202
203 for( TestProperty property : properties )
204 result.add( property );
205
206 return result;
207 }
208
209 public String getPropertyValue( String name )
210 {
211 TestProperty property = getProperty( name );
212 return property == null ? null : property.getValue();
213 }
214
215 public TestProperty removeProperty( String propertyName )
216 {
217 TestProperty property = getProperty( propertyName );
218 if( property != null )
219 {
220 if( property instanceof PropertiesStepProperty && ( ( PropertiesStepProperty )property ).isVirtualProperty() )
221 {
222 return property;
223 }
224 int ix = properties.indexOf( property );
225 propertyMap.remove( propertyName.toUpperCase() );
226 properties.remove( ix );
227 firePropertyRemoved( propertyName );
228 config.removeProperty( ix );
229 return property;
230 }
231
232 return null;
233 }
234
235 public void removeTestPropertyListener( TestPropertyListener listener )
236 {
237 listeners.remove( listener );
238 }
239
240 public void setPropertyValue( String name, String value )
241 {
242 PropertiesStepProperty property = getProperty( name );
243 if( property != null )
244 property.setValue( value );
245 else
246 addProperty( name ).setValue( value );
247 }
248
249 public void resetPropertiesConfig( PropertiesTypeConfig config )
250 {
251 this.config = config;
252
253 for( int c = 0; c < config.sizeOfPropertyArray(); c++ )
254 {
255 properties.get( c ).setConfig( config.getPropertyArray( c ) );
256 }
257 }
258
259 public boolean renameProperty( String name, String newName )
260 {
261 if( getProperty( newName ) != null )
262 return false;
263
264 PropertiesStepProperty property = getProperty( name );
265 if( property == null )
266 return false;
267
268 property.setName( newName );
269 return true;
270 }
271
272 /***
273 * Internal property class
274 *
275 * @author ole
276 */
277
278 public class PropertiesStepProperty implements RenameableTestProperty
279 {
280 private PropertyConfig propertyConfig;
281 private final TestProperty virtualProperty;
282
283 public PropertiesStepProperty( PropertyConfig propertyConfig, TestProperty virtualProperty )
284 {
285 this.propertyConfig = propertyConfig;
286 this.virtualProperty = virtualProperty;
287 }
288
289 public boolean isVirtualProperty()
290 {
291 return virtualProperty != null;
292 }
293
294 public void setConfig( PropertyConfig propertyConfig )
295 {
296 this.propertyConfig = propertyConfig;
297 }
298
299 public String getName()
300 {
301 return propertyConfig.getName();
302 }
303
304 public void setName( String name )
305 {
306 String oldName = getName();
307 propertyConfig.setName( name );
308
309 propertyMap.remove( oldName.toUpperCase() );
310 propertyMap.put( name.toUpperCase(), this );
311
312 firePropertyRenamed( oldName, name );
313 }
314
315 public String getDescription()
316 {
317 return null;
318 }
319
320 public String getValue()
321 {
322 if( overrideProperties != null && overrideProperties.containsKey( getName() ) )
323 return overrideProperties.getProperty( getName() );
324
325 if( virtualProperty != null )
326 return virtualProperty.getValue();
327
328 return propertyConfig.getValue();
329 }
330
331 public void setValue( String value )
332 {
333 String oldValue = getValue();
334 propertyConfig.setValue( value );
335
336 if( overrideProperties != null && overrideProperties.containsKey( getName() ) )
337 {
338 overrideProperties.remove( getName() );
339 if( overrideProperties.isEmpty() )
340 overrideProperties = null;
341 }
342
343 firePropertyValueChanged( getName(), oldValue, value );
344 }
345
346 public boolean isReadOnly()
347 {
348 return false;
349 }
350
351 public QName getType()
352 {
353 return XmlString.type.getName();
354 }
355
356 public ModelItem getModelItem()
357 {
358 return modelItem;
359 }
360
361 public String getDefaultValue()
362 {
363 return null;
364 }
365 }
366
367 public int saveTo( String fileName ) throws IOException
368 {
369 return TestPropertyUtils.saveTo( this, fileName );
370 }
371
372 public int getPropertyCount()
373 {
374 return properties.size();
375 }
376
377 public TestProperty getPropertyAt( int index )
378 {
379 return properties.get( index );
380 }
381
382 public Map<String, TestProperty> getProperties()
383 {
384 Map<String, TestProperty> result = new HashMap<String, TestProperty>();
385 for( TestProperty property : propertyMap.values() )
386 {
387 result.put( property.getName(), property );
388 }
389
390 return result;
391 }
392
393 public boolean hasProperty( String name )
394 {
395 return propertyMap.containsKey( name.toUpperCase() );
396 }
397
398 public int addPropertiesFromFile( String propFile )
399 {
400 if( !StringUtils.hasContent( propFile ) )
401 return 0;
402
403 try
404 {
405 InputStream input = null;
406
407 File file = new File( propFile );
408 if( file.exists() )
409 {
410 input = new FileInputStream( file );
411 }
412 else if( propFile.toLowerCase().startsWith( "http://" ) || propFile.toLowerCase().startsWith( "https://" ) )
413 {
414 UrlWsdlLoader loader = new UrlWsdlLoader( propFile, getModelItem() );
415 loader.setUseWorker( false );
416 input = loader.load();
417 }
418
419 if( input != null )
420 {
421 if( overrideProperties == null )
422 overrideProperties = new Properties();
423
424 int sz = overrideProperties.size();
425 overrideProperties.load( input );
426
427 for( Object key : overrideProperties.keySet() )
428 {
429 String name = key.toString();
430 if( !hasProperty( name ) )
431 addProperty( name );
432 }
433
434 return overrideProperties.size() - sz;
435 }
436 }
437 catch( Exception e )
438 {
439 SoapUI.logError( e );
440 }
441
442 return 0;
443 }
444
445 public ModelItem getModelItem()
446 {
447 return modelItem;
448 }
449
450 public PropertyExpansion[] getPropertyExpansions()
451 {
452 List<PropertyExpansion> result = new ArrayList<PropertyExpansion>();
453
454 return result.toArray( new PropertyExpansion[result.size()] );
455 }
456
457 public void moveProperty( String propertyName, int targetIndex )
458 {
459 PropertiesStepProperty property = getProperty( propertyName );
460 int ix = properties.indexOf( property );
461
462 if( ix == targetIndex )
463 return;
464
465 if( targetIndex < 0 )
466 targetIndex = 0;
467
468 String value = property.getValue();
469 config.removeProperty( ix );
470
471 PropertyConfig propertyConfig = null;
472
473 if( targetIndex < properties.size() )
474 {
475 properties.add( targetIndex, properties.remove( ix ) );
476 propertyConfig = config.insertNewProperty( targetIndex );
477 }
478 else
479 {
480 properties.add( properties.remove( ix ) );
481 propertyConfig = config.addNewProperty();
482 }
483
484 propertyConfig.setName( propertyName );
485 propertyConfig.setValue( value );
486
487 resetPropertiesConfig( config );
488
489 if( targetIndex > properties.size() )
490 targetIndex = properties.size();
491
492 firePropertyMoved( propertyName, ix, targetIndex );
493 }
494
495 public void clear()
496 {
497 while( size() > 0 )
498 removeProperty( getPropertyAt( 0 ).getName() );
499 }
500
501 public boolean containsKey( Object key )
502 {
503 return hasProperty( ( String )key );
504 }
505
506 public boolean containsValue( Object value )
507 {
508 return propertyMap.containsValue( value );
509 }
510
511 public Set<java.util.Map.Entry<String, TestProperty>> entrySet()
512 {
513 HashSet<java.util.Map.Entry<String, TestProperty>> result = new HashSet<Entry<String, TestProperty>>();
514
515 for( TestProperty p : propertyMap.values() )
516 {
517
518
519
520 result.add( new HashMapEntry<String, TestProperty>( p.getName(), p ) );
521 }
522
523 return result;
524 }
525
526 private static class HashMapEntry<K, V> implements java.util.Map.Entry<K, V>
527 {
528 private K key;
529 private V value;
530
531 public HashMapEntry( K key, V value )
532 {
533 this.key = key;
534 this.value = value;
535 }
536
537 public K getKey()
538 {
539 return key;
540 }
541
542 public V getValue()
543 {
544 return value;
545 }
546
547 public V setValue( V value )
548 {
549 throw new UnsupportedOperationException();
550 }
551 }
552
553 public TestProperty get( Object key )
554 {
555 return getProperty( ( String )key );
556 }
557
558 public boolean isEmpty()
559 {
560 return propertyMap.isEmpty();
561 }
562
563 public Set<String> keySet()
564 {
565 return new HashSet<String>( Arrays.asList( getPropertyNames() ) );
566 }
567
568 public TestProperty put( String key, TestProperty value )
569 {
570 TestProperty result = addProperty( key );
571 result.setValue( value.getValue() );
572 return result;
573 }
574
575 public void putAll( Map<? extends String, ? extends TestProperty> m )
576 {
577 for( TestProperty p : m.values() )
578 {
579 addProperty( p.getName() ).setValue( p.getValue() );
580 }
581 }
582
583 public TestProperty remove( Object key )
584 {
585 return removeProperty( ( String )key );
586 }
587
588 public int size()
589 {
590 return propertyMap.size();
591 }
592
593 public Collection<TestProperty> values()
594 {
595 ArrayList<TestProperty> result = new ArrayList<TestProperty>();
596 result.addAll( propertyMap.values() );
597 return result;
598 }
599
600 public String getPropertiesLabel()
601 {
602 return propertiesLabel;
603 }
604
605 public void setPropertiesLabel( String propertiesLabel )
606 {
607 this.propertiesLabel = propertiesLabel;
608 }
609 }