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

hazendaz / httpunit / 656

06 Dec 2025 09:11PM UTC coverage: 80.452% (+0.02%) from 80.435%
656

push

github

hazendaz
[maven-release-plugin] prepare for next development iteration

3213 of 4105 branches covered (78.27%)

Branch coverage included in aggregate %.

8245 of 10137 relevant lines covered (81.34%)

0.81 hits per line

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

79.41
/src/main/java/com/meterware/httpunit/FormParameter.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.protocol.UploadFileSpec;
23
import com.meterware.httpunit.scripting.ScriptableDelegate;
24

25
import java.util.ArrayList;
26
import java.util.Arrays;
27

28
/**
29
 * Represents the aggregate of all form controls with a particular name. This permits us to abstract setting values so
30
 * that changing a control type does not break a test.
31
 **/
32
public class FormParameter {
1✔
33

34
    /** The Constant UNKNOWN_PARAMETER. */
35
    private static final FormParameter UNKNOWN_PARAMETER = new FormParameter();
1✔
36

37
    /** The controls. */
38
    private FormControl[] _controls;
39

40
    /** The control list. */
41
    private ArrayList _controlList = new ArrayList<>();
1✔
42

43
    /** The group. */
44
    private RadioGroupFormControl _group;
45

46
    /** The name. */
47
    private String _name;
48

49
    /**
50
     * Gets the unknown parameter.
51
     *
52
     * @return the uNKNOWN_PARAMETER
53
     */
54
    public static FormParameter getUNKNOWN_PARAMETER() {
55
        return UNKNOWN_PARAMETER;
1✔
56
    }
57

58
    /**
59
     * return whether I am the unknown parameter.
60
     *
61
     * @return true, if is unknown
62
     */
63
    public boolean isUnknown() {
64
        return this == UNKNOWN_PARAMETER;
1✔
65
    }
66

67
    /**
68
     * add the given form control.
69
     *
70
     * @param control
71
     *            the control
72
     */
73
    void addControl(FormControl control) {
74
        _controls = null;
1✔
75
        if (_name == null) {
1✔
76
            _name = control.getName();
1✔
77
        }
78
        if (!_name.equalsIgnoreCase(control.getName())) {
1!
79
            throw new RuntimeException("all controls should have the same name");
×
80
        }
81
        if (control.isExclusive()) {
1✔
82
            getRadioGroup(control.getForm()).addRadioButton((RadioButtonFormControl) control);
1✔
83
        } else {
84
            _controlList.add(control);
1✔
85
        }
86
    }
1✔
87

88
    /**
89
     * get the controls for this form Parameter.
90
     *
91
     * @return the controls
92
     */
93
    public FormControl[] getControls() {
94
        if (_controls == null) {
1✔
95
            _controls = (FormControl[]) _controlList.toArray(new FormControl[_controlList.size()]);
1✔
96
        }
97
        return _controls;
1✔
98
    }
99

100
    /**
101
     * get the control for this form Parameter (assuming it has only one as for a text control.
102
     *
103
     * @return the controls
104
     */
105
    public FormControl getControl() {
106
        FormControl[] controls = getControls();
×
107
        if (controls.length != 1) {
×
108
            throw new RuntimeException("getControl can only be called if the number of controls is 1 but it is "
×
109
                    + controls.length + " you might want to use getControls instead");
110
        }
111
        return controls[0];
×
112
    }
113

114
    /**
115
     * Gets the scriptable object.
116
     *
117
     * @return the scriptable object
118
     */
119
    Object getScriptableObject() {
120
        if (getControls().length == 1) {
1✔
121
            return getControls()[0].getDelegate();
1✔
122
        }
123
        ArrayList list = new ArrayList<>();
1✔
124
        for (FormControl control : _controls) {
1✔
125
            list.add(control.getScriptingHandler());
1✔
126
        }
127
        return list.toArray(new ScriptableDelegate[list.size()]);
1✔
128
    }
129

130
    /**
131
     * Gets the values.
132
     *
133
     * @return the values
134
     */
135
    String[] getValues() {
136
        ArrayList valueList = new ArrayList<>();
1✔
137
        FormControl[] controls = getControls();
1✔
138
        for (FormControl control : controls) {
1✔
139
            valueList.addAll(Arrays.asList(control.getValues()));
1✔
140
        }
141
        return (String[]) valueList.toArray(new String[valueList.size()]);
1✔
142
    }
143

144
    /**
145
     * set values to the given values.
146
     *
147
     * @param values
148
     *            the new values
149
     */
150
    void setValues(String[] values) {
151
        ArrayList list = new ArrayList(values.length);
1✔
152
        list.addAll(Arrays.asList(values));
1✔
153
        FormControl[] controls = getControls();
1✔
154
        for (FormControl control : controls) {
1✔
155
            control.claimRequiredValues(list);
1✔
156
        }
157
        for (FormControl control : controls) {
1✔
158
            control.claimUniqueValue(list);
1✔
159
        }
160
        for (FormControl control : controls) {
1✔
161
            control.claimValue(list);
1✔
162
        }
163
        if (!list.isEmpty()) {
1✔
164
            throw new UnusedParameterValueException(_name, (String) list.get(0));
1✔
165
        }
166
    }
1✔
167

168
    /**
169
     * Toggle checkbox.
170
     */
171
    public void toggleCheckbox() {
172
        FormControl[] controls = getControls();
1✔
173
        if (controls.length != 1) {
1!
174
            throw new IllegalCheckboxParameterException(_name, "toggleCheckbox");
×
175
        }
176
        controls[0].toggle();
1✔
177
    }
1✔
178

179
    /**
180
     * Toggle checkbox.
181
     *
182
     * @param value
183
     *            the value
184
     */
185
    public void toggleCheckbox(String value) {
186
        FormControl[] controls = getControls();
1✔
187
        for (FormControl control : controls) {
1!
188
            if (value.equals(control.getValueAttribute())) {
1!
189
                control.toggle();
1✔
190
                return;
1✔
191
            }
192
        }
193
        throw new IllegalCheckboxParameterException(_name + "/" + value, "toggleCheckbox");
×
194
    }
195

196
    /**
197
     * Sets the value.
198
     *
199
     * @param state
200
     *            the new value
201
     */
202
    public void setValue(boolean state) {
203
        FormControl[] controls = getControls();
1✔
204
        if (controls.length != 1) {
1✔
205
            throw new IllegalCheckboxParameterException(_name, "setCheckbox");
1✔
206
        }
207
        controls[0].setState(state);
1✔
208
    }
1✔
209

210
    /**
211
     * Sets the value.
212
     *
213
     * @param value
214
     *            the value
215
     * @param state
216
     *            the state
217
     */
218
    public void setValue(String value, boolean state) {
219
        FormControl[] controls = getControls();
1✔
220
        for (FormControl control : controls) {
1✔
221
            if (value.equals(control.getValueAttribute())) {
1✔
222
                control.setState(state);
1✔
223
                return;
1✔
224
            }
225
        }
226
        throw new IllegalCheckboxParameterException(_name + "/" + value, "setCheckbox");
1✔
227
    }
228

229
    /**
230
     * Sets the files.
231
     *
232
     * @param fileArray
233
     *            the new files
234
     */
235
    void setFiles(UploadFileSpec[] fileArray) {
236
        ArrayList list = new ArrayList(fileArray.length);
1✔
237
        list.addAll(Arrays.asList(fileArray));
1✔
238
        for (int i = 0; i < getControls().length; i++) {
1✔
239
            getControls()[i].claimUploadSpecification(list);
1✔
240
        }
241
        if (!list.isEmpty()) {
1✔
242
            throw new UnusedUploadFileException(_name, fileArray.length - list.size(), fileArray.length);
1✔
243
        }
244
    }
1✔
245

246
    /**
247
     * Gets the options.
248
     *
249
     * @return the options
250
     */
251
    String[] getOptions() {
252
        ArrayList optionList = new ArrayList<>();
1✔
253
        FormControl[] controls = getControls();
1✔
254
        for (FormControl control : controls) {
1✔
255
            optionList.addAll(Arrays.asList(control.getDisplayedOptions()));
1✔
256
        }
257
        return (String[]) optionList.toArray(new String[optionList.size()]);
1✔
258
    }
259

260
    /**
261
     * Gets the option values.
262
     *
263
     * @return the option values
264
     */
265
    String[] getOptionValues() {
266
        ArrayList valueList = new ArrayList<>();
1✔
267
        for (int i = 0; i < getControls().length; i++) {
1✔
268
            valueList.addAll(Arrays.asList(getControls()[i].getOptionValues()));
1✔
269
        }
270
        return (String[]) valueList.toArray(new String[valueList.size()]);
1✔
271
    }
272

273
    /**
274
     * Checks if is multi valued parameter.
275
     *
276
     * @return true, if is multi valued parameter
277
     */
278
    boolean isMultiValuedParameter() {
279
        FormControl[] controls = getControls();
×
280
        for (FormControl control : controls) {
×
281
            if (control.isMultiValued() || !control.isExclusive() && controls.length > 1) {
×
282
                return true;
×
283
            }
284
        }
285
        return false;
×
286
    }
287

288
    /**
289
     * Gets the num text parameters.
290
     *
291
     * @return the num text parameters
292
     */
293
    int getNumTextParameters() {
294
        int result = 0;
1✔
295
        FormControl[] controls = getControls();
1✔
296
        for (FormControl control : controls) {
1✔
297
            if (control.isTextControl()) {
1!
298
                result++;
1✔
299
            }
300
        }
301
        return result;
1✔
302
    }
303

304
    /**
305
     * Checks if is text parameter.
306
     *
307
     * @return true, if is text parameter
308
     */
309
    boolean isTextParameter() {
310
        FormControl[] controls = getControls();
×
311
        for (FormControl control : controls) {
×
312
            if (control.isTextControl()) {
×
313
                return true;
×
314
            }
315
        }
316
        return false;
×
317
    }
318

319
    /**
320
     * Checks if is file parameter.
321
     *
322
     * @return true, if is file parameter
323
     */
324
    boolean isFileParameter() {
325
        FormControl[] controls = getControls();
1✔
326
        for (FormControl control : controls) {
1✔
327
            if (control.isFileParameter()) {
1✔
328
                return true;
1✔
329
            }
330
        }
331
        return false;
1✔
332
    }
333

334
    /**
335
     * is this a disabled parameter.
336
     *
337
     * @return false if one of the controls is not disabled or this is the unknown parameter
338
     */
339
    boolean isDisabledParameter() {
340
        FormControl[] controls = getControls();
1✔
341
        for (FormControl control : controls) {
1✔
342
            if (!control.isDisabled()) {
1✔
343
                return false;
1✔
344
            }
345
        }
346
        return !this.isUnknown();
1✔
347
    }
348

349
    /**
350
     * is this a read only parameter.
351
     *
352
     * @return false if one of the controls is not read only or this is the unknown parameter
353
     */
354
    boolean isReadOnlyParameter() {
355
        FormControl[] controls = getControls();
1✔
356
        for (FormControl control : controls) {
1✔
357
            if (!control.isReadOnly()) {
1✔
358
                return false;
1✔
359
            }
360
        }
361
        return !this.isUnknown();
1✔
362
    }
363

364
    /**
365
     * is this a hidden parameter?.
366
     *
367
     * @return false if one of the controls is not hidden or this is the unknown parameter
368
     */
369
    public boolean isHiddenParameter() {
370
        FormControl[] controls = getControls();
1✔
371
        for (FormControl control : controls) {
1✔
372
            if (!control.isHidden()) {
1✔
373
                return false;
1✔
374
            }
375
        }
376
        return !this.isUnknown();
1✔
377
    }
378

379
    /**
380
     * Gets the radio group.
381
     *
382
     * @param form
383
     *            the form
384
     *
385
     * @return the radio group
386
     */
387
    private RadioGroupFormControl getRadioGroup(WebForm form) {
388
        if (_group == null) {
1✔
389
            _group = new RadioGroupFormControl(form);
1✔
390
            _controlList.add(_group);
1✔
391
        }
392
        return _group;
1✔
393
    }
394

395
    // ============================= exception class UnusedParameterValueException
396
    // ======================================
397

398
    /**
399
     * This exception is thrown on an attempt to set a parameter to a value not permitted to it by the form.
400
     **/
401
    public class UnusedParameterValueException extends IllegalRequestParameterException {
402

403
        /** The Constant serialVersionUID. */
404
        private static final long serialVersionUID = 1L;
405

406
        /**
407
         * construct an exception for an unused parameter with the given name and the value that is bad.
408
         *
409
         * @param parameterName
410
         *            the parameter name
411
         * @param badValue
412
         *            the bad value
413
         */
414
        UnusedParameterValueException(String parameterName, String badValue) {
1✔
415
            _parameterName = parameterName;
1✔
416
            _badValue = badValue;
1✔
417
        }
1✔
418

419
        /**
420
         * get the message for this exception
421
         *
422
         * @return the message
423
         */
424
        @Override
425
        public String getMessage() {
426
            StringBuilder sb = new StringBuilder(HttpUnitUtils.DEFAULT_TEXT_BUFFER_SIZE);
1✔
427
            sb.append("Attempted to assign to parameter '").append(_parameterName);
1✔
428
            sb.append("' the extraneous value '").append(_badValue).append("'.");
1✔
429
            return sb.toString();
1✔
430
        }
431

432
        /** The parameter name. */
433
        private String _parameterName;
434

435
        /** The bad value. */
436
        private String _badValue;
437
    }
438

439
    // ============================= exception class UnusedUploadFileException ======================================
440

441
    /**
442
     * This exception is thrown on an attempt to upload more files than permitted by the form.
443
     **/
444
    class UnusedUploadFileException extends IllegalRequestParameterException {
445

446
        /** The Constant serialVersionUID. */
447
        private static final long serialVersionUID = 1L;
448

449
        /**
450
         * construct a new UnusedUploadFileException exception base on the parameter Name the number of files expected
451
         * and supplied.
452
         *
453
         * @param parameterName
454
         *            the parameter name
455
         * @param numFilesExpected
456
         *            the num files expected
457
         * @param numFilesSupplied
458
         *            the num files supplied
459
         */
460
        UnusedUploadFileException(String parameterName, int numFilesExpected, int numFilesSupplied) {
1✔
461
            _parameterName = parameterName;
1✔
462
            _numExpected = numFilesExpected;
1✔
463
            _numSupplied = numFilesSupplied;
1✔
464
        }
1✔
465

466
        /**
467
         * get the message for this exception
468
         */
469
        @Override
470
        public String getMessage() {
471
            StringBuilder sb = new StringBuilder(HttpUnitUtils.DEFAULT_TEXT_BUFFER_SIZE);
×
472
            sb.append("Attempted to upload ").append(_numSupplied).append(" files using parameter '")
×
473
                    .append(_parameterName);
×
474
            if (_numExpected == 0) {
×
475
                sb.append("' which is not a file parameter.");
×
476
            } else {
477
                sb.append("' which only has room for ").append(_numExpected).append('.');
×
478
            }
479
            return sb.toString();
×
480
        }
481

482
        /** The parameter name. */
483
        private String _parameterName;
484

485
        /** The num expected. */
486
        private int _numExpected;
487

488
        /** The num supplied. */
489
        private int _numSupplied;
490
    }
491

492
    // ============================= exception class IllegalCheckboxParameterException
493
    // ======================================
494

495
    /**
496
     * This exception is thrown on an attempt to set a parameter to a value not permitted to it by the form.
497
     **/
498
    static class IllegalCheckboxParameterException extends IllegalRequestParameterException {
499

500
        /** The Constant serialVersionUID. */
501
        private static final long serialVersionUID = 1L;
502

503
        /**
504
         * Instantiates a new illegal checkbox parameter exception.
505
         *
506
         * @param parameterName
507
         *            the parameter name
508
         * @param methodName
509
         *            the method name
510
         */
511
        IllegalCheckboxParameterException(String parameterName, String methodName) {
1✔
512
            _parameterName = parameterName;
1✔
513
            _methodName = methodName;
1✔
514
        }
1✔
515

516
        @Override
517
        public String getMessage() {
518
            StringBuilder sb = new StringBuilder(HttpUnitUtils.DEFAULT_TEXT_BUFFER_SIZE);
×
519
            sb.append("Attempted to invoke method '").append(_methodName);
×
520
            sb.append("' for parameter '").append(_parameterName).append("', which is not a unique checkbox control.");
×
521
            return sb.toString();
×
522
        }
523

524
        /** The parameter name. */
525
        private String _parameterName;
526

527
        /** The method name. */
528
        private String _methodName;
529
    }
530

531
}
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