CorbalocURL.java revision 608:7e06bf1dcb09
1/* 2 * Copyright (c) 2002, 2003, 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 26package com.sun.corba.se.impl.naming.namingutil; 27 28import java.util.*; 29 30import com.sun.corba.se.spi.logging.CORBALogDomains ; 31import com.sun.corba.se.impl.logging.NamingSystemException ; 32 33/** 34 * The corbaloc: URL definitions from the -ORBInitDef and -ORBDefaultInitDef's 35 * will be parsed and converted to this object. This object is capable of 36 * storing multiple Host profiles as defined in the CorbaLoc grammer. 37 * 38 * @author Hemanth 39 */ 40public class CorbalocURL extends INSURLBase 41{ 42 static NamingSystemException wrapper = NamingSystemException.get( 43 CORBALogDomains.NAMING_READ ) ; 44 45 /** 46 * This constructor parses the URL and initializes all the variables. Once 47 * the URL Object is constructed it is immutable. URL parameter is a 48 * corbaloc: URL string with 'corbaloc:' prefix stripped. 49 */ 50 public CorbalocURL( String aURL ) { 51 String url = aURL; 52 53 if( url != null ) { 54 try { 55 // First Clean the URL Escapes if there are any 56 url = Utility.cleanEscapes( url ); 57 } catch( Exception e ) { 58 // There is something wrong with the URL escapes used 59 // so throw an exception 60 badAddress( e ); 61 } 62 int endIndex = url.indexOf( '/' ); 63 if( endIndex == -1 ) { 64 // If there is no '/' then the endIndex is at the end of the URL 65 endIndex = url.length(); 66 } 67 // _REVISIT_: Add a testcase to check 'corbaloc:/' 68 if( endIndex == 0 ) { 69 // The url starts with a '/', it's an error 70 badAddress( null ); 71 } 72 // Anything between corbaloc: and / is the host,port information 73 // of the server where the Service Object is located 74 StringTokenizer endpoints = new StringTokenizer( 75 url.substring( 0, endIndex ), "," ); 76 // NOTE: 77 // There should be atleast one token, because there are checks 78 // to make sure that there is host information before the 79 // delimiter '/'. So no need to explicitly check for number of 80 // tokens != 0 81 while( endpoints.hasMoreTokens( ) ) { 82 String endpointInfo = endpoints.nextToken(); 83 IIOPEndpointInfo iiopEndpointInfo = null; 84 if( endpointInfo.startsWith( "iiop:" ) ) { 85 iiopEndpointInfo = handleIIOPColon( endpointInfo ); 86 } else if( endpointInfo.startsWith( "rir:" ) ) { 87 handleRIRColon( endpointInfo ); 88 rirFlag = true; 89 } else if( endpointInfo.startsWith( ":" ) ) { 90 iiopEndpointInfo = handleColon( endpointInfo ); 91 } else { 92 // Right now we are not allowing any other protocol 93 // other than iiop:, rir: so raise exception indicating 94 // that the URL is malformed 95 badAddress( null ); 96 } 97 if ( rirFlag == false ) { 98 // Add the Host information if RIR flag is set, 99 // If RIR is set then it means use the internal Boot 100 // Strap protocol for Key String resolution 101 if( theEndpointInfo == null ) { 102 theEndpointInfo = new java.util.ArrayList( ); 103 } 104 theEndpointInfo.add( iiopEndpointInfo ); 105 } 106 } 107 // If there is something after corbaloc:endpointInfo/ 108 // then that is the keyString 109 if( url.length() > (endIndex + 1) ) { 110 theKeyString = url.substring( endIndex + 1 ); 111 } 112 } 113 } 114 115 116 /** 117 * A Utility method to throw BAD_PARAM exception to signal malformed 118 * INS URL. 119 */ 120 private void badAddress( java.lang.Throwable e ) 121 { 122 throw wrapper.insBadAddress( e ) ; 123 } 124 125 /** 126 * If there is 'iiop:' token in the URL, this method will parses 127 * and validates that host and port information. 128 */ 129 private IIOPEndpointInfo handleIIOPColon( String iiopInfo ) 130 { 131 // Check the iiop syntax 132 iiopInfo = iiopInfo.substring( NamingConstants.IIOP_LENGTH ); 133 return handleColon( iiopInfo ); 134 } 135 136 137 /** 138 * This is to handle the case of host information with no 'iiop:' prefix. 139 * instead if ':' is specified then iiop is assumed. 140 */ 141 private IIOPEndpointInfo handleColon( String iiopInfo ) { 142 // String after ":" 143 iiopInfo = iiopInfo.substring( 1 ); 144 String hostandport = iiopInfo; 145 // The format can be 1.2@<host>:<port> 146 StringTokenizer tokenizer = new StringTokenizer( iiopInfo, "@" ); 147 IIOPEndpointInfo iiopEndpointInfo = new IIOPEndpointInfo( ); 148 int tokenCount = tokenizer.countTokens( ); 149 // There can be 1 or 2 tokens with '@' as the delimiter 150 // - if there is only 1 token then there is no GIOP version 151 // information. A Default GIOP version of 1.2 is used. 152 // - if there are 2 tokens then there is GIOP version is specified 153 // - if there are no tokens or more than 2 tokens, then that's an 154 // error 155 if( ( tokenCount == 0 ) 156 ||( tokenCount > 2 )) 157 { 158 badAddress( null ); 159 } 160 if( tokenCount == 2 ) { 161 // There is VersionInformation after iiop: 162 String version = tokenizer.nextToken( ); 163 int dot = version.indexOf('.'); 164 // There is a version without ., which means 165 // Malformed list 166 if (dot == -1) { 167 badAddress( null ); 168 } 169 try { 170 iiopEndpointInfo.setVersion( 171 Integer.parseInt( version.substring( 0, dot )), 172 Integer.parseInt( version.substring(dot+1)) ); 173 hostandport = tokenizer.nextToken( ); 174 } catch( Throwable e ) { 175 badAddress( e ); 176 } 177 } 178 try { 179 // A Hack to differentiate IPV6 address 180 // from IPV4 address, Current Resolution 181 // is to use [ ] to differentiate ipv6 host 182 int squareBracketBeginIndex = hostandport.indexOf ( '[' ); 183 if( squareBracketBeginIndex != -1 ) { 184 // ipv6Host should be enclosed in 185 // [ ], if not it will result in a 186 // BAD_PARAM exception 187 String ipv6Port = getIPV6Port( hostandport ); 188 if( ipv6Port != null ) { 189 iiopEndpointInfo.setPort( Integer.parseInt( ipv6Port )); 190 } 191 iiopEndpointInfo.setHost( getIPV6Host( hostandport )); 192 return iiopEndpointInfo; 193 } 194 tokenizer = new StringTokenizer( hostandport, ":" ); 195 // There are three possible cases here 196 // 1. Host and Port is explicitly specified by using ":" as a 197 // a separator 198 // 2. Only Host is specified without the port 199 // 3. HostAndPort info is null 200 if( tokenizer.countTokens( ) == 2 ) { 201 // Case 1: There is Host and Port Info 202 iiopEndpointInfo.setHost( tokenizer.nextToken( ) ); 203 iiopEndpointInfo.setPort( Integer.parseInt( 204 tokenizer.nextToken( ))); 205 } else { 206 if( ( hostandport != null ) 207 &&( hostandport.length() != 0 ) ) 208 { 209 // Case 2: Only Host is specified. iiopEndpointInfo is 210 // initialized to use the default INS port, if no port is 211 // specified 212 iiopEndpointInfo.setHost( hostandport ); 213 } 214 // Case 3: If no Host and Port info is provided then we use the 215 // the default LocalHost and INSPort. iiopEndpointInfo is 216 // already initialized with this info. 217 } 218 } catch( Throwable e ) { 219 // Any kind of Exception is bad here. 220 // Possible causes: A Number Format exception because port info is 221 // malformed 222 badAddress( e ); 223 } 224 Utility.validateGIOPVersion( iiopEndpointInfo ); 225 return iiopEndpointInfo; 226 } 227 228 /** 229 * Validate 'rir:' case. 230 */ 231 private void handleRIRColon( String rirInfo ) 232 { 233 if( rirInfo.length() != NamingConstants.RIRCOLON_LENGTH ) { 234 badAddress( null ); 235 } 236 } 237 238 /** 239 * Returns an IPV6 Port that is after [<ipv6>]:. There is no validation 240 * done here, if it is an incorrect port then the request through 241 * this URL results in a COMM_FAILURE, otherwise malformed list will 242 * result in BAD_PARAM exception thrown in checkcorbalocGrammer. 243 */ 244 private String getIPV6Port( String endpointInfo ) 245 { 246 int squareBracketEndIndex = endpointInfo.indexOf ( ']' ); 247 // If there is port information, then it has to be after ] bracket 248 // indexOf returns the count from the index of zero as the base, so 249 // equality check requires squareBracketEndIndex + 1. 250 if( (squareBracketEndIndex + 1) != (endpointInfo.length( )) ) { 251 if( endpointInfo.charAt( squareBracketEndIndex + 1 ) != ':' ) { 252 throw new RuntimeException( 253 "Host and Port is not separated by ':'" ); 254 } 255 // PortInformation should be after ']:' delimiter 256 // If there is an exception then it will be caught in 257 // checkcorbaGrammer method and rethrown as BAD_PARAM 258 return endpointInfo.substring( squareBracketEndIndex + 2 ); 259 } 260 return null; 261 } 262 263 264 /** 265 * Returns an IPV6 Host that is inside [ ] tokens. There is no validation 266 * done here, if it is an incorrect IPV6 address then the request through 267 * this URL results in a COMM_FAILURE, otherwise malformed list will 268 * result in BAD_PARAM exception thrown in checkcorbalocGrammer. 269 */ 270 private String getIPV6Host( String endpointInfo ) { 271 // ipv6Host should be enclosed in 272 // [ ], if not it will result in a 273 // BAD_PARAM exception 274 int squareBracketEndIndex = endpointInfo.indexOf ( ']' ); 275 // get the host between [ ] 276 String ipv6Host = endpointInfo.substring( 1, squareBracketEndIndex ); 277 return ipv6Host; 278 } 279 280 /** 281 * Will be true only in CorbanameURL class. 282 */ 283 public boolean isCorbanameURL( ) { 284 return false; 285 } 286 287 288} 289