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