View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 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;
14  
15  import java.util.List;
16  import java.util.concurrent.Future;
17  
18  import org.apache.log4j.Logger;
19  
20  import com.eviware.soapui.SoapUI;
21  import com.eviware.soapui.impl.support.AbstractHttpRequestInterface;
22  import com.eviware.soapui.impl.wsdl.submit.RequestTransport;
23  import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
24  import com.eviware.soapui.model.iface.Response;
25  import com.eviware.soapui.model.iface.Submit;
26  import com.eviware.soapui.model.iface.SubmitContext;
27  import com.eviware.soapui.model.iface.SubmitListener;
28  
29  /***
30   * Submit implementation for submitting a WsdlRequest
31   * 
32   * @author Ole.Matzura
33   */
34  
35  public final class WsdlSubmit<T extends AbstractHttpRequestInterface<?>> implements Runnable, Submit
36  {
37  	private final static Logger logger = Logger.getLogger( WsdlSubmit.class );
38  	private T request;
39  	private SubmitListener[] listeners;
40  	private Status status;
41  	private Exception error;
42  	private Response response;
43  	private volatile Future<?> future;
44  	private SubmitContext submitContext;
45  	private RequestTransport transport;
46  
47  	public WsdlSubmit( T wsdlRequest, SubmitListener[] listeners, RequestTransport transport )
48  	{
49  		this.request = wsdlRequest;
50  		this.transport = transport;
51  
52  		List<SubmitListener> regListeners = SoapUI.getListenerRegistry().getListeners( SubmitListener.class );
53  
54  		this.listeners = new SubmitListener[listeners.length + regListeners.size()];
55  		for( int c = 0; c < listeners.length; c++ )
56  			this.listeners[c] = listeners[c];
57  
58  		for( int c = 0; c < regListeners.size(); c++ )
59  			this.listeners[listeners.length + c] = regListeners.get( c );
60  
61  		error = null;
62  		status = Status.INITIALIZED;
63  		future = null;
64  	}
65  
66  	public void submitRequest( SubmitContext submitContext, boolean async )
67  	{
68  		this.submitContext = submitContext;
69  
70  		if( async && future != null )
71  			throw new RuntimeException( "Submit already running" );
72  
73  		if( async )
74  			future = SoapUI.getThreadPool().submit( this );
75  		else
76  			run();
77  	}
78  
79  	public void cancel()
80  	{
81  		if( status == Status.CANCELED )
82  			return;
83  
84  		logger.info( "Canceling request.." );
85  		if( status == Status.RUNNING )
86  		{
87  			transport.abortRequest( submitContext );
88  		}
89  
90  		status = Status.CANCELED;
91  
92  		for( int i = 0; i < listeners.length; i++ )
93  		{
94  			try
95  			{
96  				listeners[i].afterSubmit( this, submitContext );
97  			}
98  			catch( Throwable e )
99  			{
100 				SoapUI.logError( e );
101 			}
102 		}
103 	}
104 
105 	public void run()
106 	{
107 		try
108 		{
109 			submitContext.setProperty( RequestTransport.REQUEST_TRANSPORT, transport );
110 			submitContext.setProperty( RequestTransport.WSDL_REQUEST, request );
111 
112 			for( int i = 0; i < listeners.length; i++ )
113 			{
114 				if( !listeners[i].beforeSubmit( this, submitContext ) )
115 				{
116 					status = Status.CANCELED;
117 					System.err.println( "listener cancelled submit.." );
118 					return;
119 				}
120 			}
121 
122 			status = Status.RUNNING;
123 			response = transport.sendRequest( submitContext, request );
124 
125 			if( status != Status.CANCELED )
126 			{
127 				status = Status.FINISHED;
128 			}
129 
130 			if( response.getTimeTaken() == 0 )
131 			{
132 				logger.warn( "Request took 0 in thread " + Thread.currentThread().getId() + ", response length = "
133 						+ response.getContentLength() );
134 			}
135 		}
136 		catch( Exception e1 )
137 		{
138 			error = e1;
139 			status = Status.ERROR;
140 			logger.error( "Exception in request: " + e1 );
141 			SoapUI.logError( e1 );
142 			if( response == null )
143 				response = ( Response )submitContext.getProperty( BaseHttpRequestTransport.RESPONSE );
144 		}
145 		finally
146 		{
147 			if( status != Status.CANCELED )
148 			{
149 				for( int i = 0; i < listeners.length; i++ )
150 				{
151 					try
152 					{
153 						listeners[i].afterSubmit( this, submitContext );
154 					}
155 					catch( Throwable e )
156 					{
157 						SoapUI.logError( e );
158 					}
159 				}
160 			}
161 		}
162 	}
163 
164 	public T getRequest()
165 	{
166 		return request;
167 	}
168 
169 	public Status getStatus()
170 	{
171 		return status;
172 	}
173 
174 	public Exception getError()
175 	{
176 		return error;
177 	}
178 
179 	public synchronized Status waitUntilFinished()
180 	{
181 		if( future != null )
182 		{
183 			if( !future.isDone() )
184 			{
185 				try
186 				{
187 					future.get();
188 				}
189 				catch( Exception e )
190 				{
191 					SoapUI.logError( e );
192 				}
193 			}
194 		}
195 		else
196 			throw new RuntimeException( "cannot wait on null future" );
197 
198 		return getStatus();
199 	}
200 
201 	public Response getResponse()
202 	{
203 		return response;
204 	}
205 }