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

Refactoring #12

Merged
merged 2 commits into from
Feb 19, 2024
Merged
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
316 changes: 146 additions & 170 deletions src/main/java/qupath/ext/omero/core/WebClient.java

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions src/main/java/qupath/ext/omero/core/WebClients.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@ public static WebClient createClientSync(String url, WebClient.Authentication au
}
}

/**
* Retrieve the client corresponding to the provided uri.
*
* @param uri the web server URI of the client to retrieve
* @return the client corresponding to the URI, or an empty Optional if not found
*/
public static Optional<WebClient> getClientFromURI(URI uri) {
return clients.stream().filter(client -> client.getApisHandler().getWebServerURI().equals(uri)).findAny();
}

/**
* Close the given client connection. The function may return
* before the connection is actually closed.
Expand Down
52 changes: 39 additions & 13 deletions src/main/java/qupath/ext/omero/core/apis/ApisHandler.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package qupath.ext.omero.core.apis;

import com.drew.lang.annotations.Nullable;
import javafx.beans.property.*;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyIntegerProperty;
import javafx.beans.property.SimpleBooleanProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import qupath.ext.omero.core.entities.annotations.AnnotationGroup;
Expand All @@ -14,17 +17,21 @@
import qupath.ext.omero.core.entities.search.SearchQuery;
import qupath.ext.omero.core.entities.search.SearchResult;
import qupath.ext.omero.core.entities.shapes.Shape;
import qupath.lib.images.servers.*;
import qupath.ext.omero.core.WebClient;
import qupath.ext.omero.core.WebUtilities;
import qupath.ext.omero.core.entities.imagemetadata.ImageMetadataResponse;
import qupath.ext.omero.core.entities.permissions.Group;
import qupath.ext.omero.core.entities.permissions.Owner;
import qupath.ext.omero.core.entities.repositoryentities.serverentities.image.Image;
import qupath.lib.images.servers.PixelType;
import qupath.lib.images.servers.TileRequest;

import java.awt.image.BufferedImage;
import java.net.URI;
import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
Expand Down Expand Up @@ -56,6 +63,7 @@ public class ApisHandler implements AutoCloseable {
private final WebclientApi webclientApi;
private final WebGatewayApi webGatewayApi;
private final IViewerApi iViewerApi;
private final BooleanProperty areOrphanedImagesLoading = new SimpleBooleanProperty(false);
private final Map<Long, BufferedImage> thumbnails = new ConcurrentHashMap<>();
private final Map<Class<? extends RepositoryEntity>, BufferedImage> omeroIcons = new ConcurrentHashMap<>();
private final boolean canSkipAuthentication;
Expand All @@ -75,12 +83,11 @@ private ApisHandler(URI host, JsonApi jsonApi, boolean canSkipAuthentication) {
* <p>Attempt to create a request handler.</p>
* <p>This function is asynchronous.</p>
*
* @param client the corresponding web client
* @param host the base server URI (e.g. <a href="https://idr.openmicroscopy.org">https://idr.openmicroscopy.org</a>)
* @return a CompletableFuture with the request handler, an empty Optional if an error occurred
*/
public static CompletableFuture<Optional<ApisHandler>> create(WebClient client, URI host) {
return JsonApi.create(client, host).thenApplyAsync(jsonApi -> {
public static CompletableFuture<Optional<ApisHandler>> create(URI host) {
return JsonApi.create(host).thenApplyAsync(jsonApi -> {
if (jsonApi.isPresent()) {
try {
return Optional.of(new ApisHandler(host, jsonApi.get(), jsonApi.get().canSkipAuthentication().get()));
Expand Down Expand Up @@ -280,24 +287,39 @@ public CompletableFuture<Optional<Image>> getImage(long imageID) {
}

/**
* See {@link JsonApi#getNumberOfOrphanedImages()}.
* <p>Attempt to get the number of orphaned images of this server.</p>
*
* @return a CompletableFuture with the number of orphaned images, or 0 if it couldn't be retrieved
*/
public CompletableFuture<Integer> getNumberOfOrphanedImages() {
return jsonApi.getNumberOfOrphanedImages();
return getOrphanedImagesIds().thenApply(jsonApi::getNumberOfOrphanedImages);
}

/**
* See {@link JsonApi#populateOrphanedImagesIntoList(List)}.
* <p>
* Populate all orphaned images of this server to the list specified in parameter.
* This function populates and doesn't return a list because the number of images can
* be large, so this operation can take tens of seconds.
* </p>
* <p>The list can be updated from any thread.</p>
*
* @param children the list which should be populated by the orphaned images. It should
* be possible to add elements to this list
*/
public void populateOrphanedImagesIntoList(List<Image> children) {
jsonApi.populateOrphanedImagesIntoList(children);
setOrphanedImagesLoading(true);

getOrphanedImagesIds()
.thenAcceptAsync(orphanedImageIds -> jsonApi.populateOrphanedImagesIntoList(children, orphanedImageIds))
.thenRun(() -> setOrphanedImagesLoading(false));
}

/**
* See {@link JsonApi#areOrphanedImagesLoading()}.
* @return whether orphaned images are currently being loaded.
* This property may be updated from any thread
*/
public ReadOnlyBooleanProperty areOrphanedImagesLoading() {
return jsonApi.areOrphanedImagesLoading();
return areOrphanedImagesLoading;
}

/**
Expand Down Expand Up @@ -554,4 +576,8 @@ public CompletableFuture<Boolean> writeROIs(long id, Collection<Shape> shapes, b
public CompletableFuture<Optional<ImageSettings>> getImageSettings(long imageId) {
return iViewerApi.getImageSettings(imageId);
}

private synchronized void setOrphanedImagesLoading(boolean orphanedImagesLoading) {
areOrphanedImagesLoading.set(orphanedImagesLoading);
}
}
Loading
Loading