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

modified: src/main/java/org/jsoup/select/StructuralEvaluator.java as per issue #2108 #2115

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/main/java/org/jsoup/Connection.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ the lifetime of the Connection object. A socket connection is only made at the p
<p>For multi-threaded implementations, it is important to use a {@link #newRequest()} for each request. The session may
be shared across concurrent threads, but a not a specific request.</p>
*/
@SuppressWarnings("unused")
public interface Connection {

/**
* GET and POST http methods.
*/
Expand Down Expand Up @@ -470,7 +468,6 @@ default Connection auth(@Nullable RequestAuthenticator authenticator) {
* Common methods for Requests and Responses
* @param <T> Type of Base, either Request or Response
*/
@SuppressWarnings("UnusedReturnValue")
interface Base<T extends Base<T>> {
/**
* Get the URL of this Request or Response. For redirected responses, this will be the final destination URL.
Expand Down Expand Up @@ -623,7 +620,6 @@ interface Base<T extends Base<T>> {
/**
* Represents a HTTP request.
*/
@SuppressWarnings("UnusedReturnValue")
interface Request extends Base<Request> {
/**
* Get the proxy used for this request.
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/jsoup/HttpStatusException.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
/**
* Signals that a HTTP request resulted in a not OK HTTP response.
*/
@SuppressWarnings("serial")
public class HttpStatusException extends IOException {
private final int statusCode;
private final String url;
Expand All @@ -22,4 +23,4 @@ public int getStatusCode() {
public String getUrl() {
return url;
}
}
}
1 change: 1 addition & 0 deletions src/main/java/org/jsoup/SerializationException.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* A SerializationException is raised whenever serialization of a DOM element fails. This exception usually wraps an
* {@link java.io.IOException} that may be thrown due to an inaccessible output stream.
*/
@SuppressWarnings("serial")
public final class SerializationException extends RuntimeException {
/**
* Creates and initializes a new serialization exception with no error message and cause.
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/org/jsoup/UncheckedIOException.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
* @deprecated Use {@link java.io.UncheckedIOException} instead. This class acted as a compatibility shim for Java
* versions prior to 1.8.
*/
@Deprecated
@SuppressWarnings("serial")
@Deprecated (forRemoval = true)
public class UncheckedIOException extends java.io.UncheckedIOException {
public UncheckedIOException(IOException cause) {
super(cause);
Expand All @@ -19,4 +20,4 @@ public UncheckedIOException(String message) {
public IOException ioException() {
return getCause();
}
}
}
1 change: 1 addition & 0 deletions src/main/java/org/jsoup/UnsupportedMimeTypeException.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
/**
* Signals that a HTTP response returned a mime type that is not supported.
*/
@SuppressWarnings("serial")
public class UnsupportedMimeTypeException extends IOException {
private final String mimeType;
private final String url;
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/org/jsoup/helper/ChangeNotifyingArrayList.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
/**
* Implementation of ArrayList that watches out for changes to the contents.
*/
@SuppressWarnings("serial")
public abstract class ChangeNotifyingArrayList<E> extends ArrayList<E> {
public ChangeNotifyingArrayList(int initialCapacity) {
protected ChangeNotifyingArrayList(int initialCapacity) {
super(initialCapacity);
}

Expand Down Expand Up @@ -78,5 +79,4 @@ public boolean retainAll(Collection<?> c) {
onContentsChanged();
return super.retainAll(c);
}

}
}
5 changes: 2 additions & 3 deletions src/main/java/org/jsoup/helper/CookieUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ static void applyCookiesToRequest(HttpConnection.Request req, HttpURLConnection
for (Map.Entry<String, List<String>> entry : storedCookies.entrySet()) {
// might be Cookie: name=value; name=value\nCookie2: name=value; name=value
List<String> cookies = entry.getValue(); // these will be name=val
if (cookies == null || cookies.size() == 0) // the cookie store often returns just an empty "Cookie" key, no val
if (cookies == null || cookies.isEmpty()) // the cookie store often returns just an empty "Cookie" key, no val
continue;

String key = entry.getKey(); // Cookie or Cookie2
Expand Down Expand Up @@ -85,6 +85,5 @@ static URI asUri(URL url) throws IOException {

static void storeCookies(HttpConnection.Request req, URL url, Map<String, List<String>> resHeaders) throws IOException {
req.cookieManager().put(CookieUtil.asUri(url), resHeaders); // stores cookies for session

}
}
}
27 changes: 14 additions & 13 deletions src/main/java/org/jsoup/helper/DataUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
* Internal static utilities for handling data.
*
*/
@SuppressWarnings("CharsetObjectCanBeUsed")
public final class DataUtil {
private static final Pattern charsetPattern = Pattern.compile("(?i)\\bcharset=\\s*(?:[\"'])?([^\\s,;\"']*)");
public static final Charset UTF_8 = Charset.forName("UTF-8"); // Don't use StandardCharsets, as those only appear in Android API 19, and we target 10.
Expand Down Expand Up @@ -140,21 +139,23 @@ public static Document load(Path path, @Nullable String charsetName, String base
* @see Connection.Response#streamParser()
*/
public static StreamParser streamParser(Path path, @Nullable Charset charset, String baseUri, Parser parser) throws IOException {
StreamParser streamer = new StreamParser(parser);
String charsetName = charset != null? charset.name() : null;
DataUtil.CharsetDoc charsetDoc = DataUtil.detectCharset(openStream(path), charsetName, baseUri, parser);
BufferedReader reader = new BufferedReader(new InputStreamReader(charsetDoc.input, charsetDoc.charset), DefaultBufferSize);
maybeSkipBom(reader, charsetDoc);
streamer.parse(reader, baseUri); // initializes the parse and the document, but does not step() it

return streamer;
try(StreamParser streamer = new StreamParser(parser);){
String charsetName = charset != null? charset.name() : null;
DataUtil.CharsetDoc charsetDoc = DataUtil.detectCharset(openStream(path), charsetName, baseUri, parser);
BufferedReader reader = new BufferedReader(new InputStreamReader(charsetDoc.input, charsetDoc.charset), DefaultBufferSize);
maybeSkipBom(reader, charsetDoc);
streamer.parse(reader, baseUri); // initializes the parse and the document, but does not step() it

return streamer;
}
}

/** Open an input stream from a file; if it's a gzip file, returns a GZIPInputStream to unzip it. */
private static InputStream openStream(Path path) throws IOException {
final SeekableByteChannel byteChannel = Files.newByteChannel(path);
InputStream stream = Channels.newInputStream(byteChannel);
String name = Normalizer.lowerCase(path.getFileName().toString());

if (name.endsWith(".gz") || name.endsWith(".z")) {
final boolean zipped = (stream.read() == 0x1f && stream.read() == 0x8b); // gzip magic bytes
byteChannel.position(0); // reset to start of file
Expand Down Expand Up @@ -220,7 +221,7 @@ static class CharsetDoc {
}

static Document parseInputStream(@Nullable InputStream input, @Nullable String charsetName, String baseUri, Parser parser) throws IOException {
if (input == null) // empty body // todo reconsider?
if (input == null) // empty body // to do reconsider?
return new Document(baseUri);

final Document doc;
Expand Down Expand Up @@ -375,7 +376,7 @@ static ByteBuffer emptyByteBuffer() {
return null;
}

private @Nullable static String validateCharset(@Nullable String cs) {
@Nullable private static String validateCharset(@Nullable String cs) {
if (cs == null || cs.length() == 0) return null;
cs = cs.trim().replaceAll("[\"']", "");
try {
Expand All @@ -401,7 +402,7 @@ static String mimeBoundary() {
}

private static @Nullable BomCharset detectCharsetFromBom(final ByteBuffer byteData) {
@SuppressWarnings("UnnecessaryLocalVariable") final Buffer buffer = byteData; // .mark and rewind used to return Buffer, now ByteBuffer, so cast for backward compat
final Buffer buffer = byteData; // .mark and rewind used to return Buffer, now ByteBuffer, so cast for backward compat
buffer.mark();
byte[] bom = new byte[4];
if (byteData.remaining() >= bom.length) {
Expand Down Expand Up @@ -430,4 +431,4 @@ public BomCharset(String charset, boolean offset) {
this.offset = offset;
}
}
}
}
16 changes: 8 additions & 8 deletions src/main/java/org/jsoup/helper/HttpConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
* Implementation of {@link Connection}.
* @see org.jsoup.Jsoup#connect(String)
*/
@SuppressWarnings("CharsetObjectCanBeUsed")
public class HttpConnection implements Connection {
public static final String CONTENT_ENCODING = "Content-Encoding";
/**
Expand Down Expand Up @@ -389,7 +388,7 @@ public Connection postDataCharset(String charset) {
}

@SuppressWarnings("unchecked")
private static abstract class Base<T extends Connection.Base<T>> implements Connection.Base<T> {
private abstract static class Base<T extends Connection.Base<T>> implements Connection.Base<T> {
private static final URL UnsetUrl; // only used if you created a new Request()
static {
try {
Expand Down Expand Up @@ -796,7 +795,7 @@ public static class Response extends HttpConnection.Base<Connection.Response> im
private @Nullable ControllableInputStream bodyStream;
private @Nullable HttpURLConnection conn;
private @Nullable String charset;
private @Nullable final String contentType;
@Nullable private final String contentType;
private boolean executed = false;
private boolean inputStreamRead = false;
private int numRedirects = 0;
Expand Down Expand Up @@ -970,7 +969,7 @@ private InputStream prepareParse() {
@Override public Document parse() throws IOException {
InputStream stream = prepareParse();
Document doc = DataUtil.parseInputStream(stream, charset, url.toExternalForm(), req.parser());
doc.connection(new HttpConnection(req, this)); // because we're static, don't have the connection obj. // todo - maybe hold in the req?
doc.connection(new HttpConnection(req, this)); // because we're static, don't have the connection obj. // to do - maybe hold in the req?
charset = doc.outputSettings().charset().name(); // update charset from meta-equiv, possibly
safeClose();
return doc;
Expand All @@ -980,7 +979,7 @@ private InputStream prepareParse() {
InputStream stream = prepareParse();
String baseUri = url.toExternalForm();
DataUtil.CharsetDoc charsetDoc = DataUtil.detectCharset(stream, charset, baseUri, req.parser());
// note that there may be a document in CharsetDoc as a result of scanning meta-data -- but as requires a stream parse, it is not used here. todo - revisit.
// note that there may be a document in CharsetDoc as a result of scanning meta-data -- but as requires a stream parse, it is not used here. to do - revisit.

// set up the stream parser and rig this connection up to the parsed doc:
StreamParser streamer = new StreamParser(req.parser());
Expand All @@ -994,7 +993,8 @@ private InputStream prepareParse() {
return streamer;
}

private void prepareByteData() {
@SuppressWarnings("removal")
private void prepareByteData() {
Validate.isTrue(executed, "Request must be executed (with .execute(), .get(), or .post() before getting response body");
if (bodyStream != null && byteData == null) {
Validate.isFalse(inputStreamRead, "Request has already been read (with .parse())");
Expand Down Expand Up @@ -1231,12 +1231,12 @@ private static boolean looksLikeUtf8(byte[] input) {
return foundNonAscii;
}

private @Nullable static String setOutputContentType(final Connection.Request req) {
@Nullable private static String setOutputContentType(final Connection.Request req) {
final String contentType = req.header(CONTENT_TYPE);
String bound = null;
if (contentType != null) {
// no-op; don't add content type as already set (e.g. for requestBody())
// todo - if content type already set, we could add charset
// to do - if content type already set, we could add charset

// if user has set content type to multipart/form-data, auto add boundary.
if(contentType.contains(MULTIPART_FORM_DATA) && !contentType.contains("boundary")) {
Expand Down
7 changes: 3 additions & 4 deletions src/main/java/org/jsoup/helper/UrlBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,11 @@ private static void appendToAscii(String s, boolean spaceAsPlus, StringBuilder s
} else if (c > 127) { // out of ascii range
sb.append(URLEncoder.encode(new String(Character.toChars(c)), UTF_8.name()));
// ^^ is a bit heavy-handed - if perf critical, we could optimize
if (Character.charCount(c) == 2) i++; // advance past supplemental
if (Character.charCount(c) == 2)
i++; // advance past supplemental
} else {
sb.append((char) c);
}
}
}


}
}
3 changes: 2 additions & 1 deletion src/main/java/org/jsoup/helper/ValidationException.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/**
Validation exceptions, as thrown by the methods in {@link Validate}.
*/
@SuppressWarnings("serial")
public class ValidationException extends IllegalArgumentException {

public static final String Validator = Validate.class.getName();
Expand All @@ -31,4 +32,4 @@ public synchronized Throwable fillInStackTrace() {

return this;
}
}
}
12 changes: 6 additions & 6 deletions src/main/java/org/jsoup/helper/W3CDom.java
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public static String asString(Document doc, @Nullable Map<String, String> proper
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doctype.getPublicId());
if (!StringUtil.isBlank(doctype.getSystemId()))
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doctype.getSystemId());
// handle <!doctype html> for legacy dom. TODO: nicer if <!doctype html>
// handle <!doctype html> for legacy dom. TO DO: nicer if <!doctype html>
else if (doctype.getName().equalsIgnoreCase("html")
&& StringUtil.isBlank(doctype.getPublicId())
&& StringUtil.isBlank(doctype.getSystemId()))
Expand All @@ -158,12 +158,12 @@ static Properties propertiesFromMap(Map<String, String> map) {
}

/** Canned default for HTML output. */
public static HashMap<String, String> OutputHtml() {
public static Map<String, String> OutputHtml() {
return methodMap("html");
}

/** Canned default for XML output. */
public static HashMap<String, String> OutputXml() {
public static Map<String, String> OutputXml() {
return methodMap("xml");
}

Expand Down Expand Up @@ -353,7 +353,7 @@ protected static class W3CBuilder implements NodeVisitor {
private final Stack<HashMap<String, String>> namespacesStack = new Stack<>(); // stack of namespaces, prefix => urn
private Node dest;
private Syntax syntax = Syntax.xml; // the syntax (to coerce attributes to). From the input doc if available.
/*@Nullable*/ private final org.jsoup.nodes.Element contextElement; // todo - unsure why this can't be marked nullable?
/*@Nullable*/ private final org.jsoup.nodes.Element contextElement; // to do - unsure why this can't be marked nullable?

public W3CBuilder(Document doc) {
this.doc = doc;
Expand Down Expand Up @@ -414,6 +414,7 @@ private void append(Node append, org.jsoup.nodes.Node source) {
dest.appendChild(append);
}

@Override
public void tail(org.jsoup.nodes.Node source, int depth) {
if (source instanceof org.jsoup.nodes.Element && dest.getParentNode() instanceof Element) {
dest = dest.getParentNode(); // undescend
Expand Down Expand Up @@ -454,6 +455,5 @@ private String updateNamespaces(org.jsoup.nodes.Element el) {
int pos = el.tagName().indexOf(':');
return pos > 0 ? el.tagName().substring(0, pos) : "";
}

}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.jsoup.internal;

import org.jsoup.helper.DataUtil;
import org.jsoup.helper.Validate;

import java.io.BufferedInputStream;
Expand Down Expand Up @@ -110,13 +109,11 @@ public static ByteBuffer readToByteBuffer(InputStream in, int max) throws IOExce
return ByteBuffer.wrap(outStream.toByteArray());
}

@SuppressWarnings("NonSynchronizedMethodOverridesSynchronizedMethod") // not synchronized in later JDKs
@Override public void reset() throws IOException {
super.reset();
remaining = maxSize - markPos;
}

@SuppressWarnings("NonSynchronizedMethodOverridesSynchronizedMethod") // not synchronized in later JDKs
@Override public void mark(int readlimit) {
super.mark(readlimit);
markPos = maxSize - remaining;
Expand All @@ -140,4 +137,4 @@ private boolean expired() {
public BufferedInputStream inputStream() {
return buff;
}
}
}
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,12 +1,12 @@
package org.jsoup.parser;

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

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.UncheckedIOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Expand Down