Beispiel #1
0
        /**
         * Returns the clear text representation of a given URL using HTTP format.
         *
         * @param url
         *            the URL object to be converted.
         * @return the clear text representation of the specified URL.
         * @see #parseURL
         * @see URL#toExternalForm()
         */
        protected internal String toExternalForm(URL url)
        {
            java.lang.StringBuilder answer = new java.lang.StringBuilder();
            answer.append(url.getProtocol());
            answer.append(':');
            String authority = url.getAuthority();

            if (authority != null && authority.length() > 0)
            {
                answer.append("//"); //$NON-NLS-1$
                answer.append(url.getAuthority());
            }

            String file = url.getFile();
            String refJ = url.getRef();

            if (file != null)
            {
                answer.append(file);
            }
            if (refJ != null)
            {
                answer.append('#');
                answer.append(refJ);
            }
            return(answer.toString());
        }
Beispiel #2
0
        /**
         * Compares two URL objects whether they refer to the same file. In the
         * comparison included are the URL components protocol, host, port and file.
         *
         * @param url1
         *            the first URL to be compared.
         * @param url2
         *            the second URL to be compared.
         * @return {@code true} if both URLs refer to the same file, {@code false}
         *         otherwise.
         */
        protected bool sameFile(URL url1, URL url2)
        {
            String s1 = url1.getProtocol();
            String s2 = url2.getProtocol();

            if (s1 != s2 && (s1 == null || !s1.equals(s2)))
            {
                return(false);
            }

            s1 = url1.getFile();
            s2 = url2.getFile();
            if (s1 != s2 && (s1 == null || !s1.equals(s2)))
            {
                return(false);
            }
            if (!hostsEqual(url1, url2))
            {
                return(false);
            }
            int p1 = url1.getPort();

            if (p1 == -1)
            {
                p1 = getDefaultPort();
            }
            int p2 = url2.getPort();

            if (p2 == -1)
            {
                p2 = getDefaultPort();
            }
            return(p1 == p2);
        }
Beispiel #3
0
        /*
         * If the URL host is empty while protocol is file, the host is regarded as
         * localhost.
         */
        private static String getHost(URL url)
        {
            String host = url.getHost();

            if ("file".equals(url.getProtocol()) && //$NON-NLS-1$
                "".equals(host))
            {                       //$NON-NLS-1$
                host = "localhost"; //$NON-NLS-1$
            }
            return(host);
        }
Beispiel #4
0
        /**
         * Creates a new URL to the specified resource {@code spec}. This URL is
         * relative to the given {@code context}. The {@code handler} will be used
         * to parse the URL string representation. If this argument is {@code null}
         * the default {@code URLStreamHandler} will be used. If the protocol of the
         * parsed URL does not match with the protocol of the context URL, then the
         * newly created URL is absolute and bases only on the given URL represented
         * by {@code spec}. Otherwise the protocol is defined by the context URL.
         *
         * @param context
         *            the URL which is used as the context.
         * @param spec
         *            the URL string representation which has to be parsed.
         * @param handler
         *            the specific stream handler to be used by this URL.
         * @throws MalformedURLException
         *             if the given string {@code spec} could not be parsed as a URL
         *             or an invalid protocol has been found.
         */
        public URL(URL context, String spec, URLStreamHandler handler)
        {
            //throws MalformedURLException {
            if (handler != null)
            {
                java.lang.SecurityManager sm = java.lang.SystemJ.getSecurityManager();
                if (sm != null)
                {
                    sm.checkPermission(specifyStreamHandlerPermission);
                }
                strmHandler = handler;
            }

            if (spec == null)
            {
                throw new MalformedURLException();
            }
            spec = spec.trim();

            // The spec includes a protocol if it includes a colon character
            // before the first occurrence of a slash character. Note that,
            // "protocol" is the field which holds this URLs protocol.
            int index;
            try
            {
                index = spec.indexOf(':');
            }
            catch (java.lang.NullPointerException e)
            {
                throw new MalformedURLException(e.toString());
            }
            int startIPv6Addr = spec.indexOf('[');
            if (index >= 0)
            {
                if ((startIPv6Addr == -1) || (index < startIPv6Addr))
                {
                    protocol = spec.substring(0, index);
                    // According to RFC 2396 scheme part should match
                    // the following expression:
                    // alpha *( alpha | digit | "+" | "-" | "." )
                    char c = protocol.charAt(0);
                    bool valid = ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
                    for (int i = 1; valid && (i < protocol.length()); i++)
                    {
                        c = protocol.charAt(i);
                        valid = ('a' <= c && c <= 'z') ||
                                ('A' <= c && c <= 'Z') ||
                                ('0' <= c && c <= '9') ||
                                (c == '+') ||
                                (c == '-') ||
                                (c == '.');
                    }
                    if (!valid)
                    {
                        protocol = null;
                        index = -1;
                    }
                    else
                    {
                        // Ignore case in protocol names.
                        // Scheme is defined by ASCII characters.
                        protocol = Util.toASCIILowerCase(protocol);
                    }
                }
            }

            if (protocol != null)
            {
                // If the context was specified, and it had the same protocol
                // as the spec, then fill in the receiver's slots from the values
                // in the context but still allow them to be over-ridden later
                // by the values in the spec.
                if (context != null && protocol.equals(context.getProtocol()))
                {
                    String cPath = context.getPath();
                    if (cPath != null && cPath.startsWith("/"))
                    { //$NON-NLS-1$
                        set(protocol, context.getHost(), context.getPort(), context
                                .getAuthority(), context.getUserInfo(), cPath,
                                context.getQuery(), null);
                    }
                    if (strmHandler == null)
                    {
                        strmHandler = context.strmHandler;
                    }
                }
            }
            else
            {
                // If the spec did not include a protocol, then the context
                // *must* be specified. Fill in the receiver's slots from the
                // values in the context, but still allow them to be over-ridden
                // by the values in the ("relative") spec.
                if (context == null)
                {
                    throw new MalformedURLException("Protocol not found: " + spec); //$NON-NLS-1$
                }
                set(context.getProtocol(), context.getHost(), context.getPort(),
                        context.getAuthority(), context.getUserInfo(), context
                                .getPath(), context.getQuery(), null);
                if (strmHandler == null)
                {
                    strmHandler = context.strmHandler;
                }
            }

            // If the stream handler has not been determined, set it
            // to the default for the specified protocol.
            if (strmHandler == null)
            {
                setupStreamHandler();
                if (strmHandler == null)
                {
                    throw new MalformedURLException("Unknown protocol: " + protocol); //$NON-NLS-1$
                }
            }

            // Let the handler parse the URL. If the handler throws
            // any exception, throw MalformedURLException instead.
            //
            // Note: We want "index" to be the index of the start of the scheme
            // specific part of the URL. At this point, it will be either
            // -1 or the index of the colon after the protocol, so we
            // increment it to point at either character 0 or the character
            // after the colon.
            try
            {
                strmHandler.parseURL(this, spec, ++index, spec.length());
            }
            catch (Exception e)
            {
                throw new MalformedURLException(e.toString());
            }

            if (port < -1)
            {
                throw new MalformedURLException("Port out of range: " + port); //$NON-NLS-1$
            }
        }
Beispiel #5
0
        /**
         * Parses the clear text URL in {@code str} into a URL object. URL strings
         * generally have the following format:
         * <p/>
         * http://www.company.com/java/file1.java#reference
         * <p/>
         * The string is parsed in HTTP format. If the protocol has a different URL
         * format this method must be overridden.
         *
         * @param u
         *            the URL to fill in the parsed clear text URL parts.
         * @param str
         *            the URL string that is to be parsed.
         * @param start
         *            the string position from where to begin parsing.
         * @param end
         *            the string position to stop parsing.
         * @see #toExternalForm
         * @see URL
         */
        protected internal void parseURL(URL u, String str, int start, int end)
        {
            if (end < start || end < 0)
            {
                // Checks to ensure string index exception ahead of
                // security exception for compatibility.
                if (end <= java.lang.Integer.MIN_VALUE + 1 && (start >= str.length() || start < 0) ||
                    str.startsWith("//", start) && str.indexOf('/', start + 2) == -1)      //$NON-NLS-1$
                {
                    throw new java.lang.StringIndexOutOfBoundsException(end);
                }
                if (this != u.strmHandler)
                {
                    throw new java.lang.SecurityException();
                }
                return;
            }
            String parseString = str.substring(start, end);

            end -= start;
            int fileIdx = 0;

            // Default is to use info from context
            String host      = u.getHost();
            int    port      = u.getPort();
            String refJ      = u.getRef();
            String file      = u.getPath();
            String query     = u.getQuery();
            String authority = u.getAuthority();
            String userInfo  = u.getUserInfo();

            int refIdx = parseString.indexOf('#', 0);

            if (parseString.startsWith("//") && !parseString.startsWith("////")) //$NON-NLS-1$
            {
                int hostIdx = 2, portIdx = -1;
                port    = -1;
                fileIdx = parseString.indexOf('/', hostIdx);
                int questionMarkIndex = parseString.indexOf('?', hostIdx);
                if ((questionMarkIndex != -1) &&
                    ((fileIdx == -1) || (fileIdx > questionMarkIndex)))
                {
                    fileIdx = questionMarkIndex;
                }
                if (fileIdx == -1)
                {
                    fileIdx = end;
                    // Use default
                    file = ""; //$NON-NLS-1$
                }
                int hostEnd = fileIdx;
                if (refIdx != -1 && refIdx < fileIdx)
                {
                    hostEnd = refIdx;
                }
                int userIdx = parseString.lastIndexOf('@', hostEnd);
                authority = parseString.substring(hostIdx, hostEnd);
                if (userIdx > -1)
                {
                    userInfo = parseString.substring(hostIdx, userIdx);
                    hostIdx  = userIdx + 1;
                }

                portIdx = parseString.indexOf(':', userIdx == -1 ? hostIdx
                    : userIdx);
                int endOfIPv6Addr = parseString.indexOf(']');
                // if there are square braces, ie. IPv6 address, use last ':'
                if (endOfIPv6Addr != -1)
                {
                    try {
                        if (parseString.length() > endOfIPv6Addr + 1)
                        {
                            char c = parseString.charAt(endOfIPv6Addr + 1);
                            if (c == ':')
                            {
                                portIdx = endOfIPv6Addr + 1;
                            }
                            else
                            {
                                portIdx = -1;
                            }
                        }
                        else
                        {
                            portIdx = -1;
                        }
                    } catch (Exception) {
                        // Ignored
                    }
                }

                if (portIdx == -1 || portIdx > fileIdx)
                {
                    host = parseString.substring(hostIdx, hostEnd);
                }
                else
                {
                    host = parseString.substring(hostIdx, portIdx);
                    String portString = parseString.substring(portIdx + 1, hostEnd);
                    if (portString.length() == 0)
                    {
                        port = -1;
                    }
                    else
                    {
                        port = java.lang.Integer.parseInt(portString);
                    }
                }
            }

            if (refIdx > -1)
            {
                refJ = parseString.substring(refIdx + 1, end);
            }
            int fileEnd = (refIdx == -1 ? end : refIdx);

            int  queryIdx     = parseString.lastIndexOf('?', fileEnd);
            bool canonicalize = false;

            if (queryIdx > -1)
            {
                query = parseString.substring(queryIdx + 1, fileEnd);
                if (queryIdx == 0 && file != null)
                {
                    if (file.equals(""))           //$NON-NLS-1$
                    {
                        file = "/";                //$NON-NLS-1$
                    }
                    else if (file.startsWith("/")) //$NON-NLS-1$
                    {
                        canonicalize = true;
                    }
                    int last = file.lastIndexOf('/') + 1;
                    file = file.substring(0, last);
                }
                fileEnd = queryIdx;
            }
            else
            // Don't inherit query unless only the ref is changed
            if (refIdx != 0)
            {
                query = null;
            }

            if (fileIdx > -1)
            {
                if (fileIdx < end && parseString.charAt(fileIdx) == '/')
                {
                    file = parseString.substring(fileIdx, fileEnd);
                }
                else if (fileEnd > fileIdx)
                {
                    if (file == null)
                    {
                        file = "";                 //$NON-NLS-1$
                    }
                    else if (file.equals(""))      //$NON-NLS-1$
                    {
                        file = "/";                //$NON-NLS-1$
                    }
                    else if (file.startsWith("/")) //$NON-NLS-1$
                    {
                        canonicalize = true;
                    }
                    int last = file.lastIndexOf('/') + 1;
                    if (last == 0)
                    {
                        file = parseString.substring(fileIdx, fileEnd);
                    }
                    else
                    {
                        file = file.substring(0, last)
                               + parseString.substring(fileIdx, fileEnd);
                    }
                }
            }
            if (file == null)
            {
                file = ""; //$NON-NLS-1$
            }

            if (host == null)
            {
                host = ""; //$NON-NLS-1$
            }

            if (canonicalize)
            {
                // modify file if there's any relative referencing
                file = URLUtil.canonicalizePath(file);
            }

            setURL(u, u.getProtocol(), host, port, authority, userInfo, file,
                   query, refJ);
        }
Beispiel #6
0
        /**
         * Parses the clear text URL in {@code str} into a URL object. URL strings
         * generally have the following format:
         * <p/>
         * http://www.company.com/java/file1.java#reference
         * <p/>
         * The string is parsed in HTTP format. If the protocol has a different URL
         * format this method must be overridden.
         *
         * @param u
         *            the URL to fill in the parsed clear text URL parts.
         * @param str
         *            the URL string that is to be parsed.
         * @param start
         *            the string position from where to begin parsing.
         * @param end
         *            the string position to stop parsing.
         * @see #toExternalForm
         * @see URL
         */
        protected internal void parseURL(URL u, String str, int start, int end)
        {
            if (end < start || end < 0) {
            // Checks to ensure string index exception ahead of
            // security exception for compatibility.
            if (end <= java.lang.Integer.MIN_VALUE + 1 && (start >= str.length() || start < 0)
                    || str.startsWith("//", start) && str.indexOf('/', start + 2) == -1) { //$NON-NLS-1$
                throw new java.lang.StringIndexOutOfBoundsException(end);
            }
            if (this != u.strmHandler) {
                throw new java.lang.SecurityException();
            }
            return;
            }
            String parseString = str.substring(start, end);
            end -= start;
            int fileIdx = 0;

            // Default is to use info from context
            String host = u.getHost();
            int port = u.getPort();
            String refJ = u.getRef();
            String file = u.getPath();
            String query = u.getQuery();
            String authority = u.getAuthority();
            String userInfo = u.getUserInfo();

            int refIdx = parseString.indexOf('#', 0);
            if (parseString.startsWith("//") && !parseString.startsWith("////")) { //$NON-NLS-1$
            int hostIdx = 2, portIdx = -1;
            port = -1;
            fileIdx = parseString.indexOf('/', hostIdx);
            int questionMarkIndex = parseString.indexOf('?', hostIdx);
            if ((questionMarkIndex != -1)
                    && ((fileIdx == -1) || (fileIdx > questionMarkIndex))) {
                fileIdx = questionMarkIndex;
            }
            if (fileIdx == -1) {
                fileIdx = end;
                // Use default
                file = ""; //$NON-NLS-1$
            }
            int hostEnd = fileIdx;
            if (refIdx != -1 && refIdx < fileIdx) {
                hostEnd = refIdx;
            }
            int userIdx = parseString.lastIndexOf('@', hostEnd);
            authority = parseString.substring(hostIdx, hostEnd);
            if (userIdx > -1) {
                userInfo = parseString.substring(hostIdx, userIdx);
                hostIdx = userIdx + 1;
            }

            portIdx = parseString.indexOf(':', userIdx == -1 ? hostIdx
                    : userIdx);
            int endOfIPv6Addr = parseString.indexOf(']');
            // if there are square braces, ie. IPv6 address, use last ':'
            if (endOfIPv6Addr != -1) {
                try {
                    if (parseString.length() > endOfIPv6Addr + 1) {
                        char c = parseString.charAt(endOfIPv6Addr + 1);
                        if (c == ':') {
                            portIdx = endOfIPv6Addr + 1;
                        } else {
                            portIdx = -1;
                        }
                    } else {
                        portIdx = -1;
                    }
                } catch (Exception e) {
                    // Ignored
                }
            }

            if (portIdx == -1 || portIdx > fileIdx) {
                host = parseString.substring(hostIdx, hostEnd);
            } else {
                host = parseString.substring(hostIdx, portIdx);
                String portString = parseString.substring(portIdx + 1, hostEnd);
                if (portString.length() == 0) {
                    port = -1;
                } else {
                    port = java.lang.Integer.parseInt(portString);
                }
            }
            }

            if (refIdx > -1) {
            refJ = parseString.substring(refIdx + 1, end);
            }
            int fileEnd = (refIdx == -1 ? end : refIdx);

            int queryIdx = parseString.lastIndexOf('?', fileEnd);
            bool canonicalize = false;
            if (queryIdx > -1) {
            query = parseString.substring(queryIdx + 1, fileEnd);
            if (queryIdx == 0 && file != null) {
                if (file.equals("")) { //$NON-NLS-1$
                    file = "/"; //$NON-NLS-1$
                } else if (file.startsWith("/")) { //$NON-NLS-1$
                    canonicalize = true;
                }
                int last = file.lastIndexOf('/') + 1;
                file = file.substring(0, last);
            }
            fileEnd = queryIdx;
            } else
            // Don't inherit query unless only the ref is changed
            if (refIdx != 0) {
            query = null;
            }

            if (fileIdx > -1) {
            if (fileIdx < end && parseString.charAt(fileIdx) == '/') {
                file = parseString.substring(fileIdx, fileEnd);
            } else if (fileEnd > fileIdx) {
                if (file == null) {
                    file = ""; //$NON-NLS-1$
                } else if (file.equals("")) { //$NON-NLS-1$
                    file = "/"; //$NON-NLS-1$
                } else if (file.startsWith("/")) { //$NON-NLS-1$
                    canonicalize = true;
                }
                int last = file.lastIndexOf('/') + 1;
                if (last == 0) {
                    file = parseString.substring(fileIdx, fileEnd);
                } else {
                    file = file.substring(0, last)
                            + parseString.substring(fileIdx, fileEnd);
                }
            }
            }
            if (file == null) {
            file = ""; //$NON-NLS-1$
            }

            if (host == null) {
            host = ""; //$NON-NLS-1$
            }

            if (canonicalize) {
            // modify file if there's any relative referencing
            file = URLUtil.canonicalizePath(file);
            }

            setURL(u, u.getProtocol(), host, port, authority, userInfo, file,
                query, refJ);
        }
Beispiel #7
0
 /*
  * If the URL host is empty while protocol is file, the host is regarded as
  * localhost.
  */
 private static String getHost(URL url)
 {
     String host = url.getHost();
     if ("file".equals(url.getProtocol()) //$NON-NLS-1$
             && "".equals(host))
     { //$NON-NLS-1$
         host = "localhost"; //$NON-NLS-1$
     }
     return host;
 }
Beispiel #8
0
        /**
         * Compares two URL objects whether they refer to the same file. In the
         * comparison included are the URL components protocol, host, port and file.
         *
         * @param url1
         *            the first URL to be compared.
         * @param url2
         *            the second URL to be compared.
         * @return {@code true} if both URLs refer to the same file, {@code false}
         *         otherwise.
         */
        protected bool sameFile(URL url1, URL url2)
        {
            String s1 = url1.getProtocol();
            String s2 = url2.getProtocol();
            if (s1 != s2 && (s1 == null || !s1.equals(s2)))
            {
                return false;
            }

            s1 = url1.getFile();
            s2 = url2.getFile();
            if (s1 != s2 && (s1 == null || !s1.equals(s2)))
            {
                return false;
            }
            if (!hostsEqual(url1, url2))
            {
                return false;
            }
            int p1 = url1.getPort();
            if (p1 == -1)
            {
                p1 = getDefaultPort();
            }
            int p2 = url2.getPort();
            if (p2 == -1)
            {
                p2 = getDefaultPort();
            }
            return p1 == p2;
        }
Beispiel #9
0
        /**
         * Returns the clear text representation of a given URL using HTTP format.
         *
         * @param url
         *            the URL object to be converted.
         * @return the clear text representation of the specified URL.
         * @see #parseURL
         * @see URL#toExternalForm()
         */
        protected internal String toExternalForm(URL url)
        {
            java.lang.StringBuilder answer = new java.lang.StringBuilder();
            answer.append(url.getProtocol());
            answer.append(':');
            String authority = url.getAuthority();
            if (authority != null && authority.length() > 0)
            {
                answer.append("//"); //$NON-NLS-1$
                answer.append(url.getAuthority());
            }

            String file = url.getFile();
            String refJ = url.getRef();
            if (file != null)
            {
                answer.append(file);
            }
            if (refJ != null)
            {
                answer.append('#');
                answer.append(refJ);
            }
            return answer.toString();
        }
Beispiel #10
0
        /*
         * Creates a new URL to the specified resource {@code spec}. This URL is
         * relative to the given {@code context}. The {@code handler} will be used
         * to parse the URL string representation. If this argument is {@code null}
         * the default {@code URLStreamHandler} will be used. If the protocol of the
         * parsed URL does not match with the protocol of the context URL, then the
         * newly created URL is absolute and bases only on the given URL represented
         * by {@code spec}. Otherwise the protocol is defined by the context URL.
         *
         * @param context
         *            the URL which is used as the context.
         * @param spec
         *            the URL string representation which has to be parsed.
         * @param handler
         *            the specific stream handler to be used by this URL.
         * @throws MalformedURLException
         *             if the given string {@code spec} could not be parsed as a URL
         *             or an invalid protocol has been found.
         */
        public URL(URL context, String spec, URLStreamHandler handler)
        {//throws MalformedURLException {
            if (handler != null)
            {
                java.lang.SecurityManager sm = java.lang.SystemJ.getSecurityManager();
                if (sm != null)
                {
                    sm.checkPermission(specifyStreamHandlerPermission);
                }
                strmHandler = handler;
            }

            if (spec == null)
            {
                throw new MalformedURLException();
            }
            spec = spec.trim();

            // The spec includes a protocol if it includes a colon character
            // before the first occurrence of a slash character. Note that,
            // "protocol" is the field which holds this URLs protocol.
            int index;

            try
            {
                index = spec.indexOf(':');
            }
            catch (java.lang.NullPointerException e)
            {
                throw new MalformedURLException(e.toString());
            }
            int startIPv6Addr = spec.indexOf('[');

            if (index >= 0)
            {
                if ((startIPv6Addr == -1) || (index < startIPv6Addr))
                {
                    protocol = spec.substring(0, index);
                    // According to RFC 2396 scheme part should match
                    // the following expression:
                    // alpha *( alpha | digit | "+" | "-" | "." )
                    char c     = protocol.charAt(0);
                    bool valid = ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
                    for (int i = 1; valid && (i < protocol.length()); i++)
                    {
                        c     = protocol.charAt(i);
                        valid = ('a' <= c && c <= 'z') ||
                                ('A' <= c && c <= 'Z') ||
                                ('0' <= c && c <= '9') ||
                                (c == '+') ||
                                (c == '-') ||
                                (c == '.');
                    }
                    if (!valid)
                    {
                        protocol = null;
                        index    = -1;
                    }
                    else
                    {
                        // Ignore case in protocol names.
                        // Scheme is defined by ASCII characters.
                        protocol = Util.toASCIILowerCase(protocol);
                    }
                }
            }

            if (protocol != null)
            {
                // If the context was specified, and it had the same protocol
                // as the spec, then fill in the receiver's slots from the values
                // in the context but still allow them to be over-ridden later
                // by the values in the spec.
                if (context != null && protocol.equals(context.getProtocol()))
                {
                    String cPath = context.getPath();
                    if (cPath != null && cPath.startsWith("/"))
                    { //$NON-NLS-1$
                        set(protocol, context.getHost(), context.getPort(), context
                            .getAuthority(), context.getUserInfo(), cPath,
                            context.getQuery(), null);
                    }
                    if (strmHandler == null)
                    {
                        strmHandler = context.strmHandler;
                    }
                }
            }
            else
            {
                // If the spec did not include a protocol, then the context
                // *must* be specified. Fill in the receiver's slots from the
                // values in the context, but still allow them to be over-ridden
                // by the values in the ("relative") spec.
                if (context == null)
                {
                    throw new MalformedURLException("Protocol not found: " + spec); //$NON-NLS-1$
                }
                set(context.getProtocol(), context.getHost(), context.getPort(),
                    context.getAuthority(), context.getUserInfo(), context
                    .getPath(), context.getQuery(), null);
                if (strmHandler == null)
                {
                    strmHandler = context.strmHandler;
                }
            }

            // If the stream handler has not been determined, set it
            // to the default for the specified protocol.
            if (strmHandler == null)
            {
                setupStreamHandler();
                if (strmHandler == null)
                {
                    throw new MalformedURLException("Unknown protocol: " + protocol); //$NON-NLS-1$
                }
            }

            // Let the handler parse the URL. If the handler throws
            // any exception, throw MalformedURLException instead.
            //
            // Note: We want "index" to be the index of the start of the scheme
            // specific part of the URL. At this point, it will be either
            // -1 or the index of the colon after the protocol, so we
            // increment it to point at either character 0 or the character
            // after the colon.
            try
            {
                strmHandler.parseURL(this, spec, ++index, spec.length());
            }
            catch (Exception e)
            {
                throw new MalformedURLException(e.toString());
            }

            if (port < -1)
            {
                throw new MalformedURLException("Port out of range: " + port); //$NON-NLS-1$
            }
        }