• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / httpunit / 636

05 Dec 2025 03:27AM UTC coverage: 80.509%. Remained the same
636

push

github

hazendaz
Cleanup more old since tags

you guessed it, at this point going to jautodoc the rest so the warnings on builds go away ;)

3213 of 4105 branches covered (78.27%)

Branch coverage included in aggregate %.

8249 of 10132 relevant lines covered (81.42%)

0.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.76
/src/main/java/com/meterware/httpunit/WebRequestSource.java
1
/*
2
 * MIT License
3
 *
4
 * Copyright 2011-2025 Russell Gold
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
7
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
9
 * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions
12
 * of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
15
 * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
17
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18
 * DEALINGS IN THE SOFTWARE.
19
 */
20
package com.meterware.httpunit;
21

22
import com.meterware.httpunit.scripting.ScriptableDelegate;
23
import com.meterware.httpunit.scripting.ScriptingHandler;
24

25
import java.io.IOException;
26
import java.net.URL;
27
import java.util.StringTokenizer;
28

29
import org.w3c.dom.Element;
30
import org.w3c.dom.Node;
31
import org.xml.sax.SAXException;
32

33
/**
34
 * Base class for objects which can be clicked to generate new web requests.
35
 */
36
public abstract class WebRequestSource extends ParameterHolder implements HTMLElement {
37

38
    private FrameSelector _frame;
39

40
    /**
41
     * The name of the destination attribute used to create for the request, including anchors and parameters. *
42
     */
43
    private String _destinationAttribute;
44
    private ScriptingHandler _scriptable;
45

46
    /**
47
     * Returns the ID associated with this request source.
48
     */
49
    @Override
50
    public String getID() {
51
        return getAttribute("id");
1✔
52
    }
53

54
    /**
55
     * Returns the class associated with this request source.
56
     */
57
    @Override
58
    public String getClassName() {
59
        return getAttribute("class");
1✔
60
    }
61

62
    /**
63
     * Returns the name associated with this request source.
64
     */
65
    @Override
66
    public String getName() {
67
        return getAttribute("name");
1✔
68
    }
69

70
    /**
71
     * Returns the title associated with this request source.
72
     */
73
    @Override
74
    public String getTitle() {
75
        return getAttribute("title");
1✔
76
    }
77

78
    /**
79
     * Returns the target for this request source.
80
     */
81
    public String getTarget() {
82
        if (getSpecifiedTarget().isEmpty()) {
1✔
83
            return _defaultTarget;
1✔
84
        }
85
        return getSpecifiedTarget();
1✔
86
    }
87

88
    /**
89
     * Returns the name of the frame containing this request source.
90
     *
91
     * @deprecated as of 1.6, use #getFrame
92
     */
93
    @Deprecated
94
    public String getPageFrame() {
95
        return _frame.getName();
×
96
    }
97

98
    /**
99
     * Returns the frame containing this request source.
100
     */
101
    public FrameSelector getFrame() {
102
        return _frame;
1✔
103
    }
104

105
    /**
106
     * Returns the fragment identifier for this request source, used to identifier an element within an HTML document.
107
     */
108
    public String getFragmentIdentifier() {
109
        final int hashIndex = getDestination().indexOf('#');
1✔
110
        if (hashIndex < 0) {
1✔
111
            return "";
1✔
112
        }
113
        return getDestination().substring(hashIndex + 1);
1✔
114
    }
115

116
    /**
117
     * Returns a copy of the domain object model subtree associated with this entity.
118
     */
119
    public Node getDOMSubtree() {
120
        return _node.cloneNode( /* deep */true);
×
121
    }
122

123
    /**
124
     * Creates and returns a web request from this request source.
125
     */
126
    public abstract WebRequest getRequest();
127

128
    /**
129
     * Returns an array containing the names of any parameters to be sent on a request based on this request source.
130
     */
131
    @Override
132
    public abstract String[] getParameterNames();
133

134
    /**
135
     * Returns the values of the named parameter.
136
     */
137
    @Override
138
    public abstract String[] getParameterValues(String name);
139

140
    /**
141
     * Returns the URL relative to the current page which will handle the request.
142
     */
143
    String getRelativePage() {
144
        final String url = getRelativeURL();
1✔
145
        if (HttpUnitUtils.isJavaScriptURL(url)) {
1!
146
            return url;
×
147
        }
148
        final int questionMarkIndex = url.indexOf("?");
1✔
149
        if (questionMarkIndex >= 1 && questionMarkIndex < url.length() - 1) {
1!
150
            return url.substring(0, questionMarkIndex);
1✔
151
        }
152
        return url;
1✔
153
    }
154

155
    /**
156
     * get the relative URL for a weblink change spaces to %20
157
     *
158
     * @return the relative URL as a string
159
     */
160
    protected String getRelativeURL() {
161
        String result = HttpUnitUtils.encodeSpaces(HttpUnitUtils.trimFragment(getDestination()));
1✔
162
        if (result.trim().isEmpty()) {
1✔
163
            result = getBaseURL().getFile();
1✔
164
        }
165
        return result;
1✔
166
    }
167

168
    // ----------------------------- protected members
169
    // ---------------------------------------------
170

171
    /**
172
     * Contructs a web request source.
173
     *
174
     * @param response
175
     *            the response from which this request source was extracted
176
     * @param node
177
     *            the DOM subtree defining this request source
178
     * @param baseURL
179
     *            the URL on which to base all releative URL requests
180
     * @param attribute
181
     *            the attribute which defines the relative URL to which requests will be directed
182
     */
183
    WebRequestSource(WebResponse response, Node node, URL baseURL, String attribute, FrameSelector frame,
184
            String defaultTarget) {
1✔
185
        if (node == null) {
1!
186
            throw new IllegalArgumentException("node must not be null");
×
187
        }
188
        _baseResponse = response;
1✔
189
        _node = node;
1✔
190
        _baseURL = baseURL;
1✔
191
        _destinationAttribute = attribute;
1✔
192
        _frame = frame;
1✔
193
        _defaultTarget = defaultTarget;
1✔
194
    }
1✔
195

196
    protected URL getBaseURL() {
197
        return _baseURL;
1✔
198
    }
199

200
    /**
201
     * get the Destination made public per FR 2836664 make WebRequestSource.getDestination() public by Dan Lipofsky
202
     *
203
     * @return
204
     */
205
    public String getDestination() {
206
        return getElement().getAttribute(_destinationAttribute);
1✔
207
    }
208

209
    protected void setDestination(String destination) {
210
        getElement().setAttribute(_destinationAttribute, destination);
1✔
211
    }
1✔
212

213
    /**
214
     * Returns the actual DOM for this request source, not a copy.
215
     */
216
    protected Element getElement() {
217
        return (Element) _node;
1✔
218
    }
219

220
    /**
221
     * Returns the HTMLPage associated with this request source.
222
     */
223
    protected HTMLPage getHTMLPage() throws SAXException {
224
        return _baseResponse.getReceivedPage();
1✔
225
    }
226

227
    /**
228
     * Extracts any parameters specified as part of the destination URL, calling addPresetParameter for each one in the
229
     * order in which they are found.
230
     */
231
    protected final void loadDestinationParameters() {
232
        StringTokenizer st = new StringTokenizer(getParametersString(), PARAM_DELIM);
1✔
233
        while (st.hasMoreTokens()) {
1✔
234
            stripOneParameter(st.nextToken());
1✔
235
        }
236
    }
1✔
237

238
    /**
239
     * submit the given event for the given request
240
     *
241
     * @param event
242
     * @param request
243
     *
244
     * @return the response for the submitted Request
245
     *
246
     * @throws IOException
247
     * @throws SAXException
248
     */
249
    protected WebResponse submitRequest(String event, final WebRequest request) throws IOException, SAXException {
250
        WebResponse response = null;
1✔
251
        if (doEventScript(event)) {
1✔
252
            response = submitRequest(request);
1✔
253
        }
254
        if (response == null) {
1✔
255
            response = getCurrentFrameContents();
1✔
256
        }
257
        return response;
1✔
258
    }
259

260
    /**
261
     * handle the event that has the given script attached by compiling the eventScript as a function and executing it
262
     *
263
     * @param eventScript
264
     *            - the script to use
265
     *
266
     * @deprecated since 1.7 - use doEventScript instead
267
     */
268
    @Deprecated
269
    @Override
270
    public boolean doEvent(String eventScript) {
271
        return doEventScript(eventScript);
×
272
    }
273

274
    /**
275
     * optional do the event if it's defined
276
     *
277
     * @param eventScript
278
     *            - the script to handle
279
     *
280
     * @return whether the script was handled
281
     */
282
    @Override
283
    public boolean doEventScript(String eventScript) {
284
        return this.getScriptingHandler().doEventScript(eventScript);
1✔
285
    }
286

287
    @Override
288
    public boolean handleEvent(String eventName) {
289
        return this.getScriptingHandler().handleEvent(eventName);
1✔
290
    }
291

292
    protected WebResponse getCurrentFrameContents() {
293
        return getCurrentFrame(getBaseResponse().getWindow(), _frame);
1✔
294
    }
295

296
    private WebResponse getCurrentFrame(WebWindow window, FrameSelector pageFrame) {
297
        return window.hasFrame(pageFrame) ? window.getFrameContents(pageFrame) : window.getCurrentPage();
1✔
298
    }
299

300
    /**
301
     * Submits a request to the web client from which this request source was originally obtained.
302
     */
303
    protected final WebResponse submitRequest(WebRequest request) throws IOException, SAXException {
304
        return getDestination().equals("#") ? _baseResponse : _baseResponse.getWindow().sendRequest(request);
1!
305
    }
306

307
    /**
308
     * Returns the web response containing this request source.
309
     */
310
    protected final WebResponse getBaseResponse() {
311
        return _baseResponse;
1✔
312
    }
313

314
    /**
315
     * Records a parameter defined by including it in the destination URL. The value can be null, if the parameter name
316
     * was not specified with an equals sign.
317
     */
318
    abstract protected void addPresetParameter(String name, String value);
319

320
    /**
321
     * get the attribute value for the given name
322
     *
323
     * @param name
324
     *            - the name of the attribute to get
325
     */
326
    @Override
327
    public String getAttribute(final String name) {
328
        return NodeUtils.getNodeAttribute(_node, name);
1✔
329
    }
330

331
    /**
332
     * set the attribute with the given name to the given value
333
     *
334
     * @param name
335
     *            - the name of the attribute
336
     * @param value
337
     *            - the value to use
338
     */
339
    @Override
340
    public void setAttribute(final String name, final Object value) {
341
        NodeUtils.setNodeAttribute(getNode(), name, value == null ? null : value.toString());
×
342
    }
×
343

344
    /**
345
     * remove the given attribute
346
     *
347
     * @param name
348
     *            - the name of the attribute to remove
349
     */
350
    @Override
351
    public void removeAttribute(final String name) {
352
        NodeUtils.removeNodeAttribute(getNode(), name);
×
353
    }
×
354

355
    @Override
356
    public boolean isSupportedAttribute(String name) {
357
        return false;
1✔
358
    }
359

360
    @Override
361
    public Node getNode() {
362
        return _node;
1✔
363
    }
364

365
    /**
366
     * Returns the text value of this block.
367
     */
368
    @Override
369
    public String getText() {
370
        if (_node == null) {
1!
371
            return "";
×
372
        }
373
        if (_node.getNodeType() == Node.TEXT_NODE) {
1!
374
            return _node.getNodeValue().trim();
×
375
        }
376
        if (!_node.hasChildNodes()) {
1!
377
            return "";
×
378
        }
379
        return NodeUtils.asText(_node.getChildNodes()).trim();
1✔
380
    }
381

382
    @Override
383
    public String getTagName() {
384
        return _node.getNodeName();
×
385
    }
386

387
    String getAttribute(final String name, String defaultValue) {
388
        return NodeUtils.getNodeAttribute(_node, name, defaultValue);
1✔
389
    }
390

391
    // ----------------------------- private members
392
    // -----------------------------------------------
393

394
    /**
395
     * parameter Delimiter for URL parameters bug report [ 1052037 ] Semicolon not supported as URL param delimiter asks
396
     * for this to be extended to &;
397
     *
398
     * @see http://www.w3.org/TR/html4/appendix/notes.html#h-B.2 section B2.2
399
     */
400
    private static final String PARAM_DELIM = "&";
401

402
    /** The web response containing this request source. * */
403
    private WebResponse _baseResponse;
404

405
    /**
406
     * The name of the frame in which the response containing this request source is rendered. *
407
     */
408
    private String _defaultTarget;
409

410
    /** The URL of the page containing this entity. * */
411
    private URL _baseURL;
412

413
    /** The DOM node representing this entity. * */
414
    private Node _node;
415

416
    private String getSpecifiedTarget() {
417
        return getAttribute("target");
1✔
418
    }
419

420
    protected void setTargetAttribute(String value) {
421
        ((Element) _node).setAttribute("target", value);
1✔
422
    }
1✔
423

424
    /**
425
     * Gets all parameters from a URL
426
     */
427
    private String getParametersString() {
428
        String url = HttpUnitUtils.trimFragment(getDestination());
1✔
429
        if (url.trim().isEmpty()) {
1✔
430
            url = getBaseURL().toExternalForm();
1✔
431
        }
432
        if (HttpUnitUtils.isJavaScriptURL(url)) {
1!
433
            return "";
×
434
        }
435
        final int questionMarkIndex = url.indexOf("?");
1✔
436
        if (questionMarkIndex >= 1 && questionMarkIndex < url.length() - 1) {
1!
437
            return url.substring(questionMarkIndex + 1);
1✔
438
        }
439
        return "";
1✔
440
    }
441

442
    /**
443
     * Extracts a parameter of the form <name>[=[<value>]].
444
     */
445
    private void stripOneParameter(String param) {
446
        final int index = param.indexOf("=");
1✔
447
        String value = index < 0 ? null
1✔
448
                : index == param.length() - 1 ? getEmptyParameterValue() : decode(param.substring(index + 1));
1✔
449
        String name = index < 0 ? decode(param) : decode(param.substring(0, index));
1✔
450
        addPresetParameter(name, value);
1✔
451
    }
1✔
452

453
    private String decode(String string) {
454
        return HttpUnitUtils.decode(string, _baseResponse.getCharacterSet()).trim();
1✔
455
    }
456

457
    abstract protected String getEmptyParameterValue();
458

459
    /**
460
     * Returns the scriptable delegate.
461
     */
462
    @Override
463
    public ScriptingHandler getScriptingHandler() {
464
        if (_scriptable == null) {
1✔
465
            _scriptable = HttpUnitOptions.getScriptingEngine().createHandler(this);
1✔
466
        }
467
        return _scriptable;
1✔
468
    }
469

470
    @Override
471
    public ScriptableDelegate getParentDelegate() {
472
        return getBaseResponse().getDocumentScriptable();
1✔
473
    }
474

475
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc