// $Id: example1.java,v 1.3 1998/05/08 22:02:05 oliva Exp $

/* Copyright 1997,1998 Alexandre Oliva <oliva@dcc.unicamp.br>
 *
 * See the files "COPYING" and "README" for information on usage and
 * redistribution of this file.  */

import BR.unicamp.Guarana.*;

/** A few examples of reflexive behavior

    @author Alexandre Oliva
    @version $Revision: 1.3 $
*/
public class example1 {
    static class myMetaObject extends MetaLogger {
	public MetaObject configure(final Object newObject,
				    final Object object) {
	    super.configure(newObject, object);
	    if (newObject instanceof myObject) {
		System.out.println("Propagating meta-configuration to "+
				   Guarana.toString(newObject));
		return this;
	    }
	    System.out.println("Not propagating meta-configuration to "+
			       Guarana.toString(newObject));
	    return null;
	}
	public MetaObject reconfigure(final Object object,
				      final MetaObject prev,
				      final MetaObject next) {
	    super.reconfigure(object, prev, next);
	    System.out.println("Rejecting reconfiguration request for "+
			       Guarana.toString(object));
	    return this;
	}
	public void initialize(final OperationFactory fact,
			       final Object obj) {
	    super.initialize(fact, obj);
	    try {
		System.out.println("Trying to assign 2 to object's field `i'");
		fact.write(Guarana.getClass(obj).getDeclaredField("i"),
			   new Integer(2)).perform();
	    } catch (IllegalAccessException t) {
		System.out.println("Expected failure: "+t);
		System.out.println("meta-object was not associated with base-level object yet.");
	    } catch (NoSuchFieldException t) {
		System.out.println("Expected failure: "+t);
		System.out.println("couldn't find any field named `i' in object "+
				   Guarana.toString(obj));
	    } catch (Throwable t) {
		System.out.println("Failed: "+t);
	    }
	}
    }
  
    public static class myObject {
	int i;
	myObject createAnother() {
	    return new myObject();
	}
    }

    public static void main(String[] argv) {
	final myObject o = new myObject();
	final MetaObject m = new myMetaObject();
	Guarana.reconfigure(o, null, m);
	synchronized(o) {
	    System.out.println(o.i);
	    o.i = 1;
	    System.out.println(o.i);
	}
	final Object[] a = new Object[3];
	Guarana.reconfigure(a, null, m);
	Guarana.reconfigure(myObject.class, null, new myMetaObject());
	synchronized(a) {
	    System.out.println(a.length);
	    a[0] = a[1] = o;
	    System.out.println(a[1]);
	}
	System.out.println(o.hashCode());
	System.out.println(o.equals(o));
	final myObject o2 = o.createAnother();
	Guarana.reconfigure(myObject.class, null, new myMetaObject());
    }
}
