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.submit.filters;
14  
15  import com.eviware.soapui.impl.rest.RestRequest;
16  import com.eviware.soapui.impl.rest.support.XmlBeansRestParamsTestPropertyHolder;
17  import com.eviware.soapui.impl.rest.support.XmlBeansRestParamsTestPropertyHolder.RestParamProperty;
18  import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
19  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.AttachmentUtils;
20  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.RestRequestDataSource;
21  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.RestRequestMimeMessageRequestEntity;
22  import com.eviware.soapui.impl.wsdl.support.PathUtils;
23  import com.eviware.soapui.model.iface.Attachment;
24  import com.eviware.soapui.model.iface.SubmitContext;
25  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
26  import com.eviware.soapui.support.StringUtils;
27  import com.eviware.soapui.support.types.StringToStringMap;
28  import org.apache.commons.httpclient.HttpMethod;
29  import org.apache.commons.httpclient.URI;
30  import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
31  import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
32  import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
33  import org.apache.commons.httpclient.methods.StringRequestEntity;
34  import org.apache.xmlbeans.XmlBoolean;
35  
36  import javax.activation.DataHandler;
37  import javax.mail.MessagingException;
38  import javax.mail.internet.MimeBodyPart;
39  import javax.mail.internet.MimeMessage;
40  import javax.mail.internet.MimeMultipart;
41  import javax.mail.internet.PreencodedMimeBodyPart;
42  import java.io.UnsupportedEncodingException;
43  import java.net.URLEncoder;
44  import java.util.ArrayList;
45  import java.util.List;
46  
47  /***
48   * RequestFilter that adds SOAP specific headers
49   *
50   * @author Ole.Matzura
51   */
52  
53  public class RestRequestFilter extends AbstractRequestFilter
54  {
55     @SuppressWarnings( "deprecation" )
56     @Override
57     public void filterRestRequest( SubmitContext context, RestRequest request )
58     {
59        HttpMethod httpMethod = (HttpMethod) context.getProperty( BaseHttpRequestTransport.HTTP_METHOD );
60  
61        String path = request.getPath();
62        StringBuffer query = new StringBuffer();
63  
64        XmlBeansRestParamsTestPropertyHolder params = request.getParams();
65        for( int c = 0; c < params.getPropertyCount(); c++ )
66        {
67           RestParamProperty param = params.getPropertyAt( c );
68  
69           String value = PropertyExpansionUtils.expandProperties( context, param.getValue() );
70           if( !StringUtils.hasContent( value ) && !param.getRequired() )
71              continue;
72  
73           switch( param.getStyle() )
74           {
75              case HEADER:
76                 httpMethod.setRequestHeader( param.getName(), value );
77                 break;
78              case QUERY:
79                 if( query.length() > 0 )
80                    query.append( '&' );
81  
82                 query.append( URLEncoder.encode( param.getName() ) );
83                 if( StringUtils.hasContent( value ) )
84                    query.append( '=' ).append( URLEncoder.encode( value ) );
85                 break;
86              case TEMPLATE:
87                 path = path.replaceAll( "//{" + param.getName() + "//}", URLEncoder.encode( value ) );
88                 break;
89              case MATRIX:
90                 if( param.getType().equals( XmlBoolean.type.getName() ) )
91                 {
92                    if( value.toUpperCase().equals( "TRUE" ) || value.equals( "1" ) )
93                    {
94                       path += ";" + param.getName();
95                    }
96                 }
97                 else
98                 {
99                    path += ";" + param.getName();
100                   if( StringUtils.hasContent( value ) )
101                   {
102                      path += "=" + URLEncoder.encode( value );
103                   }
104                }
105          }
106       }
107 
108       if( query.length() > 0 && !request.isPostQueryString() )
109       {
110          httpMethod.setQueryString( query.toString() );
111       }
112 
113       if( PathUtils.isHttpPath( path ) )
114       {
115          try
116          {
117             httpMethod.setURI( new URI( path ) );
118          }
119          catch( Exception e )
120          {
121             e.printStackTrace();
122          }
123       }
124       else
125       {
126          httpMethod.setPath( path );
127       }
128 
129       String acceptEncoding = request.getAccept();
130       if( StringUtils.hasContent( acceptEncoding ) )
131       {
132          httpMethod.setRequestHeader( "Accept", acceptEncoding );
133       }
134 
135       String encoding = StringUtils.unquote( request.getEncoding() );
136 
137       if( request.hasRequestBody() && httpMethod instanceof EntityEnclosingMethod )
138       {
139          httpMethod.setRequestHeader( "Content-Type", request.getMediaType() );
140 
141          if( request.isPostQueryString() )
142          {
143             ( (EntityEnclosingMethod) httpMethod ).setRequestEntity( new StringRequestEntity( query.toString() ) );
144          }
145          else
146          {
147             String requestContent = request.getRequestContent();
148             List<Attachment> attachments = new ArrayList<Attachment>();
149 
150             for( Attachment attachment : request.getAttachments() )
151             {
152                if( attachment.getContentType().equals( request.getMediaType() ) )
153                {
154                   attachments.add( attachment );
155                }
156             }
157 
158             if( StringUtils.hasContent( requestContent ) && attachments.isEmpty() )
159             {
160                try
161                {
162                   byte[] content = encoding == null ? requestContent.getBytes() : requestContent.getBytes( encoding );
163                   ( (EntityEnclosingMethod) httpMethod ).setRequestEntity( new ByteArrayRequestEntity( content ) );
164                }
165                catch( UnsupportedEncodingException e )
166                {
167                   ( (EntityEnclosingMethod) httpMethod ).setRequestEntity( new ByteArrayRequestEntity( requestContent.getBytes() ) );
168                }
169             }
170             else if( attachments.size() > 0 )
171             {
172                try
173                {
174                   MimeMultipart mp = null;
175 
176                   if( StringUtils.hasContent( requestContent ) )
177                   {
178                      mp = new MimeMultipart();
179                      initRootPart( request, requestContent, mp );
180                   }
181                   else if( attachments.size() == 1 )
182                   {
183                      ( (EntityEnclosingMethod) httpMethod ).setRequestEntity( new InputStreamRequestEntity(
184                              attachments.get( 0 ).getInputStream() ) );
185 
186                      httpMethod.setRequestHeader( "Content-Type", request.getMediaType() );
187                   }
188 
189                   if( ( (EntityEnclosingMethod) httpMethod ).getRequestEntity() == null )
190                   {
191                      if( mp == null )
192                         mp = new MimeMultipart();
193 
194                      // init mimeparts
195                      AttachmentUtils.addMimeParts( request, attachments, mp, new StringToStringMap() );
196 
197                      // create request message
198                      MimeMessage message = new MimeMessage( AttachmentUtils.JAVAMAIL_SESSION );
199                      message.setContent( mp );
200                      message.saveChanges();
201                      RestRequestMimeMessageRequestEntity mimeMessageRequestEntity = new RestRequestMimeMessageRequestEntity( message, request );
202                      ( (EntityEnclosingMethod) httpMethod ).setRequestEntity( mimeMessageRequestEntity );
203                      httpMethod.setRequestHeader( "Content-Type", mimeMessageRequestEntity.getContentType() );
204                      httpMethod.setRequestHeader( "MIME-Version", "1.0" );
205                   }
206                }
207                catch( Exception e )
208                {
209                   e.printStackTrace();
210                }
211             }
212          }
213       }
214    }
215 
216    protected void initRootPart( RestRequest wsdlRequest, String requestContent, MimeMultipart mp ) throws MessagingException
217    {
218       MimeBodyPart rootPart = new PreencodedMimeBodyPart( "8bit" );
219       rootPart.setContentID( AttachmentUtils.ROOTPART_SOAPUI_ORG );
220       mp.addBodyPart( rootPart, 0 );
221 
222       DataHandler dataHandler = new DataHandler( new RestRequestDataSource( wsdlRequest, requestContent ) );
223       rootPart.setDataHandler( dataHandler );
224    }
225 }