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