1 /* URL.java -- Uniform Resource Locator Class
2 Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
41 import gnu
.java
.net
.URLParseError
;
43 import java
.io
.IOException
;
44 import java
.io
.InputStream
;
45 import java
.io
.ObjectInputStream
;
46 import java
.io
.ObjectOutputStream
;
47 import java
.io
.Serializable
;
48 import java
.security
.AccessController
;
49 import java
.security
.PrivilegedAction
;
50 import java
.util
.HashMap
;
51 import java
.util
.StringTokenizer
;
55 * Written using on-line Java Platform 1.2 API Specification, as well
56 * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
57 * Status: Believed complete and correct.
61 * This final class represents an Internet Uniform Resource Locator (URL).
62 * For details on the syntax of URL's and what they can be used for,
63 * refer to RFC 1738, available from <a
64 * href="http://ds.internic.net/rfcs/rfc1738.txt">
65 * http://ds.internic.net/rfcs/rfc1738.txt</a>
67 * There are a great many protocols supported by URL's such as "http",
68 * "ftp", and "file". This object can handle any arbitrary URL for which
69 * a URLStreamHandler object can be written. Default protocol handlers
70 * are provided for the "http" and "ftp" protocols. Additional protocols
71 * handler implementations may be provided in the future. In any case,
72 * an application or applet can install its own protocol handlers that
73 * can be "chained" with other protocol hanlders in the system to extend
74 * the base functionality provided with this class. (Note, however, that
75 * unsigned applets cannot access properties by default or install their
76 * own protocol handlers).
78 * This chaining is done via the system property java.protocol.handler.pkgs
79 * If this property is set, it is assumed to be a "|" separated list of
80 * package names in which to attempt locating protocol handlers. The
81 * protocol handler is searched for by appending the string
82 * ".<protocol>.Handler" to each packed in the list until a hander is
83 * found. If a protocol handler is not found in this list of packages, or if
84 * the property does not exist, then the default protocol handler of
85 * "gnu.java.net.<protocol>.Handler" is tried. If this is
86 * unsuccessful, a MalformedURLException is thrown.
88 * All of the constructor methods of URL attempt to load a protocol
89 * handler and so any needed protocol handlers must be installed when
90 * the URL is constructed.
92 * Here is an example of how URL searches for protocol handlers. Assume
93 * the value of java.protocol.handler.pkgs is "com.foo|com.bar" and the
94 * URL is "news://comp.lang.java.programmer". URL would looking the
95 * following places for protocol handlers:
97 * com.foo.news.Handler
98 * com.bar.news.Handler
99 * gnu.java.net.news.Handler
101 * If the protocol handler is not found in any of those locations, a
102 * MalformedURLException would be thrown.
104 * Please note that a protocol handler must be a subclass of
107 * Normally, this class caches protocol handlers. Once it finds a handler
108 * for a particular protocol, it never tries to look up a new handler
109 * again. However, if the system property
110 * gnu.java.net.nocache_protocol_handlers is set, then this
111 * caching behavior is disabled. This property is specific to this
112 * implementation. Sun's JDK may or may not do protocol caching, but it
113 * almost certainly does not examine this property.
115 * Please also note that an application can install its own factory for
116 * loading protocol handlers (see setURLStreamHandlerFactory). If this is
117 * done, then the above information is superseded and the behavior of this
118 * class in loading protocol handlers is dependent on that factory.
120 * @author Aaron M. Renn (arenn@urbanophile.com)
121 * @author Warren Levy (warrenl@cygnus.com)
123 * @see URLStreamHandler
125 public final class URL
implements Serializable
127 private static final String DEFAULT_SEARCH_PATH
=
128 "gnu.java.net.protocol|gnu.inet";
130 // Cached System ClassLoader
131 private static ClassLoader systemClassLoader
;
134 * The name of the protocol for this URL.
135 * The protocol is always stored in lower case.
137 private String protocol
;
140 * The "authority" portion of the URL.
142 private String authority
;
145 * The hostname or IP address of this protocol.
146 * This includes a possible user. For example <code>joe@some.host.net</code>.
151 * The user information necessary to establish the connection.
153 private String userInfo
;
156 * The port number of this protocol or -1 if the port number used is
157 * the default for this protocol.
159 private int port
= -1; // Initialize for constructor using context.
162 * The "file" portion of the URL. It is defined as <code>path[?query]</code>.
167 * The anchor portion of the URL.
172 * This is the hashCode for this URL
174 private int hashCode
;
177 * The protocol handler in use for this URL
179 transient URLStreamHandler ph
;
182 * If an application installs its own protocol handler factory, this is
183 * where we keep track of it.
185 private static URLStreamHandlerFactory factory
;
186 private static final long serialVersionUID
= -7627629688361524110L;
189 * This a table where we cache protocol handlers to avoid the overhead
190 * of looking them up each time.
192 private static HashMap ph_cache
= new HashMap();
195 * Whether or not to cache protocol handlers.
197 private static boolean cache_handlers
;
201 String s
= System
.getProperty("gnu.java.net.nocache_protocol_handlers");
204 cache_handlers
= true;
206 cache_handlers
= false;
210 * Constructs a URL and loads a protocol handler for the values passed as
213 * @param protocol The protocol for this URL ("http", "ftp", etc)
214 * @param host The hostname or IP address to connect to
215 * @param port The port number to use, or -1 to use the protocol's
217 * @param file The "file" portion of the URL.
219 * @exception MalformedURLException If a protocol handler cannot be loaded or
220 * a parse error occurs.
222 public URL(String protocol
, String host
, int port
, String file
)
223 throws MalformedURLException
225 this(protocol
, host
, port
, file
, null);
229 * Constructs a URL and loads a protocol handler for the values passed in
230 * as arugments. Uses the default port for the protocol.
232 * @param protocol The protocol for this URL ("http", "ftp", etc)
233 * @param host The hostname or IP address for this URL
234 * @param file The "file" portion of this URL.
236 * @exception MalformedURLException If a protocol handler cannot be loaded or
237 * a parse error occurs.
239 public URL(String protocol
, String host
, String file
)
240 throws MalformedURLException
242 this(protocol
, host
, -1, file
, null);
246 * This method initializes a new instance of <code>URL</code> with the
247 * specified protocol, host, port, and file. Additionally, this method
248 * allows the caller to specify a protocol handler to use instead of
249 * the default. If this handler is specified, the caller must have
250 * the "specifyStreamHandler" permission (see <code>NetPermission</code>)
251 * or a <code>SecurityException</code> will be thrown.
253 * @param protocol The protocol for this URL ("http", "ftp", etc)
254 * @param host The hostname or IP address to connect to
255 * @param port The port number to use, or -1 to use the protocol's default
257 * @param file The "file" portion of the URL.
258 * @param ph The protocol handler to use with this URL.
260 * @exception MalformedURLException If no protocol handler can be loaded
261 * for the specified protocol.
262 * @exception SecurityException If the <code>SecurityManager</code> exists
263 * and does not allow the caller to specify its own protocol handler.
267 public URL(String protocol
, String host
, int port
, String file
,
268 URLStreamHandler ph
) throws MalformedURLException
270 if (protocol
== null)
271 throw new MalformedURLException("null protocol");
272 protocol
= protocol
.toLowerCase();
273 this.protocol
= protocol
;
277 SecurityManager s
= System
.getSecurityManager();
279 s
.checkPermission(new NetPermission("specifyStreamHandler"));
284 this.ph
= getURLStreamHandler(protocol
);
287 throw new MalformedURLException("Protocol handler not found: "
292 this.authority
= (host
!= null) ? host
: "";
293 if (port
>= 0 && host
!= null)
294 this.authority
+= ":" + port
;
296 int hashAt
= file
.indexOf('#');
304 this.file
= file
.substring(0, hashAt
);
305 this.ref
= file
.substring(hashAt
+ 1);
307 hashCode
= hashCode(); // Used for serialization.
311 * Initializes a URL from a complete string specification such as
312 * "http://www.urbanophile.com/arenn/". First the protocol name is parsed
313 * out of the string. Then a handler is located for that protocol and
314 * the parseURL() method of that protocol handler is used to parse the
317 * @param spec The complete String representation of a URL
319 * @exception MalformedURLException If a protocol handler cannot be found
320 * or the URL cannot be parsed
322 public URL(String spec
) throws MalformedURLException
324 this((URL
) null, spec
!= null ? spec
: "", (URLStreamHandler
) null);
328 * This method parses a String representation of a URL within the
329 * context of an existing URL. Principally this means that any
330 * fields not present the URL are inheritied from the context URL.
331 * This allows relative URL's to be easily constructed. If the
332 * context argument is null, then a complete URL must be specified
333 * in the URL string. If the protocol parsed out of the URL is
334 * different from the context URL's protocol, then then URL String
335 * is also expected to be a complete URL.
337 * @param context The context on which to parse the specification
338 * @param spec The string to parse an URL
340 * @exception MalformedURLException If a protocol handler cannot be found
341 * for the URL cannot be parsed
343 public URL(URL context
, String spec
) throws MalformedURLException
345 this(context
, spec
, (URLStreamHandler
) null);
349 * Creates an URL from given arguments
350 * This method parses a String representation of a URL within the
351 * context of an existing URL. Principally this means that any fields
352 * not present the URL are inheritied from the context URL. This allows
353 * relative URL's to be easily constructed. If the context argument is
354 * null, then a complete URL must be specified in the URL string.
355 * If the protocol parsed out of the URL is different
356 * from the context URL's protocol, then then URL String is also
357 * expected to be a complete URL.
359 * Additionally, this method allows the caller to specify a protocol handler
360 * to use instead of the default. If this handler is specified, the caller
361 * must have the "specifyStreamHandler" permission
362 * (see <code>NetPermission</code>) or a <code>SecurityException</code>
365 * @param context The context in which to parse the specification
366 * @param spec The string to parse as an URL
367 * @param ph The stream handler for the URL
369 * @exception MalformedURLException If a protocol handler cannot be found
370 * or the URL cannot be parsed
371 * @exception SecurityException If the <code>SecurityManager</code> exists
372 * and does not allow the caller to specify its own protocol handler.
376 public URL(URL context
, String spec
, URLStreamHandler ph
)
377 throws MalformedURLException
379 /* A protocol is defined by the doc as the substring before a ':'
380 * as long as the ':' occurs before any '/'.
382 * If context is null, then spec must be an absolute URL.
384 * The relative URL need not specify all the components of a URL.
385 * If the protocol, host name, or port number is missing, the value
386 * is inherited from the context. A bare file component is appended
387 * to the context's file. The optional anchor is not inherited.
390 // If this is an absolute URL, then ignore context completely.
391 // An absolute URL must have chars prior to "://" but cannot have a colon
392 // right after the "://". The second colon is for an optional port value
393 // and implies that the host from the context is used if available.
395 int slash
= spec
.indexOf('/');
396 if ((colon
= spec
.indexOf("://", 1)) > 0
397 && ((colon
< slash
|| slash
< 0))
398 && ! spec
.regionMatches(colon
, "://:", 0, 4))
401 if ((colon
= spec
.indexOf(':')) > 0
402 && (colon
< slash
|| slash
< 0))
404 // Protocol specified in spec string.
405 protocol
= spec
.substring(0, colon
).toLowerCase();
406 if (context
!= null && context
.protocol
.equals(protocol
))
408 // The 1.2 doc specifically says these are copied to the new URL.
411 userInfo
= context
.userInfo
;
412 authority
= context
.authority
;
415 else if (context
!= null)
417 // Protocol NOT specified in spec string.
418 // Use context fields (except ref) as a foundation for relative URLs.
420 protocol
= context
.protocol
;
423 userInfo
= context
.userInfo
;
424 if (spec
.indexOf(":/", 1) < 0)
427 if (file
== null || file
.length() == 0)
430 authority
= context
.authority
;
432 else // Protocol NOT specified in spec. and no context available.
433 throw new MalformedURLException("Absolute URL required with null"
434 + " context: " + spec
);
436 protocol
= protocol
.trim();
440 SecurityManager s
= System
.getSecurityManager();
442 s
.checkPermission(new NetPermission("specifyStreamHandler"));
447 this.ph
= getURLStreamHandler(protocol
);
450 throw new MalformedURLException("Protocol handler not found: "
453 // JDK 1.2 doc for parseURL specifically states that any '#' ref
454 // is to be excluded by passing the 'limit' as the indexOf the '#'
455 // if one exists, otherwise pass the end of the string.
456 int hashAt
= spec
.indexOf('#', colon
+ 1);
460 this.ph
.parseURL(this, spec
, colon
+ 1,
461 hashAt
< 0 ? spec
.length() : hashAt
);
463 catch (URLParseError e
)
465 throw new MalformedURLException(e
.getMessage());
469 ref
= spec
.substring(hashAt
+ 1);
471 hashCode
= hashCode(); // Used for serialization.
475 * Test another URL for equality with this one. This will be true only if
476 * the argument is non-null and all of the fields in the URL's match
477 * exactly (ie, protocol, host, port, file, and ref). Overrides
478 * Object.equals(), implemented by calling the equals method of the handler.
480 * @param obj The URL to compare with
482 * @return true if the URL is equal, false otherwise
484 public boolean equals(Object obj
)
486 if (! (obj
instanceof URL
))
489 return ph
.equals(this, (URL
) obj
);
493 * Returns the contents of this URL as an object by first opening a
494 * connection, then calling the getContent() method against the connection
496 * @return A content object for this URL
497 * @exception IOException If opening the connection or getting the
502 public Object
getContent() throws IOException
504 return openConnection().getContent();
508 * Gets the contents of this URL
510 * @param classes The allow classes for the content object.
512 * @return a context object for this URL.
514 * @exception IOException If an error occurs
516 public Object
getContent(Class
[] classes
) throws IOException
518 // FIXME: implement this
523 * Returns the file portion of the URL.
524 * Defined as <code>path[?query]</code>.
525 * Returns the empty string if there is no file portion.
527 * @return The filename specified in this URL, or an empty string if empty.
529 public String
getFile()
531 return file
== null ?
"" : file
;
535 * Returns the path of the URL. This is the part of the file before any '?'
538 * @return The path specified in this URL, or null if empty.
542 public String
getPath()
544 // The spec says we need to return an empty string, but some
545 // applications depends on receiving null when the path is empty.
548 int quest
= file
.indexOf('?');
549 return quest
< 0 ?
getFile() : file
.substring(0, quest
);
553 * Returns the authority of the URL
555 * @return The authority specified in this URL.
559 public String
getAuthority()
565 * Returns the host of the URL
567 * @return The host specified in this URL.
569 public String
getHost()
571 int at
= (host
== null) ?
-1 : host
.indexOf('@');
572 return at
< 0 ? host
: host
.substring(at
+ 1, host
.length());
576 * Returns the port number of this URL or -1 if the default port number is
579 * @return The port number
581 * @see #getDefaultPort()
589 * Returns the default port of the URL. If the StreamHandler for the URL
590 * protocol does not define a default port it returns -1.
592 * @return The default port of the current protocol.
594 public int getDefaultPort()
596 return ph
.getDefaultPort();
600 * Returns the protocol of the URL
602 * @return The specified protocol.
604 public String
getProtocol()
610 * Returns the ref (sometimes called the "# reference" or "anchor") portion
615 public String
getRef()
621 * Returns the user information of the URL. This is the part of the host
622 * name before the '@'.
624 * @return the user at a particular host or null when no user defined.
626 public String
getUserInfo()
628 if (userInfo
!= null)
630 int at
= (host
== null) ?
-1 : host
.indexOf('@');
631 return at
< 0 ?
null : host
.substring(0, at
);
635 * Returns the query of the URL. This is the part of the file before the
638 * @return the query part of the file, or null when there is no query part.
640 public String
getQuery()
642 int quest
= (file
== null) ?
-1 : file
.indexOf('?');
643 return quest
< 0 ?
null : file
.substring(quest
+ 1, file
.length());
647 * Returns a hashcode computed by the URLStreamHandler of this URL
649 * @return The hashcode for this URL.
651 public int hashCode()
654 return hashCode
; // Use cached value if available.
656 return ph
.hashCode(this);
660 * Returns a URLConnection object that represents a connection to the remote
661 * object referred to by the URL. The URLConnection is created by calling the
662 * openConnection() method of the protocol handler
664 * @return A URLConnection for this URL
666 * @exception IOException If an error occurs
668 public URLConnection
openConnection() throws IOException
670 return ph
.openConnection(this);
674 * Opens a connection to this URL and returns an InputStream for reading
675 * from that connection
677 * @return An <code>InputStream</code> for this URL.
679 * @exception IOException If an error occurs
681 public InputStream
openStream() throws IOException
683 return openConnection().getInputStream();
687 * Tests whether or not another URL refers to the same "file" as this one.
688 * This will be true if and only if the passed object is not null, is a
689 * URL, and matches all fields but the ref (ie, protocol, host, port,
692 * @param url The URL object to test with
694 * @return true if URL matches this URL's file, false otherwise
696 public boolean sameFile(URL url
)
698 return ph
.sameFile(this, url
);
702 * Sets the specified fields of the URL. This is not a public method so
703 * that only URLStreamHandlers can modify URL fields. This might be called
704 * by the <code>parseURL()</code> method in that class. URLs are otherwise
705 * constant. If the given protocol does not exist, it will keep the previously
708 * @param protocol The protocol name for this URL
709 * @param host The hostname or IP address for this URL
710 * @param port The port number of this URL
711 * @param file The "file" portion of this URL.
712 * @param ref The anchor portion of this URL.
714 protected void set(String protocol
, String host
, int port
, String file
,
717 URLStreamHandler protocolHandler
= null;
718 protocol
= protocol
.toLowerCase();
719 if (! this.protocol
.equals(protocol
))
720 protocolHandler
= getURLStreamHandler(protocol
);
722 // It is an hidden feature of the JDK. If the protocol does not exist,
723 // we keep the previously initialized protocol.
724 if (protocolHandler
!= null)
726 this.ph
= protocolHandler
;
727 this.protocol
= protocol
;
736 this.authority
+= host
;
738 this.authority
+= ":" + port
;
740 hashCode
= hashCode(); // Used for serialization.
744 * Sets the specified fields of the URL. This is not a public method so
745 * that only URLStreamHandlers can modify URL fields. URLs are otherwise
746 * constant. If the given protocol does not exist, it will keep the previously
749 * @param protocol The protocol name for this URL.
750 * @param host The hostname or IP address for this URL.
751 * @param port The port number of this URL.
752 * @param authority The authority of this URL.
753 * @param userInfo The user and password (if needed) of this URL.
754 * @param path The "path" portion of this URL.
755 * @param query The query of this URL.
756 * @param ref The anchor portion of this URL.
760 protected void set(String protocol
, String host
, int port
, String authority
,
761 String userInfo
, String path
, String query
, String ref
)
763 URLStreamHandler protocolHandler
= null;
764 protocol
= protocol
.toLowerCase();
765 if (! this.protocol
.equals(protocol
))
766 protocolHandler
= getURLStreamHandler(protocol
);
768 // It is an hidden feature of the JDK. If the protocol does not exist,
769 // we keep the previously initialized protocol.
770 if (protocolHandler
!= null)
772 this.ph
= protocolHandler
;
773 this.protocol
= protocol
;
776 this.userInfo
= userInfo
;
778 this.authority
= authority
;
782 this.file
= path
+ "?" + query
;
784 hashCode
= hashCode(); // Used for serialization.
788 * Sets the URLStreamHandlerFactory for this class. This factory is
789 * responsible for returning the appropriate protocol handler for
792 * @param fac The URLStreamHandlerFactory class to use
794 * @exception Error If the factory is alread set.
795 * @exception SecurityException If a security manager exists and its
796 * checkSetFactory method doesn't allow the operation
798 public static synchronized void setURLStreamHandlerFactory(URLStreamHandlerFactory fac
)
801 throw new Error("URLStreamHandlerFactory already set");
803 // Throw an exception if an extant security mgr precludes
804 // setting the factory.
805 SecurityManager s
= System
.getSecurityManager();
812 * Returns a String representing this URL. The String returned is
813 * created by calling the protocol handler's toExternalForm() method.
815 * @return A string for this URL
817 public String
toExternalForm()
819 // Identical to toString().
820 return ph
.toExternalForm(this);
824 * Returns a String representing this URL. Identical to toExternalForm().
825 * The value returned is created by the protocol handler's
826 * toExternalForm method. Overrides Object.toString()
828 * @return A string for this URL
830 public String
toString()
832 // Identical to toExternalForm().
833 return ph
.toExternalForm(this);
837 * This internal method is used in two different constructors to load
838 * a protocol handler for this URL.
840 * @param protocol The protocol to load a handler for
842 * @return A URLStreamHandler for this protocol, or null when not found.
844 private static synchronized URLStreamHandler
getURLStreamHandler(String protocol
)
846 URLStreamHandler ph
= null;
848 // First, see if a protocol handler is in our cache.
851 if ((ph
= (URLStreamHandler
) ph_cache
.get(protocol
)) != null)
855 // If a non-default factory has been set, use it to find the protocol.
858 ph
= factory
.createURLStreamHandler(protocol
);
860 else if (protocol
.equals("core"))
862 ph
= new gnu
.java
.net
.protocol
.core
.Handler();
864 else if (protocol
.equals("file"))
866 // This is an interesting case. It's tempting to think that we
867 // could call Class.forName ("gnu.java.net.protocol.file.Handler") to
868 // get the appropriate class. Unfortunately, if we do that the
869 // program will never terminate, because getURLStreamHandler is
870 // eventually called by Class.forName.
872 // Treating "file" as a special case is the minimum that will
873 // fix this problem. If other protocols are required in a
874 // statically linked application they will need to be handled in
875 // the same way as "file".
876 ph
= new gnu
.java
.net
.protocol
.file
.Handler();
879 // Non-default factory may have returned null or a factory wasn't set.
880 // Use the default search algorithm to find a handler for this protocol.
883 // Get the list of packages to check and append our default handler
884 // to it, along with the JDK specified default as a last resort.
885 // Except in very unusual environments the JDK specified one shouldn't
886 // ever be needed (or available).
887 String ph_search_path
=
888 System
.getProperty("java.protocol.handler.pkgs");
890 // Tack our default package on at the ends.
891 if (ph_search_path
!= null)
892 ph_search_path
+= "|" + DEFAULT_SEARCH_PATH
;
894 ph_search_path
= DEFAULT_SEARCH_PATH
;
896 // Finally loop through our search path looking for a match.
897 StringTokenizer pkgPrefix
= new StringTokenizer(ph_search_path
, "|");
899 // Cache the systemClassLoader
900 if (systemClassLoader
== null)
902 systemClassLoader
= (ClassLoader
) AccessController
.doPrivileged
903 (new PrivilegedAction() {
906 return ClassLoader
.getSystemClassLoader();
915 // Try to get a class from the system/application
916 // classloader, initialize it, make an instance
917 // and try to cast it to a URLStreamHandler.
919 (pkgPrefix
.nextToken() + "." + protocol
+ ".Handler");
920 Class c
= Class
.forName(clsName
, true, systemClassLoader
);
921 ph
= (URLStreamHandler
) c
.newInstance();
923 catch (ThreadDeath death
)
932 while (ph
== null && pkgPrefix
.hasMoreTokens());
935 // Update the hashtable with the new protocol handler.
936 if (ph
!= null && cache_handlers
)
937 ph_cache
.put(protocol
, ph
);
944 private void readObject(ObjectInputStream ois
)
945 throws IOException
, ClassNotFoundException
947 ois
.defaultReadObject();
948 this.ph
= getURLStreamHandler(protocol
);
950 throw new IOException("Handler for protocol " + protocol
+ " not found");
953 private void writeObject(ObjectOutputStream oos
) throws IOException
955 oos
.defaultWriteObject();
959 * Returns the equivalent <code>URI</code> object for this <code>URL</code>.
960 * This is the same as calling <code>new URI(this.toString())</code>.
961 * RFC2396-compliant URLs are guaranteed a successful conversion to
962 * a <code>URI</code> instance. However, there are some values which
963 * form valid URLs, but which do not also form RFC2396-compliant URIs.
965 * @throws URISyntaxException if this URL is not RFC2396-compliant,
966 * and thus can not be successfully converted to a URI.
969 throws URISyntaxException
971 return new URI(toString());