• 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

56.47
/src/main/java/com/meterware/httpunit/parsing/NekoDOMParser.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 com.meterware.httpunit.dom.HTMLDocumentImpl;
23
import com.meterware.httpunit.scripting.ScriptingHandler;
24

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

29
import net.sourceforge.htmlunit.cyberneko.HTMLConfiguration;
30

31
import org.apache.xerces.parsers.AbstractDOMParser;
32
import org.apache.xerces.parsers.DOMParser;
33
import org.apache.xerces.xni.XNIException;
34
import org.apache.xerces.xni.parser.XMLDocumentFilter;
35
import org.apache.xerces.xni.parser.XMLErrorHandler;
36
import org.apache.xerces.xni.parser.XMLParseException;
37
import org.w3c.dom.Element;
38
import org.w3c.dom.html.HTMLDocument;
39
import org.xml.sax.SAXNotRecognizedException;
40
import org.xml.sax.SAXNotSupportedException;
41

42
class NekoDOMParser extends DOMParser implements ScriptHandler {
43

44
    /** Error reporting feature identifier. */
45
    private static final String REPORT_ERRORS = "http://cyberneko.org/html/features/report-errors";
46

47
    /** Augmentations feature identifier. */
48
    private static final String AUGMENTATIONS = "http://cyberneko.org/html/features/augmentations";
49

50
    /** Filters property identifier. */
51
    private static final String FILTERS = "http://cyberneko.org/html/properties/filters";
52

53
    /** Element case settings. possible values: "upper", "lower", "match" */
54
    private static final String TAG_NAME_CASE = "http://cyberneko.org/html/properties/names/elems";
55

56
    /** Attribute case settings. possible values: "upper", "lower", "no-change" */
57
    private static final String ATTRIBUTE_NAME_CASE = "http://cyberneko.org/html/properties/names/attrs";
58

59
    private DocumentAdapter _documentAdapter;
60

61
    /**
62
     * construct a new NekoDomParser with the given adapter and url
63
     *
64
     * @param adapter
65
     * @param url
66
     *
67
     * @return - the new parser patch [ 1211154 ] NekoDOMParser default to lowercase by Dan Allen patch [ 1176688 ]
68
     *         Allow configuration of neko parser properties by James Abley
69
     */
70
    static NekoDOMParser newParser(DocumentAdapter adapter, URL url) {
71
        final HTMLConfiguration configuration = new HTMLConfiguration();
1✔
72
        // note: Introduced in 1.9.9 nekohtml but doesn't apply against header but rather body and thus doesn't solve
73
        // issue with <noscript> needs.
74
        // configuration.setFeature(HTMLScanner.PARSE_NOSCRIPT_CONTENT, false);
75
        if (!HTMLParserFactory.getHTMLParserListeners().isEmpty() || HTMLParserFactory.isParserWarningsEnabled()) {
1!
76
            configuration.setErrorHandler(new ErrorHandler(url));
1✔
77
            configuration.setFeature(REPORT_ERRORS, true);
1✔
78
        }
79
        configuration.setFeature(AUGMENTATIONS, true);
1✔
80
        final ScriptFilter javaScriptFilter = new ScriptFilter(configuration);
1✔
81
        configuration.setProperty(FILTERS, new XMLDocumentFilter[] { javaScriptFilter });
1✔
82
        if (HTMLParserFactory.isPreserveTagCase()) {
1!
83
            configuration.setProperty(TAG_NAME_CASE, "match");
×
84
            configuration.setProperty(ATTRIBUTE_NAME_CASE, "no-change");
×
85
        } else {
86
            configuration.setProperty(TAG_NAME_CASE, "lower");
1✔
87
            configuration.setProperty(ATTRIBUTE_NAME_CASE, "lower");
1✔
88

89
            if (HTMLParserFactory.getForceUpperCase()) {
1!
90
                configuration.setProperty(TAG_NAME_CASE, "upper");
×
91
                configuration.setProperty(ATTRIBUTE_NAME_CASE, "upper");
×
92
            }
93
            // this is the default as of patch [ 1211154 ] ... just for people who rely on patch [ 1176688 ]
94
            if (HTMLParserFactory.getForceLowerCase()) {
1!
95
                configuration.setProperty(TAG_NAME_CASE, "lower");
×
96
                configuration.setProperty(ATTRIBUTE_NAME_CASE, "lower");
×
97
            }
98
        }
99

100
        try {
101
            final NekoDOMParser domParser = new NekoDOMParser(configuration, adapter);
1✔
102
            domParser.setFeature(AbstractDOMParser.DEFER_NODE_EXPANSION, false);
1✔
103
            if (HTMLParserFactory.isReturnHTMLDocument())
1!
104
                domParser.setProperty(AbstractDOMParser.DOCUMENT_CLASS_NAME, HTMLDocumentImpl.class.getName());
1✔
105
            javaScriptFilter.setScriptHandler(domParser);
1✔
106
            return domParser;
1✔
107
        } catch (SAXNotRecognizedException | SAXNotSupportedException e) {
×
108
            throw new RuntimeException(e.toString());
×
109
        }
110

111
    }
112

113
    private Element getCurrentElement() {
114
        try {
115
            return (Element) getProperty(AbstractDOMParser.CURRENT_ELEMENT_NODE);
1✔
116
        } catch (SAXNotRecognizedException e) {
×
117
            throw new RuntimeException(AbstractDOMParser.CURRENT_ELEMENT_NODE + " property not recognized");
×
118
        } catch (SAXNotSupportedException e) {
×
119
            e.printStackTrace();
×
120
            throw new RuntimeException(AbstractDOMParser.CURRENT_ELEMENT_NODE + " property not supported");
×
121
        }
122
    }
123

124
    NekoDOMParser(HTMLConfiguration configuration, DocumentAdapter adapter) {
125
        super(configuration);
1✔
126
        _documentAdapter = adapter;
1✔
127
    }
1✔
128

129
    @Override
130
    public String getIncludedScript(String srcAttribute) {
131
        try {
132
            return _documentAdapter.getIncludedScript(srcAttribute);
1✔
133
        } catch (IOException e) {
×
134
            throw new ScriptException(e);
×
135
        }
136
    }
137

138
    @Override
139
    public boolean supportsScriptLanguage(String language) {
140
        return getScriptingHandler().supportsScriptLanguage(language);
1✔
141
    }
142

143
    @Override
144
    public String runScript(final String language, final String scriptText) {
145
        getScriptingHandler().clearCaches();
1✔
146
        return getScriptingHandler().runScript(language, scriptText);
1✔
147
    }
148

149
    private ScriptingHandler getScriptingHandler() {
150
        _documentAdapter.setDocument((HTMLDocument) getCurrentElement().getOwnerDocument());
1✔
151
        return _documentAdapter.getScriptingHandler();
1✔
152
    }
153

154
    static class ScriptException extends RuntimeException {
155
        private static final long serialVersionUID = 1L;
156
        private IOException _cause;
157

158
        public ScriptException(IOException cause) {
×
159
            _cause = cause;
×
160
        }
×
161

162
        public IOException getException() {
163
            return _cause;
×
164
        }
165
    }
166
}
167

168
class ErrorHandler implements XMLErrorHandler {
169

170
    private URL _url;
171

172
    ErrorHandler(URL url) {
1✔
173
        _url = url;
1✔
174
    }
1✔
175

176
    @Override
177
    public void warning(String domain, String key, XMLParseException warningException) throws XNIException {
178
        if (HTMLParserFactory.isParserWarningsEnabled()) {
1!
179
            System.out.println("At line " + warningException.getLineNumber() + ", column "
×
180
                    + warningException.getColumnNumber() + ": " + warningException.getMessage());
×
181
        }
182

183
        List<HTMLParserListener> listeners = HTMLParserFactory.getHTMLParserListeners();
1✔
184
        for (HTMLParserListener listener : listeners) {
1✔
185
            listener.warning(_url, warningException.getMessage(), warningException.getLineNumber(),
1✔
186
                    warningException.getColumnNumber());
1✔
187
        }
1✔
188
    }
1✔
189

190
    @Override
191
    public void error(String domain, String key, XMLParseException errorException) throws XNIException {
192
        List<HTMLParserListener> listeners = HTMLParserFactory.getHTMLParserListeners();
×
193
        for (HTMLParserListener listener : listeners) {
×
194
            listener.error(_url, errorException.getMessage(), errorException.getLineNumber(),
×
195
                    errorException.getColumnNumber());
×
196
        }
×
197
    }
×
198

199
    @Override
200
    public void fatalError(String domain, String key, XMLParseException fatalError) throws XNIException {
201
        error(domain, key, fatalError);
×
202
        throw fatalError;
×
203
    }
204
}
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