Re: [jervlet-patch] Make Jervlet-Jetty accept external configurations

Peter Donald <peter-4lf8KW9E9MLMqX/[email protected]> Mon, 17 Nov 2003 18:05:56 +1100
Newsgroups gmane.comp.java.spice.devel
Message-ID <[email protected]>
On Mon, 17 Nov 2003 08:19 am, Ryan Hoegg wrote:
> > Not really, since system properties aren't scoped, they are set
> > container-wide and not per-application. which is unfortunate.
>
> Not even with something magic like classworlds?  Actually I suppose we
> could do it with some AOP trickery too.

You can with some lil magic. Attached is code I used to do much the same thing 
ages ago.

-- 
Cheers,

Peter Donald
*-----------------------------------------------------------*
"I like nonsense, it wakes up the brain cells. Fantasy is a 
necessary ingredient in living, it's a way of looking at life 
through the wrong end of a telescope and that enables you to 
laugh at life's realities." -Dr. Seuss
*-----------------------------------------------------------*
SysPropertiesRedirector.java (text/x-java, 3.8 KB)
/*
 * Copyright (C) The Spice Group. All rights reserved.
 *
 * This software is published under the terms of the Spice
 * Software License version 1.1, a copy of which has been included
 * with this distribution in the LICENSE.txt file.
 *
 * This product includes software developed by the
 * Apache Software Foundation (http://www.apache.org/).
 */
package org.realityforge.isolate;

import java.io.IOException;
import java.util.Properties;
import org.realityforge.isolate.DemuxProperties;

/**
 * This is a utility class that makes it easy to install redirecting
 * Properties objects underlying System.getProeprties() object.
 * The properties object will redirect to the properties object that is
 * associated with the current thread. A properties object becomes
 * associated with the current thread when a user calls one of the
 * bind*() methods or by inheriting the parent threads properties object
 * when thread is initially created. The default  streams will redirect
 * to the default System properties.
 *
 * @author <a href="mailto:[email protected]">Peter Donald</a>
 * @version $Revision: 1.2 $ $Date: 2003/02/25 16:28:32 $
 */
public final class SysPropertiesRedirector
{
    private static final String NOT_INSTALLED_ERR =
        "SysPropertiesRedirector not installed";

    /**
     * Cached version of original System Properties.
     * (Or at least the properties that were installed in JVM
     * when this class is loaded and resovled).
     */
    private static final Properties c_systemProperties =
        System.getProperties();

    private static DemuxProperties c_properties;

    /**
     * Private constructor to block instantiation.
     */
    private SysPropertiesRedirector()
    {
    }

    /**
     * Install the redirecting Properties object.
     *
     * @return true if installed, false if already installed
     */
    public synchronized static boolean install()
        throws IOException
    {
        if( c_properties == System.getProperties() )
        {
            //Already installed so lets ignore
            return false;
        }
        c_properties = new DemuxProperties( c_systemProperties );

        System.setProperties( c_properties );

        return true;
    }

    /**
     * Uninstall the redirecting streams and
     * replace them with streams that point to
     * FileDescriptor.in, FileDescriptor.out and
     * FileDescriptor.err.
     *
     * @return true if uninstalled, false if already uninstalled
     */
    public synchronized static boolean uninstall()
        throws IOException
    {
        if( c_properties != System.getProperties() )
        {
            //Already uninstalled so lets ignore
            return false;
        }

        c_properties = null;
        System.setProperties( c_systemProperties );

        return true;
    }

    /**
     * Bind the specified Properties object to this thread.
     *
     * @param properties the stream to bind
     * @throws java.lang.SecurityException if don't have permission to bind to input
     * @throws java.lang.IllegalStateException if redirector not installed
     */
    public static Properties bindProperties( final Properties properties )
        throws SecurityException, IllegalStateException
    {
        if( null == properties )
        {
            throw new NullPointerException( "properties" );
        }
        if( null == c_properties )
        {
            throw new IllegalStateException( NOT_INSTALLED_ERR );
        }

        final SecurityManager manager = System.getSecurityManager();
        if( null != manager )
        {
            final RuntimePermission permission =
                new RuntimePermission( "SysPropertiesRedirector.setProperties" );
            manager.checkPermission( permission );
        }

        return c_properties.bindProperties( properties );
    }
}
DemuxProperties.java (text/x-java, 3.3 KB)
/*
 * Copyright (C) The Spice Group. All rights reserved.
 *
 * This software is published under the terms of the Spice
 * Software License version 1.1, a copy of which has been included
 * with this distribution in the LICENSE.txt file.
 *
 * This product includes software developed by the
 * Apache Software Foundation (http://www.apache.org/).
 */
package org.realityforge.isolate;

import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Properties;

/**
 * Access to this Properties object is forwarded to a
 * properties that has been associated with this thread.
 *
 * @author <a href="mailto:[email protected]">Peter Donald</a>
 * @version $Revision: 1.1 $ $Date: 2002/06/25 03:19:20 $
 */
public final class DemuxProperties
    extends Properties
{
    /**
     * The properties objects associated with each thread.
     */
    private final InheritableThreadLocal m_properties =
        new InheritableThreadLocal();

    public DemuxProperties( final Properties defaults )
    {
        super( defaults );
    }

    /**
     * Bind the specified Properties object to the current thread.
     *
     * @param properties the Properties object to bind
     */
    public Properties bindProperties( final Properties properties )
    {
        final Properties oldProperties = (Properties)m_properties.get();
        m_properties.set( properties );
        return oldProperties;
    }

    public Object get( final Object key )
    {
        return getProperties().get( key );
    }

    public Object put( final Object key,
                       final Object value )
    {
        return getProperties().put( key, value );
    }

    public Object remove( final Object key )
    {
        return getProperties().remove( key );
    }

    public final int size()
    {
        return getProperties().size();
    }

    public final boolean isEmpty()
    {
        return getProperties().isEmpty();
    }

    public Enumeration keys()
    {
        return getProperties().keys();
    }

    public Enumeration elements()
    {
        return getProperties().keys();
    }

    public boolean contains( final Object value )
    {
        return getProperties().contains( value );
    }

    public boolean containsKey( final Object key )
    {
        return getProperties().containsKey( key );
    }

    public void clear()
    {
        getProperties().clear();
    }

    public Object clone()
    {
        return getProperties().clone();
    }

    public String toString()
    {
        return getProperties().toString();
    }

    public final String getProperty( final String key )
    {
        return getProperties().getProperty( key );
    }

    public final Enumeration propertyNames()
    {
        return getProperties().propertyNames();
    }

    public final void list( final PrintStream out )
    {
        getProperties().list( out );
    }

    public final void list( final PrintWriter out )
    {
        getProperties().list( out );
    }

    /**
     * Utility method to retrieve properties bound to current thread (if any).
     */
    private Properties getProperties()
    {
        final Properties properties = (Properties)m_properties.get();
        if( null != properties )
        {
            return properties;
        }
        else
        {
            return defaults;
        }
    }
}