Source code: com/meterware/httpunit/FrameHolder.java
1 package com.meterware.httpunit;
2 /********************************************************************************************************************
3 * $Id: FrameHolder.java,v 1.13 2004/09/22 02:19: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.MalformedURLException;
24 import java.util.*;
25
26 import org.xml.sax.SAXException;
27
28
29 /**
30 *
31 * @author <a href="mailto:russgold@httpunit.org">Russell Gold</a>
32 **/
33 class FrameHolder {
34
35 /** Map from a frame selector to its corresponding web response. **/
36 private Hashtable _contents = new Hashtable();
37
38 /** Map from a frame selector to its subframe selectors. **/
39 private Hashtable _subframes = new Hashtable();
40
41 /** The window which owns this frame holder. **/
42 private WebWindow _window;
43
44 /** The topmost frame in this frameholder. **/
45 private FrameSelector _topFrame;
46
47
48 FrameHolder( WebWindow window ) {
49 _window = window;
50 _topFrame = FrameSelector.newTopFrame( window );
51 DefaultWebResponse blankResponse = new DefaultWebResponse( window.getClient(), null, WebResponse.BLANK_HTML );
52 _contents.put( _topFrame, blankResponse );
53 HttpUnitOptions.getScriptingEngine().associate( blankResponse );
54 }
55
56
57 FrameSelector getTopFrame() {
58 return _topFrame;
59 }
60
61
62 WebResponse getFrameContents( FrameSelector targetFrame ) {
63 if (targetFrame == FrameSelector.TOP_FRAME) targetFrame = getTopFrame();
64 WebResponse response = get( targetFrame );
65 if (response == null) throw new NoSuchFrameException( targetFrame.getName() );
66 return response;
67 }
68
69
70 WebResponse getSubframeContents( FrameSelector frame, String subFrameName ) {
71 FrameSelector[] subframes = (FrameSelector[]) _subframes.get( frame );
72 if (subframes == null) throw new NoSuchFrameException( subFrameName );
73
74 for (int i = 0; i < subframes.length; i++) {
75 FrameSelector subframe = subframes[i];
76 if (subframe.getName().equalsIgnoreCase( subFrameName ) ) return get( subframe );
77 }
78 throw new NoSuchFrameException( subFrameName );
79 }
80
81
82 WebResponse getParentFrameContents( FrameSelector frame ) {
83 return get( frame.getParent() == null ? _topFrame : frame.getParent() );
84 }
85
86
87 WebResponse get( FrameSelector targetFrame ) {
88 return (WebResponse) _contents.get( targetFrame );
89 }
90
91
92 WebResponse get( String target ) {
93 FrameSelector frame = getFrame( _topFrame, target );
94 return frame == null ? null : (WebResponse) _contents.get( frame );
95 }
96
97
98 FrameSelector getFrame( String target ) {
99 return target.equals( _window.getName() ) ? _topFrame : getFrame( _topFrame, target );
100 }
101
102
103 private FrameSelector getFrame( FrameSelector rootFrame, String target ) {
104 if (target.equalsIgnoreCase( WebRequest.TOP_FRAME )) return _topFrame;
105 if (target.equalsIgnoreCase( rootFrame.getName() )) return rootFrame;
106
107 return lookupFrame( rootFrame, target );
108 }
109
110
111 private FrameSelector lookupFrame( FrameSelector rootFrame, String target ) {
112 FrameSelector result = getFromSubframe( rootFrame, target );
113 if (result != null) {
114 return result;
115 } else if (rootFrame.getName().equals( target )) {
116 return rootFrame;
117 } else if (rootFrame.getParent() != null) {
118 return lookupFrame( rootFrame.getParent(), target );
119 } else {
120 return null;
121 }
122 }
123
124
125 private FrameSelector getFromSubframe( FrameSelector rootFrame, String target ) {
126 FrameSelector[] subframes = (FrameSelector[]) _subframes.get( rootFrame );
127 if (subframes == null) return null;
128
129 for (int i = 0; i < subframes.length; i++) {
130 if (subframes[i].getName().equalsIgnoreCase( target )) return subframes[i];
131 }
132 for (int i = 0; i < subframes.length; i++) {
133 FrameSelector result = getFromSubframe( subframes[i], target );
134 if (result != null) return result;
135 }
136 return null;
137 }
138
139
140 List getActiveFrameNames() {
141 List result = new ArrayList();
142 for (Enumeration e = _contents.keys(); e.hasMoreElements();) {
143 result.add( ((FrameSelector) e.nextElement()).getName() );
144 }
145
146 return result;
147 }
148
149
150 /**
151 * Determines the frame in which the reply to a request will be stored.
152 */
153 FrameSelector getTargetFrame( WebRequest request ) {
154 if (WebRequest.NEW_WINDOW.equalsIgnoreCase( request.getTarget() )) {
155 return FrameSelector.NEW_FRAME;
156 } else if (WebRequest.TOP_FRAME.equalsIgnoreCase( request.getTarget() )) {
157 return _topFrame;
158 } else if (WebRequest.SAME_FRAME.equalsIgnoreCase( request.getTarget() )) {
159 return request.getSourceFrame();
160 } else if (WebRequest.PARENT_FRAME.equalsIgnoreCase( request.getTarget() )) {
161 return request.getSourceFrame().getParent();
162 } else if (request.getSourceFrame().getName().equalsIgnoreCase( request.getTarget() )) {
163 return request.getSourceFrame();
164 } else {
165 FrameSelector targetFrame = getFrame( request.getSourceFrame(), request.getTarget() );
166 if (targetFrame == null) targetFrame =_window.getClient().findFrame( request.getTarget() );
167 return (targetFrame != null) ? targetFrame : FrameSelector.NEW_FRAME;
168 }
169 }
170
171
172 void updateFrames( WebResponse response, FrameSelector frame, RequestContext requestContext ) throws MalformedURLException, IOException, SAXException {
173 removeSubFrames( frame );
174 _contents.put( frame, response );
175
176 if (response.isHTML()) {
177 if (!response.hasSubframes()) {
178 requestContext.addNewResponse( response );
179 } else {
180 HttpUnitOptions.getScriptingEngine().associate( response );
181 createSubFrames( frame, response.getFrameSelectors() );
182 WebRequest[] requests = response.getFrameRequests();
183 for (int i = 0; i < requests.length; i++) {
184 if (requests[i].getURLString().length() != 0) {
185 response.getWindow().getSubframeResponse( requests[i], requestContext );
186 }
187 }
188 HttpUnitOptions.getScriptingEngine().load( response );
189 }
190 }
191 }
192
193
194 private void removeSubFrames( FrameSelector frame ) {
195 FrameSelector[] subframes = (FrameSelector[]) _subframes.get( frame );
196 if (subframes == null) return;
197
198 _subframes.remove( frame );
199 for (int i = 0; i < subframes.length; i++) {
200 removeSubFrames( subframes[ i ] );
201 _contents.remove( subframes[ i ] );
202 }
203 }
204
205
206 private void createSubFrames( FrameSelector frame, FrameSelector[] subframes ) {
207 _subframes.put( frame, subframes );
208 for (int i = 0; i < subframes.length; i++) {
209 _contents.put( subframes[ i ], WebResponse.createBlankResponse() );
210 }
211 }
212
213
214 /**
215 * Given the qualified name of a frame and the name of a nested frame, returns the qualified name of the nested frame.
216 */
217 static FrameSelector newNestedFrame( FrameSelector parentFrame, final String relativeName ) {
218 if (relativeName == null || relativeName.length() == 0) return new FrameSelector();
219 return new FrameSelector( relativeName, parentFrame );
220 }
221
222
223 }
224