Skip to content
Open
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ public abstract class AbstractAsyncOperation<V> implements AsyncOperation,
Callable<V> {

protected final FutureTask<V> future;
protected final AsyncOperationListener listener;
protected final AsyncOperationListener<V> listener;

private int progressGranularity = 100;
private int progressMax, lastProgress, progressIncrement, nextProgress, bytesRead;
private long progressGranularity = 100;
private long progressMax, lastProgress, progressIncrement, nextProgress, bytesRead;

protected AbstractAsyncOperation(final AsyncOperationListener<V> listener) {
this.listener = listener;
Expand Down Expand Up @@ -109,8 +109,8 @@ public void start() {
}

protected void notifyProgress() {
final int last = lastProgress;
final int max = progressMax;
final long last = lastProgress;
final long max = progressMax;
Platform.runLater(() -> listener.onProgress(last, max));
}

Expand All @@ -123,11 +123,11 @@ protected void addProgress(int amount) {
}
}

protected int getProgressMax() {
protected long getProgressMax() {
return progressMax;
}

protected void setProgressMax(int progressMax) {
protected void setProgressMax(long progressMax) {
if (progressMax == 0) {
progressIncrement = progressGranularity;
}
Expand All @@ -145,11 +145,11 @@ else if (progressMax == -1) {
notifyProgress();
}

protected int getProgressGranularity() {
protected long getProgressGranularity() {
return progressGranularity;
}

protected void setProgressGranularity(int progressGranularity) {
protected void setProgressGranularity(long progressGranularity) {
this.progressGranularity = progressGranularity;
progressIncrement = progressMax / progressGranularity;
nextProgress = ((lastProgress / progressIncrement) + 1) * progressIncrement;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
* Abstract base class for representing remote resources identified by a URL. Subclasses may plug in arbitrary
Expand All @@ -46,72 +39,39 @@
*/
public abstract class AbstractRemoteResource<T> extends AbstractAsyncOperation<T> {

protected final String url;
protected final String method;
protected final String outboundContent;
protected int fileSize;
private Map<String, String> headers = new HashMap<>();
private Map<String, List<String>> responseHeaders = new HashMap<>();

protected AbstractRemoteResource(String url, AsyncOperationListener<T> listener) {
this(url, "GET", listener);
/**
* @param stream an {@link InputStream}, cannot be {@code null}
* @param size the size of the stream, or -1 if unknown
*/
public record SizedStream(InputStream stream, long size) {}

/**
* An interface to provide a stream with a known (or unknown) size that
* allows {@link IOException} to be thrown.
*/
public interface SizedStreamSupplier {
SizedStream get() throws IOException;
}

protected AbstractRemoteResource(String url, String method, AsyncOperationListener<T> listener) {
this(url, method, null, listener);
}
private final SizedStreamSupplier sizedStreamSupplier;

protected AbstractRemoteResource(String url, String method, String outboundContent, AsyncOperationListener<T> listener) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that outboundContent calls are no where used. Is this the reason we are cleaning up this code?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I generally remove code that I see is unused, if it otherwise would have needed to be adjusted.

protected AbstractRemoteResource(SizedStreamSupplier sizedStreamSupplier, AsyncOperationListener<T> listener) {
super(listener);
this.url = url;
this.method = method;
this.outboundContent = outboundContent;

this.sizedStreamSupplier = Objects.requireNonNull(sizedStreamSupplier, "sizedStreamSupplier");
}

protected abstract T processStream(InputStream stream) throws IOException;
protected abstract T processStream(InputStream stream);

@Override
public T call() throws IOException {
URL u = new URL(url);
InputStream stream = null;
final String protocol = u.getProtocol();
if(protocol.equals("http") || protocol.equals("https")) {
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setRequestMethod(method);
conn.setDoInput(true);

for (Map.Entry<String,String> entry : headers.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (value != null && !value.equals(""))
conn.setRequestProperty(key, value);
}
if(outboundContent != null && method.equals("POST")) {
conn.setDoOutput(true);
byte[] outBytes = outboundContent.getBytes("utf-8");
conn.setRequestProperty("Content-Length", String.valueOf(outBytes.length));
OutputStream out = conn.getOutputStream();
out.write(outBytes);
out.close();
}
conn.connect();
fileSize = conn.getContentLength();
setProgressMax(fileSize);
responseHeaders = conn.getHeaderFields();

stream = new ProgressInputStream(conn.getInputStream());
} else { // protocol is something other than http...
URLConnection con = u.openConnection();
setProgressMax(con.getContentLength());
stream = new ProgressInputStream(con.getInputStream());
}
SizedStream sizedStream = sizedStreamSupplier.get();

setProgressMax(sizedStream.size);

try {
try (ProgressInputStream stream = new ProgressInputStream(sizedStream.stream)) {
return processStream(stream);
}
finally {
stream.close();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have to continue closing the stream when background loading is happening with URL?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that the resource is getting closed.

}
}

protected class ProgressInputStream extends BufferedInputStream {
Expand Down Expand Up @@ -146,26 +106,4 @@ public int read(byte b[]) throws IOException {
return bytes;
}
}

public void setHeader(String header, String value) {
headers.put(header, value);
}

public String getResponseHeader(String header) {
String value = null;
List<String> list = responseHeaders.get(header);
// return a csv of the strings.
if(list != null) {
StringBuilder sb = new StringBuilder();
Iterator iter = list.iterator();
while(iter.hasNext()) {
sb.append(iter.next());
if(iter.hasNext()) {
sb.append(',');
}
}
value = sb.toString();
}
return value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
*
*/
public interface AsyncOperationListener<V> {
public void onProgress(int progressValue, int progressMax);
public void onProgress(long progressValue, long progressMax);
public void onCompletion(V value);
public void onCancel();
public void onException(Exception e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,12 @@ public ImageLoader loadImage(InputStream stream, double width, double height, bo
}

@Override
public AsyncOperation loadImageAsync(AsyncOperationListener<? extends ImageLoader> listener, String url, double width, double height, boolean preserveRatio, boolean smooth) {
public AsyncOperation loadImageAsync(AsyncOperationListener<ImageLoader> listener, String url, double width, double height, boolean preserveRatio, boolean smooth) {
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public AsyncOperation loadImageAsync(AsyncOperationListener<ImageLoader> listener, InputStream stream, double width, double height, boolean preserveRatio, boolean smooth) {
throw new UnsupportedOperationException("Not supported yet.");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -519,12 +519,17 @@ public abstract ImageLoader loadImage(InputStream stream,
boolean preserveRatio,
boolean smooth);
public abstract AsyncOperation loadImageAsync(
AsyncOperationListener<? extends ImageLoader> listener,
AsyncOperationListener<ImageLoader> listener,
String url,
double width, double height,
boolean preserveRatio,
boolean smooth);

public abstract AsyncOperation loadImageAsync(
AsyncOperationListener<ImageLoader> listener,
InputStream stream,
double width, double height,
boolean preserveRatio,
boolean smooth);
/*
* The loadPlatformImage method supports the following image types:
* - an object returned by the renderToImage method
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

package com.sun.javafx.tk.quantum;

import java.io.IOException;
import java.io.InputStream;

import com.sun.javafx.iio.ImageFrame;
Expand Down Expand Up @@ -227,7 +226,7 @@ public void imageLoadMetaData(ImageLoader loader, ImageMetadata metadata) {
}

static final class AsyncImageLoader
extends AbstractRemoteResource<PrismImageLoader2>
extends AbstractRemoteResource<com.sun.javafx.tk.ImageLoader>
{
private static final ExecutorService BG_LOADING_EXECUTOR =
createExecutor();
Expand All @@ -237,27 +236,22 @@ static final class AsyncImageLoader
boolean smooth;

public AsyncImageLoader(
AsyncOperationListener<PrismImageLoader2> listener,
String url,
AsyncOperationListener<com.sun.javafx.tk.ImageLoader> listener,
SizedStreamSupplier sizedStreamSupplier,
double width, double height, boolean preserveRatio, boolean smooth)
{
super(url, listener);
super(sizedStreamSupplier, listener);
this.width = width;
this.height = height;
this.preserveRatio = preserveRatio;
this.smooth = smooth;
}

@Override
protected PrismImageLoader2 processStream(InputStream stream) throws IOException {
protected PrismImageLoader2 processStream(InputStream stream) {
return new PrismImageLoader2(stream, width, height, preserveRatio, smooth);
}

@Override
public PrismImageLoader2 call() throws IOException {
return AsyncImageLoader.super.call();
}

@Override
public void start() {
BG_LOADING_EXECUTOR.execute(future);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@
import javafx.stage.Window;
import java.io.File;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
Expand Down Expand Up @@ -92,6 +95,8 @@
import com.sun.javafx.perf.PerformanceTracker;
import com.sun.javafx.runtime.async.AbstractRemoteResource;
import com.sun.javafx.runtime.async.AsyncOperationListener;
import com.sun.javafx.runtime.async.AbstractRemoteResource.SizedStream;
import com.sun.javafx.runtime.async.AbstractRemoteResource.SizedStreamSupplier;
import com.sun.javafx.scene.text.TextLayoutFactory;
import com.sun.javafx.sg.prism.NGNode;
import com.sun.javafx.tk.CompletionListener;
Expand Down Expand Up @@ -813,10 +818,42 @@ private float getMaxRenderScale() {
return new PrismImageLoader2(stream, width, height, preserveRatio, smooth);
}

@Override public AbstractRemoteResource<? extends ImageLoader> loadImageAsync(
AsyncOperationListener listener, String url,
@Override public AbstractRemoteResource<ImageLoader> loadImageAsync(
AsyncOperationListener<ImageLoader> listener, String url,
double width, double height, boolean preserveRatio, boolean smooth) {
return new PrismImageLoader2.AsyncImageLoader(listener, url, width, height, preserveRatio, smooth);

SizedStreamSupplier sizedStreamSupplier = () -> {
URL u = new URL(url);
String protocol = u.getProtocol();

if(protocol.equals("http") || protocol.equals("https")) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: add a space after if.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor suggestion: "http".equals()

HttpURLConnection conn = (HttpURLConnection) u.openConnection();

conn.setRequestMethod("GET");
conn.connect();

long size = conn.getContentLengthLong();

return new SizedStream(conn.getInputStream(), size);
}

// protocol is something other than http...
URLConnection conn = u.openConnection();
long size = conn.getContentLengthLong();

return new SizedStream(conn.getInputStream(), size);
};

return new PrismImageLoader2.AsyncImageLoader(listener, sizedStreamSupplier, width, height, preserveRatio, smooth);
}

@Override public AbstractRemoteResource<ImageLoader> loadImageAsync(
AsyncOperationListener<ImageLoader> listener, InputStream stream,
double width, double height, boolean preserveRatio, boolean smooth) {

SizedStreamSupplier sizedStreamSupplier = () -> new SizedStream(stream, -1);

return new PrismImageLoader2.AsyncImageLoader(listener, sizedStreamSupplier, width, height, preserveRatio, smooth);
}

// Note that this method should only be called by PlatformImpl.runLater
Expand Down
Loading