Ignore:
Timestamp:
2018-01-26T21:37:00+01:00 (6 years ago)
Author:
Don-vip
Message:

fix #15662 - allow JOSM to open JAR URLs containing exclamation marks (workaround to https://bugs.openjdk.java.net/browse/JDK-4523159)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/tools/Utils.java

    r13331 r13356  
    1414import java.io.Closeable;
    1515import java.io.File;
     16import java.io.FileNotFoundException;
    1617import java.io.IOException;
    1718import java.io.InputStream;
     
    2627import java.nio.file.Files;
    2728import java.nio.file.Path;
     29import java.nio.file.Paths;
    2830import java.nio.file.StandardCopyOption;
     31import java.nio.file.attribute.BasicFileAttributes;
     32import java.nio.file.attribute.FileTime;
    2933import java.security.AccessController;
    3034import java.security.MessageDigest;
     
    17361740        }
    17371741    }
     1742
     1743    /**
     1744     * Convenient method to open an URL stream, using JOSM HTTP client if neeeded.
     1745     * @param url URL for reading from
     1746     * @return an input stream for reading from the URL
     1747     * @throws IOException if any I/O error occurs
     1748     * @since 13356
     1749     */
     1750    public static InputStream openStream(URL url) throws IOException {
     1751        switch (url.getProtocol()) {
     1752            case "http":
     1753            case "https":
     1754                return HttpClient.create(url).connect().getContent();
     1755            case "jar":
     1756                try {
     1757                    return url.openStream();
     1758                } catch (FileNotFoundException e) {
     1759                    // Workaround to https://bugs.openjdk.java.net/browse/JDK-4523159
     1760                    String urlPath = url.getPath();
     1761                    if (urlPath.startsWith("file:/") && urlPath.split("!").length > 2) {
     1762                        try {
     1763                            // Locate jar file
     1764                            int index = urlPath.lastIndexOf("!/");
     1765                            Path jarFile = Paths.get(urlPath.substring("file:/".length(), index));
     1766                            Path filename = jarFile.getFileName();
     1767                            FileTime jarTime = Files.readAttributes(jarFile, BasicFileAttributes.class).lastModifiedTime();
     1768                            // Copy it to temp directory (hopefully free of exclamation mark) if needed (missing or older jar)
     1769                            Path jarCopy = Paths.get(System.getProperty("java.io.tmpdir")).resolve(filename);
     1770                            if (!jarCopy.toFile().exists() ||
     1771                                    Files.readAttributes(jarCopy, BasicFileAttributes.class).lastModifiedTime().compareTo(jarTime) < 0) {
     1772                                Files.copy(jarFile, jarCopy, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
     1773                            }
     1774                            // Open the stream using the copy
     1775                            return new URL(url.getProtocol() + ':' + jarCopy.toUri().toURL().toExternalForm() + urlPath.substring(index))
     1776                                    .openStream();
     1777                        } catch (RuntimeException | IOException ex) {
     1778                            Logging.warn(ex);
     1779                        }
     1780                    }
     1781                    throw e;
     1782                }
     1783            case "file":
     1784            default:
     1785                return url.openStream();
     1786        }
     1787    }
    17381788}
Note: See TracChangeset for help on using the changeset viewer.