View Javadoc

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