1 /*
   2  * Copyright (c) 2011, 2014, Oracle and/or its affiliates. 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.webkit.network;
  27 
  28 import java.net.MalformedURLException;
  29 import java.net.URL;
  30 import java.net.URLStreamHandler;
  31 import java.security.AccessController;
  32 import java.security.PrivilegedAction;
  33 import java.util.Collections;
  34 import java.util.HashMap;
  35 import java.util.Map;
  36 
  37 /**
  38  * A collection of static methods for URL creation.
  39  */
  40 public final class URLs {
  41     
  42     /**
  43      * The mapping between WebPane-specific protocol names and their
  44      * respective handlers.
  45      */
  46     private static final Map<String,URLStreamHandler> handlerMap;
  47     static {
  48         Map<String,URLStreamHandler> map =
  49                 new HashMap<String,URLStreamHandler>(2);
  50         map.put("about", new com.sun.webkit.network.about.Handler());
  51         map.put("data", new com.sun.webkit.network.data.Handler());
  52         handlerMap = Collections.unmodifiableMap(map);
  53     }
  54 
  55 
  56     /**
  57      * The private default constructor. Ensures non-instantiability.
  58      */
  59     private URLs() {
  60         throw new AssertionError();
  61     }
  62 
  63 
  64     /**
  65      * Creates a {@code URL} object from the {@code String} representation.
  66      * This method is equivalent to the {@link URL#URL(String)} constructor
  67      * with the additional support for WebPane-specific protocol handlers.
  68      * @param spec the {@code String} to parse as a {@code URL}.
  69      * @throws MalformedURLException if the string specifies an unknown
  70      *         protocol.
  71      */
  72     public static URL newURL(String spec) throws MalformedURLException {
  73         return newURL(null, spec);
  74     }
  75 
  76     /**
  77      * Creates a URL by parsing the given spec within a specified context.
  78      * This method is equivalent to the {@link URL#URL(URL,String)}
  79      * constructor with the additional support for WebPane-specific protocol
  80      * handlers.
  81      * @param context the context in which to parse the specification.
  82      * @param spec the {@code String} to parse as a {@code URL}.
  83      * @throws MalformedURLException if no protocol is specified, or an
  84      *         unknown protocol is found.
  85      */
  86     public static URL newURL(final URL context, final String spec)
  87         throws MalformedURLException
  88     {
  89         try {
  90             // Try the standard protocol handler selection procedure
  91             return new URL(context, spec);
  92         } catch (MalformedURLException ex) {
  93             // Try WebPane-specific protocol handler, if any
  94             int colonPosition = spec.indexOf(':');
  95             if (colonPosition != -1) {
  96                 final URLStreamHandler handler = handlerMap.get(
  97                     spec.substring(0, colonPosition).toLowerCase());
  98                 
  99                 try {
 100                     // We should be able to specify one of our stream handlers for the URL
 101                     // when running as an applet or a web start app.
 102                     return AccessController.doPrivileged((PrivilegedAction<URL>) () -> {
 103                         try {
 104                             return new URL(context, spec, handler);
 105                         } catch (MalformedURLException muex) {
 106                             throw new RuntimeException(muex);
 107                         }
 108                     });
 109                 } catch (RuntimeException re) {
 110                     if (re.getCause() instanceof MalformedURLException) {
 111                         throw (MalformedURLException)re.getCause();
 112                     }
 113                     throw re;
 114                 }
 115             }
 116             throw ex;
 117         }
 118     }
 119 }