Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] aspectj presentation

Philip <philipvanbogaert@xxxxxxxxxx> writes:

> Hi,
>
> Can anybody give me some good pointers for an aspectj presentation. I'm more 
> technical oriented any abstract or high level view is welcome.

I'm giving an AOP presentation tomorrow using AspectJ for examples.
My main point is that a certain constraint programming model can be
implemented very succinctly and modularly using AspectJ.  Previously,
we considered that Lisp/CLOS/MOP was the only language that could do
this in a reasonable way.  The aforementioned constraint model is used
in a very large Lisp application that plans activities for the Hubble
Space Telescope.

The high-level view of AOP/AspectJ is pretty easy to communicate and I
think the available presentations do a reasonable job.  My audience is
very technical.  I plan to walk them through portions of the
programming manual before presenting my example.

I also plan to use the BeanShell to give an interactive demonstration
of how the code works.  This makes it easier to show different things
without have to have several main scripts or a configurable main.

Here's my code:

/*
 * constraint.java
 */
package cosi;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import java.util.*;
import java.lang.reflect.*;

public aspect constraint {

	static Stack pendingDeps = new Stack();
	static Stack readContext = new Stack();

	pointcut inConstraint() : execution(void trans.ModelObject+.c_* (..));

	pointcut readField() : get(* trans.ModelObject+.*)
		&& !get(* trans.ModelObject+.deps)
		&& if (!readContext.empty());

	pointcut writeField() : set(* trans.ModelObject+.*) 
		&& !set(* trans.ModelObject+.deps);

	before() : inConstraint() {
		readContext.push(thisJoinPoint);
	}
	after() : inConstraint() {
		readContext.pop();
	}

	before() : readField() {
		/* Get the context of the object that is reading a field. */
		JoinPoint rctx = (JoinPoint) readContext.peek();
		trans.ModelObject reader = (trans.ModelObject) rctx.getThis();
		String readerMethod = rctx.getSignature().getName();

		/* Get the context of the object that owns the field. */
		trans.ModelObject target = (trans.ModelObject) thisJoinPoint.getThis();
		String field = thisJoinPoint.getSignature().getName();

		/* cosi.Entities do not track self access */
		if (reader != target) {
			System.out.println(
				reader + "." + readerMethod + " read " + target + "." + field);
			target.recordDependency(field, reader, readerMethod);
		}
	}

	after() : writeField() {
		/* Get the context of the object that owns the field. */
		trans.ModelObject target = (trans.ModelObject) thisJoinPoint.getTarget();
		String field = thisJoinPoint.getSignature().getName();
		System.out.println("write of " + target + "." + field);
		Stack fdeps = (Stack) target.deps.get(field);
		if (null != fdeps) {
			while(!fdeps.empty()) {
				pendingDeps.push(fdeps.pop());
			}
		}
	}

	static public void propagate() {
		System.out.println("Propagating...");
		Iterator itr = pendingDeps.iterator();
		while (!pendingDeps.empty()) {
			Dependency dep = (Dependency) pendingDeps.pop();
			try {
				Class _class = dep.obj.getClass();
				Method meth = _class.getMethod(dep.meth, null);
				meth.invoke(dep.obj, null);
			} catch (Exception e) {
				System.out.println("Dang.");
			}
		}
	}

	public static class Dependency {
		private Dependency() {
		}
		public Dependency(trans.ModelObject _obj, String _meth) {
			obj = _obj;
			meth = _meth;
		}
		public boolean equals(Dependency other) {
			return obj == other.obj && meth.equals(other.meth);
		}
		public trans.ModelObject obj;
		public String meth;
	}

	public HashMap trans.ModelObject.deps = new HashMap();

	public void trans.ModelObject.showDeps() {
		/* Print out the dependency table */
		Iterator itr = deps.keySet().iterator();
		while (itr.hasNext()) {
			String fieldName = (String) itr.next();
			System.out.println(fieldName);
			Stack depSet = (Stack) deps.get(fieldName);
			Iterator _itr = depSet.iterator();
			while (_itr.hasNext()) {
				Dependency invoc = (Dependency) _itr.next();
				System.out.println("  " + invoc.meth + "  " + invoc.obj);
			}
		}
	}

	private void trans.ModelObject.recordDependency(
		String field,
		trans.ModelObject obj,
		String meth) {
		Dependency newDep = new Dependency(obj, meth);
		Stack stack = (Stack) deps.get(field);
		if (null == stack) {
			stack = new Stack();
			deps.put(field, stack);
		}
		if (-1 == stack.search(newDep)) {
			stack.push(newDep);
		}
	}

}


/*
 * Alignment.java
 */
package trans;

public class Alignment implements ModelObject {
	public Alignment() {
		exp = new Exposure(1);
	}
	public void c_foo () {
		alTime += exp.f_getDuration();
	}
	public void m_foo () {
		exp.duration = 41;
	}
	public int alTime;
	public Exposure exp;
}


/*
 * Exposure.java
 */
package trans;

public class Exposure implements ModelObject {
	public Exposure() {
	}
	public Exposure(int _duration) {
		duration = _duration;
	}
	public int f_getDuration() {
		return duration;
	}
	
	public int duration;
	public int fooby = 11;
}

/*
 * ModelObject.java
 */
package trans;

/**
 * @author jmadams
 */
public interface ModelObject {

}
aspect FaultHandler {

	private boolean Server.disabled = false;

	private void reportFault() {
		System.out.println("Failure! Please fix it.");
	}

	public static void fixServer(Server s) {
		s.disabled = false;
	}

	pointcut services(Server s) : target(s) && call(public * * (..));

	before(Server s) : services(s) {
		if (s.disabled)
			throw new DisabledException();
	}

	after(Server s) throwing(FaultException e) : services(s) {
		s.disabled = true;
		reportFault();
	}
}

And here's a Beanshell session that demonstrates:

bsh % show();
<true>
bsh % addClassPath("cosi.jar");
bsh % a = new trans.Alignment();
<trans.Alignment@50a649>
write of trans.Exposure@5d391d.fooby
write of trans.Exposure@5d391d.duration
write of trans.Alignment@xxxxxxxxxx
bsh % a.c_foo();
trans.Alignment@50a649.c_foo read trans.Exposure@5d391d.duration
write of trans.Alignment@50a649.alTime
bsh % a.exp.showDeps();
duration
  c_foo  trans.Alignment@50a649
bsh % a.m_foo();
write of trans.Exposure@5d391d.duration
bsh % cosi.constraint.aspectOf().propagate();
Propagating...
trans.Alignment@50a649.c_foo read trans.Exposure@5d391d.duration
write of trans.Alignment@50a649.alTime
bsh % a.alTime;
<42>

(altime was initially 0)

-- 
John M. Adams



Back to the top