001: /*
002: * Copyright 1999-2005 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 com.sun.jndi.cosnaming;
027:
028: import javax.naming.Name;
029: import javax.naming.NamingException;
030:
031: import java.net.MalformedURLException;
032: import java.util.Vector;
033: import java.util.StringTokenizer;
034: import com.sun.jndi.toolkit.url.UrlUtil;
035:
036: /**
037: * Extract components of an "iiop" or "iiopname" URL.
038: *
039: * The format of an iiopname URL is defined in INS 98-10-11 as follows:
040: *
041: * iiopname url = "iiopname://" [addr_list]["/" string_name]
042: * addr_list = [address ","]* address
043: * address = [version host [":" port]]
044: * host = DNS style host name | IP address
045: * version = major "." minor "@" | empty_string
046: * port = number
047: * major = number
048: * minor = number
049: * string_name = stringified name | empty_string
050: *
051: * The default port is 9999. The default version is "1.0"
052: * US-ASCII alphanumeric characters are not escaped. Any characters outside
053: * of this range are escaped except for the following:
054: * ; / : ? : @ & = + $ , - _ . ! ~ * ' ( )
055: * Escaped characters is escaped by using a % followed by its 2 hexadecimal
056: * numbers representing the octet.
057: *
058: * For backward compatibility, the "iiop" URL as defined in INS 97-6-6
059: * is also supported:
060: *
061: * iiop url = "iiop://" [host [":" port]] ["/" string_name]
062: * The default port is 900.
063: *
064: * @author Rosanna Lee
065: * @version 1.15 07/05/05
066: */
067:
068: public final class IiopUrl {
069: static final private int DEFAULT_IIOPNAME_PORT = 9999;
070: static final private int DEFAULT_IIOP_PORT = 900;
071: static final private String DEFAULT_HOST = "localhost";
072: private Vector addresses;
073: private String stringName;
074:
075: public static class Address {
076: public int port = -1;
077: public int major, minor;
078: public String host;
079:
080: public Address(String hostPortVers, boolean oldFormat)
081: throws MalformedURLException {
082: // [version host [":" port]]
083: int start;
084:
085: // Parse version
086: int at;
087: if (oldFormat || (at = hostPortVers.indexOf('@')) < 0) {
088: major = 1;
089: minor = 0;
090: start = 0; // start at the beginning
091: } else {
092: int dot = hostPortVers.indexOf('.');
093: if (dot < 0) {
094: throw new MalformedURLException("invalid version: "
095: + hostPortVers);
096: }
097: try {
098: major = Integer.parseInt(hostPortVers.substring(0,
099: dot));
100: minor = Integer.parseInt(hostPortVers.substring(
101: dot + 1, at));
102: } catch (NumberFormatException e) {
103: throw new MalformedURLException(
104: "Nonnumeric version: " + hostPortVers);
105: }
106: start = at + 1; // skip '@' sign
107: }
108:
109: // Parse host and port
110: int slash = hostPortVers.indexOf('/', start);
111: if (slash < 0) {
112: slash = hostPortVers.length();
113: }
114: if (hostPortVers.startsWith("[", start)) { // at IPv6 literal
115: int brac = hostPortVers.indexOf(']', start + 1);
116: if (brac < 0 || brac > slash) {
117: throw new IllegalArgumentException(
118: "IiopURL: name is an Invalid URL: "
119: + hostPortVers);
120: }
121:
122: // include brackets
123: host = hostPortVers.substring(start, brac + 1);
124: start = brac + 1;
125: } else { // at hostname or IPv4
126: int colon = hostPortVers.indexOf(':', start);
127: int hostEnd = (colon < 0 || colon > slash) ? slash
128: : colon;
129: if (start < hostEnd) {
130: host = hostPortVers.substring(start, hostEnd);
131: }
132: start = hostEnd; // skip past host
133: }
134: if ((start + 1 < slash)) {
135: if (hostPortVers.startsWith(":", start)) { // parse port
136: start++; // skip past ":"
137: port = Integer.parseInt(hostPortVers.substring(
138: start, slash));
139: } else {
140: throw new IllegalArgumentException(
141: "IiopURL: name is an Invalid URL: "
142: + hostPortVers);
143: }
144: }
145: start = slash;
146: if ("".equals(host) || host == null) {
147: host = DEFAULT_HOST;
148: }
149: if (port == -1) {
150: port = (oldFormat ? DEFAULT_IIOP_PORT
151: : DEFAULT_IIOPNAME_PORT);
152: }
153: }
154: }
155:
156: public Vector getAddresses() {
157: return addresses;
158: }
159:
160: /**
161: * Returns a possibly empty but non-null string that is the "string_name"
162: * portion of the URL.
163: */
164: public String getStringName() {
165: return stringName;
166: }
167:
168: public Name getCosName() throws NamingException {
169: return CNCtx.parser.parse(stringName);
170: }
171:
172: public IiopUrl(String url) throws MalformedURLException {
173: int addrStart;
174: boolean oldFormat;
175:
176: if (url.startsWith("iiopname://")) {
177: oldFormat = false;
178: addrStart = 11;
179: } else if (url.startsWith("iiop://")) {
180: oldFormat = true;
181: addrStart = 7;
182: } else {
183: throw new MalformedURLException(
184: "Invalid iiop/iiopname URL: " + url);
185: }
186: int addrEnd = url.indexOf('/', addrStart);
187: if (addrEnd < 0) {
188: addrEnd = url.length();
189: stringName = "";
190: } else {
191: stringName = UrlUtil.decode(url.substring(addrEnd + 1));
192: }
193: addresses = new Vector(3);
194: if (oldFormat) {
195: // Only one host:port part, not multiple
196: addresses.addElement(new Address(url.substring(addrStart,
197: addrEnd), oldFormat));
198: } else {
199: StringTokenizer tokens = new StringTokenizer(url.substring(
200: addrStart, addrEnd), ",");
201: while (tokens.hasMoreTokens()) {
202: addresses.addElement(new Address(tokens.nextToken(),
203: oldFormat));
204: }
205: if (addresses.size() == 0) {
206: addresses.addElement(new Address("", oldFormat));
207: }
208: }
209: }
210:
211: // for testing only
212: /*public static void main(String[] args) {
213: try {
214: IiopUrl url = new IiopUrl(args[0]);
215: Vector addrs = url.getAddresses();
216: String name = url.getStringName();
217:
218: for (int i = 0; i < addrs.size(); i++) {
219: Address addr = (Address)addrs.elementAt(i);
220: System.out.println("host: " + addr.host);
221: System.out.println("port: " + addr.port);
222: System.out.println("version: " + addr.major + " " + addr.minor);
223: }
224: System.out.println("name: " + name);
225: } catch (MalformedURLException e) {
226: e.printStackTrace();
227: }
228: } */
229: }
|