jdk/src/windows/classes/sun/nio/fs/WindowsUriSupport.java
changeset 2057 3acf8e5e2ca0
child 5506 202f599c92aa
equal deleted inserted replaced
2056:115e09b7a004 2057:3acf8e5e2ca0
       
     1 /*
       
     2  * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 package sun.nio.fs;
       
    27 
       
    28 import java.net.URI;
       
    29 import java.net.URISyntaxException;
       
    30 
       
    31 /**
       
    32  * Utility methods to convert between Path and URIs.
       
    33  */
       
    34 
       
    35 class WindowsUriSupport {
       
    36     private WindowsUriSupport() {
       
    37     }
       
    38 
       
    39     // suffix for IPv6 literal address
       
    40     private static final String IPV6_LITERAL_SUFFIX = ".ipv6-literal.net";
       
    41 
       
    42     /**
       
    43      * Returns URI to represent the given (absolute) path
       
    44      */
       
    45     private static URI toUri(String path, boolean isUnc, boolean addSlash) {
       
    46         String uriHost;
       
    47         String uriPath;
       
    48 
       
    49         if (isUnc) {
       
    50             int slash = path.indexOf('\\', 2);
       
    51             uriHost = path.substring(2, slash);
       
    52             uriPath = path.substring(slash).replace('\\', '/');
       
    53 
       
    54             // handle IPv6 literal addresses
       
    55             // 1. drop .ivp6-literal.net
       
    56             // 2. replace "-" with ":"
       
    57             // 3. replace "s" with "%" (zone/scopeID delimiter)
       
    58             if (uriHost.endsWith(IPV6_LITERAL_SUFFIX)) {
       
    59                 uriHost = uriHost
       
    60                     .substring(0, uriHost.length() - IPV6_LITERAL_SUFFIX.length())
       
    61                     .replace('-', ':')
       
    62                     .replace('s', '%');
       
    63             }
       
    64         } else {
       
    65             uriHost = "";
       
    66             uriPath = "/" + path.replace('\\', '/');
       
    67         }
       
    68 
       
    69         // append slash if known to be directory
       
    70         if (addSlash)
       
    71             uriPath += "/";
       
    72 
       
    73         // return file:///C:/My%20Documents or file://server/share/foo
       
    74         try {
       
    75             return new URI("file", uriHost, uriPath, null);
       
    76         } catch (URISyntaxException x) {
       
    77             if (!isUnc)
       
    78                 throw new AssertionError(x);
       
    79         }
       
    80 
       
    81         // if we get here it means we've got a UNC with reserved characters
       
    82         // in the server name. The authority component cannot contain escaped
       
    83         // octets so fallback to encoding the server name into the URI path
       
    84         // component.
       
    85         uriPath = "//" + path.replace('\\', '/');
       
    86         if (addSlash)
       
    87             uriPath += "/";
       
    88         try {
       
    89             return new URI("file", null, uriPath, null);
       
    90         } catch (URISyntaxException x) {
       
    91             throw new AssertionError(x);
       
    92         }
       
    93     }
       
    94 
       
    95     /**
       
    96      * Converts given Path to a URI
       
    97      */
       
    98     static URI toUri(WindowsPath path) {
       
    99         path = path.toAbsolutePath();
       
   100         String s = path.toString();
       
   101 
       
   102         // trailing slash will be added if file is a directory. Skip check if
       
   103         // already have trailing space
       
   104         boolean addSlash = false;
       
   105         if (!s.endsWith("\\")) {
       
   106             try {
       
   107                  addSlash = WindowsFileAttributes.get(path, true).isDirectory();
       
   108             } catch (WindowsException x) {
       
   109             }
       
   110         }
       
   111 
       
   112         return toUri(s, path.isUnc(), addSlash);
       
   113     }
       
   114 
       
   115     /**
       
   116      * Converts given URI to a Path
       
   117      */
       
   118     static WindowsPath fromUri(WindowsFileSystem fs, URI uri) {
       
   119         if (!uri.isAbsolute())
       
   120             throw new IllegalArgumentException("URI is not absolute");
       
   121         if (uri.isOpaque())
       
   122             throw new IllegalArgumentException("URI is not hierarchical");
       
   123         String scheme = uri.getScheme();
       
   124         if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
       
   125             throw new IllegalArgumentException("URI scheme is not \"file\"");
       
   126         if (uri.getFragment() != null)
       
   127             throw new IllegalArgumentException("URI has a fragment component");
       
   128         if (uri.getQuery() != null)
       
   129             throw new IllegalArgumentException("URI has a query component");
       
   130         String path = uri.getPath();
       
   131         if (path.equals(""))
       
   132             throw new IllegalArgumentException("URI path component is empty");
       
   133 
       
   134         // UNC
       
   135         String auth = uri.getAuthority();
       
   136         if (auth != null && !auth.equals("")) {
       
   137             String host = uri.getHost();
       
   138             if (host == null)
       
   139                 throw new IllegalArgumentException("URI authority component has undefined host");
       
   140             if (uri.getUserInfo() != null)
       
   141                 throw new IllegalArgumentException("URI authority component has user-info");
       
   142             if (uri.getPort() != -1)
       
   143                 throw new IllegalArgumentException("URI authority component has port number");
       
   144 
       
   145             // IPv6 literal
       
   146             // 1. drop enclosing brackets
       
   147             // 2. replace ":" with "-"
       
   148             // 3. replace "%" with "s" (zone/scopeID delimiter)
       
   149             // 4. Append .ivp6-literal.net
       
   150             if (host.startsWith("[")) {
       
   151                 host = host.substring(1, host.length()-1)
       
   152                            .replace(':', '-')
       
   153                            .replace('%', 's');
       
   154                 host += IPV6_LITERAL_SUFFIX;
       
   155             }
       
   156 
       
   157             // reconstitute the UNC
       
   158             path = "\\\\" + host + path;
       
   159         } else {
       
   160             if ((path.length() > 2) && (path.charAt(2) == ':')) {
       
   161                 // "/c:/foo" --> "c:/foo"
       
   162                 path = path.substring(1);
       
   163             }
       
   164         }
       
   165         return WindowsPath.parse(fs, path);
       
   166     }
       
   167 }