• 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

43.12
/src/main/java/com/meterware/httpunit/parsing/HTMLParserFactory.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.parsing;
21

22
import java.lang.reflect.InvocationTargetException;
23
import java.util.ArrayList;
24
import java.util.List;
25

26
/**
27
 * Factory for creating HTML parsers. Parser customization properties can be specified but do not necessarily work for
28
 * every parser type.
29
 **/
30
public abstract class HTMLParserFactory {
×
31

32
    /** The listeners. */
33
    private static List<HTMLParserListener> _listeners = new ArrayList<>();
1✔
34

35
    /** The jtidy parser. */
36
    private static HTMLParser _jtidyParser;
37

38
    /** The neko parser. */
39
    private static HTMLParser _nekoParser;
40

41
    /** The html parser. */
42
    private static HTMLParser _htmlParser;
43

44
    /** The preserve tag case. */
45
    private static boolean _preserveTagCase;
46

47
    /** The return HTML document. */
48
    private static boolean _returnHTMLDocument;
49

50
    /** The parser warnings enabled. */
51
    private static boolean _parserWarningsEnabled;
52

53
    /** The force upper. */
54
    // for parsers that support forcing Case
55
    private static boolean _forceUpper;
56

57
    /** The force lower. */
58
    private static boolean _forceLower;
59

60
    /**
61
     * Resets all settings to their default values. This includes the parser selection.
62
     */
63
    public static void reset() {
64
        _preserveTagCase = false;
1✔
65
        _returnHTMLDocument = true;
1✔
66
        _parserWarningsEnabled = false;
1✔
67
        _htmlParser = null;
1✔
68
        _forceUpper = false;
1✔
69
        _forceLower = false;
1✔
70
        _listeners.clear();
1✔
71
    }
1✔
72

73
    /**
74
     * Selects the JTidy parser, if present.
75
     */
76
    public static void useJTidyParser() {
77
        if (_jtidyParser == null) {
×
78
            throw new RuntimeException("JTidy parser not available");
×
79
        }
80
        _htmlParser = _jtidyParser;
×
81
    }
×
82

83
    /**
84
     * Selects the NekoHTML parser, if present.
85
     */
86
    public static void useNekoHTMLParser() {
87
        if (_nekoParser == null) {
×
88
            throw new RuntimeException("NekoHTML parser not available");
×
89
        }
90
        _htmlParser = _nekoParser;
×
91
    }
×
92

93
    /**
94
     * Specifies the parser to use.
95
     *
96
     * @param htmlParser
97
     *            the new HTML parser
98
     */
99
    public static void setHTMLParser(HTMLParser htmlParser) {
100
        _htmlParser = htmlParser;
1✔
101
    }
1✔
102

103
    /**
104
     * Returns the current selected parser.
105
     *
106
     * @return the HTML parser
107
     */
108
    public static HTMLParser getHTMLParser() {
109
        if (_htmlParser == null) {
1✔
110
            if (_nekoParser != null) {
1!
111
                _htmlParser = _nekoParser;
1✔
112
            } else if (_jtidyParser != null) {
×
113
                _htmlParser = _jtidyParser;
×
114
            } else {
115
                throw new RuntimeException(
×
116
                        "No HTML parser found. Make sure that either nekoHTML.jar or Tidy.jar is in the in classpath");
117
            }
118
        }
119
        return _htmlParser;
1✔
120
    }
121

122
    /**
123
     * Returns true if the current parser will preserve the case of HTML tags and attributes.
124
     *
125
     * @return true, if is preserve tag case
126
     */
127
    public static boolean isPreserveTagCase() {
128
        return _preserveTagCase && getHTMLParser().supportsPreserveTagCase();
1!
129
    }
130

131
    /**
132
     * Specifies whether the parser should preserve the case of HTML tags and attributes. Not every parser can support
133
     * this capability. Note that enabling this will disable support for the HTMLDocument class. override any previous
134
     * behaviour configured by calling {@link #setForceUpperCase(boolean)} or {@link #setForceLowerCase(boolean)}
135
     *
136
     * @param preserveTagCase
137
     *            the new preserve tag case
138
     *
139
     * @see #setReturnHTMLDocument
140
     * @see #setForceUpperCase(boolean)
141
     * @see #setForceLowerCase(boolean)
142
     */
143
    public static void setPreserveTagCase(boolean preserveTagCase) {
144
        _preserveTagCase = preserveTagCase;
1✔
145
        if (preserveTagCase) {
1!
146
            _forceLower = false;
×
147
            _forceUpper = false;
×
148
        }
149
    }
1✔
150

151
    /**
152
     * Returns true if the current parser will return an HTMLDocument object rather than a Document object.
153
     *
154
     * @return true, if is return HTML document
155
     */
156
    public static boolean isReturnHTMLDocument() {
157
        return _returnHTMLDocument && !isPreserveTagCase() && getHTMLParser().supportsReturnHTMLDocument();
1!
158
    }
159

160
    /**
161
     * Specifies whether the parser should return an HTMLDocument object rather than a Document object. Not every parser
162
     * can support this capability. Note that enabling this will disable preservation of tag case. and/or the forcing of
163
     * the tag case to upper or lower case.
164
     *
165
     * @param returnHTMLDocument
166
     *            the new return HTML document
167
     *
168
     * @see #setPreserveTagCase
169
     * @see #setForceUpperCase(boolean)
170
     * @see #setForceLowerCase(boolean)
171
     */
172
    public static void setReturnHTMLDocument(boolean returnHTMLDocument) {
173
        _returnHTMLDocument = returnHTMLDocument;
×
174
        if (returnHTMLDocument) {
×
175
            _preserveTagCase = false;
×
176
            _forceLower = false;
×
177
            _forceUpper = false;
×
178
        }
179
    }
×
180

181
    /**
182
     * Specifies whether the parser should force the case of HTML tags and attributes to be upper case. Not every parser
183
     * can support this capability. Note that enabling this will disable support for the HTMLDocument class and override
184
     * any previous behaviour configured by enabling {@link #setPreserveTagCase(boolean)} or
185
     * {@link #setForceLowerCase(boolean)}
186
     *
187
     * @param forceUpper
188
     *            boolean indicating whether to enable this functionality
189
     *
190
     * @see #setReturnHTMLDocument
191
     * @see #setPreserveTagCase(boolean)
192
     * @see #setForceLowerCase(boolean)
193
     */
194
    public static void setForceUpperCase(boolean forceUpper) {
195
        _forceUpper = forceUpper;
×
196
        if (_forceUpper) {
×
197
            _forceLower = false;
×
198
            _preserveTagCase = false;
×
199
            // _returnHTMLDocument = false;
200
        }
201
    }
×
202

203
    /**
204
     * Return true if the current parser will support forcing the tags and attributes to upper case.
205
     *
206
     * @return boolean flag
207
     */
208
    public static boolean getForceUpperCase() {
209
        return _forceUpper && getHTMLParser().supportsPreserveTagCase();
1!
210
    }
211

212
    /**
213
     * Specifies whether the parser should force the case of HTML tags and attributes to lower case. Not every parser
214
     * can support this capability. Note that enabling this will disable support for the HTMLDocument class and override
215
     * any previous behaviour configured by enabling {@link #setPreserveTagCase(boolean)} or
216
     * {@link #setForceUpperCase(boolean)}
217
     *
218
     * @param forceLower
219
     *            boolean indicating whether to enable this functionality
220
     *
221
     * @see #setReturnHTMLDocument
222
     * @see #setPreserveTagCase(boolean)
223
     * @see #setForceUpperCase(boolean)
224
     */
225
    public static void setForceLowerCase(boolean forceLower) {
226
        _forceLower = forceLower;
×
227
        if (_forceLower) {
×
228
            _forceUpper = false;
×
229
            _preserveTagCase = false;
×
230
            // _returnHTMLDocument = false;
231
        }
232
    }
×
233

234
    /**
235
     * Return true if the current parser will support forcing the tags and attributes to lower case.
236
     *
237
     * @return boolean flag
238
     */
239
    public static boolean getForceLowerCase() {
240
        return _forceLower && getHTMLParser().supportsPreserveTagCase();
1!
241
    }
242

243
    /**
244
     * Returns true if parser warnings are enabled.
245
     *
246
     * @return true, if is parser warnings enabled
247
     */
248
    public static boolean isParserWarningsEnabled() {
249
        return _parserWarningsEnabled && getHTMLParser().supportsParserWarnings();
1!
250
    }
251

252
    /**
253
     * If true, tells the parser to display warning messages. The default is false (warnings are not shown).
254
     *
255
     * @param enabled
256
     *            the new parser warnings enabled
257
     */
258
    public static void setParserWarningsEnabled(boolean enabled) {
259
        _parserWarningsEnabled = enabled;
1✔
260
    }
1✔
261

262
    /**
263
     * Remove an HTML Parser listener.
264
     *
265
     * @param el
266
     *            the el
267
     */
268
    public static void removeHTMLParserListener(HTMLParserListener el) {
269
        _listeners.remove(el);
1✔
270
    }
1✔
271

272
    /**
273
     * Add an HTML Parser listener.
274
     *
275
     * @param el
276
     *            the el
277
     */
278
    public static void addHTMLParserListener(HTMLParserListener el) {
279
        _listeners.add(el);
1✔
280
    }
1✔
281

282
    // ------------------------------------- package protected members
283
    // ------------------------------------------------------
284

285
    /**
286
     * Get the list of Html Error Listeners.
287
     *
288
     * @return the HTML parser listeners
289
     */
290
    static List<HTMLParserListener> getHTMLParserListeners() {
291
        return _listeners;
1✔
292
    }
293

294
    /**
295
     * Load parser if supported.
296
     *
297
     * @param testClassName
298
     *            the test class name
299
     * @param parserClassName
300
     *            the parser class name
301
     *
302
     * @return the HTML parser
303
     */
304
    private static HTMLParser loadParserIfSupported(final String testClassName, final String parserClassName) {
305
        try {
306
            Class.forName(testClassName);
1✔
307
            return (HTMLParser) Class.forName(parserClassName).getDeclaredConstructor().newInstance();
1✔
308
        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
×
309
                | NoSuchMethodException | SecurityException | ClassNotFoundException e) {
310
            e.printStackTrace();
×
311
        }
312
        return null;
×
313
    }
314

315
    static {
316
        _jtidyParser = loadParserIfSupported("org.w3c.tidy.Parser", "com.meterware.httpunit.parsing.JTidyHTMLParser");
1✔
317
        _nekoParser = loadParserIfSupported("net.sourceforge.htmlunit.cyberneko.HTMLConfiguration",
1✔
318
                "com.meterware.httpunit.parsing.NekoHTMLParser");
319
        reset();
1✔
320
    }
1✔
321

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