View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.impl.rest.support;
14  
15  import java.beans.PropertyChangeListener;
16  import java.beans.PropertyChangeSupport;
17  import java.io.File;
18  import java.io.FileInputStream;
19  import java.io.InputStream;
20  import java.util.ArrayList;
21  import java.util.Arrays;
22  import java.util.Collection;
23  import java.util.HashMap;
24  import java.util.HashSet;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Properties;
28  import java.util.Set;
29  
30  import javax.xml.namespace.QName;
31  
32  import org.apache.xmlbeans.XmlObject;
33  import org.apache.xmlbeans.XmlString;
34  
35  import com.eviware.soapui.SoapUI;
36  import com.eviware.soapui.config.RestParameterConfig;
37  import com.eviware.soapui.config.RestParametersConfig;
38  import com.eviware.soapui.impl.wsdl.support.wsdl.UrlWsdlLoader;
39  import com.eviware.soapui.model.ModelItem;
40  import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
41  import com.eviware.soapui.model.testsuite.TestProperty;
42  import com.eviware.soapui.model.testsuite.TestPropertyListener;
43  import com.eviware.soapui.support.StringUtils;
44  
45  public class XmlBeansRestParamsTestPropertyHolder implements RestParamsPropertyHolder
46  {
47  	private RestParametersConfig config;
48  	private List<RestParamProperty> properties = new ArrayList<RestParamProperty>();
49  	private Map<String, RestParamProperty> propertyMap = new HashMap<String, RestParamProperty>();
50  	private Set<TestPropertyListener> listeners = new HashSet<TestPropertyListener>();
51  	private ModelItem modelItem;
52  	private Properties overrideProperties;
53  	private String propertiesLabel = "Test Properties";
54  
55  	public XmlBeansRestParamsTestPropertyHolder( ModelItem modelItem, RestParametersConfig config )
56  	{
57  		this.modelItem = modelItem;
58  		this.config = config;
59  
60  		for( RestParameterConfig propertyConfig : config.getParameterList() )
61  		{
62  			addProperty( propertyConfig, false );
63  		}
64  	}
65  
66  	protected XmlBeansRestParamProperty addProperty( RestParameterConfig propertyConfig, boolean notify )
67  	{
68  		XmlBeansRestParamProperty propertiesStepProperty = new XmlBeansRestParamProperty( propertyConfig );
69  		properties.add( propertiesStepProperty );
70  		propertyMap.put( propertiesStepProperty.getName().toUpperCase(), propertiesStepProperty );
71  
72  		if( notify )
73  		{
74  			firePropertyAdded( propertiesStepProperty.getName() );
75  		}
76  
77  		return propertiesStepProperty;
78  	}
79  
80  	private void firePropertyAdded( String name )
81  	{
82  		TestPropertyListener[] listenersArray = listeners.toArray( new TestPropertyListener[listeners.size()] );
83  		for( TestPropertyListener listener : listenersArray )
84  		{
85  			listener.propertyAdded( name );
86  		}
87  	}
88  
89  	private void firePropertyRemoved( String name )
90  	{
91  		TestPropertyListener[] listenersArray = listeners.toArray( new TestPropertyListener[listeners.size()] );
92  		for( TestPropertyListener listener : listenersArray )
93  		{
94  			listener.propertyRemoved( name );
95  		}
96  	}
97  
98  	private void firePropertyMoved( String name, int oldIndex, int newIndex )
99  	{
100 		TestPropertyListener[] listenersArray = listeners.toArray( new TestPropertyListener[listeners.size()] );
101 		for( TestPropertyListener listener : listenersArray )
102 		{
103 			listener.propertyMoved( name, oldIndex, newIndex );
104 		}
105 	}
106 
107 	private void firePropertyRenamed( String oldName, String newName )
108 	{
109 		TestPropertyListener[] listenersArray = listeners.toArray( new TestPropertyListener[listeners.size()] );
110 		for( TestPropertyListener listener : listenersArray )
111 		{
112 			listener.propertyRenamed( oldName, newName );
113 		}
114 	}
115 
116 	private void firePropertyValueChanged( String name, String oldValue, String newValue )
117 	{
118 		TestPropertyListener[] listenersArray = listeners.toArray( new TestPropertyListener[listeners.size()] );
119 		for( TestPropertyListener listener : listenersArray )
120 		{
121 			listener.propertyValueChanged( name, oldValue, newValue );
122 		}
123 	}
124 
125 	public XmlBeansRestParamProperty addProperty( String name )
126 	{
127 		RestParameterConfig propertyConfig = config.addNewParameter();
128 		propertyConfig.setName( name );
129 		return addProperty( propertyConfig, true );
130 	}
131 
132 	public void addTestPropertyListener( TestPropertyListener listener )
133 	{
134 		listeners.add( listener );
135 	}
136 
137 	/*
138 	 * (non-Javadoc)
139 	 * 
140 	 * @see
141 	 * com.eviware.soapui.impl.rest.support.RestParamsPropertyHolder#getProperty
142 	 * (java.lang.String)
143 	 */
144 	public RestParamProperty getProperty( String name )
145 	{
146 		return propertyMap.get( name.toUpperCase() );
147 	}
148 
149 	public String[] getPropertyNames()
150 	{
151 		String[] result = new String[properties.size()];
152 		for( int c = 0; c < properties.size(); c++ )
153 			result[c] = properties.get( c ).getName();
154 
155 		return result;
156 	}
157 
158 	public String getPropertyValue( String name )
159 	{
160 		TestProperty property = getProperty( name );
161 		return property == null ? null : property.getValue();
162 	}
163 
164 	public RestParamProperty removeProperty( String propertyName )
165 	{
166 		RestParamProperty property = getProperty( propertyName );
167 		if( property != null )
168 		{
169 			int ix = properties.indexOf( property );
170 			propertyMap.remove( propertyName.toUpperCase() );
171 			properties.remove( ix );
172 			config.removeParameter( ix );
173 
174 			firePropertyRemoved( propertyName );
175 			return property;
176 		}
177 
178 		return null;
179 	}
180 
181 	public void removeTestPropertyListener( TestPropertyListener listener )
182 	{
183 		listeners.remove( listener );
184 	}
185 
186 	public void setPropertyValue( String name, String value )
187 	{
188 		RestParamProperty property = getProperty( name );
189 		if( property != null )
190 			property.setValue( value );
191 		else
192 			addProperty( name ).setValue( value );
193 	}
194 
195 	/*
196 	 * (non-Javadoc)
197 	 * 
198 	 * @see
199 	 * com.eviware.soapui.impl.rest.support.RestParamsPropertyHolder#resetValues
200 	 * ()
201 	 */
202 	public void resetValues()
203 	{
204 		for( RestParamProperty property : properties )
205 		{
206 			( ( XmlBeansRestParamProperty )property ).reset();
207 		}
208 	}
209 
210 	public void resetPropertiesConfig( RestParametersConfig config )
211 	{
212 		this.config = config;
213 
214 		for( int c = 0; c < config.sizeOfParameterArray(); c++ )
215 		{
216 			( ( XmlBeansRestParamProperty )properties.get( c ) ).setConfig( config.getParameterArray( c ) );
217 		}
218 	}
219 
220 	public boolean renameProperty( String name, String newName )
221 	{
222 		if( getProperty( newName ) != null )
223 			return false;
224 
225 		RestParamProperty property = getProperty( name );
226 		if( property == null )
227 			return false;
228 
229 		property.setName( newName );
230 		return true;
231 	}
232 
233 	/*
234 	 * (non-Javadoc)
235 	 * 
236 	 * @see
237 	 * com.eviware.soapui.impl.rest.support.RestParamsPropertyHolder#getPropertyIndex
238 	 * (java.lang.String)
239 	 */
240 	public int getPropertyIndex( String name )
241 	{
242 		for( int c = 0; c < properties.size(); c++ )
243 		{
244 			if( properties.get( c ).getName().equals( name ) )
245 			{
246 				return c;
247 			}
248 		}
249 
250 		return -1;
251 	}
252 
253 	public class XmlBeansRestParamProperty implements RestParamProperty
254 	{
255 		private RestParameterConfig propertyConfig;
256 		private PropertyChangeSupport propertySupport;
257 
258 		public XmlBeansRestParamProperty( RestParameterConfig propertyConfig )
259 		{
260 			this.propertyConfig = propertyConfig;
261 
262 			propertySupport = new PropertyChangeSupport( this );
263 		}
264 
265 		/*
266 		 * (non-Javadoc)
267 		 * 
268 		 * @seecom.eviware.soapui.impl.rest.support.RestParamProperty#
269 		 * addPropertyChangeListener(java.beans.PropertyChangeListener)
270 		 */
271 		public void addPropertyChangeListener( PropertyChangeListener listener )
272 		{
273 			propertySupport.addPropertyChangeListener( listener );
274 		}
275 
276 		/*
277 		 * (non-Javadoc)
278 		 * 
279 		 * @seecom.eviware.soapui.impl.rest.support.RestParamProperty#
280 		 * addPropertyChangeListener(java.lang.String,
281 		 * java.beans.PropertyChangeListener)
282 		 */
283 		public void addPropertyChangeListener( String propertyName, PropertyChangeListener listener )
284 		{
285 			propertySupport.addPropertyChangeListener( propertyName, listener );
286 		}
287 
288 		/*
289 		 * (non-Javadoc)
290 		 * 
291 		 * @seecom.eviware.soapui.impl.rest.support.RestParamProperty#
292 		 * removePropertyChangeListener(java.beans.PropertyChangeListener)
293 		 */
294 		public void removePropertyChangeListener( PropertyChangeListener listener )
295 		{
296 			propertySupport.removePropertyChangeListener( listener );
297 		}
298 
299 		/*
300 		 * (non-Javadoc)
301 		 * 
302 		 * @seecom.eviware.soapui.impl.rest.support.RestParamProperty#
303 		 * removePropertyChangeListener(java.lang.String,
304 		 * java.beans.PropertyChangeListener)
305 		 */
306 		public void removePropertyChangeListener( String propertyName, PropertyChangeListener listener )
307 		{
308 			propertySupport.removePropertyChangeListener( propertyName, listener );
309 		}
310 
311 		public void setConfig( RestParameterConfig restParameterConfig )
312 		{
313 			this.propertyConfig = restParameterConfig;
314 		}
315 
316 		public String getName()
317 		{
318 			return propertyConfig.getName();
319 		}
320 
321 		public void setName( String name )
322 		{
323 			String oldName = getName();
324 			propertyConfig.setName( name );
325 
326 			propertyMap.remove( oldName.toUpperCase() );
327 			propertyMap.put( name.toUpperCase(), this );
328 
329 			firePropertyRenamed( oldName, name );
330 		}
331 
332 		public String getDescription()
333 		{
334 			return propertyConfig.getDescription();
335 		}
336 
337 		public void setDescription( String description )
338 		{
339 			String old = getDescription();
340 			propertyConfig.setDescription( description );
341 			propertySupport.firePropertyChange( "description", old, description );
342 		}
343 
344 		public ParameterStyle getStyle()
345 		{
346 			if( propertyConfig.xgetStyle() == null )
347 				propertyConfig.setStyle( RestParameterConfig.Style.QUERY );
348 
349 			return ParameterStyle.valueOf( propertyConfig.getStyle().toString() );
350 		}
351 
352 		public void setStyle( ParameterStyle style )
353 		{
354 			ParameterStyle old = getStyle();
355 
356 			propertyConfig.setStyle( RestParameterConfig.Style.Enum.forString( style.name() ) );
357 			propertySupport.firePropertyChange( "style", old, style );
358 		}
359 
360 		public String getValue()
361 		{
362 			if( overrideProperties != null && overrideProperties.containsKey( getName() ) )
363 				return overrideProperties.getProperty( getName() );
364 
365 			return propertyConfig.getValue() == null ? "" : propertyConfig.getValue();
366 		}
367 
368 		public void setValue( String value )
369 		{
370 			String oldValue = getValue();
371 			propertyConfig.setValue( value );
372 
373 			if( overrideProperties != null && overrideProperties.containsKey( getName() ) )
374 			{
375 				overrideProperties.remove( getName() );
376 				if( overrideProperties.isEmpty() )
377 					overrideProperties = null;
378 			}
379 
380 			firePropertyValueChanged( getName(), oldValue, value );
381 		}
382 
383 		public boolean isReadOnly()
384 		{
385 			return false;
386 		}
387 
388 		public ModelItem getModelItem()
389 		{
390 			return modelItem;
391 		}
392 
393 		public String getDefaultValue()
394 		{
395 			return propertyConfig.isSetDefault() ? propertyConfig.getDefault() : "";
396 		}
397 
398 		public String[] getOptions()
399 		{
400 			return propertyConfig.getOptionList().toArray( new String[propertyConfig.sizeOfOptionArray()] );
401 		}
402 
403 		public boolean getRequired()
404 		{
405 			return propertyConfig.getRequired();
406 		}
407 
408 		/*
409 		 * (non-Javadoc)
410 		 * 
411 		 * @see
412 		 * com.eviware.soapui.impl.rest.support.RestParamProperty#isDisableUrlEncoding
413 		 * ()
414 		 */
415 		public boolean isDisableUrlEncoding()
416 		{
417 			return propertyConfig.getDisableUrlEncoding();
418 		}
419 
420 		/*
421 		 * (non-Javadoc)
422 		 * 
423 		 * @seecom.eviware.soapui.impl.rest.support.RestParamProperty#
424 		 * setDisableUrlEncoding(boolean)
425 		 */
426 		public void setDisableUrlEncoding( boolean encode )
427 		{
428 			boolean old = isDisableUrlEncoding();
429 			if( old == encode )
430 				return;
431 
432 			propertyConfig.setDisableUrlEncoding( encode );
433 			propertySupport.firePropertyChange( "disableUrlEncoding", old, encode );
434 		}
435 
436 		public QName getType()
437 		{
438 			return propertyConfig.isSetType() ? propertyConfig.getType() : XmlString.type.getName();
439 		}
440 
441 		public void setOptions( String[] arg0 )
442 		{
443 			String[] old = getOptions();
444 			propertyConfig.setOptionArray( arg0 );
445 			propertySupport.firePropertyChange( "options", old, arg0 );
446 		}
447 
448 		public void setRequired( boolean arg0 )
449 		{
450 			boolean old = getRequired();
451 			if( old == arg0 )
452 				return;
453 			propertyConfig.setRequired( arg0 );
454 			propertySupport.firePropertyChange( "required", old, arg0 );
455 		}
456 
457 		public void setType( QName arg0 )
458 		{
459 			propertyConfig.setType( arg0 );
460 		}
461 
462 		public void setDefaultValue( String default1 )
463 		{
464 			String old = default1;
465 			propertyConfig.setDefault( default1 );
466 			propertySupport.firePropertyChange( "defaultValue", old, default1 );
467 		}
468 
469 		public RestParameterConfig getConfig()
470 		{
471 			return propertyConfig;
472 		}
473 
474 		@Override
475 		public boolean equals( Object obj )
476 		{
477 			if( obj instanceof XmlBeansRestParamProperty )
478 			{
479 				return propertyConfig.toString().equals( ( ( XmlBeansRestParamProperty )obj ).propertyConfig.toString() );
480 			}
481 
482 			return super.equals( obj );
483 		}
484 
485 		public void reset()
486 		{
487 			setValue( getDefaultValue() );
488 		}
489 	}
490 
491 	/*
492 	 * (non-Javadoc)
493 	 * 
494 	 * @see
495 	 * com.eviware.soapui.impl.rest.support.RestParamsPropertyHolder#saveTo(java
496 	 * .util.Properties)
497 	 */
498 	public void saveTo( Properties props )
499 	{
500 		int cnt = 0;
501 		for( RestParamProperty p : properties )
502 		{
503 			String name = p.getName();
504 			String value = p.getValue();
505 			if( value == null )
506 				value = "";
507 
508 			props.setProperty( name, value );
509 			cnt++ ;
510 		}
511 	}
512 
513 	public int getPropertyCount()
514 	{
515 		return properties.size();
516 	}
517 
518 	/*
519 	 * (non-Javadoc)
520 	 * 
521 	 * @see
522 	 * com.eviware.soapui.impl.rest.support.RestParamsPropertyHolder#getPropertyAt
523 	 * (int)
524 	 */
525 	public RestParamProperty getPropertyAt( int index )
526 	{
527 		return properties.get( index );
528 	}
529 
530 	public List<TestProperty> getPropertyList()
531 	{
532 		List<TestProperty> result = new ArrayList<TestProperty>();
533 
534 		for( TestProperty property : properties )
535 			result.add( property );
536 
537 		return result;
538 	}
539 
540 	public Map<String, TestProperty> getProperties()
541 	{
542 		Map<String, TestProperty> result = new HashMap<String, TestProperty>();
543 		for( RestParamProperty property : propertyMap.values() )
544 		{
545 			result.put( property.getName(), property );
546 		}
547 
548 		return result;
549 	}
550 
551 	public boolean hasProperty( String name )
552 	{
553 		return propertyMap.containsKey( name.toUpperCase() );
554 	}
555 
556 	public int addPropertiesFromFile( String propFile )
557 	{
558 		if( !StringUtils.hasContent( propFile ) )
559 			return 0;
560 
561 		try
562 		{
563 			InputStream input = null;
564 
565 			File file = new File( propFile );
566 			if( file.exists() )
567 			{
568 				input = new FileInputStream( file );
569 			}
570 			else if( propFile.toLowerCase().startsWith( "http://" ) || propFile.toLowerCase().startsWith( "https://" ) )
571 			{
572 				UrlWsdlLoader loader = new UrlWsdlLoader( propFile, getModelItem() );
573 				loader.setUseWorker( false );
574 				input = loader.load();
575 			}
576 
577 			if( input != null )
578 			{
579 				if( overrideProperties == null )
580 					overrideProperties = new Properties();
581 
582 				int sz = overrideProperties.size();
583 				overrideProperties.load( input );
584 
585 				for( Object key : overrideProperties.keySet() )
586 				{
587 					String name = key.toString();
588 					if( !hasProperty( name ) )
589 						addProperty( name );
590 				}
591 
592 				return overrideProperties.size() - sz;
593 			}
594 		}
595 		catch( Exception e )
596 		{
597 			SoapUI.logError( e );
598 		}
599 
600 		return 0;
601 	}
602 
603 	public ModelItem getModelItem()
604 	{
605 		return modelItem;
606 	}
607 
608 	/*
609 	 * (non-Javadoc)
610 	 * 
611 	 * @seecom.eviware.soapui.impl.rest.support.RestParamsPropertyHolder#
612 	 * getPropertyExpansions()
613 	 */
614 	public PropertyExpansion[] getPropertyExpansions()
615 	{
616 		List<PropertyExpansion> result = new ArrayList<PropertyExpansion>();
617 
618 		return result.toArray( new PropertyExpansion[result.size()] );
619 	}
620 
621 	public void moveProperty( String propertyName, int targetIndex )
622 	{
623 		RestParamProperty property = getProperty( propertyName );
624 		int ix = properties.indexOf( property );
625 
626 		if( ix == targetIndex )
627 			return;
628 
629 		if( targetIndex < 0 )
630 			targetIndex = 0;
631 
632 		String value = property.getValue();
633 		config.removeParameter( ix );
634 
635 		RestParameterConfig propertyConfig = null;
636 
637 		if( targetIndex < properties.size() )
638 		{
639 			properties.add( targetIndex, properties.remove( ix ) );
640 			propertyConfig = config.insertNewParameter( targetIndex );
641 		}
642 		else
643 		{
644 			properties.add( properties.remove( ix ) );
645 			propertyConfig = config.addNewParameter();
646 		}
647 
648 		propertyConfig.setName( propertyName );
649 		propertyConfig.setValue( value );
650 
651 		resetPropertiesConfig( config );
652 
653 		if( targetIndex > properties.size() )
654 			targetIndex = properties.size();
655 
656 		firePropertyMoved( propertyName, ix, targetIndex );
657 	}
658 
659 	public void clear()
660 	{
661 		while( size() > 0 )
662 			removeProperty( getPropertyAt( 0 ).getName() );
663 	}
664 
665 	public boolean containsKey( Object key )
666 	{
667 		return hasProperty( ( String )key );
668 	}
669 
670 	public boolean containsValue( Object value )
671 	{
672 		return propertyMap.containsValue( value );
673 	}
674 
675 	public Set<java.util.Map.Entry<String, TestProperty>> entrySet()
676 	{
677 		HashSet<java.util.Map.Entry<String, TestProperty>> result = new HashSet<Entry<String, TestProperty>>();
678 
679 		for( TestProperty p : propertyMap.values() )
680 		{
681 			// This does not compile on JDK 1.5:
682 			// result.add( new java.util.HashMap.SimpleEntry<String,
683 			// TestProperty>(p.getName(), p));
684 			result.add( new HashMapEntry<String, TestProperty>( p.getName(), p ) );
685 		}
686 
687 		return result;
688 	}
689 
690 	private static class HashMapEntry<K, V> implements java.util.Map.Entry<K, V>
691 	{
692 		private K key;
693 		private V value;
694 
695 		public HashMapEntry( K key, V value )
696 		{
697 			this.key = key;
698 			this.value = value;
699 		}
700 
701 		public K getKey()
702 		{
703 			return key;
704 		}
705 
706 		public V getValue()
707 		{
708 			return value;
709 		}
710 
711 		public V setValue( V value )
712 		{
713 			throw new UnsupportedOperationException();
714 		}
715 	}
716 
717 	public RestParamProperty get( Object key )
718 	{
719 		return getProperty( ( String )key );
720 	}
721 
722 	public boolean isEmpty()
723 	{
724 		return propertyMap.isEmpty();
725 	}
726 
727 	public Set<String> keySet()
728 	{
729 		return new HashSet<String>( Arrays.asList( getPropertyNames() ) );
730 	}
731 
732 	public TestProperty put( String key, TestProperty value )
733 	{
734 		TestProperty result = addProperty( key );
735 		result.setValue( value.getValue() );
736 		return result;
737 	}
738 
739 	public void putAll( Map<? extends String, ? extends TestProperty> m )
740 	{
741 		for( TestProperty p : m.values() )
742 		{
743 			addProperty( p.getName() ).setValue( p.getValue() );
744 		}
745 	}
746 
747 	public TestProperty remove( Object key )
748 	{
749 		return removeProperty( ( String )key );
750 	}
751 
752 	public int size()
753 	{
754 		return propertyMap.size();
755 	}
756 
757 	public Collection<TestProperty> values()
758 	{
759 		ArrayList<TestProperty> result = new ArrayList<TestProperty>();
760 		result.addAll( propertyMap.values() );
761 		return result;
762 	}
763 
764 	public String getPropertiesLabel()
765 	{
766 		return propertiesLabel;
767 	}
768 
769 	public void setPropertiesLabel( String propertiesLabel )
770 	{
771 		this.propertiesLabel = propertiesLabel;
772 	}
773 
774 	public XmlObject getConfig()
775 	{
776 		return config;
777 	}
778 
779 	public void addParameters( RestParamsPropertyHolder params )
780 	{
781 		for( int c = 0; c < params.getPropertyCount(); c++ )
782 		{
783 			RestParamProperty property = params.getPropertyAt( c );
784 			if( !hasProperty( property.getName() ) )
785 			{
786 				addParameter( property );
787 			}
788 		}
789 	}
790 
791 	public void addParameter( RestParamProperty property )
792 	{
793 		RestParamProperty prop = addProperty( property.getName() );
794 		prop.setStyle( property.getStyle() );
795 		prop.setValue( property.getValue() );
796 		prop.setType( property.getType() );
797 		prop.setDefaultValue( property.getDefaultValue() );
798 		prop.setDescription( property.getDescription() );
799 		prop.setOptions( property.getOptions() );
800 		prop.setRequired( property.getRequired() );
801 	}
802 
803 	public void release()
804 	{
805 	}
806 
807 	public RestParamProperty addProperty( XmlBeansRestParamProperty prop )
808 	{
809 		RestParameterConfig propertyConfig = ( RestParameterConfig )config.addNewParameter().set( prop.getConfig() );
810 		return addProperty( propertyConfig, true );
811 	}
812 }