Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/meterware/httpunit/WebWindow.java


1   package com.meterware.httpunit;
2   /********************************************************************************************************************
3    * $Id: WebWindow.java,v 1.19 2004/06/30 23:54:49 russgold Exp $
4    *
5    * Copyright (c) 2002-2004, Russell Gold
6    *
7    * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
8    * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
9    * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
10   * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
11   *
12   * The above copyright notice and this permission notice shall be included in all copies or substantial portions
13   * of the Software.
14   *
15   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
16   * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
18   * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19   * DEALINGS IN THE SOFTWARE.
20   *
21   *******************************************************************************************************************/
22  import java.io.IOException;
23  import java.net.HttpURLConnection;
24  import java.net.MalformedURLException;
25  import java.util.List;
26  
27  import org.xml.sax.SAXException;
28  
29  /**
30   * A window managed by a {@link com.meterware.httpunit.WebClient WebClient}.
31   *
32   * @author <a href="mailto:russgold@httpunit.org">Russell Gold</a>
33   **/
34  public class WebWindow {
35  
36      /** The client which created this window. **/
37      private WebClient _client;
38  
39      /** A map of frame names to current contents. **/
40      private FrameHolder _frameContents;
41  
42      /** The name of the window, set via JavaScript. **/
43      private String _name = "";
44  
45      /** The web response containing the reference that opened this window **/
46      private WebResponse _opener;
47  
48      /** True if this window has been closed. **/
49      private boolean _closed;
50  
51  
52      static final String NO_NAME = "$$HttpUnit_Window$$_";
53  
54  
55      /**
56       * Returns the web client associated with this window.
57       */
58      public WebClient getClient() {
59          return _client;
60      }
61  
62  
63      /**
64       * Returns true if this window has been closed.
65       */
66      public boolean isClosed() {
67          return _closed;
68      }
69  
70  
71      /**
72       * Closes this window.
73       */
74      public void close() {
75          if (!_closed) _client.close( this );
76          _closed = true;
77      }
78  
79  
80      /**
81       * Returns the name of this window. Windows created through normal HTML or browser commands have empty names,
82       * but JavaScript can set the name. A name may be used as a target for a request.
83       */
84      public String getName() {
85          return _name;
86      }
87  
88  
89      /**
90       * Returns the web response that contained the script which opened this window.
91       */
92      public WebResponse getOpener() {
93          return _opener;
94      }
95  
96  
97      /**
98       * Submits a GET method request and returns a response.
99       * @exception SAXException thrown if there is an error parsing the retrieved page
100      **/
101     public WebResponse getResponse( String urlString ) throws MalformedURLException, IOException, SAXException {
102         return getResponse( new GetMethodWebRequest( urlString ) );
103     }
104 
105 
106     /**
107      * Submits a web request and returns a response. This is an alternate name for the getResponse method.
108      */
109     public WebResponse sendRequest( WebRequest request ) throws MalformedURLException, IOException, SAXException {
110         return getResponse( request );
111     }
112 
113 
114     /**
115      * Submits a web request and returns a response, using all state developed so far as stored in
116      * cookies as requested by the server.
117      * @exception SAXException thrown if there is an error parsing the retrieved page
118      **/
119     public WebResponse getResponse( WebRequest request ) throws MalformedURLException, IOException, SAXException {
120         final RequestContext requestContext = new RequestContext();
121         final WebResponse response = getSubframeResponse( request, requestContext );
122         requestContext.runScripts();
123         return response == null ? null : response.getWindow().getFrameContents( response.getFrame() ); // javascript might replace the response in its frame
124     }
125 
126 
127     WebResponse getSubframeResponse( WebRequest request, RequestContext requestContext ) throws IOException, SAXException {
128         WebResponse response = getResource( request );
129 
130         return response == null ? null : updateWindow( request.getTarget(), response, requestContext );
131     }
132 
133 
134     /**
135      * Updates this web client based on a received response. This includes updating
136      * cookies and frames.
137      **/
138     WebResponse updateWindow( String requestTarget, WebResponse response, RequestContext requestContext ) throws MalformedURLException, IOException, SAXException {
139         _client.updateClient( response );
140         if (getClient().getClientProperties().isAutoRefresh() && response.getRefreshRequest() != null) {
141             return getResponse( response.getRefreshRequest() );
142         } else if (shouldFollowRedirect( response )) {
143             delay( HttpUnitOptions.getRedirectDelay() );
144             return getResponse( new RedirectWebRequest( response ) );
145         } else {
146             _client.updateFrameContents( this, requestTarget, response, requestContext );
147             return response;
148         }
149     }
150 
151 
152     /**
153      * Returns the resource specified by the request. Does not update the window or load included framesets.
154      * May return null if the resource is a JavaScript URL which would normally leave the client unchanged.
155      */
156     public WebResponse getResource( WebRequest request ) throws IOException {
157         _client.tellListeners( request );
158 
159         WebResponse response = null;
160         String urlString = request.getURLString().trim();
161         if (urlString.startsWith( "about:" )) {
162             response = new DefaultWebResponse( _client, _frameContents.getTargetFrame( request ), null, "" );
163         } else if (!HttpUnitUtils.isJavaScriptURL( urlString )) {
164             response = _client.newResponse( request, _frameContents.getTargetFrame( request ) );
165         } else {
166             WebRequestSource wrs = request.getWebRequestSource();
167             String result = (wrs == null) ? getCurrentPage().getScriptableObject().evaluateExpression( urlString )
168                                           : wrs.getScriptableDelegate().evaluateExpression( urlString );
169             if (result != null) response = new DefaultWebResponse( _client, _frameContents.getTargetFrame( request ), request.getURL(), result );
170         }
171 
172         if (response != null) _client.tellListeners( response );
173         return response;
174     }
175 
176 
177     /**
178      * Returns the name of the currently active frames.
179      **/
180     public String[] getFrameNames() {
181         final List names = _frameContents.getActiveFrameNames();
182         return (String[]) names.toArray( new String[ names.size() ] );
183     }
184 
185 
186     /**
187      * Returns true if the specified frame name is defined in this window.
188      */
189     public boolean hasFrame( String frameName ) {
190         return _frameContents.get( frameName ) != null;
191     }
192 
193 
194     boolean hasFrame( FrameSelector frame ) {
195         return _frameContents.get( frame ) != null;
196     }
197 
198 
199     /**
200      * Returns the response associated with the specified frame name.
201      * Throws a runtime exception if no matching frame is defined.
202      **/
203     public WebResponse getFrameContents( String frameName ) {
204         WebResponse response = _frameContents.get( frameName );
205         if (response == null) throw new NoSuchFrameException( frameName );
206         return response;
207     }
208 
209 
210     /**
211      * Returns the response associated with the specified frame target.
212      * Throws a runtime exception if no matching frame is defined.
213      **/
214     WebResponse getFrameContents( FrameSelector targetFrame ) {
215         return _frameContents.getFrameContents( targetFrame );
216     }
217 
218 
219     WebResponse getSubframeContents( FrameSelector frame, String subFrameName ) {
220         return _frameContents.getSubframeContents( frame, subFrameName );
221     }
222 
223 
224     WebResponse getParentFrameContents( FrameSelector frame ) {
225         return _frameContents.getParentFrameContents( frame );
226     }
227 
228 
229     /**
230      * Returns the response representing the main page in this window.
231      */
232     public WebResponse getCurrentPage() {
233         return getFrameContents( WebRequest.TOP_FRAME );
234     }
235 
236 
237     WebWindow( WebClient client ) {
238         _client = client;
239         _frameContents = new FrameHolder( this );
240         _name = NO_NAME + _client.getOpenWindows().length;
241     }
242 
243 
244     WebWindow( WebClient client, WebResponse opener ) {
245         this( client );
246         _opener = opener;
247     }
248 
249 
250     void updateFrameContents( WebResponse response, RequestContext requestContext ) throws IOException, SAXException {
251         response.setWindow( this );
252         _frameContents.updateFrames( response, response.getFrame(), requestContext );
253     }
254 
255 
256     void setName( String name ) {
257         _name = name;
258     }
259 
260 
261     /**
262      * Delays the specified amount of time.
263      **/
264     private void delay( int numMilliseconds ) {
265         if (numMilliseconds == 0) return;
266         try {
267             Thread.sleep( numMilliseconds );
268         } catch (InterruptedException e) {
269             // ignore the exception
270         }
271     }
272 
273 
274     private boolean shouldFollowRedirect( WebResponse response ) {
275         return getClient().getClientProperties().isAutoRedirect()
276             && response.getResponseCode() >= HttpURLConnection.HTTP_MOVED_PERM
277             && response.getResponseCode() <= HttpURLConnection.HTTP_MOVED_TEMP
278             && response.getHeaderField( "Location" ) != null;
279     }
280 
281 
282     FrameSelector getTopFrame() {
283         return _frameContents.getTopFrame();
284     }
285 
286 
287     FrameSelector getFrame( String target ) {
288         return _frameContents.getFrame( target );
289     }
290 
291 }