1. Project Clover database mar. janv. 20 2026 12:32:22 CET
  2. Package org.devacfr.maven.skins.reflow

File JsoupUtils.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart5.png
80% of files have more coverage

Code metrics

24
52
9
1
174
111
31
0,6
5,78
9
3,44

Classes

Class Line # Actions
JsoupUtils 47 52 0% 31 47
0.4470588344,7%
 

Contributing tests

This file is covered by 35 tests. .

Source view

1    /*
2    * Copyright 2012-2025 Christophe Friederich
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10    * Unless required by applicable law or agreed to in writing, software
11    * distributed under the License is distributed on an "AS IS" BASIS,
12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    * See the License for the specific language governing permissions and
14    * limitations under the License.
15    */
16    package org.devacfr.maven.skins.reflow;
17   
18    import static java.util.Objects.requireNonNull;
19   
20    import java.nio.charset.StandardCharsets;
21    import javax.annotation.Nonnull;
22    import org.jsoup.Jsoup;
23    import org.jsoup.nodes.Document;
24    import org.jsoup.nodes.Element;
25    import org.jsoup.nodes.Node;
26    import org.jsoup.parser.Parser;
27    import org.jsoup.parser.Tag;
28   
29    /*
30    * Licensed to the Apache Software Foundation (ASF) under one
31    * or more contributor license agreements. See the NOTICE file
32    * distributed with this work for additional information
33    * regarding copyright ownership. The ASF licenses this file
34    * to you under the Apache License, Version 2.0 (the
35    * "License"); you may not use this file except in compliance
36    * with the License. You may obtain a copy of the License at
37    *
38    * http://www.apache.org/licenses/LICENSE-2.0
39    *
40    * Unless required by applicable law or agreed to in writing,
41    * software distributed under the License is distributed on an
42    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
43    * KIND, either express or implied. See the License for the
44    * specific language governing permissions and limitations
45    * under the License.
46    */
 
47    public final class JsoupUtils {
48   
 
49  0 toggle private JsoupUtils() {
50    // util
51    }
52   
53    /**
54    * Parse HTML string into a Jsoup Document with XML output settings.
55    *
56    * @param html
57    * HTML string
58    * @return Jsoup Document
59    */
 
60  188 toggle @Nonnull
61    public static Document createHtmlDocument(@Nonnull String html) {
62  188 requireNonNull(html);
63  188 Document doc = Jsoup.parse(html, "", createHtmlParser());
64    // doc.outputSettings()
65    // .outline(false)
66    // .syntax(Document.OutputSettings.Syntax.xml)
67    // .prettyPrint(false)
68    // .escapeMode(Entities.EscapeMode.xhtml)
69    // .charset(StandardCharsets.UTF_8);
70  188 return doc;
71    }
72   
 
73  0 toggle @Nonnull
74    public static Document createXmlDocument(@Nonnull String html) {
75  0 requireNonNull(html);
76  0 Document doc = Jsoup.parse(html, "", createXmlParser());
77  0 doc.outputSettings()
78    .outline(false)
79    .syntax(Document.OutputSettings.Syntax.xml)
80    .prettyPrint(false)
81    .escapeMode(org.jsoup.nodes.Entities.EscapeMode.xhtml)
82    .charset(StandardCharsets.UTF_8);
83  0 return doc;
84    }
85   
 
86  188 toggle @Nonnull
87    public static Parser createHtmlParser() {
88  188 Parser parser = Parser.htmlParser();
89  188 parser.tagSet().onNewTag(tag -> {
90  1030 if (!tag.isKnownTag())
91  125 tag.set(Tag.SelfClose);
92    });
93  188 return parser;
94    }
95   
 
96  0 toggle @Nonnull
97    public static Parser createXmlParser() {
98  0 Parser parser = Parser.xmlParser();
99  0 return parser;
100    }
101   
 
102  6 toggle public static Element link(Document doc,
103    String href,
104    String name,
105    String target,
106    String img,
107    String icon,
108    String className) {
109  6 Element a = doc.createElement("a");
110  6 if (href != null && !href.isEmpty()) {
111  6 a.attr("href", href);
112    }
113  6 if (name != null && !name.isEmpty()) {
114  6 a.attr("title", name);
115    }
116  6 if (target != null && !target.isEmpty()) {
117  0 a.attr("target", target);
118    }
119  6 if (className != null && !className.isEmpty()) {
120  0 a.addClass(className);
121    }
122  6 if (img != null && !img.isEmpty()) {
123    // Image on the left side of the name
124  0 Element image = image(doc, img, "", "", "", "");
125  0 a.appendChild(image);
126  0 a.appendText(name);
127  6 } else if (icon != null && !icon.isEmpty()) {
128    // No image - optional icon though on the right of the name
129  0 a.appendText(name);
130  0 Element i = doc.createElement("i");
131  0 i.addClass(icon);
132  0 a.appendChild(i);
133    } else {
134    // No image - no icon
135  6 a.appendText(name);
136    }
137  6 return a;
138    }
139   
 
140  0 toggle public static Element image(Document doc, String src, String alt, String border, String width, String height) {
141  0 Element image = doc.createElement("img");
142  0 image.addClass("image-link");
143  0 image.attr("src", src);
144  0 if (alt != null && !alt.isEmpty()) {
145  0 image.attr("alt", alt);
146    }
147  0 if (border != null && !border.isEmpty()) {
148  0 image.attr("border", border);
149    }
150  0 if (width != null && !width.isEmpty()) {
151  0 image.attr("width", width);
152    }
153  0 if (height != null && !height.isEmpty()) {
154  0 image.attr("height", height);
155    }
156  0 return image;
157    }
158   
 
159  17968 toggle public static String getNodeName(Node node) {
160  17968 if (node instanceof Element) {
161  17968 return ((Element) node).tagName();
162    } else {
163  0 return node.nodeName();
164    }
165    }
166   
 
167  66 toggle public static boolean hasTextNode(Node node) {
168  66 return node.childNodes().stream().anyMatch(n -> {
169  22 boolean match = n.nodeName().equals("#text") && !n.toString().trim().isEmpty();
170  22 return match;
171    });
172    }
173   
174    }