DataCollectorBase.java revision 608:7e06bf1dcb09
1/* 2 * Copyright (c) 2002, 2004, 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.orb ; 27 28import com.sun.corba.se.impl.orbutil.GetPropertyAction ; 29 30import java.security.PrivilegedAction ; 31import java.security.AccessController ; 32 33import java.applet.Applet ; 34 35import java.util.Properties ; 36import java.util.Vector ; 37import java.util.Set ; 38import java.util.HashSet ; 39import java.util.Enumeration ; 40import java.util.Iterator ; 41import java.util.StringTokenizer ; 42 43import java.net.URL ; 44 45import java.security.AccessController ; 46 47import java.io.File ; 48import java.io.FileInputStream ; 49 50import com.sun.corba.se.spi.orb.DataCollector ; 51import com.sun.corba.se.spi.orb.PropertyParser ; 52 53import com.sun.corba.se.impl.orbutil.ORBConstants ; 54import com.sun.corba.se.impl.orbutil.ORBUtility; 55 56public abstract class DataCollectorBase implements DataCollector { 57 private PropertyParser parser ; 58 private Set propertyNames ; 59 private Set propertyPrefixes ; 60 private Set URLPropertyNames ; 61 protected String localHostName ; 62 protected String configurationHostName ; 63 private boolean setParserCalled ; 64 private Properties originalProps ; 65 private Properties resultProps ; 66 67 public DataCollectorBase( Properties props, String localHostName, 68 String configurationHostName ) 69 { 70 // XXX This is fully initialized here. So do we ever want to 71 // generalize this (or perhaps this is the wrong place for this?) 72 URLPropertyNames = new HashSet() ; 73 URLPropertyNames.add( ORBConstants.INITIAL_SERVICES_PROPERTY ) ; 74 75 propertyNames = new HashSet() ; 76 77 // Make sure that we are ready to handle -ORBInitRef. This is special 78 // due to the need to handle multiple -ORBInitRef args as prefix 79 // parsing. 80 propertyNames.add( ORBConstants.ORB_INIT_REF_PROPERTY ) ; 81 82 propertyPrefixes = new HashSet() ; 83 84 this.originalProps = props ; 85 this.localHostName = localHostName ; 86 this.configurationHostName = configurationHostName ; 87 setParserCalled = false ; 88 resultProps = new Properties() ; 89 } 90 91////////////////////////////////////////////////////////// 92// Public interface defined in DataCollector 93////////////////////////////////////////////////////////// 94 95 public boolean initialHostIsLocal() 96 { 97 checkSetParserCalled() ; 98 return localHostName.equals( resultProps.getProperty( 99 ORBConstants.INITIAL_HOST_PROPERTY ) ) ; 100 } 101 102 public void setParser( PropertyParser parser ) 103 { 104 Iterator iter = parser.iterator() ; 105 while (iter.hasNext()) { 106 ParserAction pa = (ParserAction)(iter.next()) ; 107 if (pa.isPrefix()) 108 propertyPrefixes.add( pa.getPropertyName() ) ; 109 else 110 propertyNames.add( pa.getPropertyName() ) ; 111 } 112 113 collect() ; 114 setParserCalled = true ; 115 } 116 117 public Properties getProperties() 118 { 119 checkSetParserCalled() ; 120 return resultProps ; 121 } 122 123////////////////////////////////////////////////////////// 124// public interface from DataCollector that must be defined 125// in subclasses 126////////////////////////////////////////////////////////// 127 128 public abstract boolean isApplet() ; 129 130////////////////////////////////////////////////////////// 131// Implementation methods needed in subclasses 132////////////////////////////////////////////////////////// 133 134 protected abstract void collect() ; 135 136////////////////////////////////////////////////////////// 137// methods for use by subclasses 138////////////////////////////////////////////////////////// 139 140 protected void checkPropertyDefaults() 141 { 142 String host = 143 resultProps.getProperty( ORBConstants.INITIAL_HOST_PROPERTY ) ; 144 145 if ((host == null) || (host.equals(""))) 146 setProperty( ORBConstants.INITIAL_HOST_PROPERTY, 147 configurationHostName ); 148 149 String serverHost = 150 resultProps.getProperty( ORBConstants.SERVER_HOST_PROPERTY ) ; 151 152 if (serverHost == null || 153 serverHost.equals("") || 154 serverHost.equals("0.0.0.0") || 155 serverHost.equals("::") || 156 serverHost.toLowerCase().equals("::ffff:0.0.0.0")) 157 { 158 setProperty(ORBConstants.SERVER_HOST_PROPERTY, 159 localHostName); 160 setProperty(ORBConstants.LISTEN_ON_ALL_INTERFACES, 161 ORBConstants.LISTEN_ON_ALL_INTERFACES); 162 } 163 } 164 165 protected void findPropertiesFromArgs( String[] params ) 166 { 167 if (params == null) 168 return; 169 170 // All command-line args are of the form "-ORBkey value". 171 // The key is mapped to <prefix>.ORBkey. 172 173 String name ; 174 String value ; 175 176 for ( int i=0; i<params.length; i++ ) { 177 value = null ; 178 name = null ; 179 180 if ( params[i] != null && params[i].startsWith("-ORB") ) { 181 String argName = params[i].substring( 1 ) ; 182 name = findMatchingPropertyName( propertyNames, argName ) ; 183 184 if (name != null) 185 if ( i+1 < params.length && params[i+1] != null ) { 186 value = params[++i]; 187 } 188 } 189 190 if (value != null) { 191 setProperty( name, value ) ; 192 } 193 } 194 } 195 196 protected void findPropertiesFromApplet( final Applet app ) 197 { 198 // Cannot use propertyPrefixes here, since there is no 199 // way to fetch properties by prefix from an Applet. 200 if (app == null) 201 return; 202 203 PropertyCallback callback = new PropertyCallback() { 204 public String get(String name) { 205 return app.getParameter(name); 206 } 207 } ; 208 209 findPropertiesByName( propertyNames.iterator(), callback ) ; 210 211 // Special Case: 212 // 213 // Convert any applet parameter relative URLs to an 214 // absolute URL based on the Document Root. This is so HTML 215 // URLs can be kept relative which is sometimes useful for 216 // managing the Document Root layout. 217 PropertyCallback URLCallback = new PropertyCallback() { 218 public String get( String name ) { 219 String value = resultProps.getProperty(name); 220 if (value == null) 221 return null ; 222 223 try { 224 URL url = new URL( app.getDocumentBase(), value ) ; 225 return url.toExternalForm() ; 226 } catch (java.net.MalformedURLException exc) { 227 // Just preserve the original (malformed) value: 228 // the error will be handled later. 229 return value ; 230 } 231 } 232 } ; 233 234 findPropertiesByName( URLPropertyNames.iterator(), 235 URLCallback ) ; 236 } 237 238 private void doProperties( final Properties props ) 239 { 240 PropertyCallback callback = new PropertyCallback() { 241 public String get(String name) { 242 return props.getProperty(name); 243 } 244 } ; 245 246 findPropertiesByName( propertyNames.iterator(), callback ) ; 247 248 findPropertiesByPrefix( propertyPrefixes, 249 makeIterator( props.propertyNames()), callback ); 250 } 251 252 protected void findPropertiesFromFile() 253 { 254 final Properties fileProps = getFileProperties() ; 255 if (fileProps==null) 256 return ; 257 258 doProperties( fileProps ) ; 259 } 260 261 protected void findPropertiesFromProperties() 262 { 263 if (originalProps == null) 264 return; 265 266 doProperties( originalProps ) ; 267 } 268 269 // 270 // Map System properties to ORB properties. 271 // Security bug fix 4278205: 272 // Only allow reading of system properties with ORB prefixes. 273 // Previously a malicious subclass was able to read ANY system property. 274 // Note that other prefixes are fine in other contexts; it is only 275 // system properties that should impose a restriction. 276 protected void findPropertiesFromSystem() 277 { 278 Set normalNames = getCORBAPrefixes( propertyNames ) ; 279 Set prefixNames = getCORBAPrefixes( propertyPrefixes ) ; 280 281 PropertyCallback callback = new PropertyCallback() { 282 public String get(String name) { 283 return getSystemProperty(name); 284 } 285 } ; 286 287 findPropertiesByName( normalNames.iterator(), callback ) ; 288 289 findPropertiesByPrefix( prefixNames, 290 getSystemPropertyNames(), callback ) ; 291 } 292 293////////////////////////////////////////////////////////// 294// internal implementation 295////////////////////////////////////////////////////////// 296 297 // Store name, value in resultProps, with special 298 // treatment of ORBInitRef. All updates to resultProps 299 // must happen through this method. 300 private void setProperty( String name, String value ) 301 { 302 if( name.equals( ORBConstants.ORB_INIT_REF_PROPERTY ) ) { 303 // Value is <name>=<URL> 304 StringTokenizer st = new StringTokenizer( value, "=" ) ; 305 if (st.countTokens() != 2) 306 throw new IllegalArgumentException() ; 307 308 String refName = st.nextToken() ; 309 String refValue = st.nextToken() ; 310 311 resultProps.setProperty( name + "." + refName, refValue ) ; 312 } else { 313 resultProps.setProperty( name, value ) ; 314 } 315 } 316 317 private void checkSetParserCalled() 318 { 319 if (!setParserCalled) 320 throw new IllegalStateException( "setParser not called." ) ; 321 } 322 323 // For each prefix in prefixes, For each name in propertyNames, 324 // if (prefix is a prefix of name) get value from getProperties and 325 // setProperty (name, value). 326 private void findPropertiesByPrefix( Set prefixes, 327 Iterator propertyNames, PropertyCallback getProperty ) 328 { 329 while (propertyNames.hasNext()) { 330 String name = (String)(propertyNames.next()) ; 331 Iterator iter = prefixes.iterator() ; 332 while (iter.hasNext()) { 333 String prefix = (String)(iter.next()) ; 334 if (name.startsWith( prefix )) { 335 String value = getProperty.get( name ) ; 336 337 // Note: do a put even if value is null since just 338 // the presence of the property may be significant. 339 setProperty( name, value ) ; 340 } 341 } 342 } 343 } 344 345 // For each prefix in names, get the corresponding property 346 // value from the callback, and store the name/value pair in 347 // the result. 348 private void findPropertiesByName( Iterator names, 349 PropertyCallback getProperty ) 350 { 351 while (names.hasNext()) { 352 String name = (String)(names.next()) ; 353 String value = getProperty.get( name ) ; 354 if (value != null) 355 setProperty( name, value ) ; 356 } 357 } 358 359 private static String getSystemProperty(final String name) 360 { 361 return (String)AccessController.doPrivileged( 362 new GetPropertyAction(name)); 363 } 364 365 // Map command-line arguments to ORB properties. 366 // 367 private String findMatchingPropertyName( Set names, 368 String suffix ) 369 { 370 Iterator iter = names.iterator() ; 371 while (iter.hasNext()) { 372 String name = (String)(iter.next()) ; 373 if (name.endsWith( suffix )) 374 return name ; 375 } 376 377 return null ; 378 } 379 380 private static Iterator makeIterator( final Enumeration enumeration ) 381 { 382 return new Iterator() { 383 public boolean hasNext() { return enumeration.hasMoreElements() ; } 384 public Object next() { return enumeration.nextElement() ; } 385 public void remove() { throw new UnsupportedOperationException() ; } 386 } ; 387 } 388 389 private static Iterator getSystemPropertyNames() 390 { 391 // This will not throw a SecurityException because this 392 // class was loaded from rt.jar using the bootstrap classloader. 393 Enumeration enumeration = (Enumeration) 394 AccessController.doPrivileged( 395 new PrivilegedAction() { 396 public java.lang.Object run() { 397 return System.getProperties().propertyNames(); 398 } 399 } 400 ); 401 402 return makeIterator( enumeration ) ; 403 } 404 405 private void getPropertiesFromFile( Properties props, String fileName ) 406 { 407 try { 408 File file = new File( fileName ) ; 409 if (!file.exists()) 410 return ; 411 412 FileInputStream in = new FileInputStream( file ) ; 413 414 try { 415 props.load( in ) ; 416 } finally { 417 in.close() ; 418 } 419 } catch (Exception exc) { 420 // if (ORBInitDebug) 421 // dprint( "ORB properties file " + fileName + " not found: " + 422 // exc) ; 423 } 424 } 425 426 private Properties getFileProperties() 427 { 428 Properties defaults = new Properties() ; 429 430 String javaHome = getSystemProperty( "java.home" ) ; 431 String fileName = javaHome + File.separator + "lib" + File.separator + 432 "orb.properties" ; 433 434 getPropertiesFromFile( defaults, fileName ) ; 435 436 Properties results = new Properties( defaults ) ; 437 438 String userHome = getSystemProperty( "user.home" ) ; 439 fileName = userHome + File.separator + "orb.properties" ; 440 441 getPropertiesFromFile( results, fileName ) ; 442 return results ; 443 } 444 445 private boolean hasCORBAPrefix( String prefix ) 446 { 447 return prefix.startsWith( ORBConstants.ORG_OMG_PREFIX ) || 448 prefix.startsWith( ORBConstants.SUN_PREFIX ) || 449 prefix.startsWith( ORBConstants.SUN_LC_PREFIX ) || 450 prefix.startsWith( ORBConstants.SUN_LC_VERSION_PREFIX ) ; 451 } 452 453 // Return only those element of prefixes for which hasCORBAPrefix 454 // is true. 455 private Set getCORBAPrefixes( final Set prefixes ) 456 { 457 Set result = new HashSet() ; 458 Iterator iter = prefixes.iterator() ; 459 while (iter.hasNext()) { 460 String element = (String)(iter.next()) ; 461 if (hasCORBAPrefix( element )) 462 result.add( element ) ; 463 } 464 465 return result ; 466 } 467} 468 469// Used to collect properties from various sources. 470abstract class PropertyCallback 471{ 472 abstract public String get(String name); 473} 474