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          propertyConfig.setDescription( description );
296       }
297 
298       public ParameterStyle getStyle()
299       {
300          if( propertyConfig.xgetStyle() == null )
301             propertyConfig.setStyle( RestParameterConfig.Style.QUERY );
302 
303          return ParameterStyle.valueOf( propertyConfig.getStyle().toString() );
304       }
305 
306       public void setStyle( ParameterStyle style )
307       {
308          propertyConfig.setStyle( RestParameterConfig.Style.Enum.forString( style.name() ) );
309       }
310 
311       public String getValue()
312       {
313          if( overrideProperties != null && overrideProperties.containsKey( getName() ) )
314             return overrideProperties.getProperty( getName() );
315 
316          return propertyConfig.getValue();
317       }
318 
319       public void setValue( String value )
320       {
321          String oldValue = getValue();
322          propertyConfig.setValue( value );
323 
324          if( overrideProperties != null && overrideProperties.containsKey( getName() ) )
325          {
326             overrideProperties.remove( getName() );
327             if( overrideProperties.isEmpty() )
328                overrideProperties = null;
329          }
330 
331          firePropertyValueChanged( getName(), oldValue, value );
332       }
333 
334       public boolean isReadOnly()
335       {
336          return false;
337       }
338 
339       public ModelItem getModelItem()
340       {
341          return modelItem;
342       }
343 
344       public String getDefaultValue()
345       {
346          return propertyConfig.isSetDefault() ? propertyConfig.getDefault() : "";
347       }
348 
349       public String[] getOptions()
350       {
351          return propertyConfig.getOptionList().toArray( new String[propertyConfig.sizeOfOptionArray()] );
352       }
353 
354       public boolean getRequired()
355       {
356          return propertyConfig.getRequired();
357       }
358 
359       public boolean isDisableUrlEncoding()
360       {
361          return propertyConfig.getDisableUrlEncoding();
362       }
363 
364       public void setDisableUrlEncoding( boolean encode )
365       {
366          propertyConfig.setDisableUrlEncoding( encode );
367       }
368 
369       public QName getType()
370       {
371          return propertyConfig.isSetType() ? propertyConfig.getType() : XmlString.type.getName();
372       }
373 
374       public void setOptions( String[] arg0 )
375       {
376          propertyConfig.setOptionArray( arg0 );
377       }
378 
379       public void setRequired( boolean arg0 )
380       {
381          propertyConfig.setRequired( arg0 );
382       }
383 
384       public void setType( QName arg0 )
385       {
386          propertyConfig.setType( arg0 );
387       }
388 
389       public void setDefaultValue( String default1 )
390       {
391          propertyConfig.setDefault( default1 );
392       }
393 
394       public RestParameterConfig getConfig()
395       {
396          return propertyConfig;
397       }
398 
399       @Override
400       public boolean equals( Object obj )
401       {
402          if( obj instanceof RestParamProperty )
403          {
404             return propertyConfig.toString().equals( ( (RestParamProperty) obj ).propertyConfig.toString() );
405          }
406 
407          return super.equals( obj );
408       }
409 
410       public void reset()
411       {
412          setValue( getDefaultValue() );
413       }
414    }
415 
416    public void saveTo( Properties props )
417    {
418       int cnt = 0;
419       for( RestParamProperty p : properties )
420       {
421          String name = p.getName();
422          String value = p.getValue();
423          if( value == null )
424             value = "";
425 
426          props.setProperty( name, value );
427          cnt++;
428       }
429    }
430 
431    public int getPropertyCount()
432    {
433       return properties.size();
434    }
435 
436    public RestParamProperty getPropertyAt( int index )
437    {
438       return properties.get( index );
439    }
440 
441    public Map<String, TestProperty> getProperties()
442    {
443       Map<String, TestProperty> result = new HashMap<String, TestProperty>();
444       for( TestProperty property : propertyMap.values() )
445       {
446          result.put( property.getName(), property );
447       }
448 
449       return result;
450    }
451 
452    public boolean hasProperty( String name )
453    {
454       return propertyMap.containsKey( name.toUpperCase() );
455    }
456 
457    public int addPropertiesFromFile( String propFile )
458    {
459       if( !StringUtils.hasContent( propFile ) )
460          return 0;
461 
462       try
463       {
464          InputStream input = null;
465 
466          File file = new File( propFile );
467          if( file.exists() )
468          {
469             input = new FileInputStream( file );
470          }
471          else if( propFile.toLowerCase().startsWith( "http://" ) || propFile.toLowerCase().startsWith( "https://" ) )
472          {
473             UrlWsdlLoader loader = new UrlWsdlLoader( propFile, getModelItem() );
474             loader.setUseWorker( false );
475             input = loader.load();
476          }
477 
478          if( input != null )
479          {
480             if( overrideProperties == null )
481                overrideProperties = new Properties();
482 
483             int sz = overrideProperties.size();
484             overrideProperties.load( input );
485 
486             for( Object key : overrideProperties.keySet() )
487             {
488                String name = key.toString();
489                if( !hasProperty( name ) )
490                   addProperty( name );
491             }
492 
493             return overrideProperties.size() - sz;
494          }
495       }
496       catch( Exception e )
497       {
498          SoapUI.logError( e );
499       }
500 
501       return 0;
502    }
503 
504    public ModelItem getModelItem()
505    {
506       return modelItem;
507    }
508 
509    public PropertyExpansion[] getPropertyExpansions()
510    {
511       List<PropertyExpansion> result = new ArrayList<PropertyExpansion>();
512 
513       return result.toArray( new PropertyExpansion[result.size()] );
514    }
515 
516    public void moveProperty( String propertyName, int targetIndex )
517    {
518       RestParamProperty property = getProperty( propertyName );
519       int ix = properties.indexOf( property );
520 
521       if( ix == targetIndex )
522          return;
523 
524       if( targetIndex < 0 )
525          targetIndex = 0;
526 
527       String value = property.getValue();
528       config.removeParameter( ix );
529 
530       RestParameterConfig propertyConfig = null;
531 
532       if( targetIndex < properties.size() )
533       {
534          properties.add( targetIndex, properties.remove( ix ) );
535          propertyConfig = config.insertNewParameter( targetIndex );
536       }
537       else
538       {
539          properties.add( properties.remove( ix ) );
540          propertyConfig = config.addNewParameter();
541       }
542 
543       propertyConfig.setName( propertyName );
544       propertyConfig.setValue( value );
545 
546       resetPropertiesConfig( config );
547 
548       if( targetIndex > properties.size() )
549          targetIndex = properties.size();
550 
551       firePropertyMoved( propertyName, ix, targetIndex );
552    }
553 
554    public void clear()
555    {
556       while( size() > 0 )
557          removeProperty( getPropertyAt( 0 ).getName() );
558    }
559 
560    public boolean containsKey( Object key )
561    {
562       return hasProperty( (String) key );
563    }
564 
565    public boolean containsValue( Object value )
566    {
567       return propertyMap.containsValue( value );
568    }
569 
570    public Set<java.util.Map.Entry<String, TestProperty>> entrySet()
571    {
572       HashSet<java.util.Map.Entry<String, TestProperty>> result = new HashSet<Entry<String, TestProperty>>();
573 
574       for( TestProperty p : propertyMap.values() )
575       {
576 // This does not compile on JDK 1.5:
577 //			result.add( new java.util.HashMap.SimpleEntry<String, TestProperty>(p.getName(), p));
578          result.add( new HashMapEntry<String, TestProperty>( p.getName(), p ) );
579       }
580 
581       return result;
582    }
583 
584    private static class HashMapEntry<K, V> implements java.util.Map.Entry<K, V>
585    {
586       private K key;
587       private V value;
588 
589       public HashMapEntry( K key, V value )
590       {
591          this.key = key;
592          this.value = value;
593       }
594 
595       public K getKey()
596       {
597          return key;
598       }
599 
600       public V getValue()
601       {
602          return value;
603       }
604 
605       public V setValue( V value )
606       {
607          throw new UnsupportedOperationException();
608       }
609    }
610 
611    public RestParamProperty get( Object key )
612    {
613       return getProperty( (String) key );
614    }
615 
616    public boolean isEmpty()
617    {
618       return propertyMap.isEmpty();
619    }
620 
621    public Set<String> keySet()
622    {
623       return new HashSet<String>( Arrays.asList( getPropertyNames() ) );
624    }
625 
626    public TestProperty put( String key, TestProperty value )
627    {
628       TestProperty result = addProperty( key );
629       result.setValue( value.getValue() );
630       return result;
631    }
632 
633    public void putAll( Map<? extends String, ? extends TestProperty> m )
634    {
635       for( TestProperty p : m.values() )
636       {
637          addProperty( p.getName() ).setValue( p.getValue() );
638       }
639    }
640 
641    public TestProperty remove( Object key )
642    {
643       return removeProperty( (String) key );
644    }
645 
646    public int size()
647    {
648       return propertyMap.size();
649    }
650 
651    public Collection<TestProperty> values()
652    {
653       ArrayList<TestProperty> result = new ArrayList<TestProperty>();
654       result.addAll( propertyMap.values() );
655       return result;
656    }
657 
658    public String getPropertiesLabel()
659    {
660       return propertiesLabel;
661    }
662 
663    public void setPropertiesLabel( String propertiesLabel )
664    {
665       this.propertiesLabel = propertiesLabel;
666    }
667 
668    public XmlObject getConfig()
669    {
670       return config;
671    }
672 
673    public void addParameters( XmlBeansRestParamsTestPropertyHolder params )
674    {
675       for( int c = 0; c < params.getPropertyCount(); c++ )
676       {
677          RestParamProperty property = params.getPropertyAt( c );
678          if( !hasProperty( property.getName() ) )
679          {
680             RestParamProperty prop = addProperty( property.getName() );
681             prop.setStyle( property.getStyle() );
682             prop.setValue( property.getValue() );
683             prop.setType( property.getType() );
684             prop.setDefaultValue( property.getDefaultValue() );
685             prop.setDescription( property.getDescription() );
686             prop.setOptions( property.getOptions() );
687             prop.setRequired( property.getRequired() );
688          }
689       }
690    }
691 
692    public void release()
693    {
694    }
695 
696    public RestParamProperty addProperty( RestParamProperty prop )
697    {
698       RestParameterConfig propertyConfig = (RestParameterConfig) config.addNewParameter().set( prop.getConfig() );
699       return addProperty( propertyConfig, true );
700    }
701 }