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