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

hazendaz / httpunit / #155

20 Aug 2024 11:42PM UTC coverage: 80.622% (+0.004%) from 80.618%
#155

push

github

hazendaz
[ci] format the code

3231 of 4119 branches covered (78.44%)

Branch coverage included in aggregate %.

68 of 80 new or added lines in 21 files covered. (85.0%)

4 existing lines in 4 files now uncovered.

8285 of 10165 relevant lines covered (81.51%)

0.82 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-2024 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.DOMParser;
32
import org.apache.xerces.xni.XNIException;
33
import org.apache.xerces.xni.parser.XMLDocumentFilter;
34
import org.apache.xerces.xni.parser.XMLErrorHandler;
35
import org.apache.xerces.xni.parser.XMLParseException;
36
import org.w3c.dom.Element;
37
import org.w3c.dom.html.HTMLDocument;
38
import org.xml.sax.SAXNotRecognizedException;
39
import org.xml.sax.SAXNotSupportedException;
40

41
/**
42
 * @author <a href="russgold@httpunit.org">Russell Gold</a>
43
 * @author <a href="mailto:Artashes.Aghajanyan@lycos-europe.com">Artashes Aghajanyan</a>
44
 **/
45
class NekoDOMParser extends DOMParser implements ScriptHandler {
46

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

50
    /** Augmentations feature identifier. */
51
    private static final String AUGMENTATIONS = "http://cyberneko.org/html/features/augmentations";
52

53
    /** Filters property identifier. */
54
    private static final String FILTERS = "http://cyberneko.org/html/properties/filters";
55

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

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

62
    private DocumentAdapter _documentAdapter;
63

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

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

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

114
    }
115

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

127
    NekoDOMParser(HTMLConfiguration configuration, DocumentAdapter adapter) {
128
        super(configuration);
1✔
129
        _documentAdapter = adapter;
1✔
130
    }
1✔
131

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

141
    @Override
142
    public boolean supportsScriptLanguage(String language) {
143
        return getScriptingHandler().supportsScriptLanguage(language);
1✔
144
    }
145

146
    @Override
147
    public String runScript(final String language, final String scriptText) {
148
        getScriptingHandler().clearCaches();
1✔
149
        return getScriptingHandler().runScript(language, scriptText);
1✔
150
    }
151

152
    private ScriptingHandler getScriptingHandler() {
153
        _documentAdapter.setDocument((HTMLDocument) getCurrentElement().getOwnerDocument());
1✔
154
        return _documentAdapter.getScriptingHandler();
1✔
155
    }
156

157
    static class ScriptException extends RuntimeException {
158
        private static final long serialVersionUID = 1L;
159
        private IOException _cause;
160

161
        public ScriptException(IOException cause) {
×
162
            _cause = cause;
×
163
        }
×
164

165
        public IOException getException() {
166
            return _cause;
×
167
        }
168
    }
169
}
170

171
class ErrorHandler implements XMLErrorHandler {
172

173
    private URL _url;
174

175
    ErrorHandler(URL url) {
1✔
176
        _url = url;
1✔
177
    }
1✔
178

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

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

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

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