blob: 56b389915285be6b2b90b353910c1e5493bdf058 [file] [log] [blame]
/*
* Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.corba.se.impl.orb ;
import com.sun.corba.se.impl.orbutil.GetPropertyAction ;
import java.security.PrivilegedAction ;
import java.security.AccessController ;
import java.applet.Applet ;
import java.util.Properties ;
import java.util.Vector ;
import java.util.Set ;
import java.util.HashSet ;
import java.util.Enumeration ;
import java.util.Iterator ;
import java.util.StringTokenizer ;
import java.net.URL ;
import java.security.AccessController ;
import java.io.File ;
import java.io.FileInputStream ;
import com.sun.corba.se.spi.orb.DataCollector ;
import com.sun.corba.se.spi.orb.PropertyParser ;
import com.sun.corba.se.impl.orbutil.ORBConstants ;
import com.sun.corba.se.impl.orbutil.ORBUtility;
public abstract class DataCollectorBase implements DataCollector {
private PropertyParser parser ;
private Set propertyNames ;
private Set propertyPrefixes ;
private Set URLPropertyNames ;
protected String localHostName ;
protected String configurationHostName ;
private boolean setParserCalled ;
private Properties originalProps ;
private Properties resultProps ;
public DataCollectorBase( Properties props, String localHostName,
String configurationHostName )
{
// XXX This is fully initialized here. So do we ever want to
// generalize this (or perhaps this is the wrong place for this?)
URLPropertyNames = new HashSet() ;
URLPropertyNames.add( ORBConstants.INITIAL_SERVICES_PROPERTY ) ;
propertyNames = new HashSet() ;
// Make sure that we are ready to handle -ORBInitRef. This is special
// due to the need to handle multiple -ORBInitRef args as prefix
// parsing.
propertyNames.add( ORBConstants.ORB_INIT_REF_PROPERTY ) ;
propertyPrefixes = new HashSet() ;
this.originalProps = props ;
this.localHostName = localHostName ;
this.configurationHostName = configurationHostName ;
setParserCalled = false ;
resultProps = new Properties() ;
}
//////////////////////////////////////////////////////////
// Public interface defined in DataCollector
//////////////////////////////////////////////////////////
public boolean initialHostIsLocal()
{
checkSetParserCalled() ;
return localHostName.equals( resultProps.getProperty(
ORBConstants.INITIAL_HOST_PROPERTY ) ) ;
}
public void setParser( PropertyParser parser )
{
Iterator iter = parser.iterator() ;
while (iter.hasNext()) {
ParserAction pa = (ParserAction)(iter.next()) ;
if (pa.isPrefix())
propertyPrefixes.add( pa.getPropertyName() ) ;
else
propertyNames.add( pa.getPropertyName() ) ;
}
collect() ;
setParserCalled = true ;
}
public Properties getProperties()
{
checkSetParserCalled() ;
return resultProps ;
}
//////////////////////////////////////////////////////////
// public interface from DataCollector that must be defined
// in subclasses
//////////////////////////////////////////////////////////
public abstract boolean isApplet() ;
//////////////////////////////////////////////////////////
// Implementation methods needed in subclasses
//////////////////////////////////////////////////////////
protected abstract void collect() ;
//////////////////////////////////////////////////////////
// methods for use by subclasses
//////////////////////////////////////////////////////////
protected void checkPropertyDefaults()
{
String host =
resultProps.getProperty( ORBConstants.INITIAL_HOST_PROPERTY ) ;
if ((host == null) || (host.equals("")))
setProperty( ORBConstants.INITIAL_HOST_PROPERTY,
configurationHostName );
String serverHost =
resultProps.getProperty( ORBConstants.SERVER_HOST_PROPERTY ) ;
if (serverHost == null ||
serverHost.equals("") ||
serverHost.equals("0.0.0.0") ||
serverHost.equals("::") ||
serverHost.toLowerCase().equals("::ffff:0.0.0.0"))
{
setProperty(ORBConstants.SERVER_HOST_PROPERTY,
localHostName);
setProperty(ORBConstants.LISTEN_ON_ALL_INTERFACES,
ORBConstants.LISTEN_ON_ALL_INTERFACES);
}
}
protected void findPropertiesFromArgs( String[] params )
{
if (params == null)
return;
// All command-line args are of the form "-ORBkey value".
// The key is mapped to <prefix>.ORBkey.
String name ;
String value ;
for ( int i=0; i<params.length; i++ ) {
value = null ;
name = null ;
if ( params[i] != null && params[i].startsWith("-ORB") ) {
String argName = params[i].substring( 1 ) ;
name = findMatchingPropertyName( propertyNames, argName ) ;
if (name != null)
if ( i+1 < params.length && params[i+1] != null ) {
value = params[++i];
}
}
if (value != null) {
setProperty( name, value ) ;
}
}
}
protected void findPropertiesFromApplet( final Applet app )
{
// Cannot use propertyPrefixes here, since there is no
// way to fetch properties by prefix from an Applet.
if (app == null)
return;
PropertyCallback callback = new PropertyCallback() {
public String get(String name) {
return app.getParameter(name);
}
} ;
findPropertiesByName( propertyNames.iterator(), callback ) ;
// Special Case:
//
// Convert any applet parameter relative URLs to an
// absolute URL based on the Document Root. This is so HTML
// URLs can be kept relative which is sometimes useful for
// managing the Document Root layout.
PropertyCallback URLCallback = new PropertyCallback() {
public String get( String name ) {
String value = resultProps.getProperty(name);
if (value == null)
return null ;
try {
URL url = new URL( app.getDocumentBase(), value ) ;
return url.toExternalForm() ;
} catch (java.net.MalformedURLException exc) {
// Just preserve the original (malformed) value:
// the error will be handled later.
return value ;
}
}
} ;
findPropertiesByName( URLPropertyNames.iterator(),
URLCallback ) ;
}
private void doProperties( final Properties props )
{
PropertyCallback callback = new PropertyCallback() {
public String get(String name) {
return props.getProperty(name);
}
} ;
findPropertiesByName( propertyNames.iterator(), callback ) ;
findPropertiesByPrefix( propertyPrefixes,
makeIterator( props.propertyNames()), callback );
}
protected void findPropertiesFromFile()
{
final Properties fileProps = getFileProperties() ;
if (fileProps==null)
return ;
doProperties( fileProps ) ;
}
protected void findPropertiesFromProperties()
{
if (originalProps == null)
return;
doProperties( originalProps ) ;
}
//
// Map System properties to ORB properties.
// Security bug fix 4278205:
// Only allow reading of system properties with ORB prefixes.
// Previously a malicious subclass was able to read ANY system property.
// Note that other prefixes are fine in other contexts; it is only
// system properties that should impose a restriction.
protected void findPropertiesFromSystem()
{
Set normalNames = getCORBAPrefixes( propertyNames ) ;
Set prefixNames = getCORBAPrefixes( propertyPrefixes ) ;
PropertyCallback callback = new PropertyCallback() {
public String get(String name) {
return getSystemProperty(name);
}
} ;
findPropertiesByName( normalNames.iterator(), callback ) ;
findPropertiesByPrefix( prefixNames,
getSystemPropertyNames(), callback ) ;
}
//////////////////////////////////////////////////////////
// internal implementation
//////////////////////////////////////////////////////////
// Store name, value in resultProps, with special
// treatment of ORBInitRef. All updates to resultProps
// must happen through this method.
private void setProperty( String name, String value )
{
if( name.equals( ORBConstants.ORB_INIT_REF_PROPERTY ) ) {
// Value is <name>=<URL>
StringTokenizer st = new StringTokenizer( value, "=" ) ;
if (st.countTokens() != 2)
throw new IllegalArgumentException() ;
String refName = st.nextToken() ;
String refValue = st.nextToken() ;
resultProps.setProperty( name + "." + refName, refValue ) ;
} else {
resultProps.setProperty( name, value ) ;
}
}
private void checkSetParserCalled()
{
if (!setParserCalled)
throw new IllegalStateException( "setParser not called." ) ;
}
// For each prefix in prefixes, For each name in propertyNames,
// if (prefix is a prefix of name) get value from getProperties and
// setProperty (name, value).
private void findPropertiesByPrefix( Set prefixes,
Iterator propertyNames, PropertyCallback getProperty )
{
while (propertyNames.hasNext()) {
String name = (String)(propertyNames.next()) ;
Iterator iter = prefixes.iterator() ;
while (iter.hasNext()) {
String prefix = (String)(iter.next()) ;
if (name.startsWith( prefix )) {
String value = getProperty.get( name ) ;
// Note: do a put even if value is null since just
// the presence of the property may be significant.
setProperty( name, value ) ;
}
}
}
}
// For each prefix in names, get the corresponding property
// value from the callback, and store the name/value pair in
// the result.
private void findPropertiesByName( Iterator names,
PropertyCallback getProperty )
{
while (names.hasNext()) {
String name = (String)(names.next()) ;
String value = getProperty.get( name ) ;
if (value != null)
setProperty( name, value ) ;
}
}
private static String getSystemProperty(final String name)
{
return (String)AccessController.doPrivileged(
new GetPropertyAction(name));
}
// Map command-line arguments to ORB properties.
//
private String findMatchingPropertyName( Set names,
String suffix )
{
Iterator iter = names.iterator() ;
while (iter.hasNext()) {
String name = (String)(iter.next()) ;
if (name.endsWith( suffix ))
return name ;
}
return null ;
}
private static Iterator makeIterator( final Enumeration enumeration )
{
return new Iterator() {
public boolean hasNext() { return enumeration.hasMoreElements() ; }
public Object next() { return enumeration.nextElement() ; }
public void remove() { throw new UnsupportedOperationException() ; }
} ;
}
private static Iterator getSystemPropertyNames()
{
// This will not throw a SecurityException because this
// class was loaded from rt.jar using the bootstrap classloader.
Enumeration enumeration = (Enumeration)
AccessController.doPrivileged(
new PrivilegedAction() {
public java.lang.Object run() {
return System.getProperties().propertyNames();
}
}
);
return makeIterator( enumeration ) ;
}
private void getPropertiesFromFile( Properties props, String fileName )
{
try {
File file = new File( fileName ) ;
if (!file.exists())
return ;
FileInputStream in = new FileInputStream( file ) ;
try {
props.load( in ) ;
} finally {
in.close() ;
}
} catch (Exception exc) {
// if (ORBInitDebug)
// dprint( "ORB properties file " + fileName + " not found: " +
// exc) ;
}
}
private Properties getFileProperties()
{
Properties defaults = new Properties() ;
String javaHome = getSystemProperty( "java.home" ) ;
String fileName = javaHome + File.separator + "lib" + File.separator +
"orb.properties" ;
getPropertiesFromFile( defaults, fileName ) ;
Properties results = new Properties( defaults ) ;
String userHome = getSystemProperty( "user.home" ) ;
fileName = userHome + File.separator + "orb.properties" ;
getPropertiesFromFile( results, fileName ) ;
return results ;
}
private boolean hasCORBAPrefix( String prefix )
{
return prefix.startsWith( ORBConstants.ORG_OMG_PREFIX ) ||
prefix.startsWith( ORBConstants.SUN_PREFIX ) ||
prefix.startsWith( ORBConstants.SUN_LC_PREFIX ) ||
prefix.startsWith( ORBConstants.SUN_LC_VERSION_PREFIX ) ;
}
// Return only those element of prefixes for which hasCORBAPrefix
// is true.
private Set getCORBAPrefixes( final Set prefixes )
{
Set result = new HashSet() ;
Iterator iter = prefixes.iterator() ;
while (iter.hasNext()) {
String element = (String)(iter.next()) ;
if (hasCORBAPrefix( element ))
result.add( element ) ;
}
return result ;
}
}
// Used to collect properties from various sources.
abstract class PropertyCallback
{
abstract public String get(String name);
}