Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   *
   * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
   *
   * The contents of this file are subject to the terms of either the GNU
   * General Public License Version 2 only ("GPL") or the Common Development
   * and Distribution License("CDDL") (collectively, the "License").  You
   * may not use this file except in compliance with the License.  You can
  * obtain a copy of the License at
  * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
  * or packager/legal/LICENSE.txt.  See the License for the specific
  * language governing permissions and limitations under the License.
  *
  * When distributing the software, include this License Header Notice in each
  * file and include the License file at packager/legal/LICENSE.txt.
  *
  * GPL Classpath Exception:
  * Oracle designates this particular file as subject to the "Classpath"
  * exception as provided by Oracle in the GPL Version 2 section of the License
  * file that accompanied this code.
  *
  * Modifications:
  * If applicable, add the following below the License Header, with the fields
  * enclosed by brackets [] replaced by your own identifying information:
  * "Portions Copyright [year] [name of copyright owner]"
  *
  * Contributor(s):
  * If you wish your version of this file to be governed by only the CDDL or
  * only the GPL Version 2, indicate your decision by adding "[Contributor]
  * elects to include this software in this distribution under the [CDDL or GPL
  * Version 2] license."  If you don't indicate a single choice of license, a
  * recipient has the option to distribute your version of this file under
  * either the CDDL, the GPL Version 2 or to extend the choice of license to
  * its licensees as provided above.  However, if you add GPL Version 2 code
  * and therefore, elected the GPL Version 2 license, then the option applies
  * only if the new code is made subject to such option by the copyright
  * holder.
  *
  *
  * This file incorporates work covered by the following copyright and
  * permission notice:
  *
  * Copyright 2004 The Apache Software Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package org.apache.tomcat.util.net;
 
 

URL is designed to provide public APIs for parsing and synthesizing Uniform Resource Locators as similar as possible to the APIs of java.net.URL, but without the ability to open a stream or connection. One of the consequences of this is that you can construct URLs for protocols for which a URLStreamHandler is not available (such as an "https" URL when JSSE is not installed).

WARNING - This class assumes that the string representation of a URL conforms to the spec argument as described in RFC 2396 "Uniform Resource Identifiers: Generic Syntax":

   <scheme>//<authority><path>?<query>#<fragment>
 

FIXME - This class really ought to end up in a Commons package someplace.

Author(s):
Craig R. McClanahan
Version:
$Revision: 1.4.6.1 $ $Date: 2008/04/17 18:38:17 $
 
 
 public final class URL implements Serializable {
 
 
     // ----------------------------------------------------------- Constructors
 

    
Create a URL object from the specified String representation.

Parameters:
spec String representation of the URL
Throws:
java.net.MalformedURLException if the string representation cannot be parsed successfully
    public URL(String specthrows MalformedURLException {
        this(nullspec);
    }


    
Create a URL object by parsing a string representation relative to a specified context. Based on logic from JDK 1.3.1's java.net.URL.

Parameters:
context URL against which the relative representation is resolved
spec String representation of the URL (usually relative)
Throws:
java.net.MalformedURLException if the string representation cannot be parsed successfully
    public URL(URL contextString specthrows MalformedURLException {
        String original = spec;
        int ilimitc;
        int start = 0;
        String newProtocol = null;
        boolean aRef = false;
        try {
            // Eliminate leading and trailing whitespace
            limit = spec.length();
            while ((limit > 0) && (spec.charAt(limit - 1) <= ' ')) {
                limit--;
            }
            while ((start < limit) && (spec.charAt(start) <= ' ')) {
                start++;
            }
            // If the string representation starts with "url:", skip it
            if (spec.regionMatches(truestart"url:", 0, 4)) {
                start += 4;
            }
            // Is this a ref relative to the context URL?
            if ((start < spec.length()) && (spec.charAt(start) == '#')) {
                aRef = true;
            }
            // Parse out the new protocol
            for (i = start; !aRef && (i < limit) &&
                     ((c = spec.charAt(i)) != '/'); i++) {
                if (c == ':') {
                    String s = spec.substring(starti).toLowerCase();
                    // Assume all protocols are valid
                    newProtocol = s;
                    start = i + 1;
                    break;
                } else ifc == '#' ) {
                    aRef = true;
                } else ifc == '?' ) {
                    break;
                }
            }
            // Only use our context if the protocols match
             = newProtocol;
            if ((context != null) && ((newProtocol == null) ||
                 newProtocol.equalsIgnoreCase(context.getProtocol()))) {
                // If the context is a hierarchical URL scheme and the spec
                // contains a matching scheme then maintain backwards
                // compatibility and treat it as if the spec didn't contain
                // the scheme; see 5.2.3 of RFC2396
                if ((context.getPath() != null) &&
                    (context.getPath().startsWith("/")))
                    newProtocol = null;
                if (newProtocol == null) {
                     = context.getProtocol();
                     = context.getAuthority();
                     = context.getUserInfo();
                     = context.getHost();
                     = context.getPort();
                     = context.getFile();
                    int question = .lastIndexOf("?");
                    if (question < 0)
                         = ;
                    else
                         = .substring(0, question);
                }
            }
            if ( == null)
                throw new MalformedURLException("no protocol: " + original);
            // Parse out any ref portion of the spec
            i = spec.indexOf('#'start);
            if (i >= 0) {
                 = spec.substring(i + 1, limit);
                limit = i;
            }
            // Parse the remainder of the spec in a protocol-specific fashion
            parse(specstartlimit);
            if (context != null)
                normalize();
        } catch (MalformedURLException e) {
            throw e;
        } catch (Exception e) {
            throw new MalformedURLException(e.toString());
        }
    }





    
Create a URL object from the specified components. The default port number for the specified protocol will be used.

Parameters:
protocol Name of the protocol to use
host Name of the host addressed by this protocol
file Filename on the specified host
Throws:
java.net.MalformedURLException is never thrown, but present for compatible APIs
    public URL(String protocolString hostString file)
        throws MalformedURLException {
        this(protocolhost, -1, file);
    }


    
Create a URL object from the specified components. Specifying a port number of -1 indicates that the URL should use the default port for that protocol. Based on logic from JDK 1.3.1's java.net.URL.

Parameters:
protocol Name of the protocol to use
host Name of the host addressed by this protocol
port Port number, or -1 for the default port for this protocol
file Filename on the specified host
Throws:
java.net.MalformedURLException is never thrown, but present for compatible APIs
    public URL(String protocolString hostint portString file)
        throws MalformedURLException {
        this. = protocol;
        this. = host;
        this. = port;
        int hash = file.indexOf('#');
        this. = hash < 0 ? file : file.substring(0, hash);
        this. = hash < 0 ? null : file.substring(hash + 1);
        int question = file.lastIndexOf('?');
        if (question >= 0) {
             = file.substring(question + 1);
             = file.substring(0, question);
        } else
             = file;
        if ((host != null) && (host.length() > 0))
             = (port == -1) ? host : host + ":" + port;
    }
    // ----------------------------------------------------- Instance Variables


    
The authority part of the URL.
    private String authority = null;


    
The filename part of the URL.
    private String file = null;


    
The host name part of the URL.
    private String host = null;


    
The path part of the URL.
    private String path = null;


    
The port number part of the URL.
    private int port = -1;


    
The protocol name part of the URL.
    private String protocol = null;


    
The query part of the URL.
    private String query = null;


    
The reference part of the URL.
    private String ref = null;


    
The user info part of the URL.
    private String userInfo = null;
    // --------------------------------------------------------- Public Methods


    
Compare two URLs for equality. The result is true if and only if the argument is not null, and is a URL object that represents the same URL as this object. Two URLs are equal if they have the same protocol and reference the same host, the same port number on the host, and the same file and anchor on the host.

Parameters:
obj The URL to compare against
    public boolean equals(Object obj) {
        if (obj == null)
            return (false);
        if (!(obj instanceof URL))
            return (false);
        URL other = (URLobj;
        if (!sameFile(other))
            return (false);
        return (compare(other.getRef()));
    }


    
Returns the hash code value for this object.

Returns:
a hash code value for this object.
    public int hashCode() {
        int hashCode = 0;
        if (getProtocol() != null) {
            hashCode += getProtocol().hashCode();
        } 
        if (getHost() != null) {
            hashCode += getHost().hashCode();
        }
        hashCode += getPort();
        if (getFile() != null) {
            hashCode += getFile().hashCode();
        }
        if (getRef() != null) {
            hashCode += getRef().hashCode();
        }
        return hashCode;
    }


    
Return the authority part of the URL.
    public String getAuthority() {
        return (this.);
    }


    
Return the filename part of the URL. NOTE - For compatibility with java.net.URL, this value includes the query string if there was one. For just the path portion, call getPath() instead.
    public String getFile() {
        if ( == null)
            return ("");
        return (this.);
    }


    
Return the host name part of the URL.
    public String getHost() {
        return (this.);
    }


    
Return the path part of the URL.
    public String getPath() {
        if (this. == null)
            return ("");
        return (this.);
    }


    
Return the port number part of the URL.
    public int getPort() {
        return (this.);
    }


    
Return the protocol name part of the URL.
    public String getProtocol() {
        return (this.);
    }


    
Return the query part of the URL.
    public String getQuery() {
        return (this.);
    }


    
Return the reference part of the URL.
    public String getRef() {
        return (this.);
    }


    
Return the user info part of the URL.
    public String getUserInfo() {
        return (this.);
    }


    
Normalize the path (and therefore file) portions of this URL.

NOTE - This method is not part of the public API of java.net.URL, but is provided as a value added service of this implementation.

Throws:
java.net.MalformedURLException if a normalization error occurs, such as trying to move about the hierarchical root
    public void normalize() throws MalformedURLException {
        // Special case for null path
        if ( == null) {
            if ( != null)
                 = "?" + ;
            else
                 = "";
            return;
        }
        // Create a place for the normalized path
        String normalized = ;
        if (normalized.equals("/.")) {
             = "/";
            if ( != null)
                 =  + "?" + ;
            else
                 = ;
            return;
        }
        // Normalize the slashes and add leading slash if necessary
        if (normalized.indexOf('\\') >= 0)
            normalized = normalized.replace('\\''/');
        if (!normalized.startsWith("/"))
            normalized = "/" + normalized;
        // Resolve occurrences of "//" in the normalized path
        while (true) {
            int index = normalized.indexOf("//");
            if (index < 0)
                break;
            normalized = normalized.substring(0, index) +
                normalized.substring(index + 1);
        }
        // Resolve occurrences of "/./" in the normalized path
        while (true) {
            int index = normalized.indexOf("/./");
            if (index < 0)
                break;
            normalized = normalized.substring(0, index) +
                normalized.substring(index + 2);
        }
        // Resolve occurrences of "/../" in the normalized path
        while (true) {
            int index = normalized.indexOf("/../");
            if (index < 0)
                break;
            if (index == 0)
                throw new MalformedURLException
                    ("Invalid relative URL reference");
            int index2 = normalized.lastIndexOf('/'index - 1);
            normalized = normalized.substring(0, index2) +
                normalized.substring(index + 3);
        }
        // Resolve occurrences of "/." at the end of the normalized path
        if (normalized.endsWith("/."))
            normalized = normalized.substring(0, normalized.length() - 1);
        // Resolve occurrences of "/.." at the end of the normalized path
        if (normalized.endsWith("/..")) {
            int index = normalized.length() - 3;
            int index2 = normalized.lastIndexOf('/'index - 1);
            if (index2 < 0)
                throw new MalformedURLException
                    ("Invalid relative URL reference");
            normalized = normalized.substring(0, index2 + 1);
        }
        // Return the normalized path that we have completed
         = normalized;
        if ( != null)
             =  + "?" + ;
        else
             = ;
    }


    
Compare two URLs, excluding the "ref" fields. Returns true if this URL and the other argument both refer to the same resource. The two URLs might not both contain the same anchor.
    public boolean sameFile(URL other) {
        if (!compare(other.getProtocol()))
            return (false);
        if (!compare(other.getHost()))
            return (false);
        if ( != other.getPort())
            return (false);
        if (!compare(other.getFile()))
            return (false);
        return (true);
    }


    
Return a string representation of this URL. This follow the rules in RFC 2396, Section 5.2, Step 7.
    public String toExternalForm() {
        StringBuffer sb = new StringBuffer();
        if ( != null) {
            sb.append();
            sb.append(":");
        }
        if ( != null) {
            sb.append("//");
            sb.append();
        }
        if ( != null)
            sb.append();
        if ( != null) {
            sb.append('?');
            sb.append();
        }
        if ( != null) {
            sb.append('#');
            sb.append();
        }
        return (sb.toString());
    }


    
Return a string representation of this object.
    public String toString() {
        StringBuffer sb = new StringBuffer("URL[");
        sb.append("authority=");
        sb.append();
        sb.append(", file=");
        sb.append();
        sb.append(", host=");
        sb.append();
        sb.append(", port=");
        sb.append();
        sb.append(", protocol=");
        sb.append();
        sb.append(", query=");
        sb.append();
        sb.append(", ref=");
        sb.append();
        sb.append(", userInfo=");
        sb.append();
        sb.append("]");
        return (sb.toString());
        //        return (toExternalForm());
    }
    // -------------------------------------------------------- Private Methods


    
Compare to String values for equality, taking appropriate care if one or both of the values are null.

Parameters:
first First string
second Second string
    private boolean compare(String firstString second) {
        if (first == null) {
            if (second == null)
                return (true);
            else
                return (false);
        } else {
            if (second == null)
                return (false);
            else
                return (first.equals(second));
        }
    }


    
Parse the specified portion of the string representation of a URL, assuming that it has a format similar to that for http.

FIXME - This algorithm can undoubtedly be optimized for performance. However, that needs to wait until after sufficient unit tests are implemented to guarantee correct behavior with no regressions.

Parameters:
spec String representation being parsed
start Starting offset, which will be just after the ':' (if there is one) that determined the protocol name
limit Ending position, which will be the position of the '#' (if there is one) that delimited the anchor
Throws:
java.net.MalformedURLException if a parsing error occurs
    private void parse(String specint startint limit)
        throws MalformedURLException {
        // Trim the query string (if any) off the tail end
        int question = spec.lastIndexOf('?'limit - 1);
        if ((question >= 0) && (question < limit)) {
             = spec.substring(question + 1, limit);
            limit = question;
        } else {
             = null;
        }
        // Parse the authority section
        if (spec.indexOf("//"start) == start) {
            int pathStart = spec.indexOf("/"start + 2);
            if ((pathStart >= 0) && (pathStart < limit)) {
                 = spec.substring(start + 2, pathStart);
                start = pathStart;
            } else {
                 = spec.substring(start + 2, limit);
                start = limit;
            }
            if (.length() > 0) {
                int at = .indexOf('@');
                ifat >= 0 ) {
                     = .substring(0,at);
                }
                int ipv6 = .indexOf('[',at+1);
                int hStart = at+1;
                ifipv6 >= 0 ) {
                    hStart = ipv6;
                    ipv6 = .indexOf(']'ipv6);
                    ifipv6 < 0 ) {
                        throw new MalformedURLException(
                                                        "Closing ']' not found in IPV6 address: " + );
                    } else {
                        at = ipv6-1;
                    }
                }
                                                        
                int colon = .indexOf(':'at+1);
                if (colon >= 0) {
                    try {
                         =
                            Integer.parseInt(.substring(colon + 1));
                    } catch (NumberFormatException e) {
                        throw new MalformedURLException(e.toString());
                    }
                     = .substring(hStartcolon);
                } else {
                     = .substring(hStart);
                     = -1;
                }
            }
        }
        // Parse the path section
        if (spec.indexOf("/"start) == start) {     // Absolute path
             = spec.substring(startlimit);
            if ( != null)
                 =  + "?" + ;
            else
                 = ;
            return;
        }
        // Resolve relative path against our context's file
        if ( == null) {
            if ( != null)
                 = "?" + ;
            else
                 = null;
            return;
        }
        if (!.startsWith("/"))
            throw new MalformedURLException
                ("Base path does not start with '/'");
        if (!.endsWith("/"))
             += "/../";
         += spec.substring(startlimit);
        if ( != null)
             =  + "?" + ;
        else
             = ;
        return;
    }
New to GrepCode? Check out our FAQ X