001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.io;
003
004import java.net.URL;
005import java.util.Collections;
006import java.util.EnumSet;
007import java.util.Map;
008import java.util.Set;
009import java.util.concurrent.ConcurrentHashMap;
010
011import org.openstreetmap.josm.tools.Logging;
012
013/**
014 * Handles global network features (errors and online/offline resources).
015 * @since 14121
016 */
017public final class NetworkManager {
018
019    private static final Map<String, Throwable> NETWORK_ERRORS = new ConcurrentHashMap<>();
020
021    private static final Set<OnlineResource> OFFLINE_RESOURCES = EnumSet.noneOf(OnlineResource.class);
022
023    private NetworkManager() {
024        // Hide constructor
025    }
026
027    /**
028     * Adds a new network error that occur to give a hint about broken Internet connection.
029     * Do not use this method for errors known for sure thrown because of a bad proxy configuration.
030     *
031     * @param url The accessed URL that caused the error
032     * @param t The network error
033     * @return The previous error associated to the given resource, if any. Can be {@code null}
034     */
035    public static Throwable addNetworkError(String url, Throwable t) {
036        if (url != null && t != null) {
037            return NETWORK_ERRORS.put(url, t);
038        }
039        return null;
040    }
041
042    /**
043     * Adds a new network error that occur to give a hint about broken Internet connection.
044     * Do not use this method for errors known for sure thrown because of a bad proxy configuration.
045     *
046     * @param url The accessed URL that caused the error
047     * @param t The network error
048     * @return The previous error associated to the given resource, if any. Can be {@code null}
049     */
050    public static Throwable addNetworkError(URL url, Throwable t) {
051        if (url != null && t != null) {
052            Throwable old = addNetworkError(url.toExternalForm(), t);
053            if (old != null) {
054                Logging.warn("Already here "+old);
055            }
056            return old;
057        }
058        return null;
059    }
060
061    /**
062     * Returns the network errors that occurred until now.
063     * @return the network errors that occurred until now, indexed by URL
064     */
065    public static Map<String, Throwable> getNetworkErrors() {
066        return Collections.unmodifiableMap(NETWORK_ERRORS);
067    }
068
069    /**
070     * Clears the network errors cache.
071     */
072    public static void clearNetworkErrors() {
073        NETWORK_ERRORS.clear();
074    }
075
076    /**
077     * Determines if the given online resource specified as URL is currently offline.
078     * @param url the online resource specified as URL
079     * @return {@code true} if {@code url} is offline and should not be accessed
080     * @since 16426
081     */
082    public static boolean isOffline(String url) {
083        return OFFLINE_RESOURCES.stream().anyMatch(r -> r.matches(url));
084    }
085
086    /**
087     * Determines if the given online resource is currently offline.
088     * @param r the online resource
089     * @return {@code true} if {@code r} is offline and should not be accessed
090     */
091    public static boolean isOffline(OnlineResource r) {
092        return OFFLINE_RESOURCES.contains(r) || OFFLINE_RESOURCES.contains(OnlineResource.ALL);
093    }
094
095    /**
096     * Sets the given online resource to offline state.
097     * @param r the online resource
098     * @return {@code true} if {@code r} was not already offline
099     */
100    public static boolean setOffline(OnlineResource r) {
101        return OFFLINE_RESOURCES.add(r);
102    }
103
104    /**
105     * Sets the given online resource to online state.
106     * @param r the online resource
107     * @return {@code true} if {@code r} was offline
108     */
109    public static boolean setOnline(OnlineResource r) {
110        return OFFLINE_RESOURCES.remove(r);
111    }
112
113    /**
114     * Replies the set of online resources currently offline.
115     * @return the set of online resources currently offline
116     */
117    public static Set<OnlineResource> getOfflineResources() {
118        return EnumSet.copyOf(OFFLINE_RESOURCES);
119    }
120}