A
download Surrogate.java
Language: Java
License: LGPL
Copyright: (C) 2000 Intersect Software Corporation
LOC: 110
Project Info
wotonomy
Server: SourceForge
Type: cvs
...wotonomy\net\wotonomy\util\
   BrowserLauncher.java
   Duplicator.java
   Introspector.java
   IntrospectorException.java
   ...gPropertyException.java
   NetworkClassLoader.java
   ...PrimitiveException.java
   package.html
   PropertyComparator.java
   PropertyListParser.java
   QueueMap.java
   Surrogate.java
   URLResourceReader.java
   ValueConverter.java
   WotonomyException.java

/*
Wotonomy: OpenStep design patterns for pure Java applications.
Copyright (C) 2000 Intersect Software Corporation

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library 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
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see http://www.gnu.org
*/

package net.wotonomy.util;

import net.wotonomy.foundation.NSMutableDictionary;
import net.wotonomy.control.EOObserverCenter;

/**
* A Surrogate is a special object that can be used in a display
* group when you wish to emulate other objects or modify their
* behaviors.  Because it is a Map, it makes use of Introspector's
* ability to treat keys in a map as if they were properties to
* implement the following features.
* <ul>
* <li>By default, Surrogate works like a Map, and reading and 
* writing properties to a Surrogate gets and puts values in the 
* Map.</li>
* <li>If one or more delegate objects are specified, property keys 
* that do not exist in the map are read from and written to the 
* delegate object.</li>
* <li>If a default value is specified, that value will be returned
* for all property reads that do not exist in the map or in the
* delegate object.  (Subsequent writes to those properties will
* create a key in the map and then subsequent reads will read not
* read the default object.)</li>
* <li>Subclasses can override the get(Object) method to further
* customize the behavior of a Surrogate.
* </ul>
*
* @author michael@mpowers.net
* @date $Date: 2000/12/21 15:52:21 $
* @revision $Revision: 1.1.1.1 $
*/
public class Surrogate extends NSMutableDictionary
{
	protected Object[] delegates;
	protected Object defaultValue;
	
	/**
	* Default constructor with no delegate object and no default value.
	*/
	public Surrogate()
	{
		delegates = null;
		defaultValue = null;
	}
	
	/**
	* Constructor specifying a delegate object.
	*/
	public Surrogate( Object[] aDelegateArray )
	{
		setDelegates( aDelegateArray );
	}

	/**
	* Constructor specifying a default value.
	*/
	public Surrogate( Object aDefault )
	{
		setDefaultValue( aDefault );
	}

	/**
	* Constructor specifying a delegate object and a default value.
	*/
	public Surrogate( Object[] aDelegateArray, Object aDefault )
	{
		setDelegates( aDelegateArray );
		setDefaultValue( aDefault );
	}

	/**
	* Returns the first delegate object, or null if no delegates exist.
	*/
	public Object getDelegate()
	{
		if ( delegates == null ) return null;
		if ( delegates.length == 0 ) return null;
		return delegates[0];
	}
	
	/**
	* Sets the delegate object list to contain only the
	* specified object.
	*/
	public void setDelegate( Object aDelegate )
	{
		setDelegates( new Object[] { aDelegate } );
	}
	
	/**
	* Returns the list of delegates in the order in which
	* they are consulted.
	*/
	public Object[] getDelegates()
	{
		if ( delegates == null ) delegates = new Object[0];
		return delegates;	
	}
	
	/**
	* Sets the list of delegates in the order in which they
	* will be consulted.
	*/
	public void setDelegates( Object[] aDelegateArray )
	{
		delegates = aDelegateArray;
	}

	/**
	* Returns the current default value, or null if no default exists.
	*/
	public Object getDefaultValue()
	{
		return defaultValue;
	}
	
	/**
	* Sets the default value.
	*/
	public void setDefaultValue( Object aDefault )
	{
		defaultValue = aDefault;
	}
	
	/**
	* Called by get to retrieve a value from the internal map.
	* This implementation simply calls super.get().
	*/
	public Object directGet( Object aKey )
	{
		return super.get( aKey );	
	}
	
	/**
	* Called by put to retrieve a value from the internal map.
	* This implementation simply calls super.put().
	*/
	public Object directPut( Object aKey, Object aValue )
	{
		return super.put( aKey, aValue );	
	}
	
	/**
	* Overridden to consult each delegate before 
	* checking the internal list of keys.  No matching
	* key is found, returns the default object, or 
	* null if no default object exists.
	*/
	public Object get( Object aKey )
	{
		// check all delegates in order
		int i, j;
		Object[] list = getDelegates();
		String[] properties;
		for ( i = 0; i < list.length; i++ )
		{
			// for each delegate
			properties = 
				Introspector.getReadPropertiesForObject( list[i] );
			for ( j = 0; j < properties.length; j++ )
			{
				// if delegate has property
				if ( properties[j].equals( aKey ) )
				{
					// use this delegate
					return Introspector.get( list[i], aKey.toString() );	
				}
			}
		}
		
		// return from internal map
		Object result = directGet( aKey );
		if ( result == null )
		{
			// if not in map, return default object
			result = getDefaultValue();
		}
		return result;		
	}
	
	/** 
	* Overridden to attempt to write each delegate, writing to
	* only the first successful delegate, before storing the 
	* value in the internal map.
	*/
	public Object put( Object aKey, Object aValue )
	{
		// check all delegates in order
		int i, j;
		Object[] list = getDelegates();
		String[] properties;
		for ( i = 0; i < list.length; i++ )
		{
			// for each delegate
			properties = 
				Introspector.getWritePropertiesForObject( list[i] );
			for ( j = 0; j < properties.length; j++ )
			{
				// if delegate has property
				if ( properties[j].equals( aKey ) )
				{
					// use this delegate
					EOObserverCenter.notifyObserversObjectWillChange( list[i] );
					return Introspector.set( list[i], aKey.toString(), aValue );	
				}
			}
		}
		
		// set on internal map
		EOObserverCenter.notifyObserversObjectWillChange( this );
		return directPut( aKey, aValue );
	}

	/**
	* Overridden to compare by reference.
	*/
	public boolean equals( Object anObject )
	{
		return ( this == anObject );
	}

}

/*
 * $Log: Surrogate.java,v $
 * Revision 1.1.1.1  2000/12/21 15:52:21  mpowers
 * Contributing wotonomy.
 *
 * Revision 1.2  2000/12/20 16:25:48  michael
 * Added log to all files.
 *
 *
 */

About Koders | Resources | Downloads | Support | Black Duck | Terms of Service | DMCA | Privacy Policy | Contact Us