Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removed previously deprecated class & method, enable Element Iterator #2246

Merged
merged 2 commits into from
Dec 15, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -7,6 +7,9 @@
* Updated the minimum Android API Level validation from 10 to **21**. As with previous jsoup versions, Android
developers need to enable core library desugaring. The minimum Java version remains Java 8.
[2173](https://github.com/jhy/jsoup/pull/2173)
* Removed previously deprecated class: `org.jsoup.UncheckedIOException` (replace with `java.io.UncheckedIOException`);
method `Element Element#forEach(Consumer)` to
`void Element#forEach(Consumer())`. [2246](https://github.com/jhy/jsoup/pull/2246)

### Improvements

@@ -16,6 +19,7 @@
* Added `Element#selectStream(String query)` and `Element#selectStream(Evaluator )` methods, that return a `Stream` of
matching elements. Elements are evaluated and returned as they are found, and the stream can be
terminated early. [2092](https://github.com/jhy/jsoup/pull/2092)
* `Element` objects now implement `Iterable`, enabling them to be used in enhanced for loops.

### Bug Fixes

1 change: 0 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
@@ -260,7 +260,6 @@
<breakBuildOnSourceIncompatibleModifications>true</breakBuildOnSourceIncompatibleModifications>
<excludes>
<exclude>@java.lang.Deprecated</exclude>
<exclude>org.jsoup.UncheckedIOException</exclude>
</excludes>
<overrideCompatibilityChangeParameters>
<!-- allows new default and move to default methods. compatible as long as existing binaries aren't making calls via reflection. if so, they need to catch errors anyway. -->
22 changes: 0 additions & 22 deletions src/main/java/org/jsoup/UncheckedIOException.java

This file was deleted.

3 changes: 1 addition & 2 deletions src/main/java/org/jsoup/helper/HttpConnection.java
Original file line number Diff line number Diff line change
@@ -3,15 +3,13 @@
import org.jsoup.Connection;
import org.jsoup.HttpStatusException;
import org.jsoup.Progress;
import org.jsoup.UncheckedIOException;
import org.jsoup.UnsupportedMimeTypeException;
import org.jsoup.internal.ControllableInputStream;
import org.jsoup.internal.Functions;
import org.jsoup.internal.StringUtil;
import org.jsoup.nodes.Document;
import org.jsoup.parser.Parser;
import org.jsoup.parser.StreamParser;
import org.jsoup.parser.TokenQueue;
import org.jspecify.annotations.Nullable;

import javax.net.ssl.HttpsURLConnection;
@@ -25,6 +23,7 @@
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UncheckedIOException;
import java.net.CookieManager;
import java.net.CookieStore;
import java.net.HttpURLConnection;
20 changes: 13 additions & 7 deletions src/main/java/org/jsoup/nodes/Element.java
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -44,7 +45,7 @@ An HTML Element consists of a tag name, attributes, and child nodes (including t
<p>
From an Element, you can extract data, traverse the node graph, and manipulate the HTML.
*/
public class Element extends Node {
public class Element extends Node implements Iterable<Element> {
private static final List<Element> EmptyChildren = Collections.emptyList();
private static final Pattern ClassSplit = Pattern.compile("\\s+");
private static final String BaseUriKey = Attributes.internalKey("baseUri");
@@ -1911,15 +1912,20 @@ public Element forEachNode(Consumer<? super Node> action) {
Perform the supplied action on this Element and each of its descendant Elements, during a depth-first traversal.
Elements may be inspected, changed, added, replaced, or removed.
@param action the function to perform on the element
@return this Element, for chaining
@see Node#forEachNode(Consumer)
@deprecated use {@link #stream()}.{@link Stream#forEach(Consumer) forEach(Consumer)} instead. (Removing this method
so Element can implement Iterable, which this signature conflicts with due to the non-void return.)
*/
@Deprecated
public Element forEach(Consumer<? super Element> action) {
@Override
public void forEach(Consumer<? super Element> action) {
stream().forEach(action);
return this;
}

/**
Returns an Iterator that iterates this Element and each of its descendant Elements, in document order.
@return an Iterator
*/
@Override
public Iterator<Element> iterator() {
return new NodeIterator<>(this, Element.class);
}

@Override
2 changes: 1 addition & 1 deletion src/main/java/org/jsoup/parser/CharacterReader.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package org.jsoup.parser;

import org.jsoup.UncheckedIOException;
import org.jsoup.helper.Validate;
import org.jsoup.internal.SoftPool;
import org.jspecify.annotations.Nullable;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
21 changes: 21 additions & 0 deletions src/test/java/org/jsoup/nodes/ElementTest.java
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -26,6 +27,8 @@
import java.util.regex.Pattern;
import java.util.stream.Stream;

import static org.jsoup.nodes.NodeIteratorTest.assertIterates;
import static org.jsoup.nodes.NodeIteratorTest.trackSeen;
import static org.jsoup.select.SelectorTest.assertSelectedOwnText;
import static org.junit.jupiter.api.Assertions.*;

@@ -2992,4 +2995,22 @@ void prettySerializationRoundTrips(Document.OutputSettings settings) {

assertEquals("Hello world", div.text());
}

@Test void elementIsIterable() {
Document doc = Jsoup.parse("<div><a id=1>One</a> Two <a id=2>Three<b>Four</a><a id=3>Five</a></div>");
String expect = "div;a#1;a#2;b;b;a#3;"; // elements only, in doc order
Element div = doc.expectFirst("div");

// for each pattern
StringBuilder seen = new StringBuilder();
for (Element el: div) {
trackSeen(el, seen);
}
assertEquals(expect, seen.toString());

// iterator
seen = new StringBuilder();
Iterator<Element> iterator = div.iterator();
assertIterates(iterator, expect);
}
}
5 changes: 3 additions & 2 deletions src/test/java/org/jsoup/nodes/NodeIteratorTest.java
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
import org.jsoup.Jsoup;
import org.junit.jupiter.api.Test;

import java.util.Iterator;
import java.util.NoSuchElementException;

import static org.junit.jupiter.api.Assertions.*;
@@ -230,7 +231,7 @@ class NodeIteratorTest {
assertContents(doc, "#root;html;head;body;div#1;p;One++;p;Two++;div#2;p;Three++;p;Four++;");
}

static <T extends Node> void assertIterates(NodeIterator<T> it, String expected) {
static <T extends Node> void assertIterates(Iterator<T> it, String expected) {
Node previous = null;
StringBuilder actual = new StringBuilder();
while (it.hasNext()) {
@@ -263,4 +264,4 @@ else if (node instanceof TextNode)
actual.append(";");
}

}
}