1 /* 2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.jndi.cosnaming; 27 28 import javax.naming.Name; 29 import javax.naming.NamingException; 30 31 import java.net.MalformedURLException; 32 import java.util.Vector; 33 import java.util.StringTokenizer; 34 import com.sun.jndi.toolkit.url.UrlUtil; 35 36 /** 37 * Extract components of an "iiop" or "iiopname" URL. 38 * 39 * The format of an iiopname URL is defined in INS 98-10-11 as follows: 40 * 41 * iiopname url = "iiopname://" [addr_list]["/" string_name] 42 * addr_list = [address ","]* address 43 * address = [version host [":" port]] 44 * host = DNS style host name | IP address 45 * version = major "." minor "@" | empty_string 46 * port = number 47 * major = number 48 * minor = number 49 * string_name = stringified name | empty_string 50 * 51 * The default port is 9999. The default version is "1.0" 52 * US-ASCII alphanumeric characters are not escaped. Any characters outside 53 * of this range are escaped except for the following: 54 * ; / : ? : @ & = + $ , - _ . ! ~ * ' ( ) 55 * Escaped characters is escaped by using a % followed by its 2 hexadecimal 56 * numbers representing the octet. 57 * 58 * For backward compatibility, the "iiop" URL as defined in INS 97-6-6 59 * is also supported: 60 * 61 * iiop url = "iiop://" [host [":" port]] ["/" string_name] 62 * The default port is 900. 63 * 64 * @author Rosanna Lee 65 */ 66 67 public final class IiopUrl { 68 static final private int DEFAULT_IIOPNAME_PORT = 9999; 69 static final private int DEFAULT_IIOP_PORT = 900; 70 static final private String DEFAULT_HOST = "localhost"; 71 private Vector<Address> addresses; 72 private String stringName; 73 74 public static class Address { 75 public int port = -1; 76 public int major, minor; 77 public String host; 78 79 public Address(String hostPortVers, boolean oldFormat) 80 throws MalformedURLException { 81 // [version host [":" port]] 82 int start; 83 84 // Parse version 85 int at; 86 if (oldFormat || (at = hostPortVers.indexOf('@')) < 0) { 87 major = 1; 88 minor = 0; 89 start = 0; // start at the beginning 90 } else { 91 int dot = hostPortVers.indexOf('.'); 92 if (dot < 0) { 93 throw new MalformedURLException( 94 "invalid version: " + hostPortVers); 95 } 96 try { 97 major = Integer.parseInt(hostPortVers.substring(0, dot)); 98 minor = Integer.parseInt(hostPortVers.substring(dot+1, at)); 99 } catch (NumberFormatException e) { 100 throw new MalformedURLException( 101 "Nonnumeric version: " + hostPortVers); 102 } 103 start = at + 1; // skip '@' sign 104 } 105 106 // Parse host and port 107 int slash = hostPortVers.indexOf('/', start); 108 if (slash < 0) { 109 slash = hostPortVers.length(); 110 } 111 if (hostPortVers.startsWith("[", start)) { // at IPv6 literal 112 int brac = hostPortVers.indexOf(']', start + 1); 113 if (brac < 0 || brac > slash) { 114 throw new IllegalArgumentException( 115 "IiopURL: name is an Invalid URL: " + hostPortVers); 116 } 117 118 // include brackets 119 host = hostPortVers.substring(start, brac + 1); 120 start = brac + 1; 121 } else { // at hostname or IPv4 122 int colon = hostPortVers.indexOf(':', start); 123 int hostEnd = (colon < 0 || colon > slash) 124 ? slash 125 : colon; 126 if (start < hostEnd) { 127 host = hostPortVers.substring(start, hostEnd); 128 } 129 start = hostEnd; // skip past host 130 } 131 if ((start + 1 < slash)) { 132 if ( hostPortVers.startsWith(":", start)) { // parse port 133 start++; // skip past ":" 134 port = Integer.parseInt(hostPortVers. 135 substring(start, slash)); 136 } else { 137 throw new IllegalArgumentException( 138 "IiopURL: name is an Invalid URL: " + hostPortVers); 139 } 140 } 141 start = slash; 142 if ("".equals(host) || host == null) { 143 host = DEFAULT_HOST ; 144 } 145 if (port == -1) { 146 port = (oldFormat ? DEFAULT_IIOP_PORT : 147 DEFAULT_IIOPNAME_PORT); 148 } 149 } 150 } 151 152 public Vector<Address> getAddresses() { 153 return addresses; 154 } 155 156 /** 157 * Returns a possibly empty but non-null string that is the "string_name" 158 * portion of the URL. 159 */ 160 public String getStringName() { 161 return stringName; 162 } 163 164 public Name getCosName() throws NamingException { 165 return CNCtx.parser.parse(stringName); 166 } 167 168 public IiopUrl(String url) throws MalformedURLException { 169 int addrStart; 170 boolean oldFormat; 171 172 if (url.startsWith("iiopname://")) { 173 oldFormat = false; 174 addrStart = 11; 175 } else if (url.startsWith("iiop://")) { 176 oldFormat = true; 177 addrStart = 7; 178 } else { 179 throw new MalformedURLException("Invalid iiop/iiopname URL: " + url); 180 } 181 int addrEnd = url.indexOf('/', addrStart); 182 if (addrEnd < 0) { 183 addrEnd = url.length(); 184 stringName = ""; 185 } else { 186 stringName = UrlUtil.decode(url.substring(addrEnd+1)); 187 } 188 addresses = new Vector<>(3); 189 if (oldFormat) { 190 // Only one host:port part, not multiple 191 addresses.addElement( 192 new Address(url.substring(addrStart, addrEnd), oldFormat)); 193 } else { 194 StringTokenizer tokens = 195 new StringTokenizer(url.substring(addrStart, addrEnd), ","); 196 while (tokens.hasMoreTokens()) { 197 addresses.addElement(new Address(tokens.nextToken(), oldFormat)); 198 } 199 if (addresses.size() == 0) { 200 addresses.addElement(new Address("", oldFormat)); 201 } 202 } 203 } 204 205 // for testing only 206 /*public static void main(String[] args) { 207 try { 208 IiopUrl url = new IiopUrl(args[0]); 209 Vector addrs = url.getAddresses(); 210 String name = url.getStringName(); 211 212 for (int i = 0; i < addrs.size(); i++) { 213 Address addr = (Address)addrs.elementAt(i); 214 System.out.println("host: " + addr.host); 215 System.out.println("port: " + addr.port); 216 System.out.println("version: " + addr.major + " " + addr.minor); 217 } 218 System.out.println("name: " + name); 219 } catch (MalformedURLException e) { 220 e.printStackTrace(); 221 } 222 } */ 223 }