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