| /* |
| * 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); |
| } |