Source Code Cross Referenced for URLStreamHandler.java in  » 6.0-JDK-Core » net » java » net » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » net » java.net 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 1995-2006 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025
026        package java.net;
027
028        import java.io.IOException;
029        import java.io.InputStream;
030        import java.io.File;
031        import java.io.OutputStream;
032        import java.util.Hashtable;
033        import sun.net.util.IPAddressUtil;
034        import sun.net.www.ParseUtil;
035
036        /**
037         * The abstract class <code>URLStreamHandler</code> is the common
038         * superclass for all stream protocol handlers. A stream protocol
039         * handler knows how to make a connection for a particular protocol
040         * type, such as <code>http</code>, <code>ftp</code>, or
041         * <code>gopher</code>.
042         * <p>
043         * In most cases, an instance of a <code>URLStreamHandler</code>
044         * subclass is not created directly by an application. Rather, the
045         * first time a protocol name is encountered when constructing a
046         * <code>URL</code>, the appropriate stream protocol handler is
047         * automatically loaded.
048         *
049         * @author  James Gosling
050         * @version 1.79, 05/05/07
051         * @see     java.net.URL#URL(java.lang.String, java.lang.String, int, java.lang.String)
052         * @since   JDK1.0
053         */
054        public abstract class URLStreamHandler {
055            /**
056             * Opens a connection to the object referenced by the
057             * <code>URL</code> argument.
058             * This method should be overridden by a subclass.
059             *
060             * <p>If for the handler's protocol (such as HTTP or JAR), there
061             * exists a public, specialized URLConnection subclass belonging
062             * to one of the following packages or one of their subpackages:
063             * java.lang, java.io, java.util, java.net, the connection
064             * returned will be of that subclass. For example, for HTTP an
065             * HttpURLConnection will be returned, and for JAR a
066             * JarURLConnection will be returned.
067             *
068             * @param      u   the URL that this connects to.
069             * @return     a <code>URLConnection</code> object for the <code>URL</code>.
070             * @exception  IOException  if an I/O error occurs while opening the
071             *               connection.
072             */
073            abstract protected URLConnection openConnection(URL u)
074                    throws IOException;
075
076            /**
077             * Same as openConnection(URL), except that the connection will be
078             * made through the specified proxy; Protocol handlers that do not
079             * support proxying will ignore the proxy parameter and make a
080             * normal connection.
081             *
082             * Calling this method preempts the system's default ProxySelector
083             * settings.
084             * 
085             * @param      u   the URL that this connects to.
086             * @param      p   the proxy through which the connection will be made.
087             *                 If direct connection is desired, Proxy.NO_PROXY
088             *                 should be specified.
089             * @return     a <code>URLConnection</code> object for the <code>URL</code>.
090             * @exception  IOException  if an I/O error occurs while opening the
091             *               connection.
092             * @exception  IllegalArgumentException if either u or p is null,
093             *               or p has the wrong type.
094             * @exception  UnsupportedOperationException if the subclass that
095             *               implements the protocol doesn't support this method.
096             * @since      1.5
097             */
098            protected URLConnection openConnection(URL u, Proxy p)
099                    throws IOException {
100                throw new UnsupportedOperationException(
101                        "Method not implemented.");
102            }
103
104            /**
105             * Parses the string representation of a <code>URL</code> into a
106             * <code>URL</code> object.
107             * <p>
108             * If there is any inherited context, then it has already been
109             * copied into the <code>URL</code> argument.
110             * <p>
111             * The <code>parseURL</code> method of <code>URLStreamHandler</code>
112             * parses the string representation as if it were an
113             * <code>http</code> specification. Most URL protocol families have a
114             * similar parsing. A stream protocol handler for a protocol that has
115             * a different syntax must override this routine.
116             *
117             * @param   u       the <code>URL</code> to receive the result of parsing
118             *                  the spec.
119             * @param   spec    the <code>String</code> representing the URL that
120             *                  must be parsed.
121             * @param   start   the character index at which to begin parsing. This is
122             *                  just past the '<code>:</code>' (if there is one) that
123             *                  specifies the determination of the protocol name.
124             * @param   limit   the character position to stop parsing at. This is the
125             *                  end of the string or the position of the
126             *                  "<code>#</code>" character, if present. All information
127             *                  after the sharp sign indicates an anchor.
128             */
129            protected void parseURL(URL u, String spec, int start, int limit) {
130                // These fields may receive context content if this was relative URL
131                String protocol = u.getProtocol();
132                String authority = u.getAuthority();
133                String userInfo = u.getUserInfo();
134                String host = u.getHost();
135                int port = u.getPort();
136                String path = u.getPath();
137                String query = u.getQuery();
138
139                // This field has already been parsed
140                String ref = u.getRef();
141
142                boolean isRelPath = false;
143                boolean queryOnly = false;
144
145                // FIX: should not assume query if opaque
146                // Strip off the query part
147                if (start < limit) {
148                    int queryStart = spec.indexOf('?');
149                    queryOnly = queryStart == start;
150                    if ((queryStart != -1) && (queryStart < limit)) {
151                        query = spec.substring(queryStart + 1, limit);
152                        if (limit > queryStart)
153                            limit = queryStart;
154                        spec = spec.substring(0, queryStart);
155                    }
156                }
157
158                int i = 0;
159                // Parse the authority part if any
160                boolean isUNCName = (start <= limit - 4)
161                        && (spec.charAt(start) == '/')
162                        && (spec.charAt(start + 1) == '/')
163                        && (spec.charAt(start + 2) == '/')
164                        && (spec.charAt(start + 3) == '/');
165                if (!isUNCName && (start <= limit - 2)
166                        && (spec.charAt(start) == '/')
167                        && (spec.charAt(start + 1) == '/')) {
168                    start += 2;
169                    i = spec.indexOf('/', start);
170                    if (i < 0) {
171                        i = spec.indexOf('?', start);
172                        if (i < 0)
173                            i = limit;
174                    }
175
176                    host = authority = spec.substring(start, i);
177
178                    int ind = authority.indexOf('@');
179                    if (ind != -1) {
180                        userInfo = authority.substring(0, ind);
181                        host = authority.substring(ind + 1);
182                    } else {
183                        userInfo = null;
184                    }
185                    if (host != null) {
186                        // If the host is surrounded by [ and ] then its an IPv6 
187                        // literal address as specified in RFC2732
188                        if (host.length() > 0 && (host.charAt(0) == '[')) {
189                            if ((ind = host.indexOf(']')) > 2) {
190
191                                String nhost = host;
192                                host = nhost.substring(0, ind + 1);
193                                if (!IPAddressUtil.isIPv6LiteralAddress(host
194                                        .substring(1, ind))) {
195                                    throw new IllegalArgumentException(
196                                            "Invalid host: " + host);
197                                }
198
199                                port = -1;
200                                if (nhost.length() > ind + 1) {
201                                    if (nhost.charAt(ind + 1) == ':') {
202                                        ++ind;
203                                        // port can be null according to RFC2396
204                                        if (nhost.length() > (ind + 1)) {
205                                            port = Integer.parseInt(nhost
206                                                    .substring(ind + 1));
207                                        }
208                                    } else {
209                                        throw new IllegalArgumentException(
210                                                "Invalid authority field: "
211                                                        + authority);
212                                    }
213                                }
214                            } else {
215                                throw new IllegalArgumentException(
216                                        "Invalid authority field: " + authority);
217                            }
218                        } else {
219                            ind = host.indexOf(':');
220                            port = -1;
221                            if (ind >= 0) {
222                                // port can be null according to RFC2396
223                                if (host.length() > (ind + 1)) {
224                                    port = Integer.parseInt(host
225                                            .substring(ind + 1));
226                                }
227                                host = host.substring(0, ind);
228                            }
229                        }
230                    } else {
231                        host = "";
232                    }
233                    if (port < -1)
234                        throw new IllegalArgumentException(
235                                "Invalid port number :" + port);
236                    start = i;
237                    // If the authority is defined then the path is defined by the
238                    // spec only; See RFC 2396 Section 5.2.4.
239                    if (authority != null && authority.length() > 0)
240                        path = "";
241                }
242
243                if (host == null) {
244                    host = "";
245                }
246
247                // Parse the file path if any
248                if (start < limit) {
249                    if (spec.charAt(start) == '/') {
250                        path = spec.substring(start, limit);
251                    } else if (path != null && path.length() > 0) {
252                        isRelPath = true;
253                        int ind = path.lastIndexOf('/');
254                        String seperator = "";
255                        if (ind == -1 && authority != null)
256                            seperator = "/";
257                        path = path.substring(0, ind + 1) + seperator
258                                + spec.substring(start, limit);
259
260                    } else {
261                        String seperator = (authority != null) ? "/" : "";
262                        path = seperator + spec.substring(start, limit);
263                    }
264                } else if (queryOnly && path != null) {
265                    int ind = path.lastIndexOf('/');
266                    if (ind < 0)
267                        ind = 0;
268                    path = path.substring(0, ind) + "/";
269                }
270                if (path == null)
271                    path = "";
272
273                if (isRelPath) {
274                    // Remove embedded /./
275                    while ((i = path.indexOf("/./")) >= 0) {
276                        path = path.substring(0, i) + path.substring(i + 2);
277                    }
278                    // Remove embedded /../ if possible
279                    i = 0;
280                    while ((i = path.indexOf("/../", i)) >= 0) {
281                        /* 
282                         * A "/../" will cancel the previous segment and itself, 
283                         * unless that segment is a "/../" itself
284                         * i.e. "/a/b/../c" becomes "/a/c"
285                         * but "/../../a" should stay unchanged
286                         */
287                        if (i > 0
288                                && (limit = path.lastIndexOf('/', i - 1)) >= 0
289                                && (path.indexOf("/../", limit) != 0)) {
290                            path = path.substring(0, limit)
291                                    + path.substring(i + 3);
292                            i = 0;
293                        } else {
294                            i = i + 3;
295                        }
296                    }
297                    // Remove trailing .. if possible
298                    while (path.endsWith("/..")) {
299                        i = path.indexOf("/..");
300                        if ((limit = path.lastIndexOf('/', i - 1)) >= 0) {
301                            path = path.substring(0, limit + 1);
302                        } else {
303                            break;
304                        }
305                    }
306                    // Remove starting .
307                    if (path.startsWith("./") && path.length() > 2)
308                        path = path.substring(2);
309
310                    // Remove trailing .
311                    if (path.endsWith("/."))
312                        path = path.substring(0, path.length() - 1);
313                }
314
315                setURL(u, protocol, host, port, authority, userInfo, path,
316                        query, ref);
317            }
318
319            /**
320             * Returns the default port for a URL parsed by this handler. This method
321             * is meant to be overidden by handlers with default port numbers.
322             * @return the default port for a <code>URL</code> parsed by this handler.
323             * @since 1.3
324             */
325            protected int getDefaultPort() {
326                return -1;
327            }
328
329            /**
330             * Provides the default equals calculation. May be overidden by handlers
331             * for other protocols that have different requirements for equals().
332             * This method requires that none of its arguments is null. This is 
333             * guaranteed by the fact that it is only called by java.net.URL class.
334             * @param u1 a URL object
335             * @param u2 a URL object
336             * @return <tt>true</tt> if the two urls are 
337             * considered equal, ie. they refer to the same 
338             * fragment in the same file.
339             * @since 1.3
340             */
341            protected boolean equals(URL u1, URL u2) {
342                String ref1 = u1.getRef();
343                String ref2 = u2.getRef();
344                return (ref1 == ref2 || (ref1 != null && ref1.equals(ref2)))
345                        && sameFile(u1, u2);
346            }
347
348            /**
349             * Provides the default hash calculation. May be overidden by handlers for
350             * other protocols that have different requirements for hashCode
351             * calculation.
352             * @param u a URL object
353             * @return an <tt>int</tt> suitable for hash table indexing
354             * @since 1.3
355             */
356            protected int hashCode(URL u) {
357                int h = 0;
358
359                // Generate the protocol part.
360                String protocol = u.getProtocol();
361                if (protocol != null)
362                    h += protocol.hashCode();
363
364                // Generate the host part.
365                InetAddress addr = getHostAddress(u);
366                if (addr != null) {
367                    h += addr.hashCode();
368                } else {
369                    String host = u.getHost();
370                    if (host != null)
371                        h += host.toLowerCase().hashCode();
372                }
373
374                // Generate the file part.
375                String file = u.getFile();
376                if (file != null)
377                    h += file.hashCode();
378
379                // Generate the port part.
380                if (u.getPort() == -1)
381                    h += getDefaultPort();
382                else
383                    h += u.getPort();
384
385                // Generate the ref part.
386                String ref = u.getRef();
387                if (ref != null)
388                    h += ref.hashCode();
389
390                return h;
391            }
392
393            /**
394             * Compare two urls to see whether they refer to the same file,
395             * i.e., having the same protocol, host, port, and path.
396             * This method requires that none of its arguments is null. This is 
397             * guaranteed by the fact that it is only called indirectly
398             * by java.net.URL class.
399             * @param u1 a URL object
400             * @param u2 a URL object
401             * @return true if u1 and u2 refer to the same file
402             * @since 1.3
403             */
404            protected boolean sameFile(URL u1, URL u2) {
405                // Compare the protocols.
406                if (!((u1.getProtocol() == u2.getProtocol()) || (u1
407                        .getProtocol() != null && u1.getProtocol()
408                        .equalsIgnoreCase(u2.getProtocol()))))
409                    return false;
410
411                // Compare the files.
412                if (!(u1.getFile() == u2.getFile() || (u1.getFile() != null && u1
413                        .getFile().equals(u2.getFile()))))
414                    return false;
415
416                // Compare the ports.
417                int port1, port2;
418                port1 = (u1.getPort() != -1) ? u1.getPort() : u1.handler
419                        .getDefaultPort();
420                port2 = (u2.getPort() != -1) ? u2.getPort() : u2.handler
421                        .getDefaultPort();
422                if (port1 != port2)
423                    return false;
424
425                // Compare the hosts.
426                if (!hostsEqual(u1, u2))
427                    return false;
428
429                return true;
430            }
431
432            /**
433             * Get the IP address of our host. An empty host field or a DNS failure
434             * will result in a null return.
435             *
436             * @param u a URL object
437             * @return an <code>InetAddress</code> representing the host
438             * IP address.
439             * @since 1.3
440             */
441            protected synchronized InetAddress getHostAddress(URL u) {
442                if (u.hostAddress != null)
443                    return u.hostAddress;
444
445                String host = u.getHost();
446                if (host == null || host.equals("")) {
447                    return null;
448                } else {
449                    try {
450                        u.hostAddress = InetAddress.getByName(host);
451                    } catch (UnknownHostException ex) {
452                        return null;
453                    } catch (SecurityException se) {
454                        return null;
455                    }
456                }
457                return u.hostAddress;
458            }
459
460            /**
461             * Compares the host components of two URLs.
462             * @param u1 the URL of the first host to compare 
463             * @param u2 the URL of the second host to compare 
464             * @return	<tt>true</tt> if and only if they 
465             * are equal, <tt>false</tt> otherwise.
466             * @since 1.3
467             */
468            protected boolean hostsEqual(URL u1, URL u2) {
469                InetAddress a1 = getHostAddress(u1);
470                InetAddress a2 = getHostAddress(u2);
471                // if we have internet address for both, compare them
472                if (a1 != null && a2 != null) {
473                    return a1.equals(a2);
474                    // else, if both have host names, compare them
475                } else if (u1.getHost() != null && u2.getHost() != null)
476                    return u1.getHost().equalsIgnoreCase(u2.getHost());
477                else
478                    return u1.getHost() == null && u2.getHost() == null;
479            }
480
481            /**
482             * Converts a <code>URL</code> of a specific protocol to a
483             * <code>String</code>.
484             *
485             * @param   u   the URL.
486             * @return  a string representation of the <code>URL</code> argument.
487             */
488            protected String toExternalForm(URL u) {
489
490                // pre-compute length of StringBuffer
491                int len = u.getProtocol().length() + 1;
492                if (u.getAuthority() != null && u.getAuthority().length() > 0)
493                    len += 2 + u.getAuthority().length();
494                if (u.getPath() != null) {
495                    len += u.getPath().length();
496                }
497                if (u.getQuery() != null) {
498                    len += 1 + u.getQuery().length();
499                }
500                if (u.getRef() != null)
501                    len += 1 + u.getRef().length();
502
503                StringBuffer result = new StringBuffer(len);
504                result.append(u.getProtocol());
505                result.append(":");
506                if (u.getAuthority() != null && u.getAuthority().length() > 0) {
507                    result.append("//");
508                    result.append(u.getAuthority());
509                }
510                if (u.getPath() != null) {
511                    result.append(u.getPath());
512                }
513                if (u.getQuery() != null) {
514                    result.append('?');
515                    result.append(u.getQuery());
516                }
517                if (u.getRef() != null) {
518                    result.append("#");
519                    result.append(u.getRef());
520                }
521                return result.toString();
522            }
523
524            /**
525             * Sets the fields of the <code>URL</code> argument to the indicated values.
526             * Only classes derived from URLStreamHandler are supposed to be able
527             * to call the set method on a URL.
528             *
529             * @param   u         the URL to modify.
530             * @param   protocol  the protocol name.
531             * @param   host      the remote host value for the URL.
532             * @param   port      the port on the remote machine.
533             * @param   authority the authority part for the URL.
534             * @param   userInfo the userInfo part of the URL.
535             * @param   path      the path component of the URL. 
536             * @param   query     the query part for the URL.
537             * @param   ref       the reference.
538             * @exception	SecurityException	if the protocol handler of the URL is 
539             *					different from this one
540             * @see     java.net.URL#set(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)
541             * @since 1.3
542             */
543            protected void setURL(URL u, String protocol, String host,
544                    int port, String authority, String userInfo, String path,
545                    String query, String ref) {
546                if (this  != u.handler) {
547                    throw new SecurityException(
548                            "handler for url different from " + "this handler");
549                }
550                // ensure that no one can reset the protocol on a given URL.
551                u.set(u.getProtocol(), host, port, authority, userInfo, path,
552                        query, ref);
553            }
554
555            /**
556             * Sets the fields of the <code>URL</code> argument to the indicated values.
557             * Only classes derived from URLStreamHandler are supposed to be able
558             * to call the set method on a URL.
559             *
560             * @param   u         the URL to modify.
561             * @param   protocol  the protocol name. This value is ignored since 1.2.
562             * @param   host      the remote host value for the URL.
563             * @param   port      the port on the remote machine.
564             * @param   file      the file.
565             * @param   ref       the reference.
566             * @exception	SecurityException	if the protocol handler of the URL is 
567             *					different from this one
568             * @deprecated Use setURL(URL, String, String, int, String, String, String,
569             *             String);
570             */
571            @Deprecated
572            protected void setURL(URL u, String protocol, String host,
573                    int port, String file, String ref) {
574                /*
575                 * Only old URL handlers call this, so assume that the host
576                 * field might contain "user:passwd@host". Fix as necessary.
577                 */
578                String authority = null;
579                String userInfo = null;
580                if (host != null && host.length() != 0) {
581                    authority = (port == -1) ? host : host + ":" + port;
582                    int at = host.lastIndexOf('@');
583                    if (at != -1) {
584                        userInfo = host.substring(0, at);
585                        host = host.substring(at + 1);
586                    }
587                }
588
589                /*
590                 * Assume file might contain query part. Fix as necessary.
591                 */
592                String path = null;
593                String query = null;
594                if (file != null) {
595                    int q = file.lastIndexOf('?');
596                    if (q != -1) {
597                        query = file.substring(q + 1);
598                        path = file.substring(0, q);
599                    } else
600                        path = file;
601                }
602                setURL(u, protocol, host, port, authority, userInfo, path,
603                        query, ref);
604            }
605        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.