View Javadoc

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