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.support;
14  
15  import com.eviware.soapui.SoapUI;
16  import com.eviware.soapui.config.AbstractRequestConfig;
17  import com.eviware.soapui.config.AttachmentConfig;
18  import com.eviware.soapui.config.CredentialsConfig;
19  import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
20  import com.eviware.soapui.impl.wsdl.HttpAttachmentPart;
21  import com.eviware.soapui.impl.wsdl.MutableAttachmentContainer;
22  import com.eviware.soapui.impl.wsdl.WsdlRequest;
23  import com.eviware.soapui.impl.wsdl.submit.transports.http.HttpResponse;
24  import com.eviware.soapui.impl.wsdl.support.CompressedStringSupport;
25  import com.eviware.soapui.impl.wsdl.support.FileAttachment;
26  import com.eviware.soapui.impl.wsdl.support.ModelItemIconAnimator;
27  import com.eviware.soapui.impl.wsdl.support.RequestFileAttachment;
28  import com.eviware.soapui.impl.wsdl.teststeps.SettingPathPropertySupport;
29  import com.eviware.soapui.model.iface.*;
30  import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
31  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContainer;
32  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
33  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionsResult;
34  import com.eviware.soapui.settings.WsdlSettings;
35  import com.eviware.soapui.support.StringUtils;
36  import com.eviware.soapui.support.UISupport;
37  import com.eviware.soapui.support.resolver.ResolveContext;
38  import com.eviware.soapui.support.types.StringToStringMap;
39  import org.apache.log4j.Logger;
40  
41  import javax.swing.*;
42  import java.beans.PropertyChangeListener;
43  import java.io.File;
44  import java.io.IOException;
45  import java.util.ArrayList;
46  import java.util.HashSet;
47  import java.util.List;
48  import java.util.Set;
49  
50  public abstract class AbstractHttpRequest<T extends AbstractRequestConfig> extends AbstractWsdlModelItem<T> implements Request,
51          PropertyExpansionContainer, MutableAttachmentContainer
52  {
53     public final static Logger log = Logger.getLogger( AbstractHttpRequest.class );
54  
55     public static final String RESPONSE_PROPERTY = WsdlRequest.class.getName() + "@response";
56     public static final String REMOVE_EMPTY_CONTENT = WsdlRequest.class.getName() + "@remove_empty_content";
57     public static final String STRIP_WHITESPACES = WsdlRequest.class.getName() + "@strip-whitespaces";
58     public static final String REQUEST_HEADERS_PROPERTY = WsdlRequest.class.getName() + "@request-headers";
59     public static final String BIND_ADDRESS = WsdlRequest.class.getName() + "@bind_address";
60     public static final String DISABLE_MULTIPART_ATTACHMENTS = WsdlRequest.class.getName() + "@disable-multipart-attachments";
61     public static final String DUMP_FILE = AbstractHttpRequest.class.getName() + "@dump-file";
62     public static final String MAX_SIZE = AbstractHttpRequest.class.getName() + "@max-size";
63     ;
64  
65     public enum RequestMethod
66     {
67        GET, POST, PUT, DELETE, HEAD;
68  
69        public static String[] getMethodsAsString()
70        {
71           return new String[] {};
72        }
73     }
74  
75     private Set<SubmitListener> submitListeners = new HashSet<SubmitListener>();
76     private String requestContent;
77     private RequestIconAnimator<?> iconAnimator;
78     private HttpResponse response;
79     private SettingPathPropertySupport dumpFile;
80     private List<FileAttachment<?>> attachments = new ArrayList<FileAttachment<?>>();
81  
82     protected AbstractHttpRequest( T config, AbstractHttpOperation parent, String icon, boolean forLoadTest )
83     {
84        super( config, parent, icon );
85  
86        if( !forLoadTest && !UISupport.isHeadless() )
87        {
88           iconAnimator = initIconAnimator();
89           addSubmitListener( iconAnimator );
90        }
91  
92        initAttachments();
93  
94        dumpFile = new SettingPathPropertySupport( this, DUMP_FILE );
95     }
96  
97     private void initAttachments()
98     {
99        for( AttachmentConfig ac : getConfig().getAttachmentList() )
100       {
101          RequestFileAttachment attachment = new RequestFileAttachment( ac, this );
102          attachments.add( attachment );
103       }
104    }
105 
106    protected List<FileAttachment<?>> getAttachmentsList()
107    {
108       return attachments;
109    }
110 
111    /* (non-Javadoc)
112 	 * @see com.eviware.soapui.impl.wsdl.AttachmentContainer#attachFile(java.io.File, boolean)
113 	 */
114    
115    public Attachment attachFile( File file, boolean cache ) throws IOException
116    {
117       RequestFileAttachment fileAttachment = new RequestFileAttachment( file, cache, this );
118       attachments.add( fileAttachment );
119       notifyPropertyChanged( ATTACHMENTS_PROPERTY, null, fileAttachment );
120       return fileAttachment;
121    }
122 
123    public abstract RequestMethod getMethod();
124 
125    /***
126     * Override just to get a better return type
127     *
128     * @see com.eviware.soapui.impl.wsdl.AttachmentContainer#getAttachmentPart(java.lang.String)
129     */
130 
131    public abstract HttpAttachmentPart getAttachmentPart( String partName );
132 
133    /* (non-Javadoc)
134      * @see com.eviware.soapui.impl.wsdl.AttachmentContainer#getAttachmentCount()
135      */
136    public int getAttachmentCount()
137    {
138       return attachments.size();
139    }
140 
141    /* (non-Javadoc)
142      * @see com.eviware.soapui.impl.wsdl.AttachmentContainer#getAttachmentAt(int)
143      */
144    public Attachment getAttachmentAt( int index )
145    {
146       return attachments.get( index );
147    }
148 
149    /* (non-Javadoc)
150      * @see com.eviware.soapui.impl.wsdl.AttachmentContainer#getAttachmentsForPart(java.lang.String)
151      */
152    public Attachment[] getAttachmentsForPart( String partName )
153    {
154       List<Attachment> result = new ArrayList<Attachment>();
155 
156       for( Attachment attachment : attachments )
157       {
158          if( partName.equals( attachment.getPart()) )
159             result.add( attachment );
160       }
161 
162       return result.toArray( new Attachment[result.size()] );
163    }
164 
165    /* (non-Javadoc)
166      * @see com.eviware.soapui.impl.wsdl.AttachmentContainer#removeAttachment(com.eviware.soapui.model.iface.Attachment)
167      */
168    public void removeAttachment( Attachment attachment )
169    {
170       int ix = attachments.indexOf( attachment );
171       attachments.remove( ix );
172 
173       try
174       {
175          notifyPropertyChanged( ATTACHMENTS_PROPERTY, attachment, null );
176       }
177       finally
178       {
179          getConfig().removeAttachment( ix );
180       }
181    }
182 
183    /* (non-Javadoc)
184      * @see com.eviware.soapui.impl.wsdl.AttachmentContainer#getAttachments()
185      */
186    public Attachment[] getAttachments()
187    {
188       return attachments.toArray( new Attachment[attachments.size()] );
189    }
190 
191    protected RequestIconAnimator<?> initIconAnimator()
192    {
193       return new RequestIconAnimator<AbstractHttpRequest<?>>( this, "/request.gif", "/exec_request", 4, "gif" );
194    }
195 
196    public void addSubmitListener( SubmitListener listener )
197    {
198       submitListeners.add( listener );
199    }
200 
201    public void removeSubmitListener( SubmitListener listener )
202    {
203       submitListeners.remove( listener );
204    }
205 
206    public boolean isMultipartEnabled()
207    {
208       return !getSettings().getBoolean( DISABLE_MULTIPART_ATTACHMENTS );
209    }
210 
211    public void setMultipartEnabled( boolean multipartEnabled )
212    {
213       getSettings().setBoolean( DISABLE_MULTIPART_ATTACHMENTS, !multipartEnabled );
214    }
215 
216    @Override
217    public void release()
218    {
219       submitListeners.clear();
220 
221       super.release();
222    }
223 
224    public SubmitListener[] getSubmitListeners()
225    {
226       return submitListeners.toArray( new SubmitListener[submitListeners.size()] );
227    }
228 
229    public AbstractHttpOperation getOperation()
230    {
231       return (AbstractHttpOperation) getParent();
232    }
233 
234    public void copyAttachmentsTo( WsdlRequest newRequest )
235    {
236       if( getAttachmentCount() > 0 )
237       {
238          try
239          {
240             UISupport.setHourglassCursor();
241             for( int c = 0; c < getAttachmentCount(); c++ )
242             {
243                try
244                {
245                   Attachment attachment = getAttachmentAt( c );
246                   newRequest.importAttachment( attachment );
247                }
248                catch( Exception e )
249                {
250                   SoapUI.logError( e );
251                }
252             }
253          }
254          finally
255          {
256             UISupport.resetCursor();
257          }
258       }
259    }
260 
261    public Attachment importAttachment( Attachment attachment )
262    {
263       if( attachment instanceof FileAttachment )
264       {
265          AttachmentConfig oldConfig = ( (FileAttachment<?>) attachment ).getConfig();
266          AttachmentConfig newConfig = (AttachmentConfig) getConfig().addNewAttachment().set( oldConfig );
267          RequestFileAttachment newAttachment = new RequestFileAttachment( newConfig, this );
268          attachments.add( newAttachment );
269          return newAttachment;
270       }
271       else log.error( "Unkown attachment type: " + attachment );
272 
273       return null;
274    }
275 
276    public void addAttachmentsChangeListener( PropertyChangeListener listener )
277    {
278       addPropertyChangeListener( ATTACHMENTS_PROPERTY, listener );
279    }
280 
281    public boolean isReadOnly()
282    {
283       return false;
284    }
285 
286    public void removeAttachmentsChangeListener( PropertyChangeListener listener )
287    {
288       removePropertyChangeListener( ATTACHMENTS_PROPERTY, listener );
289    }
290 
291    public String getRequestContent()
292    {
293       if( getConfig().getRequest() == null )
294          getConfig().addNewRequest();
295 
296       if( requestContent == null )
297          requestContent = CompressedStringSupport.getString( getConfig().getRequest() );
298 
299       return requestContent;
300    }
301 
302    public void setRequestContent( String request )
303    {
304       String old = getRequestContent();
305 
306       if( StringUtils.isNullOrEmpty( request ) && StringUtils.isNullOrEmpty( old ) ||
307               ( request != null && request.equals( old ) ) )
308          return;
309 
310       requestContent = request;
311       notifyPropertyChanged( REQUEST_PROPERTY, old, request );
312    }
313 
314    public boolean isPrettyPrint()
315    {
316       return getSettings().getBoolean( WsdlSettings.PRETTY_PRINT_RESPONSE_MESSAGES );
317    }
318 
319    public void setPrettyPrint( boolean prettyPrint )
320    {
321       boolean old = getSettings().getBoolean( WsdlSettings.PRETTY_PRINT_RESPONSE_MESSAGES );
322       getSettings().setBoolean( WsdlSettings.PRETTY_PRINT_RESPONSE_MESSAGES, prettyPrint );
323       notifyPropertyChanged( WsdlSettings.PRETTY_PRINT_RESPONSE_MESSAGES, old, prettyPrint );
324    }
325 
326    public void setEndpoint( String endpoint )
327    {
328       String old = getEndpoint();
329       if( old != null && old.equals( endpoint ) )
330          return;
331 
332       getConfig().setEndpoint( endpoint );
333       notifyPropertyChanged( ENDPOINT_PROPERTY, old, endpoint );
334    }
335 
336    public String getEndpoint()
337    {
338       return getConfig().getEndpoint();
339    }
340 
341    public String getEncoding()
342    {
343       return getConfig().getEncoding();
344    }
345 
346    public void setEncoding( String encoding )
347    {
348       String old = getEncoding();
349       getConfig().setEncoding( encoding );
350       notifyPropertyChanged( ENCODING_PROPERTY, old, encoding );
351    }
352 
353    public StringToStringMap getRequestHeaders()
354    {
355       return StringToStringMap.fromXml( getSettings().getString( REQUEST_HEADERS_PROPERTY, null ) );
356    }
357 
358    public RequestIconAnimator<?> getIconAnimator()
359    {
360       return iconAnimator;
361    }
362 
363    public void setRequestHeaders( StringToStringMap map )
364    {
365       StringToStringMap old = getRequestHeaders();
366       getSettings().setString( REQUEST_HEADERS_PROPERTY, map.toXml() );
367       notifyPropertyChanged( REQUEST_HEADERS_PROPERTY, old, map );
368    }
369 
370    @Override
371    public ImageIcon getIcon()
372    {
373       return iconAnimator == null ? null : iconAnimator.getIcon();
374    }
375 
376    public PropertyExpansion[] getPropertyExpansions()
377    {
378       PropertyExpansionsResult result = new PropertyExpansionsResult( this, this );
379 
380       result.addAll( PropertyExpansionUtils.extractPropertyExpansions( this, this, "requestContent" ) );
381       result.addAll( PropertyExpansionUtils.extractPropertyExpansions( this, this, "endpoint" ) );
382       result.addAll( PropertyExpansionUtils.extractPropertyExpansions( this, this, "username" ) );
383       result.addAll( PropertyExpansionUtils.extractPropertyExpansions( this, this, "password" ) );
384       result.addAll( PropertyExpansionUtils.extractPropertyExpansions( this, this, "domain" ) );
385 
386       return result.toArray();
387    }
388 
389    public String getUsername()
390    {
391       CredentialsConfig credentialsConfig = getConfig().getCredentials();
392       if( credentialsConfig == null )
393          return null;
394 
395       return credentialsConfig.getUsername();
396    }
397 
398    public String getPassword()
399    {
400       CredentialsConfig credentialsConfig = getConfig().getCredentials();
401       if( credentialsConfig == null )
402          return null;
403 
404       return credentialsConfig.getPassword();
405    }
406 
407    public String getDomain()
408    {
409       CredentialsConfig credentialsConfig = getConfig().getCredentials();
410       if( credentialsConfig == null )
411          return null;
412 
413       return credentialsConfig.getDomain();
414    }
415 
416    public void setUsername( String username )
417    {
418       String old = getUsername();
419       CredentialsConfig credentialsConfig = getConfig().getCredentials();
420       if( credentialsConfig == null )
421          credentialsConfig = getConfig().addNewCredentials();
422 
423       credentialsConfig.setUsername( username );
424       notifyPropertyChanged( "username", old, username );
425    }
426 
427    public void setPassword( String password )
428    {
429       String old = getPassword();
430       CredentialsConfig credentialsConfig = getConfig().getCredentials();
431       if( credentialsConfig == null )
432          credentialsConfig = getConfig().addNewCredentials();
433 
434       credentialsConfig.setPassword( password );
435       notifyPropertyChanged( "password", old, password );
436    }
437 
438    public void setDomain( String domain )
439    {
440       String old = getDomain();
441       CredentialsConfig credentialsConfig = getConfig().getCredentials();
442       if( credentialsConfig == null )
443          credentialsConfig = getConfig().addNewCredentials();
444 
445       credentialsConfig.setDomain( domain );
446       notifyPropertyChanged( "domain", old, domain );
447    }
448 
449    public String getSslKeystore()
450    {
451       return getConfig().getSslKeystore();
452    }
453 
454    public void setSslKeystore( String sslKeystore )
455    {
456       String old = getSslKeystore();
457       getConfig().setSslKeystore( sslKeystore );
458       notifyPropertyChanged( "sslKeystore", old, sslKeystore );
459    }
460 
461    public String getBindAddress()
462    {
463       return getSettings().getString( BIND_ADDRESS, "" );
464    }
465 
466    public void setBindAddress( String bindAddress )
467    {
468       String old = getSettings().getString( BIND_ADDRESS, "" );
469       getSettings().setString( BIND_ADDRESS, bindAddress );
470       notifyPropertyChanged( BIND_ADDRESS, old, bindAddress );
471    }
472 
473    public long getMaxSize()
474    {
475       return getSettings().getLong( MAX_SIZE, 0 );
476    }
477 
478    public void setMaxSize( long maxSize )
479    {
480       long old = getSettings().getLong( MAX_SIZE, 0 );
481       getSettings().setLong( MAX_SIZE, maxSize );
482       notifyPropertyChanged( MAX_SIZE, old, maxSize );
483    }
484 
485    public String getDumpFile()
486    {
487       return dumpFile.expand();
488    }
489 
490    public void setDumpFile( String df )
491    {
492       String old = getDumpFile();
493       dumpFile.set( df, false );
494       notifyPropertyChanged( DUMP_FILE, old, getDumpFile() );
495    }
496 
497    public boolean isRemoveEmptyContent()
498    {
499       return getSettings().getBoolean( REMOVE_EMPTY_CONTENT );
500    }
501 
502    public void setRemoveEmptyContent( boolean removeEmptyContent )
503    {
504       boolean old = getSettings().getBoolean( REMOVE_EMPTY_CONTENT );
505       getSettings().setBoolean( REMOVE_EMPTY_CONTENT, removeEmptyContent );
506       notifyPropertyChanged( REMOVE_EMPTY_CONTENT, old, removeEmptyContent );
507    }
508 
509    public boolean isStripWhitespaces()
510    {
511       return getSettings().getBoolean( STRIP_WHITESPACES );
512    }
513 
514    public void setStripWhitespaces( boolean stripWhitespaces )
515    {
516       boolean old = getSettings().getBoolean( STRIP_WHITESPACES );
517       getSettings().setBoolean( STRIP_WHITESPACES, stripWhitespaces );
518       notifyPropertyChanged( STRIP_WHITESPACES, old, stripWhitespaces );
519    }
520 
521    @Override
522    public void beforeSave()
523    {
524       if( requestContent != null )
525       {
526          if( getConfig().getRequest() == null )
527             getConfig().addNewRequest();
528 
529          CompressedStringSupport.setString( getConfig().getRequest(), requestContent );
530          requestContent = null;
531       }
532    }
533 
534    public static class RequestIconAnimator<T extends AbstractHttpRequest<?>> extends ModelItemIconAnimator<T> implements SubmitListener
535    {
536       public RequestIconAnimator( T modelItem, String baseIcon, String animIconRoot, int iconCount, String iconExtension )
537       {
538          super( modelItem, baseIcon, animIconRoot, iconCount, iconExtension );
539       }
540 
541       public boolean beforeSubmit( Submit submit, SubmitContext context )
542       {
543          if( isEnabled() && submit.getRequest() == getTarget() )
544             start();
545          return true;
546       }
547 
548       public void afterSubmit( Submit submit, SubmitContext context )
549       {
550          if( submit.getRequest() == getTarget() )
551             stop();
552       }
553    }
554 
555    public void setIconAnimator( RequestIconAnimator<?> iconAnimator )
556    {
557       if( this.iconAnimator != null )
558          removeSubmitListener( this.iconAnimator );
559 
560       this.iconAnimator = iconAnimator;
561       addSubmitListener( this.iconAnimator );
562    }
563 
564    public HttpResponse getResponse()
565    {
566       return response;
567    }
568 
569    public void setResponse( HttpResponse response, SubmitContext context )
570    {
571       HttpResponse oldResponse = getResponse();
572       this.response = response;
573 
574       notifyPropertyChanged( RESPONSE_PROPERTY, oldResponse, response );
575    }
576 
577    @Override
578    public void resolve( ResolveContext context )
579    {
580       super.resolve( context );
581 
582       for( FileAttachment<?> attachment : attachments )
583          attachment.resolve( context );
584    }
585 
586    public boolean hasEndpoint()
587    {
588       return StringUtils.hasContent( getEndpoint() );
589    }
590 }