17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 59a70fc3bSMark J. Nelson * Common Development and Distribution License (the "License"). 69a70fc3bSMark J. Nelson * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 227c478bd9Sstevel@tonic-gate * Copyright (c) 1999 by Sun Microsystems, Inc. 237c478bd9Sstevel@tonic-gate * All rights reserved. 247c478bd9Sstevel@tonic-gate * 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 279a70fc3bSMark J. Nelson // ServiceURL.java : The service URL. 287c478bd9Sstevel@tonic-gate // Author: James Kempf, Erik Guttman 297c478bd9Sstevel@tonic-gate // 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate package com.sun.slp; 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate import java.util.*; 347c478bd9Sstevel@tonic-gate import java.io.*; 357c478bd9Sstevel@tonic-gate import java.net.*; 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate /** 387c478bd9Sstevel@tonic-gate * The ServiceURL object models the SLP service URL. Both service: URLs 397c478bd9Sstevel@tonic-gate * and regular URLs are handled by this class. 407c478bd9Sstevel@tonic-gate * 417c478bd9Sstevel@tonic-gate * @author James Kempf, Erik Guttman 427c478bd9Sstevel@tonic-gate */ 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate public class ServiceURL extends Object implements Serializable { 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate // Recognized transports. 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate private final static String IPX = "ipx"; 497c478bd9Sstevel@tonic-gate private final static String AT = "at"; 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate /** 527c478bd9Sstevel@tonic-gate * Indicates that no port information is required or was returned 537c478bd9Sstevel@tonic-gate * for this service URL. 547c478bd9Sstevel@tonic-gate */ 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate public static final int NO_PORT = 0; 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate /** 597c478bd9Sstevel@tonic-gate * No life time parameter is given. 607c478bd9Sstevel@tonic-gate */ 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate public static final int LIFETIME_NONE = 0; 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate /** 657c478bd9Sstevel@tonic-gate * Default lifetime, 3 hours. 667c478bd9Sstevel@tonic-gate */ 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate public static final int LIFETIME_DEFAULT = 10800; 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate /** 717c478bd9Sstevel@tonic-gate * Maximum lifetime, approximately 18 hours. 727c478bd9Sstevel@tonic-gate */ 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate public static final int LIFETIME_MAXIMUM = 0xFFFF; 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate /** 777c478bd9Sstevel@tonic-gate * Reregister periodically. 787c478bd9Sstevel@tonic-gate */ 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate public static final int LIFETIME_PERMANENT = -1; 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate // Maximum port size. 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate static final int PORT_MAXIMUM = 0xFFFF; 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate // 887c478bd9Sstevel@tonic-gate // data fields 897c478bd9Sstevel@tonic-gate // 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate private ServiceType serviceType = null; 927c478bd9Sstevel@tonic-gate private ServiceType originalServiceType = null; 937c478bd9Sstevel@tonic-gate private String transport = ""; 947c478bd9Sstevel@tonic-gate private String host = ""; 957c478bd9Sstevel@tonic-gate private int port = NO_PORT; 967c478bd9Sstevel@tonic-gate private String URLPath = ""; 977c478bd9Sstevel@tonic-gate private int lifetime = LIFETIME_DEFAULT; 987c478bd9Sstevel@tonic-gate private boolean isPermanent = false; 997c478bd9Sstevel@tonic-gate private boolean noDoubleSlash = false; 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate /** 1027c478bd9Sstevel@tonic-gate * Construct a service URL object. 1037c478bd9Sstevel@tonic-gate * 1047c478bd9Sstevel@tonic-gate * @param URL The service URL as a string. 1057c478bd9Sstevel@tonic-gate * @param iLifetime The service advertisement lifetime. 1067c478bd9Sstevel@tonic-gate * @exception IllegalArgumentException Thrown if parse 1077c478bd9Sstevel@tonic-gate * errors occur in the 1087c478bd9Sstevel@tonic-gate * parameter. 1097c478bd9Sstevel@tonic-gate */ 1107c478bd9Sstevel@tonic-gate ServiceURL(String URL, int iLifetime)1117c478bd9Sstevel@tonic-gate public ServiceURL(String URL, int iLifetime) 1127c478bd9Sstevel@tonic-gate throws IllegalArgumentException { 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate Assert.nonNullParameter(URL, "URL"); 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate if ((iLifetime > LIFETIME_MAXIMUM) || 1177c478bd9Sstevel@tonic-gate (iLifetime < LIFETIME_PERMANENT)) { 1187c478bd9Sstevel@tonic-gate throw 1197c478bd9Sstevel@tonic-gate new IllegalArgumentException( 1207c478bd9Sstevel@tonic-gate SLPConfig.getSLPConfig().formatMessage("lifetime_error", 1217c478bd9Sstevel@tonic-gate new Object[0])); 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate checkURLString(URL); 1257c478bd9Sstevel@tonic-gate parseURL(URL); 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate if (iLifetime == LIFETIME_PERMANENT) { 1287c478bd9Sstevel@tonic-gate isPermanent = true; 1297c478bd9Sstevel@tonic-gate iLifetime = LIFETIME_MAXIMUM; 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate } 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate lifetime = iLifetime; 1347c478bd9Sstevel@tonic-gate } 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate // 1377c478bd9Sstevel@tonic-gate // ------------------------------------------------------------------ 1387c478bd9Sstevel@tonic-gate // Accessors 1397c478bd9Sstevel@tonic-gate // ------------------------------------------------------------------ 1407c478bd9Sstevel@tonic-gate // 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate /** 1437c478bd9Sstevel@tonic-gate * @return The service type name. 1447c478bd9Sstevel@tonic-gate */ 1457c478bd9Sstevel@tonic-gate getServiceType()1467c478bd9Sstevel@tonic-gate public ServiceType getServiceType() { 1477c478bd9Sstevel@tonic-gate return serviceType; 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate /** 1527c478bd9Sstevel@tonic-gate * Set service type and naming authority if this is not a service: URL. 1537c478bd9Sstevel@tonic-gate * 1547c478bd9Sstevel@tonic-gate * @param type The new ServiceType object. 1557c478bd9Sstevel@tonic-gate * @exception IllegalArgumentException If the service type name or 1567c478bd9Sstevel@tonic-gate * naming authority name is invalid. 1577c478bd9Sstevel@tonic-gate */ 1587c478bd9Sstevel@tonic-gate setServiceType(ServiceType type)1597c478bd9Sstevel@tonic-gate public void setServiceType(ServiceType type) { 1607c478bd9Sstevel@tonic-gate if (!serviceType.isServiceURL()) { 1617c478bd9Sstevel@tonic-gate serviceType = type; 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate /** 1687c478bd9Sstevel@tonic-gate * @return The machine name or IP address. 1697c478bd9Sstevel@tonic-gate */ 1707c478bd9Sstevel@tonic-gate getHost()1717c478bd9Sstevel@tonic-gate public String getHost() { 1727c478bd9Sstevel@tonic-gate return host; 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate } 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate /** 1777c478bd9Sstevel@tonic-gate * @return The port number, if any. 1787c478bd9Sstevel@tonic-gate */ 1797c478bd9Sstevel@tonic-gate getPort()1807c478bd9Sstevel@tonic-gate public int getPort() { 1817c478bd9Sstevel@tonic-gate return port; 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate /** 1867c478bd9Sstevel@tonic-gate * @return The URL path description, if any. 1877c478bd9Sstevel@tonic-gate */ 1887c478bd9Sstevel@tonic-gate getURLPath()1897c478bd9Sstevel@tonic-gate public String getURLPath() { 1907c478bd9Sstevel@tonic-gate return URLPath; 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate /** 1957c478bd9Sstevel@tonic-gate * @return The service advertisement lifetime. 1967c478bd9Sstevel@tonic-gate */ 1977c478bd9Sstevel@tonic-gate getLifetime()1987c478bd9Sstevel@tonic-gate public int getLifetime() { 1997c478bd9Sstevel@tonic-gate return lifetime; 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate /** 2047c478bd9Sstevel@tonic-gate * Formats the service URL into standard URL form. 2057c478bd9Sstevel@tonic-gate * 2067c478bd9Sstevel@tonic-gate * @return Formatted string with the service URL. 2077c478bd9Sstevel@tonic-gate */ 2087c478bd9Sstevel@tonic-gate toString()2097c478bd9Sstevel@tonic-gate public String toString() { // Overrides Object.toString(); 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate return 2127c478bd9Sstevel@tonic-gate originalServiceType.toString() + 2137c478bd9Sstevel@tonic-gate ":/" + transport + (noDoubleSlash == false ? "/":"") + 2147c478bd9Sstevel@tonic-gate host + (port != NO_PORT ? (":" + port) : "") + 2157c478bd9Sstevel@tonic-gate URLPath; 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate hashCode()2197c478bd9Sstevel@tonic-gate public int hashCode() { 2207c478bd9Sstevel@tonic-gate return 2217c478bd9Sstevel@tonic-gate serviceType.hashCode() + 2227c478bd9Sstevel@tonic-gate transport.hashCode() + 2237c478bd9Sstevel@tonic-gate host.hashCode() + 2247c478bd9Sstevel@tonic-gate port + 2257c478bd9Sstevel@tonic-gate URLPath.hashCode(); 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate equals(Object obj)2287c478bd9Sstevel@tonic-gate public boolean equals(Object obj) { 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate if (obj == this) { 2317c478bd9Sstevel@tonic-gate return true; 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate } 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate if (!(obj instanceof ServiceURL)) { 2367c478bd9Sstevel@tonic-gate return false; 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate ServiceURL surl = (ServiceURL)obj; 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate return 2427c478bd9Sstevel@tonic-gate serviceType.equals(surl.serviceType) && 2437c478bd9Sstevel@tonic-gate transport.equals(surl.transport) && 2447c478bd9Sstevel@tonic-gate host.equals(surl.host) && 2457c478bd9Sstevel@tonic-gate (port == surl.port) && 2467c478bd9Sstevel@tonic-gate (noDoubleSlash == surl.noDoubleSlash) && 2477c478bd9Sstevel@tonic-gate URLPath.equals(surl.URLPath); 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate } 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate // Return permanent status. 2527c478bd9Sstevel@tonic-gate getIsPermanent()2537c478bd9Sstevel@tonic-gate boolean getIsPermanent() { 2547c478bd9Sstevel@tonic-gate return isPermanent; 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate // Check URL characters for correctness. 2597c478bd9Sstevel@tonic-gate checkURLString(String s)2607c478bd9Sstevel@tonic-gate private void checkURLString(String s) 2617c478bd9Sstevel@tonic-gate throws IllegalArgumentException { 2627c478bd9Sstevel@tonic-gate for (int i = 0; i < s.length(); i++) { 2637c478bd9Sstevel@tonic-gate char c = s.charAt(i); 2647c478bd9Sstevel@tonic-gate // allowed by RFC1738 2657c478bd9Sstevel@tonic-gate if (c == '/' || c == ':' || c == '-' || c == ':' || 2667c478bd9Sstevel@tonic-gate c == '.' || c == '%' || c == '_' || c == '\'' || 2677c478bd9Sstevel@tonic-gate c == '*' || c == '(' || c == ')' || c == '$' || 2687c478bd9Sstevel@tonic-gate c == '!' || c == ',' || c == '+' || c == '\\') { 2697c478bd9Sstevel@tonic-gate // defer to Windows 2707c478bd9Sstevel@tonic-gate continue; 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate // reserved by RFC1738, and thus allowed, pg. 20 2757c478bd9Sstevel@tonic-gate if (c == ';' || c == '@' || c == '?' || c == '&' || c == '=') { 2767c478bd9Sstevel@tonic-gate continue; 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate } 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate if (Character.isLetterOrDigit(c)) { 2817c478bd9Sstevel@tonic-gate continue; 2827c478bd9Sstevel@tonic-gate } 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate SLPConfig conf = SLPConfig.getSLPConfig(); 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate throw 2877c478bd9Sstevel@tonic-gate new IllegalArgumentException( 2887c478bd9Sstevel@tonic-gate conf.formatMessage("url_char_error", 2897c478bd9Sstevel@tonic-gate new Object[] { 2907c478bd9Sstevel@tonic-gate new Character(c)})); 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate // Parse the incoming service URL specification. 2957c478bd9Sstevel@tonic-gate parseURL(String sURL)2967c478bd9Sstevel@tonic-gate private void parseURL(String sURL) 2977c478bd9Sstevel@tonic-gate throws IllegalArgumentException { 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate StringTokenizer st = new StringTokenizer(sURL, "/", true); 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate try { 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate // This loop is a kludgy way to break out of the parse so 3047c478bd9Sstevel@tonic-gate // we only throw at one location in the code. 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate do { 3077c478bd9Sstevel@tonic-gate String typeName = st.nextToken(); 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate // First token must be service type name. 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate if (typeName.equals("/")) { 3127c478bd9Sstevel@tonic-gate break; // error! 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate // Check for colon terminator, not part of service 3177c478bd9Sstevel@tonic-gate // type name. 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate if (!typeName.endsWith(":")) { 3207c478bd9Sstevel@tonic-gate break; // error! 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate } 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate // Create service type, remove trailing colon. 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate serviceType = 3277c478bd9Sstevel@tonic-gate new ServiceType(typeName.substring(0, 3287c478bd9Sstevel@tonic-gate typeName.length() - 1)); 3297c478bd9Sstevel@tonic-gate originalServiceType = serviceType; 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate // Separator between service type name and transport. 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate String slash1 = st.nextToken(); 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate if (!slash1.equals("/")) { 3367c478bd9Sstevel@tonic-gate break; // error! 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate String slash2 = st.nextToken(); 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate String sAddr = ""; // address... 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate // Check for abstract type or alternate transport. 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate if (!slash2.equals("/")) { 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate // If this is an abstract type, then we could have 3497c478bd9Sstevel@tonic-gate // something like: service:file-printer:file:/foo/bar. 3507c478bd9Sstevel@tonic-gate // This is OK. Also, if this is a non-service: URL, 3517c478bd9Sstevel@tonic-gate // something like file:/foo/bar is OK. 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate if (!serviceType.isServiceURL()) { 3547c478bd9Sstevel@tonic-gate sAddr = slash2; 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate noDoubleSlash = true; 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate } else { 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate // We only recognize IPX and Appletalk at this point. 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate if (!slash2.equalsIgnoreCase(IPX) && 3637c478bd9Sstevel@tonic-gate !slash2.equalsIgnoreCase(AT)) { 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate // Abstract type is OK. We must check here because 3667c478bd9Sstevel@tonic-gate // something like 3677c478bd9Sstevel@tonic-gate // service:printing:lpr:/ipx/foo/bar 3687c478bd9Sstevel@tonic-gate // is allowed. 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate if (serviceType.isAbstractType()) { 3717c478bd9Sstevel@tonic-gate sAddr = slash2; 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate noDoubleSlash = true; 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate } else { 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate break; // error! 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate } 3807c478bd9Sstevel@tonic-gate } else { 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate transport = slash2.toLowerCase(); 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate // Check for separator between transport and host. 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate if (!st.nextToken().equals("/")) { 3877c478bd9Sstevel@tonic-gate break; // error! 388*55fea89dSDan Cross 3897c478bd9Sstevel@tonic-gate } 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate sAddr = st.nextToken(); 3927c478bd9Sstevel@tonic-gate } 3937c478bd9Sstevel@tonic-gate } 3947c478bd9Sstevel@tonic-gate } else { 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate // Not abstract type, no alternate transport. Get host. 3977c478bd9Sstevel@tonic-gate 3987c478bd9Sstevel@tonic-gate sAddr = st.nextToken(); 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate } 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate if (sAddr.equals("/")) {// no host part 4037c478bd9Sstevel@tonic-gate URLPath = "/" + st.nextToken(""); 4047c478bd9Sstevel@tonic-gate return; // we're done! 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate } 4077c478bd9Sstevel@tonic-gate 4087c478bd9Sstevel@tonic-gate host = sAddr; 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate // Need to check for port number if this is an IP transport. 4117c478bd9Sstevel@tonic-gate 4127c478bd9Sstevel@tonic-gate if (transport.equals("")) { 4137c478bd9Sstevel@tonic-gate StringTokenizer tk = new StringTokenizer(host, ":"); 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate host = tk.nextToken(); 4167c478bd9Sstevel@tonic-gate 4177c478bd9Sstevel@tonic-gate // Get port if any. 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate if (tk.hasMoreTokens()) { 4207c478bd9Sstevel@tonic-gate String p = tk.nextToken(); 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate if (tk.hasMoreTokens()) { 4237c478bd9Sstevel@tonic-gate break; // error! 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate } 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate try { 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate port = Integer.parseInt(p); 4307c478bd9Sstevel@tonic-gate 4317c478bd9Sstevel@tonic-gate } catch (NumberFormatException ex) { 4327c478bd9Sstevel@tonic-gate break; // error! 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate } 4357c478bd9Sstevel@tonic-gate 4367c478bd9Sstevel@tonic-gate if (port <= 0 || port > PORT_MAXIMUM) { 4377c478bd9Sstevel@tonic-gate break; // error! 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate } 4407c478bd9Sstevel@tonic-gate } 4417c478bd9Sstevel@tonic-gate } 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate // 4447c478bd9Sstevel@tonic-gate // after this point we have to check if there is a token 4457c478bd9Sstevel@tonic-gate // remaining before we read it: It is legal to stop at any 4467c478bd9Sstevel@tonic-gate // point now. Before all the tokens were required, so 4477c478bd9Sstevel@tonic-gate // missing any was an error. 4487c478bd9Sstevel@tonic-gate // 4497c478bd9Sstevel@tonic-gate if (st.hasMoreTokens() == false) { 4507c478bd9Sstevel@tonic-gate // minimal url service:t:// a 4517c478bd9Sstevel@tonic-gate return; // we're done! 4527c478bd9Sstevel@tonic-gate 4537c478bd9Sstevel@tonic-gate } 4547c478bd9Sstevel@tonic-gate 4557c478bd9Sstevel@tonic-gate String sSep = st.nextToken(); 4567c478bd9Sstevel@tonic-gate 4577c478bd9Sstevel@tonic-gate if (!sSep.equals("/")) { 4587c478bd9Sstevel@tonic-gate break; // error! 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate } 461*55fea89dSDan Cross 4627c478bd9Sstevel@tonic-gate // there is a URL path 4637c478bd9Sstevel@tonic-gate // URLPath is all remaining tokens 4647c478bd9Sstevel@tonic-gate URLPath = sSep; 4657c478bd9Sstevel@tonic-gate 4667c478bd9Sstevel@tonic-gate if (st.hasMoreTokens()) { 4677c478bd9Sstevel@tonic-gate URLPath += st.nextToken(""); 4687c478bd9Sstevel@tonic-gate 4697c478bd9Sstevel@tonic-gate } 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate URLPath = URLPath.trim(); 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate return; // done! 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate } while (false); // done with parse. 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate } catch (NoSuchElementException ex) { 4787c478bd9Sstevel@tonic-gate throw 4797c478bd9Sstevel@tonic-gate new IllegalArgumentException( 4807c478bd9Sstevel@tonic-gate SLPConfig.getSLPConfig().formatMessage("url_syntax_error", 4817c478bd9Sstevel@tonic-gate new Object[] {sURL})); 4827c478bd9Sstevel@tonic-gate 4837c478bd9Sstevel@tonic-gate } 4847c478bd9Sstevel@tonic-gate 4857c478bd9Sstevel@tonic-gate // The only way to get here is if there was an error in the 4867c478bd9Sstevel@tonic-gate // parse. 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate throw 4897c478bd9Sstevel@tonic-gate new IllegalArgumentException( 4907c478bd9Sstevel@tonic-gate SLPConfig.getSLPConfig().formatMessage("url_syntax_error", 4917c478bd9Sstevel@tonic-gate new Object[] {sURL})); 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate } 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate } 496