Now, the location more closely resembles where it is on the website.
Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
+++ /dev/null
-/*
- * Copyright (c) 1998-2002 Xerox Corporation,
- * 2004 Contributors. All rights reserved.
- *
- * Use and copying of this software and preparation of derivative works based
- * upon this software are permitted. Any distribution of this software or
- * derivative works must comply with all applicable United States export
- * control laws.
- *
- * This software is made available AS IS, and Xerox Corporation makes no
- * warranty about the software, its performance or its conformity to any
- * specification.
- */
-
-package bean;
-
-import java.beans.*;
-import java.io.Serializable;
-
-/**
- * Add bound properties and serialization to Point objects
- */
-aspect BoundPoint {
- /*
- * privately declare a field on Point to hold the property
- * change support object. `this' is a reference to a Point object.
- */
- private PropertyChangeSupport Point.support = new PropertyChangeSupport(this);
-
- /*
- * Declare property change registration methods on Point,
- * and introduce implementation of the Serializable interface.
- */
-
- public void Point.addPropertyChangeListener(PropertyChangeListener listener){
- support.addPropertyChangeListener(listener);
- }
-
- public void Point.addPropertyChangeListener(String propertyName,
- PropertyChangeListener listener){
- support.addPropertyChangeListener(propertyName, listener);
- }
-
- public void Point.removePropertyChangeListener(String propertyName,
- PropertyChangeListener listener) {
- support.removePropertyChangeListener(propertyName, listener);
- }
-
- public void Point.removePropertyChangeListener(PropertyChangeListener listener) {
- support.removePropertyChangeListener(listener);
- }
-
- public void Point.hasListeners(String propertyName) {
- support.hasListeners(propertyName);
- }
-
- declare parents: Point implements Serializable;
-
- /**
- * Send property change event after X setter completes normally.
- * Use around advice to keep the old value on the stack.
- */
- void around(Point p): execution(void Point.setX(int)) && target(p) {
- int oldValue = p.getX();
- proceed(p);
- firePropertyChange(p, "x", oldValue, p.getX());
- }
-
- /**
- * Send property change event after Y setter completes normally.
- * Use around advice to keep the old value on the stack.
- */
- void around(Point p): execution(void Point.setY(int)) && target(p) {
- int oldValue = p.getY();
- proceed(p);
- firePropertyChange(p, "y", oldValue, p.getY());
- }
-
- /*
- * Utility to fire the property change event.
- */
- void firePropertyChange(Point p,
- String property,
- double oldval,
- double newval) {
- p.support.firePropertyChange(property,
- new Double(oldval),
- new Double(newval));
- }
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-*/
-
-package bean;
-
-import java.beans.*;
-import java.io.*;
-
-public class Demo implements PropertyChangeListener {
-
- static final String fileName = "test.tmp";
-
- /**
- * when Demo is playing the listener role,
- * this method reports that a propery has changed
- */
- public void propertyChange(PropertyChangeEvent e){
- System.out.println("Property " + e.getPropertyName() + " changed from " +
- e.getOldValue() + " to " + e.getNewValue() );
- }
-
- /**
- * main: test the program
- */
- public static void main(String[] args){
- Point p1 = new Point();
- p1.addPropertyChangeListener(new Demo());
- System.out.println("p1 =" + p1);
- p1.setRectangular(5,2);
- System.out.println("p1 =" + p1);
- p1.setX( 6 );
- p1.setY( 3 );
- System.out.println("p1 =" + p1);
- p1.offset(6,4);
- System.out.println("p1 =" + p1);
- save(p1, fileName);
- Point p2 = (Point) restore(fileName);
- System.out.println("Had: " + p1);
- System.out.println("Got: " + p2);
- }
-
- /**
- * Save a serializable object to a file
- */
- static void save(Serializable p, String fn){
- try {
- System.out.println("Writing to file: " + p);
- FileOutputStream fo = new FileOutputStream(fn);
- ObjectOutputStream so = new ObjectOutputStream(fo);
- so.writeObject(p);
- so.flush();
- } catch (Exception e) {
- System.out.println(e);
- System.exit(1);
- }
- }
-
- /**
- * Restore a serializable object from the file
- */
- static Object restore(String fn){
- try {
- Object result;
- System.out.println("Reading from file: " + fn);
- FileInputStream fi = new FileInputStream(fn);
- ObjectInputStream si = new ObjectInputStream(fi);
- return si.readObject();
- } catch (Exception e) {
- System.out.println(e);
- System.exit(1);
- }
- return null;
- }
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package bean;
-
-class Point {
-
- protected int x = 0;
- protected int y = 0;
-
- /**
- * Return the X coordinate
- */
- public int getX(){
- return x;
- }
-
- /**
- * Return the y coordinate
- */
- public int getY(){
- return y;
- }
-
- /**
- * Set the x and y coordinates
- */
- public void setRectangular(int newX, int newY){
- setX(newX);
- setY(newY);
- }
-
- /**
- * Set the X coordinate
- */
- public void setX(int newX) {
- x = newX;
- }
-
- /**
- * set the y coordinate
- */
- public void setY(int newY) {
- y = newY;
- }
-
- /**
- * Move the point by the specified x and y offset
- */
- public void offset(int deltaX, int deltaY){
- setRectangular(x + deltaX, y + deltaY);
- }
-
- /**
- * Make a string of this
- */
- public String toString(){
- return "(" + getX() + ", " + getY() + ")" ;
- }
-}
+++ /dev/null
-BoundPoint.java
-Point.java
-Demo.java
+++ /dev/null
-
-<!-- ========================================================================= -->
-<!-- Copyright (c) 1999-2001 Xerox Corporation, -->
-<!-- 2002 Palo Alto Research Center, Incorporated (PARC). -->
-<!-- All rights reserved. -->
-<!-- This program and the accompanying materials are made available -->
-<!-- under the terms of the Eclipse Public License v 2.0 -->
-<!-- which accompanies this distribution and is available at -->
-<!-- https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt -->
-<!-- -->
-<!-- Contributors: -->
-<!-- Xerox/PARC initial implementation -->
-<!-- ========================================================================= -->
-
-<project name="aspectj-examples" default="spacewar" basedir=".">
-
- <target name="info" >
- <echo>
- This script builds the AspectJ examples.
-
- Relevant targets:
- spacewar build and run spacewar with debugging (default)
- all build and run each example
- {example} build and run any {example}
- (use -projecthelp to list {example} names)
- tracing-bc use AspectJ 1.1 bytecode weaving to build tracing example
-
- Setup:
- - Run from the doc/examples directory in your AspectJ distribution.
- The tasks in ../../lib/aspectjtools.jar are used automatically.
-
- Variants:
- - To avoid running (i.e., compile only), define variable "norun"
- - To define a variable, use the Ant -D option - e.g., on Windows:
-
- ant -f build.xml -DJAVA_HOME=c:\jdk1.3.1 -Dnorun=skip
-
- </echo>
- </target>
-
- <!-- ============================================================= -->
- <!-- setup and cleanup targets -->
- <!-- ============================================================= -->
-
- <target name="clean" depends="init"
- description="clean and create classes/jar dir, .ajesym files">
- <delete quiet="on" dir="${classes.dir}"/>
- <delete quiet="on" dir="${jar.dir}"/>
- <delete quiet="on">
- <fileset dir="${example.dir}" includes="**/*.ajesym"/>
- </delete>
- <mkdir dir="${classes.dir}"/>
- <mkdir dir="${jar.dir}"/>
- </target>
-
- <target name="init" depends="init.variables,init.taskdefs"/>
-
- <target name="init.variables"
- description="init variables">
-
- <!-- build.compiler value to pick up our CompilerAdapter for javac -->
- <property name="ajc.adapter"
- value="org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter"/>
-
- <!-- required directories - run from examples or predefine -->
- <property name="example.dir"
- location="${basedir}"/>
- <property name="aspectj.lib.dir"
- location="${basedir}/../../lib"/>
-
- <!-- required libraries - install or predefine -->
- <property name="aspectjrt.jar"
- location="${aspectj.lib.dir}/aspectjrt.jar"/>
- <property name="aspectjtools.jar"
- location="${aspectj.lib.dir}/aspectjtools.jar"/>
- <property name="aspectjweaver.jar"
- location="${aspectj.lib.dir}/aspectjweaver.jar"/>
-
- <!-- created directories -->
- <property name="classes.dir"
- location="${example.dir}/classes"/>
- <property name="jar.dir"
- location="${example.dir}/jars"/>
-
- <!-- checking required libraries -->
- <available file="${aspectjtools.jar}"
- property="aspectjtools.jar.available"/>
- <available file="${aspectjrt.jar}"
- property="aspectjrt.jar.available"/>
-
- <property name="example.packages"
- value="bean, coordination, evolution, figures, figures.gui,
- helloworld, icount, icount.lib, introduction,
- observer, shadow, shadow.version1, shadow.version2,
- spacewar, telecom, telecom.version1, timeserver, tjp,
- tracing, tracing.lib tracing.version1, tracing.version2,
- tracing.version3"/>
- </target>
-
- <target name="init.taskdefs" depends="init.variables,
- aspectjtools.jar.available,
- aspectjrt.jar.available"
- unless="taskdefs.init">
- <!-- sets name of new task to iajc, old task to ajc -->
- <taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties">
- <classpath>
- <pathelement path="${aspectjtools.jar}"/>
- </classpath>
- </taskdef>
- <property name="taskdefs.init" value="true"/>
- </target>
-
- <!-- targets to fail unless required libraries available -->
-
- <target name="aspectjrt.jar.available" depends="init.variables"
- unless="aspectjrt.jar.available" >
- <fail message="expecting aspectjrt.jar at ${aspectjrt.jar}"/>
- </target>
-
- <target name="aspectjtools.jar.available" depends="init.variables"
- unless="aspectjtools.jar.available" >
- <fail message="expecting aspectjtools.jar at ${aspectjtools.jar}"/>
- </target>
-
- <!-- ============================================================= -->
- <!-- these targets compile and run any example -->
- <!-- ============================================================= -->
- <target name="Ajx" depends="init"
- description="compile {list} and run {class} of example">
- <echo message="##### Ajx list=${list} class=${class}" />
- <antcall target="clean" />
- <!-- can use ajc or iajc here -->
- <iajc destdir="${classes.dir}" argfiles="${list}"
- fork="true"
- forkclasspath="${aspectjtools.jar}"
- classpath="${aspectjrt.jar}"/>
-
- <antcall target="Ajx-run" >
- <param name="class" value="${class}"/>
- </antcall>
-
- </target>
-
- <target name="Ajx-run"
- description="run {class} unless {norun} is set"
- unless="norun" >
- <echo message="##### Ajx-run list=${list} class=${class}" />
- <java classname="${class}" fork="yes">
- <classpath>
- <pathelement path="${classes.dir}"/>
- <pathelement path="${aspectjrt.jar}"/>
- </classpath>
- </java>
- </target>
-
- <!-- ============================================================= -->
- <!-- example targets -->
- <!-- ============================================================= -->
- <target name="all"
- description="build and run all examples"
- depends="bean,intro,intro-clone,intro-compare,intro-hash,
- observer,spacewar,spacewar-demo,telecom,
- telecom-timing,tracing-none,tracing-1,
- tracing-2,tracing-3,tracing-lt,tjp"/>
-
- <target name="nonGui"
- description="build and run non-GUI examples"
- depends="bean,intro,intro-clone,intro-compare,intro-hash,
- telecom,telecom-timing,tracing-none,tracing-1,
- tracing-2,tracing-3,tracing-lt,tjp"/>
-
- <target name="bean"
- description="build bean example">
- <antcall target="Ajx">
- <param name="list" value="bean/files.lst"/>
- <param name="class" value="bean.Demo"/>
- </antcall>
- </target>
-
- <target name="intro"
- description="build inter-type declaration example">
- <antcall target="Ajx">
- <param name="list" value="introduction/files.lst"/>
- <param name="class" value="introduction.Point"/>
- </antcall>
- </target>
-
- <target name="intro-clone"
- description="build inter-type declaration (clone) example">
- <antcall target="Ajx">
- <param name="list" value="introduction/files.lst"/>
- <param name="class" value="introduction.CloneablePoint"/>
- </antcall>
- </target>
-
- <target name="intro-compare"
- description="build inter-type declaration (Comparable) example">
- <antcall target="Ajx">
- <param name="list" value="introduction/files.lst"/>
- <param name="class" value="introduction.ComparablePoint"/>
- </antcall>
- </target>
-
- <target name="intro-hash"
- description="build inter-type declaration (hashcode) example">
- <antcall target="Ajx">
- <param name="list" value="introduction/files.lst"/>
- <param name="class" value="introduction.HashablePoint"/>
- </antcall>
- </target>
-
- <target name="observer"
- description="build observer example">
- <antcall target="Ajx">
- <param name="list" value="observer/files.lst"/>
- <param name="class" value="observer.Demo"/>
- </antcall>
- </target>
-
- <target name="spacewar"
- description="build spacewar debug example">
- <antcall target="Ajx">
- <param name="list" value="spacewar/debug.lst"/>
- <param name="class" value="spacewar.Game"/>
- </antcall>
- </target>
-
- <target name="spacewar-demo"
- description="build spacewar demo (no debug) example">
- <antcall target="Ajx">
- <param name="list" value="spacewar/demo.lst"/>
- <param name="class" value="spacewar.Game"/>
- </antcall>
- </target>
-
- <target name="telecom"
- description="build telecom basic example">
- <antcall target="Ajx">
- <param name="list" value="telecom/basic.lst"/>
- <param name="class" value="telecom.BasicSimulation"/>
- </antcall>
- </target>
-
- <target name="telecom-billing"
- description="build telecom billing example">
- <antcall target="Ajx">
- <param name="list" value="telecom/billing.lst"/>
- <param name="class" value="telecom.BillingSimulation"/>
- </antcall>
- </target>
-
- <target name="telecom-timing"
- description="build telecome timing example">
- <antcall target="Ajx">
- <param name="list" value="telecom/timing.lst"/>
- <param name="class" value="telecom.TimingSimulation"/>
- </antcall>
- </target>
-
- <target name="tjp"
- description="build thisJoinPoint example">
- <antcall target="Ajx">
- <param name="list" value="tjp/files.lst"/>
- <param name="class" value="tjp.Demo"/>
- </antcall>
- </target>
-
- <target name="tracing-none"
- description="build tracing (base) example">
- <antcall target="Ajx">
- <param name="list" value="tracing/notrace.lst"/>
- <param name="class" value="tracing.ExampleMain"/>
- </antcall>
- </target>
-
- <target name="tracing-1"
- description="build tracing (version 1) example">
- <antcall target="Ajx">
- <param name="list" value="tracing/tracev1.lst"/>
- <param name="class" value="tracing.version1.TraceMyClasses"/>
- </antcall>
- </target>
-
- <target name="tracing-2"
- description="build tracing (version 2) example">
- <antcall target="Ajx">
- <param name="list" value="tracing/tracev2.lst"/>
- <param name="class" value="tracing.version2.TraceMyClasses"/>
- </antcall>
- </target>
-
- <target name="tracing-3"
- description="build tracing (version 3) example">
- <antcall target="Ajx">
- <param name="list" value="tracing/tracev3.lst"/>
- <param name="class" value="tracing.version3.TraceMyClasses"/>
- </antcall>
- </target>
-
- <!-- ============================================================= -->
- <!-- do tracing example using compiler adapter -->
- <!-- ============================================================= -->
- <target name="tracing-adapter" depends="init"
- description="tracing example compiled via javac task">
- <antcall target="clean" />
- <!-- to fork, set adapter.fork=true
- and put aspectjtools.jar on ant classpath -->
- <javac destdir="${classes.dir}"
- fork="${adapter.fork}">
- <src path="${example.dir}"/>
- <include name="tracing/*.java"/>
-
- <!-- compilerarg's ignored unless using our compiler adapter -->
- <compilerarg compiler="${ajc.adapter}"
- line="-verbose -Xlint -proceedOnError"/>
- <!-- use separate values if a path might have spaces -->
- <compilerarg compiler="${ajc.adapter}"
- value="-classpath"/>
- <compilerarg compiler="${ajc.adapter}"
- value="${aspectjrt.jar}"/>
- <compilerarg compiler="${ajc.adapter}"
- path="${example.dir}/tracing/version3/Trace.java"/>
- <compilerarg compiler="${ajc.adapter}"
- path="${example.dir}/tracing/version3/TraceMyClasses.java"/>
- </javac>
- </target>
-
- <target name="tracing-adapter-ajc" depends="init"
- description="tracing example compiled using ajc via compiler adapter">
- <!-- aspectjtools.jar must be on system/ant classpath -->
- <antcall target="tracing-adapter">
- <param name="build.compiler" value="${ajc.adapter}"/>
- </antcall>
- </target>
-
- <!-- ============================================================= -->
- <!-- do tracing example with 1.1 bytecode weaving (binary aspects) -->
- <!-- (and use fork/forkclasspath to avoid Eclipse 2.x bug) -->
- <!-- ============================================================= -->
- <target name="tracing-bc" depends="init"
- description="tracing example with bytecode weaving (binary aspects)">
- <antcall target="clean" />
-
- <!-- build application classes -->
- <iajc outjar="${jar.dir}/tracingApp.jar"
- classpath="${aspectjrt.jar}"
- fork="true"
- forkclasspath="${aspectjtools.jar}"
- verbose="off">
- <src path="${example.dir}"/>
- <include name="tracing/*.java" />
- </iajc>
-
- <!-- test standalone application by running without tracing -->
- <echo message="---------- running without tracing - START"/>
- <java classname="tracing.ExampleMain">
- <classpath>
- <pathelement path="${aspectjrt.jar}"/>
- <pathelement path="${jar.dir}/tracingApp.jar"/>
- </classpath>
- </java>
- <echo message="---------- running without tracing - FINISH "/>
-
- <!-- Build a read-only tracing library -->
- <iajc outjar="${jar.dir}/tracingLib.jar"
- classpath="${aspectjrt.jar}"
- fork="true"
- forkclasspath="${aspectjtools.jar}"
- verbose="off">
- <src path="${example.dir}"/>
- <include name="tracing/version3/Trace.java" />
- </iajc>
-
- <!-- weave them -->
- <!-- This example uses a concrete aspect in source form, -->
- <!-- but the aspects could be written to be binary only. -->
- <iajc outjar="${jar.dir}/tracedApp.jar"
- inpath="${jar.dir}/tracingApp.jar"
- aspectpath="${jar.dir}/tracingLib.jar"
- classpath="${aspectjrt.jar}"
- fork="true"
- forkclasspath="${aspectjtools.jar}"
- verbose="off">
- <src path="${example.dir}"/>
- <include name="tracing/version3/TraceMyClasses.java" />
- </iajc>
-
- <!-- run with tracing -->
- <echo message="---------- running with tracing - START"/>
- <java classname="tracing.version3.TraceMyClasses">
- <classpath>
- <pathelement path="${aspectjrt.jar}"/>
- <pathelement path="${jar.dir}/tracingLib.jar"/>
- <pathelement path="${jar.dir}/tracedApp.jar"/>
- </classpath>
- </java>
- <echo message="---------- running with tracing - FINISH"/>
-
- </target>
-
- <!-- ============================================================= -->
- <!-- do tracing example with 1.2 load-time weaving -->
- <!-- (and use fork/forkclasspath to avoid Eclipse 2.x bug) -->
- <!-- ============================================================= -->
- <target name="tracing-lt" depends="init"
- description="tracing example with load-time aspect weaving">
- <antcall target="clean" />
-
- <!-- build application classes -->
- <iajc outjar="${jar.dir}/tracingApp.jar"
- classpath="${aspectjrt.jar}"
- fork="true"
- forkclasspath="${aspectjtools.jar}"
- verbose="off">
- <src path="${example.dir}"/>
- <include name="tracing/*.java" />
- </iajc>
-
- <!-- Build a read-only tracing library -->
- <iajc outjar="${jar.dir}/tracingLib.jar"
- classpath="${aspectjrt.jar}:${jar.dir}/tracingApp.jar"
- fork="true"
- forkclasspath="${aspectjtools.jar}"
- verbose="off">
- <src path="${example.dir}"/>
- <include name="tracing/version2/Trace.java" />
- <include name="tracing/version2/TraceMyClasses.java" />
- </iajc>
-
- <!-- test standalone application by running without tracing -->
- <echo message="---------- running without tracing - START"/>
- <java classname="tracing.ExampleMain">
- <classpath>
- <pathelement path="${aspectjrt.jar}"/>
- <pathelement path="${jar.dir}/tracingApp.jar"/>
- </classpath>
- </java>
- <echo message="---------- running without tracing - FINISH "/>
-
- <!-- run application with LTW to add tracing -->
- <echo message="---------- running with tracing - START"/>
- <java classname="tracing.ExampleMain"
- fork="true">
- <classpath>
- <pathelement path="${aspectjweaver.jar}"/>
- </classpath>
- <jvmarg line="-showversion"/>
- <sysproperty key="java.system.class.loader" value="org.aspectj.weaver.loadtime.WeavingURLClassLoader"/>
- <sysproperty key="aj.weaving.verbose" value="True"/>
- <sysproperty key="org.aspectj.weaver.showWeaveInfo" value="True"/>
- <sysproperty key="aj.class.path" path="${jar.dir}/tracingLib.jar:${jar.dir}/tracingApp.jar"/>
- <sysproperty key="aj.aspect.path" path="${jar.dir}/tracingLib.jar"/>
- </java>
- <echo message="---------- running with tracing - FINISH"/>
-
- </target>
-
-</project>
+++ /dev/null
-/* -*- Mode: Java; -*-
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-
-package coordination;
-
-
-/**
- * Interface for pre-conditions that are passed to guardedEntry methods of
- * Coordinator.
- * Conditions should be passed as anonymous classes that simply implement
- * the checkit method.
- *
- */
-public interface Condition {
-
- /**
- * This method is called automatically by Coordinator.guardedEntry(...)
- * and it's called everytime the coordination state changes.
- */
-
- public boolean checkit();
-}
+++ /dev/null
-/* -*- Mode: Java; -*-
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-
-package coordination;
-
-
-/**
- * Interface for coordination actions that are passed to guardedEntry methods of
- * Coordinator.
- * Coordination actions should be passed as anonymous classes that simply
- * implement the doit method.
- *
- */
-public interface CoordinationAction {
- /**
- * This method is called by Coordinator.guardedEntry(...) and
- * Coordinator.guardedExit(...). Use it for changing coordination state
- * upon entering and exiting methods.
- */
-
- public void doit();
-}
+++ /dev/null
-/* -*- Mode: Java; -*-
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-
-package coordination;
-
-import java.util.*; //!!!
-
-/**
- * The Coordinator class provides the basic functionality for synchronizing
- * and coordinating different threads upon entering and exiting methods.
- * It can be used in two different ways:
- * 1) by instantiating regular coordinator objects that are used by aspects; or
- * 2) by extending it (sub-classing) with coordinator aspects.
- * <P>
- * Method invocations are the smallest units for defining critical sections
- * and pre-conditions. The use of coordinators, either regular objects or aspect
- * instances, should always end up by invoking guardedEntry(...) in a
- * before weave and guardedExit(...) in an after weave for all methods that
- * need coordination. guardedEntry and guardedExit are the methods that
- * actually manage the synchronization and coordination constraints given
- * by their parameters and by pre-existent exclusion markers.
- * <P>
- * The synchronization of threads for the execution of critical section
- * methods in an object is done by marking those methods as self- and/or
- * mutually-exclusive (addSelfex, addMutex).
- * Just by itself, addSelfex("M") does not enforce the self-exclusion
- * of method M - enforcement is done by invoking guardedEntry before
- * M is executed. Similarly, addMutex(new String[] {"M1", "M2"}) does
- * not enforce the mutual exclusion between methods M1 and M2.
- * <P>
- * A guardedEntry on a method that has been marked as self-exclusive
- * ensures that the method is executed in the invoked object by only one thread
- * at a time. A guardedEntry on a method that has been marked has mutually-
- * exclusive with other methods ensures that the execution of that method
- * by a thread in the invoked object temporarily blocks the execution by
- * other threads of the methods that are in the same mutex set.
- * <P>
- * The coordination of threads, i.e. their explicit suspension and
- * resumption, is done through the use of pre-conditions and coordination
- * actions that are passed as parameters to guardedEntry and guardedExit
- * with the form of anonymous classes.
- */
-public abstract aspect Coordinator {
- private Hashtable methods = null;
- private Vector exclusions = null;
-
- abstract protected pointcut synchronizationPoint();
-
- public Coordinator() {
- methods = new Hashtable();
- exclusions = new Vector(5);
- }
-
- before (): synchronizationPoint() {
- this.guardedEntry(thisJoinPointStaticPart.getSignature().getName());
- }
-
- after (): synchronizationPoint() {
- this.guardedExit(thisJoinPointStaticPart.getSignature().getName());
- }
-
- /**
- * Takes a multi-part method name (eg "BoundedBuffer.put")
- * and marks that method as self-exclusive.
- * No checks are made with respect to the existence of the method
- * whose name is given.
- */
- public synchronized void addSelfex(String methName) {
- Selfex sex = new Selfex (methName);
-
- // update db of all exclusions in this coordinator
- exclusions.addElement(sex);
-
- // update local info in method
- Method aMeth = getOrSetMethod(methName);
- aMeth.addExclusion(sex);
- }
-
- /**
- * Takes a multi-part method name (e.g. "BoundedBuffer.put")
- * and removes that method from the list of self-exclusive methods.
- */
- public synchronized void removeSelfex(String methName) {
- for (int i = 0; i < exclusions.size(); i++) {
- Exclusion sex = (Exclusion)exclusions.elementAt(i);
- if ((sex instanceof Selfex) &&
- (((Selfex)sex).methodName.equals(methName))) {
-
- // update db of all exclusions in this coordinator
- exclusions.removeElementAt(i);
-
- // update local info in method
- Method aMeth = getOrSetMethod(methName);
- aMeth.removeExclusion(sex);
- }
- }
- }
-
- /**
- * Takes an array of multi-part method names and marks those
- * methods as mutually exclusive.
- * No checks are made with respect to the existence of the methods
- * whose names are given.
- */
- public synchronized void addMutex(String[] methNames) {
- Mutex mux = new Mutex(methNames);
-
- // update db of all exclusions in this coordinator
- exclusions.addElement(mux);
-
- // update local info in each method
- for (int i = 0; i < methNames.length; i++) {
- Method aMeth = getOrSetMethod(methNames[i]);
- aMeth.addExclusion(mux);
- }
- }
-
- /**
- * Takes an array of multi-part method names that correspond
- * to an existing mutex set and remove the mutual exclusion constraint.
- * If the given mutex set does not exist, removeMutex does nothing.
- */
- public synchronized void removeMutex(String[] methNames) {
- for (int i = 0; i < exclusions.size(); i++) {
- Exclusion mux = (Exclusion)exclusions.elementAt(i);
- if (mux instanceof Mutex) {
- boolean same = true;
- for (int j = 0; j < methNames.length; j++)
- if (!methNames[j].equals(((Mutex)mux).methodNames[j]))
- same = false;
- if (same) {
- // update db of all exclusions in this coordinator
- exclusions.removeElementAt(i);
-
- // update local info in each method involved
- for (int j = 0; j < methNames.length; j++) {
- Method aMeth = getOrSetMethod(methNames[j]);
- aMeth.removeExclusion(mux);
- }
- }
- }
- }
- }
-
- /**
- * This method is the guard for enforcing all synchronization and
- * coordination constraints of a given method, and it should be called
- * just before the method is executed.
- * In this form, only the method name is given. The only constraints
- * checked are the exclusion constraints.
- * If the method was previousely marked as selfex (through addSelfex),
- * guardedEntry ensures that the method is executed only when no other
- * thread is executing it.
- * If the method was previousely marked as being in one or more mutex
- * sets, guardedEntry ensures that the method is executed only when no other
- * thread is executing any of the methods with which the give method is
- * mutexed.
- */
- public synchronized void guardedEntry(String methName) {
- guardedEntry(methName, new Condition() {
- public boolean checkit() {
- return true;
- }
- }, null);
- }
-
- /**
- * Just like guardedEntry(String methName), but the given method is executed
- * only when the given condition is true.
- * guardedEntry is the guard for enforcing all synchronization and
- * coordination constraints of a given method, and it should be called
- * just before the method is executed.
- * In this form, the method name is given along with a condition.
- * The constraints checked are the exclusion constraints and whether
- * the given condition is true.
- * If the method was previousely marked as selfex (through addSelfex),
- * guardedEntry ensures that the method is executed only when no other
- * thread is executing it.
- * If the method was previousely marked as being in one or more mutex
- * sets, guardedEntry ensures that the method is executed only when no other
- * thread is executing any of the methods with which the give method is
- * mutexed.
- * If the condition is false, guardedEntry suspends the current thread.
- * That thread remains suspended until the condition becomes true, in
- * which case all constraints are rechecked before the method is executed.
- * When all exclusion constraints are checked and the given condition is
- * true, the given method is executed.
- */
- public synchronized void guardedEntry(String methName, Condition condition) {
- guardedEntry(methName, condition, null);
- }
-
- /**
- * Just like guardedEntry(String methName), but with an additional
- * coordination action that is executed before the given method is
- * executed.
- * guardedEntry is the guard for enforcing all synchronization and
- * coordination constraints of a given method, and it should be called
- * just before the method is executed.
- * In this form, the method name is given along with a coordination action.
- * The only constraints checked are the exclusion constraints.
- * If the method was previousely marked as selfex (through addSelfex),
- * guardedEntry ensures that the method is executed only when no other
- * thread is executing it.
- * If the method was previousely marked as being in one or more mutex
- * sets, guardedEntry ensures that the method is executed only when no other
- * thread is executing any of the methods with which the give method is
- * mutexed.
- * The given coordination action is executed just before the given method
- * is executed.
- */
- public synchronized void guardedEntry(String methName,
- CoordinationAction action) {
- guardedEntry(methName, new Condition() {
- public boolean checkit() {
- return true;
- }
- },
- action);
- }
-
- /**
- * Just like guardedEntry(String methName), but the given method is executed
- * only when the given condition is true; the additional
- * coordination action that is executed before the given method is
- * executed.
- * guardedEntry is the guard for enforcing all synchronization and
- * coordination constraints of a given method, and it should be called
- * just before the method is executed.
- * In this form, the method name is given along with a condition and
- * a coordination action.
- * The constraints checked are the exclusion constraints and whether the
- * given condition is true.
- * If the method was previousely marked as selfex (through addSelfex),
- * guardedEntry ensures that the method is executed only when no other
- * thread is executing it.
- * If the method was previousely marked as being in one or more mutex
- * sets, guardedEntry ensures that the method is executed only when no other
- * thread is executing any of the methods with which the give method is
- * mutexed.
- * If the condition is false, guardedEntry suspends the current thread.
- * That thread remains suspended until the condition becomes true, in
- * which case all constraints are rechecked before the method is executed.
- * When all exclusion constraints are checked and the given condition is
- * true, the given method is executed.
- * The given coordination action is executed just before the given method
- * is executed.
- */
- public synchronized void guardedEntry(String methName,
- Condition condition,
- CoordinationAction action) {
- Method aMeth = getOrSetMethod(methName);
- boolean canGo = false;
-
- // test pre-conditions for entering the method
- while (!canGo) {
- canGo = true;
- for (int i = 0; i < aMeth.exes.size() && canGo; i++)
- if (!((Exclusion)aMeth.exes.elementAt(i)).testExclusion(aMeth.name)) {
- canGo = false;
- }
- if (canGo && !condition.checkit()) {
- canGo = false;
- }
- if (!canGo)
- try {
- wait();
- } catch (InterruptedException e) { }
- }
-
- // OK.
- enterMethod(aMeth, action);
- }
-
- /**
- * This method is similar to guardedEntry, but it takes
- * an additional parameter - the milliseconds after which any suspension
- * will abort with a timeout.
- */
- public synchronized void guardedEntryWithTimeout(String methName,
- long millis)
- throws TimeoutException {
- guardedEntryWithTimeout(methName, new Condition() {
- public boolean checkit() {
- return true;
- }
- }, null, millis);
- }
-
- /**
- * This method is similar to guardedEntry, but it takes
- * an additional parameter - the milliseconds after which any suspension
- * will abort with a timeout.
- */
- public synchronized void guardedEntryWithTimeout(String methName,
- Condition condition,
- long millis)
- throws TimeoutException {
- guardedEntryWithTimeout(methName, condition, null, millis);
- }
-
- /**
- * This method is similar to guardedEntry, but it takes
- * an additional parameter - the milliseconds after which any suspension
- * will abort with a timeout.
- */
- public synchronized void guardedEntryWithTimeout(String methName,
- CoordinationAction action,
- long millis)
- throws TimeoutException {
- guardedEntryWithTimeout(methName, new Condition() {
- public boolean checkit() {
- return true;
- }
- }, action, millis);
- }
-
- /**
- * This method is similar to guardedEntry, but it takes
- * an additional parameter - the milliseconds after which any suspension
- * will abort with a timeout.
- */
- public synchronized void guardedEntryWithTimeout(String methName,
- Condition condition,
- CoordinationAction action,
- long millis)
- throws TimeoutException {
-
- Method aMeth = getOrSetMethod(methName);
- boolean canGo = false;
- long waitTime = millis;
- long startTime = System.currentTimeMillis();
-
- // test pre-conditions for entering the method
- while (!canGo) {
- canGo = true;
- for (int i = 0; i < aMeth.exes.size() && canGo; i++)
- if ((!((Exclusion)aMeth.exes.elementAt(i)).testExclusion(aMeth.name)) ||
- (!condition.checkit())) {
- canGo = false;
- }
- if (!canGo) {
- try {
- wait(waitTime);
- } catch (InterruptedException e) {}
-
- long now = System.currentTimeMillis();
- long timeSoFar = now - startTime;
- if (timeSoFar >= millis) // timeout!
- throw new TimeoutException(timeSoFar);
- else // adjust time
- waitTime = millis - timeSoFar;
- }
- }
-
- // OK.
- enterMethod(aMeth, action);
- }
-
- /**
- * This method provides the means for updating all synchronization and
- * coordination state after the execution of a given method, and it should be
- * called after the method is executed.
- * In this form, only the method name is given.
- * The synchronization state for self- and mutual-exclusion is
- * automatically upadted.
- */
- public synchronized void guardedExit(String methName) {
- guardedExit(methName, null);
- }
-
- /**
- * Just like guardedExit(String methName) but with an additional
- * coordination action that is executed.
- * guardedExit provides the means for updating all synchronization and
- * coordination state after the execution of a given method, and it should be
- * called after the method is executed.
- * In this form, the method name is given along with a coordination action.
- * The synchronization state for self- and mutual-exclusion is
- * automatically upadted.
- * The given coordination action is executed.
- */
- public synchronized void guardedExit(String methName,
- CoordinationAction action) {
- Method aMeth = getOrSetMethod(methName);
-
- for (int i = 0; i < aMeth.exes.size(); i++)
- ((Exclusion)aMeth.exes.elementAt(i)).exitExclusion(methName);
- if (action != null) action.doit();
- notifyAll();
- }
-
- private Method getOrSetMethod(String methName) {
- Method aMeth = null;
- if (!methods.containsKey(methName)) {
- methods.put(methName, (aMeth = new Method(methName)));
- }
- else {
- aMeth = (Method) methods.get(methName);
- }
- return aMeth;
- }
-
- private void enterMethod(Method aMeth, CoordinationAction action) {
- for (int i = 0; i < aMeth.exes.size(); i++)
- ((Exclusion)aMeth.exes.elementAt(i)).enterExclusion(aMeth.name);
-
- if (action != null) action.doit();
- }
-
-
-
-}
-
-class Method {
- String name;
- Vector exes = new Vector(3);
-
- Method(String n) {
- name = n;
- }
-
- void addExclusion(Exclusion ex) {
- exes.addElement(ex);
- }
-
- void removeExclusion(Exclusion ex) {
- for (int i = 0; i < exes.size(); i++) {
- if (exes.elementAt(i) == ex)
- exes.removeElementAt(i);
- }
- }
-}
-
+++ /dev/null
-/* -*- Mode: Java; -*-
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-
-package coordination;
-
-
-interface Exclusion {
-
- boolean testExclusion(String methodName);
-
- void enterExclusion(String methodName);
-
- void exitExclusion(String methodName);
-
- // for debug !!!
- void printNames();
-}
-
+++ /dev/null
-/* -*- Mode: Java; -*-
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-
-package coordination;
-
-import java.util.Vector;
-import java.util.Enumeration;
-
-
-class MethodState {
-
- Vector threads=new Vector();
-
- void enterInThread (Thread t) {
- threads.addElement(t);
- }
-
- void exitInThread(Thread t) {
- threads.removeElement(t);
- }
-
- boolean hasOtherThreadThan(Thread t) {
- Enumeration e = threads.elements();
- while (e.hasMoreElements())
- if (e.nextElement() != t)
- return(true);
- return (false);
- }
-
-}
+++ /dev/null
-/* -*- Mode: Java; -*-
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-
-package coordination;
-
-import java.lang.String;
-
-
-class Mutex implements Exclusion {
- String[] methodNames;
- MethodState[] methodStates;
-
- String prettyName;
-
- Mutex (String[] _methodNames) {
- methodNames = _methodNames;
- methodStates = new MethodState[methodNames.length];
- for (int i = 0; i < methodNames.length; i++) {
- methodStates[i] = new MethodState();
- }
- }
-
- private boolean isMethodIn (String _methodName) {
- for (int i = 0; i < methodNames.length; i++) {
- if (_methodName.equals(methodNames[i]))
- return(true);
- }
- return(false);
- }
-
- private MethodState getMethodState (String _methodName) {
- for (int i = 0; i < methodNames.length; i++) {
- if (_methodName.equals(methodNames[i]))
- return(methodStates[i]);
- }
- return(null);
- }
-
- public boolean testExclusion (String _methodName) {
- Thread ct = Thread.currentThread();
- //
- // Loop through each of the other methods in this exclusion set, to be sure
- // that no other thread is running them. Note that we have to be careful
- // about selfex.
- //
- for (int i = 0; i < methodNames.length; i++) {
- if (!_methodName.equals(methodNames[i])) {
- if (methodStates[i].hasOtherThreadThan(ct))
- return(false);
- }
- }
- return (true);
- }
-
- public void enterExclusion (String _methodName) {
- MethodState methodState = getMethodState(_methodName);
- methodState.enterInThread(Thread.currentThread());
- }
-
- public void exitExclusion (String _methodName) {
- MethodState methodState = getMethodState(_methodName);
- methodState.exitInThread(Thread.currentThread());
- }
-
- public void printNames() {
- System.out.print("Mutex names: ");
- for (int i = 0; i < methodNames.length; i++)
- System.out.print(methodNames[i] + " ");
- System.out.println();
- }
-}
+++ /dev/null
-/* -*- Mode: Java; -*-
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-
-package coordination;
-
-
-import java.lang.String;
-
-class Selfex implements Exclusion {
- String methodName;
- Thread thread;
- int count = 0;
-
- Selfex (String _methodName) {
- methodName = _methodName;
- }
-
- public boolean testExclusion (String _methodName) {
- if (count == 0)
- return(true);
- return (thread == Thread.currentThread());
- }
-
- public void enterExclusion (String _methodName) {
- count++;
- thread = Thread.currentThread(); // note that if count wasn't 0
- // we aren't changing thread
- }
-
- public void exitExclusion (String _methodName) {
- count--;
- if (count == 0) // not stricly necessary, but...
- thread = null;
- }
-
- public void printNames() {
- System.out.println("Selfex name: " + methodName);
- }
-
-}
+++ /dev/null
-/* -*- Mode: Java; -*-
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-
-package coordination;
-
-
-public class TimeoutException extends Exception {
- long time;
- TimeoutException(long _time) {
- time = _time;
- }
-}
+++ /dev/null
-Condition.java
-CoordinationAction.java
-Coordinator.java
-Exclusion.java
-MethodState.java
-Mutex.java
-Selfex.java
-TimeoutException.java
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-*/
-package introduction;
-
-public aspect CloneablePoint {
-
- declare parents: Point implements Cloneable;
-
- public Object Point.clone() throws CloneNotSupportedException {
- // we choose to bring all fields up to date before cloning.
- makeRectangular();
- makePolar();
- return super.clone();
- }
-
- public static void main(String[] args){
- Point p1 = new Point();
- Point p2 = null;
-
- p1.setPolar(Math.PI, 1.0);
- try {
- p2 = (Point)p1.clone();
- } catch (CloneNotSupportedException e) {}
- System.out.println("p1 =" + p1 );
- System.out.println("p2 =" + p2 );
-
- p1.rotate(Math.PI / -2);
- System.out.println("p1 =" + p1 );
- System.out.println("p2 =" + p2 );
- }
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package introduction;
-
-public aspect ComparablePoint {
-
- declare parents: Point implements Comparable;
-
- public int Point.compareTo(Object o) {
- return (int) (this.getRho() - ((Point)o).getRho());
- }
-
- public static void main(String[] args){
- Point p1 = new Point();
- Point p2 = new Point();
-
- System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
-
- p1.setRectangular(2,5);
- p2.setRectangular(2,5);
- System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
-
- p2.setRectangular(3,6);
- System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
-
- p1.setPolar(Math.PI, 4);
- p2.setPolar(Math.PI, 4);
- System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
-
- p1.rotate(Math.PI / 4.0);
- System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
-
- p1.offset(1,1);
- System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
- }
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package introduction;
-
-import java.util.Hashtable;
-
-public aspect HashablePoint {
-
- public int Point.hashCode() {
- return (int) (getX() + getY() % Integer.MAX_VALUE);
- }
-
- public boolean Point.equals(Object o) {
- if (o == this) { return true; }
- if (!(o instanceof Point)) { return false; }
- Point other = (Point)o;
- return (getX() == other.getX()) && (getY() == other.getY());
- }
-
- public static void main(String[] args) {
- Hashtable h = new Hashtable();
- Point p1 = new Point();
-
- p1.setRectangular(10, 10);
- Point p2 = new Point();
-
- p2.setRectangular(10, 10);
-
- System.out.println("p1 = " + p1);
- System.out.println("p2 = " + p2);
- System.out.println("p1.hashCode() = " + p1.hashCode());
- System.out.println("p2.hashCode() = " + p2.hashCode());
-
- h.put(p1, "P1");
- System.out.println("Got: " + h.get(p2));
- }
-}
+++ /dev/null
-/*
- Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
- Use and copying of this software and preparation of derivative works based
- upon this software are permitted. Any distribution of this software or
- derivative works must comply with all applicable United States export control
- laws.
-
- This software is made available AS IS, and Xerox Corporation makes no warranty
- about the software, its performance or its conformity to any specification.
-*/
-
-package introduction;
-
-public class Point {
-
- protected double x = 0;
- protected double y = 0;
- protected double theta = 0;
- protected double rho = 0;
-
- protected boolean polar = true;
- protected boolean rectangular = true;
-
- public double getX(){
- makeRectangular();
- return x;
- }
-
- public double getY(){
- makeRectangular();
- return y;
- }
-
- public double getTheta(){
- makePolar();
- return theta;
- }
-
- public double getRho(){
- makePolar();
- return rho;
- }
-
- public void setRectangular(double newX, double newY){
- x = newX;
- y = newY;
- rectangular = true;
- polar = false;
- }
-
- public void setPolar(double newTheta, double newRho){
- theta = newTheta;
- rho = newRho;
- rectangular = false;
- polar = true;
- }
-
- public void rotate(double angle){
- setPolar(theta + angle, rho);
- }
-
- public void offset(double deltaX, double deltaY){
- setRectangular(x + deltaX, y + deltaY);
- }
-
- protected void makePolar(){
- if (!polar){
- theta = Math.atan2(y,x);
- rho = y / Math.sin(theta);
- polar = true;
- }
- }
-
- protected void makeRectangular(){
- if (!rectangular) {
- y = rho * Math.sin(theta);
- x = rho * Math.cos(theta);
- rectangular = true;
- }
- }
-
- public String toString(){
- return "(" + getX() + ", " + getY() + ")["
- + getTheta() + " : " + getRho() + "]";
- }
-
- public static void main(String[] args){
- Point p1 = new Point();
- System.out.println("p1 =" + p1);
- p1.setRectangular(5,2);
- System.out.println("p1 =" + p1);
- p1.setPolar( Math.PI / 4.0 , 1.0);
- System.out.println("p1 =" + p1);
- p1.setPolar( 0.3805 , 5.385);
- System.out.println("p1 =" + p1);
- }
-}
+++ /dev/null
-Point.java
-CloneablePoint.java
-ComparablePoint.java
-HashablePoint.java
+++ /dev/null
-/*
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
- *
- * Contributors:
- * Matthew Webster initial implementation
- */
-public class HelloWorld {
-
- public static void main (String[] args) {
- System.out.println("Hello World!");
- }
-}
+++ /dev/null
-\r
-For users of JDK 1.4 the bin directory of your AspectJ distribution \r
-contains a script "aj" to perform load-time weaving. Java classes on \r
-the CLASSPATH are loaded and woven with aspects also on the CLASSPATH \r
-which are declared in an aop.xml file. This file is either created by\r
-the user or generated by the compiler. Alternatively aspects can be \r
-loaded from an explicitly defined ASPECTPATH. \r
-\r
-For users of JDK 1.5 the bin directory of your AspectJ distribution \r
-contains a script "aj5" to perform load-time weaving using an agent. \r
-This uses an aop.xml as described above.\r
-\r
---To compile the HelloWorld program--\r
-\r
- ajc -outjar hello.jar HelloWorld.java\r
-\r
---To compile the Tracing aspect--\r
-\r
- ajc -outjar tracing.jar -outxml Tracing.aj\r
-\r
---To run the example--\r
-\r
- set CLASSPATH to include hello.jar\r
-\r
- aj HelloWorld\r
-\r
---To run the example with tracing--\r
-\r
- set CLASSPATH to include "tracing.jar"\r
-\r
- aj HelloWorld\r
-\r
---To run the example with tracing using ASPECTPATH--\r
-\r
- set ASPECTPATH=tracing.jar\r
-\r
- aj HelloWorld\r
-\r
---To run the example with tracing using an agent--\r
-\r
- aj5 HelloWorld\r
-\r
+++ /dev/null
-/*
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
- *
- * Contributors:
- * Matthew Webster initial implementation
- */
-public aspect Tracing {
-
- private pointcut mainMethod () :
- execution(public static void main(String[]));
-
- before () : mainMethod() {
- System.out.println("> " + thisJoinPoint);
- }
-
- after () : mainMethod() {
- System.out.println("< " + thisJoinPoint);
- }
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-
-package observer;
-
-import java.awt.Color;
-import java.awt.event.ActionListener;
-import java.awt.event.ActionEvent;
-
-class Button extends java.awt.Button {
-
- static final Color defaultBackgroundColor = Color.gray;
- static final Color defaultForegroundColor = Color.black;
- static final String defaultText = "cycle color";
-
- Button(Display display) {
- super();
- setLabel(defaultText);
- setBackground(defaultBackgroundColor);
- setForeground(defaultForegroundColor);
- addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- Button.this.click();
- }
- });
- display.addToFrame(this);
- }
-
- public void click() {}
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package observer;
-import java.awt.Color;
-import java.awt.Label;
-
-class ColorLabel extends Label {
-
- ColorLabel(Display display) {
- super();
- display.addToFrame(this);
- }
-
- final static Color[] colors = {Color.red, Color.blue,
- Color.green, Color.magenta};
- private int colorIndex = 0;
- private int cycleCount = 0;
- void colorCycle() {
- cycleCount++;
- colorIndex = (colorIndex + 1) % colors.length;
- setBackground(colors[colorIndex]);
- setText("" + cycleCount);
- }
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package observer;
-
-public class Demo {
- public static void main(String[] args) {
-
- Display display = new Display();
- Button b1 = new Button(display);
- Button b2 = new Button(display);
- ColorLabel c1 = new ColorLabel(display);
- ColorLabel c2 = new ColorLabel(display);
- ColorLabel c3 = new ColorLabel(display);
-
- b1.addObserver(c1);
- b1.addObserver(c2);
- b2.addObserver(c3);
- }
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package observer;
-import java.awt.Frame;
-import java.awt.Panel;
-import java.awt.Container;
-import java.awt.Component;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.awt.BorderLayout;
-
-/*
- * Display is the container class that holds all the views of the
- * colored number.
- * In this demo, it holds buttons.
- */
-
-class Display extends Panel {
-
- protected Frame frame = new Frame("Subject/Observer Demo");
-
- Display() {
- frame.addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {System.exit(0);}
- });
-
- frame.add(this, BorderLayout.CENTER);
- frame.pack();
- frame.setVisible(true);
- }
-
- void addToFrame(Component c) {
- add(c);
- frame.pack();
- }
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-package observer;
-
-interface Observer {
- void setSubject(Subject s);
- Subject getSubject();
- void update();
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package observer;
-import java.util.Vector;
-
-interface Subject {
- void addObserver(Observer obs);
- void removeObserver(Observer obs);
- Vector getObservers();
- Object getData();
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package observer;
-
-import java.util.Vector;
-
-abstract aspect SubjectObserverProtocol {
-
- abstract pointcut stateChanges(Subject s);
-
- after(Subject s): stateChanges(s) {
- for (int i = 0; i < s.getObservers().size(); i++) {
- ((Observer)s.getObservers().elementAt(i)).update();
- }
- }
-
- private Vector Subject.observers = new Vector();
- public void Subject.addObserver(Observer obs) {
- observers.addElement(obs);
- obs.setSubject(this);
- }
- public void Subject.removeObserver(Observer obs) {
- observers.removeElement(obs);
- obs.setSubject(null);
- }
- public Vector Subject.getObservers() { return observers; }
-
- private Subject Observer.subject = null;
- public void Observer.setSubject(Subject s) { subject = s; }
- public Subject Observer.getSubject() { return subject; }
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package observer;
-
-import java.util.Vector;
-
-aspect SubjectObserverProtocolImpl extends SubjectObserverProtocol {
-
- declare parents: Button implements Subject;
- public Object Button.getData() { return this; }
-
- declare parents: ColorLabel implements Observer;
- public void ColorLabel.update() {
- colorCycle();
- }
-
- pointcut stateChanges(Subject s):
- target(s) &&
- call(void Button.click());
-
-}
+++ /dev/null
-ColorLabel.java
-Button.java
-Display.java
-Subject.java
-Observer.java
-SubjectObserverProtocol.java
-SubjectObserverProtocolImpl.java
-Demo.java
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-
-Bullet.java
-Part of the Spacewar game.
-
-*/
-
-package spacewar;
-
-class Bullet extends SpaceObject {
-
- static private final int SIZE = 3; //Can't be changed for now!!!
- static private int LIFETIME = 50;
-
- private int lifeLeft;
-
- Bullet (Game theGame, double xP, double yP, double xV, double yV) {
- super(theGame, xP, yP, xV, yV);
- lifeLeft = LIFETIME;
- }
-
- int getSize() { return SIZE; }
-
- void handleCollision(SpaceObject obj) {
- die();
- }
-
- void clockTick() {
- if (--lifeLeft == 0)
- die();
- super.clockTick();
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-Debug.java
-Part of the Spacewar system.
-
-*/
-
-package spacewar;
-
-import java.awt.Menu;
-import java.awt.CheckboxMenuItem;
-import java.awt.Frame;
-import java.awt.TextArea;
-import java.awt.Dimension;
-
-/**
- * This aspect specifies debugging information to be output to the
- * information window.
- *
- * When the debug aspect is compiled in the Frame menu has several checkbox
- * items that can be used to control the amount of tracing information
- * displayed. (By default the first three are off, because they generate
- * so much information.)
- *
- * There are two reasons to gather all this debugging code into an aspect
- * like this:
- *
- * (1) It makes it easier to understand when it is all in one place.
- *
- * (2) It means that we can "plug and debug". We can enable/disable
- * the debugging code simply by weaving or not weaving this
- * aspect in.
- *
- * All in all, this is a lot better than the usual practice of writing
- * complex debugging code and then deleting it when the bug is found,
- * only to regret it a month later when a related bug surfaces. (Or even
- * the same bug!)
- *
- * This file also defines a class InfoWin, which it uses to display all the
- * debugging information.
- */
-aspect Debug {
-
- private static InfoWin infoWin = new InfoWin();
-
- private static Menu menu = new Menu("Debug");
-
- private static CheckboxMenuItem traceConstructors =
- new CheckboxMenuItem("trace constructors", false);
- private static CheckboxMenuItem traceInitializations =
- new CheckboxMenuItem("trace initializations", false);
- private static CheckboxMenuItem traceMethods =
- new CheckboxMenuItem("trace methods", false);
- private static CheckboxMenuItem traceClockTick =
- new CheckboxMenuItem("trace clock tick", false);
- private static CheckboxMenuItem traceRegistry =
- new CheckboxMenuItem("trace registry", true);
- private static CheckboxMenuItem traceFireCollideDamage =
- new CheckboxMenuItem("trace fire, collide, damage", true);
-
- after() returning (SWFrame frame): call(SWFrame+.new(..)) {
- menu.add(traceConstructors);
- menu.add(traceInitializations);
- menu.add(traceMethods);
- menu.add(traceClockTick);
- menu.add(traceRegistry);
- menu.add(traceFireCollideDamage);
- frame.getMenuBar().add(menu);
- }
-
- /*
- * all constructors
- */
- pointcut allConstructorsCut():
- call((spacewar.* && !(Debug+ || InfoWin+)).new(..));
-
- before(): allConstructorsCut() {
- if (traceConstructors.getState()) {
- infoWin.println("begin constructing " + thisJoinPoint.getSignature());
- }
- }
-
- after() returning: allConstructorsCut() {
- if (traceConstructors.getState()) {
- infoWin.println("done constructing " + thisJoinPoint.getSignature());
- }
- }
-
- /*
- * All dynamic initializations
- */
- pointcut allInitializationsCut():
- initialization((spacewar.* && !(Debug+ || InfoWin+)).new(..));
-
- before(): allInitializationsCut() {
- if (traceConstructors.getState()) {
- infoWin.println("begin initializing " + thisJoinPoint.getSignature());
- }
- }
- after() returning : allInitializationsCut() {
- if (traceConstructors.getState()) {
- infoWin.println("done initializing " + thisJoinPoint.getSignature());
- }
- }
-
- /*
- * all methods
- */
- pointcut allMethodsCut():
- execution(* (spacewar.* && !(Debug+ || InfoWin+)).*(..));
-
- before(): allMethodsCut() {
- if (traceMethods.getState()) {
- infoWin.println("entering " + thisJoinPoint.getSignature());
- }
- }
- after() returning : allMethodsCut() {
- if (traceMethods.getState()) {
- infoWin.println("exiting " + thisJoinPoint.getSignature());
- }
- }
-
- /*
- * clock ticks
- */
- after(Object obj) returning :
- (target(obj) && (target(Game) ||
- target(Registry) ||
- target(SpaceObject)))
- && call(void clockTick()) {
- if (traceClockTick.getState())
- infoWin.println("ticking " + obj);
- }
-
- /*
- * registry contents
- */
- after(Registry registry) returning :
- target(registry) && (call(void register(..)) ||
- call(void unregister(..))) {
- if (traceRegistry.getState())
- infoWin.println(registry.getTable().size() +
- " space objects in the registry.");
- }
-
- /*
- * fire, collide, damage
- */
- after() returning : call(void Ship.fire()) {
- if (traceFireCollideDamage.getState())
- infoWin.println("firing");
- }
-
- after(Ship ship, SpaceObject obj) returning :
- call(void handleCollision(SpaceObject)) && target(ship) && args(obj) {
- if (traceFireCollideDamage.getState())
- infoWin.println(ship + " collides with " + obj);
- }
-
- after(Ship shipA, Ship shipB) returning :
- execution(void Ship.bounce(Ship, Ship)) && args(shipA, shipB) {
- if (traceFireCollideDamage.getState())
- infoWin.println(shipA + " bounces with " + shipB);
- }
-
- before(Ship ship, double amount):
- call(void Ship.inflictDamage(double)) && target(ship) && args(amount) {
- if (traceFireCollideDamage.getState())
- if (amount > 0)
- infoWin.println(ship + "gets " +
- amount + " damage (" +
- ship.getDamage() + ")");
- }
-
-}
-
-class InfoWin {
- private Frame frame;
- private TextArea info;
-
- InfoWin() {
- frame = new Frame("debugging info for spacewar game");
- info = new TextArea();
- info.setEditable(false);
-
- Dimension screenSize = frame.getToolkit().getScreenSize();
- frame.setSize(250, 600);
- frame.setLocation(screenSize.width - 250, 0);
- frame.add(info);
- frame.show();
- frame.toFront();
- }
-
- void clear() {
- info.setText("");
- }
-
- void println(String line) {
- info.append(line + "\n");
- }
-
- void print(String line) {
- info.append(line);
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-
-Display.java
-Part of the Spacewar system.
-*/
-
-package spacewar;
-
-import java.util.Vector;
-import java.util.Enumeration;
-import java.awt.Graphics;
-import java.awt.Canvas;
-import java.awt.Image;
-
-/**
- * The display aspects capture the look and feel of the Game in modular
- * pluggable units.
- *
- * The model is that constructing a concrete subclass of Display attaches that
- * kind of display to the game. It will Display the game as it goes along.
- * A game can have any number of displays. Any of the displays will accept
- * keyboard input.
- *
- */
-
-class Display extends Canvas {
-
- private static Vector DISPLAYS = new Vector(2);
- private static Vector PLAYERS = new Vector(2);
- private static Pilot pilot1, pilot2;
-
- Game game;
- SWFrame frame;
- Image offImage;
- Graphics offGraphics;
-
- Game getGame() { return game; }
- static Pilot getPilot1() { return pilot1; }
- static Pilot getPilot2() { return pilot2; }
-
- Display(Game g) {
- super();
- game = g;
-
- frame = new SWFrame(game, this);
- DISPLAYS.addElement(this);
- }
-
-
- void noticeSizeChange() {
- initializeOffImage();
- }
-
- private void initializeOffImage () {
- int w = getSize().width;
- int h = getSize().height;
- if ( w > 0 & h > 0) {
- offImage = createImage(w, h);
- offGraphics = offImage.getGraphics();
- }
- }
-
- /*
- * In our double buffering scheme, painting just means copying the buffer
- * to the screen. The Display aspect draws into the buffer.
- */
- public void paint(Graphics g) {
- if (offImage != null)
- g.drawImage(offImage, 0, 0, null);
- }
-
- public void update(Graphics g) {
- /*
- * There are 4 steps to this:
- * - clear the double buffer
- * - paint the objects into the double buffer
- * - paint the status into the double buffer
- * - paint the doublebuffer into the buffer
- */
- offGraphics.setColor(getBackground());
- offGraphics.fillRect(0, 0, getBounds().width, getBounds().height);
- paintObjects(offGraphics);
- paintStatus(offGraphics);
- g.drawImage(offImage, 0, 0, null);
- }
-
- void paintObjects(Graphics g) { }
- void paintStatus(Graphics g) {}
-
- static aspect DisplayAspect {
-
- after (String mode) returning (Game game): call(Game+.new(String)) && args(mode) {
- new Display1(game);
- new Display2(game);
-
- if ( mode.equals("1") ) {
- pilot1 = game.newPlayer(1);
- }
- else if ( mode.equals("2") ) {
- pilot1 = game.newPlayer(1);
- pilot2 = game.newPlayer(2);
- }
- else if (mode. equals("demo")) {
- pilot1 = game.newRobot(1);
- pilot2 = game.newRobot(2);
- } else {
- game.error("Invalid mode: " + mode);
- game.quit();
- }
- }
-
-
- /*
- * I'm not really sure this belongs here.
- *
- * Being here what it does is makes the Display aspect
- * responsible for having the Players couple up to it. That's
- * kind of nice, but its a bit incomplete, since Player is
- * really part of the GUI, not part of the core Game.
- *
- * In a future re-factoring this will get worked out better.
- * What will happen is that GUI will be an aspect that has the
- * core GUI. Each of the different kinds of displays will be
- * aspects that tie themselves in.
- */
- after () returning (Player player): call(Player+.new(..)) {
- Enumeration elements = DISPLAYS.elements();
- while ( elements.hasMoreElements() ) {
- Display display = (Display)elements.nextElement();
- display.addKeyListener(player);
- }
- }
-
- after() returning (Display display): call(Display+.new(..)) {
- display.noticeSizeChange();
- }
-
- after(Display display) returning (): call(void setSize(..)) && target(display) {
- display.noticeSizeChange();
- }
-
- after() returning : call(void Game.clockTick()) {
- Enumeration elements = DISPLAYS.elements();
- while ( elements.hasMoreElements() ) {
- Display display = (Display)elements.nextElement();
- display.repaint();
- }
- }
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-
-Display1.java
-Part of the Spacewar system.
-*/
-
-package spacewar;
-
-
-import java.awt.Graphics;
-import java.awt.Color;
-import java.util.Random;
-
-/**
- * This is the standard display aspect.
- */
-class Display1 extends Display {
- /*
- * Here's the color scheme for the game. No other places in this file
- * should say Color.xxx. Instead, that color should be given a symbolic
- * name here.
- */
- private static Color backgroundColor = Color.black;
- private static Color player1ShipColor = Color.white;
- private static Color player2ShipColor = Color.gray;
- private static Color robotShipColor = new Color(0xa00000);
- private static Color flameColor = Color.red;
- private static Color shipExplosionColor = Color.red;
- private static Color bulletColor = Color.green;
- private static Color energyPacketOuterColor = Color.blue;
- private static Color energyPacketInnerColor = new Color(0x7070FF);
- private static Color statusLabelsColor = Color.white;
- private static Color statusMeterBorderColor = Color.white;
- private static Color energyStatusMeterColor = Color.blue;
- private static Color damageStatusMeterColor = Color.red;
-
-
- Display1(Game game) {
- super(game);
- frame.setLocation(20, 20);
- }
-
- void noticeSizeChange() {
- super.noticeSizeChange();
- setBackground(backgroundColor);
- }
-
- void paintObjects(Graphics g) {
- SpaceObject[] objects = game.getRegistry().getObjects();
- final int len = objects.length;
- for (int i = 0; i < len; i++) {
- objects[i].paint(g);
- }
- }
-
- static aspect SpaceObjectPainting {
-
- abstract private void SpaceObject.paint(Graphics g);
-
- /*
- * Ships are by far and away the most complex of the space Objects
- * to paint. First off, we need to set the color when the ship
- * is made.
- */
- private Color Ship.color;
-
- after(Pilot pilot) returning (Ship ship): call(Ship Game.newShip(Pilot)) && args(pilot) {
- if (pilot.getNumber() == 1)
- ship.color = player1ShipColor;
- else if (pilot.getNumber() == 2)
- ship.color = player2ShipColor;
- else
- ship.color = robotShipColor;
- }
-
- private void Ship.paint(Graphics g) {
- final double PI = Math.PI;
- int[] radius = {15, 12, -4, 12, -9, -15, -9};
- double[] angle = {0, PI * 3/4, 0, -PI * 3/4, PI/8, 0, -PI/8};
- int[] x;
- int[] y;
-
- Random random = new Random();
-
- if (this.getDamage() >= this.MAX_DAMAGE) {
- int lines = 20;
- x = new int[lines];
- y = new int[lines];
- g.setColor(shipExplosionColor);
- for (int i = 0; i < lines; i++) {
- x[i] = (int)(this.getXPos()) + random.nextInt() % 20;
- y[i] = (int)(this.getYPos()) + random.nextInt() % 20;
- }
- for (int i = 0; i < lines; i++)
- g.drawLine(x[i], y[i], x[(i + 1) % lines], y[(i + 1) % lines]);
- } else {
- x = new int[7];
- y = new int[7];
-
- g.setColor(this.color);
-
- radius[5] += random.nextInt() % 3;
- // convert coordinates from polar to cartesian
- for (int i = 0; i < 7; i++) {
- x[i] = (int)
- (this.getXPos() +
- Math.cos(this.getOrientation() + angle[i]) * radius[i]);
- y[i] = (int)
- (this.getYPos() +
- Math.sin(this.getOrientation() + angle[i]) * radius[i]);
- }
-
- // draw the body as a polygon
- g.drawPolygon(x, y, 4);
-
- // if the ship is accelerating, draw in a flame
- if (this.getRAcc() != 0) {
- g.setColor(flameColor);
- g.drawLine(x[4], y[4], x[5], y[5]);
- g.drawLine(x[5], y[5], x[6], y[6]);
- }
- }
- }
-
- /*
- * Bullets
- */
- private void Bullet.paint(Graphics g) {
- g.setColor(bulletColor);
- g.fillOval((int)this.getXPos() - 1,
- (int)this.getYPos() - 1,
- 3,
- 3);
- }
-
- /*
- * energy packets
- */
- private void EnergyPacket.paint(Graphics g) {
- g.setColor(energyPacketOuterColor);
- g.fillOval((int)this.getXPos() - 5,
- (int)this.getYPos() - 5,
- 10, 10);
- g.setColor(energyPacketInnerColor);
- g.fillOval((int)this.getXPos() - 2,
- (int)this.getYPos() - 2,
- 3, 3);
- }
- }
-
-
- void paintStatus(Graphics g) {
- int left1 = 60;
- int top1 = 0;
-
- int left2 = 200;
- int top2 = 0;
-
- g.setColor(statusLabelsColor);
- g.drawString("energy:", 5, top1 + 15);
- g.drawString("damage:", 5, top1 + 30);
-
- if (getPilot1() != null)
- paintLevels(g, getPilot1().getShip(), top1, left1);
- if (getPilot2() != null)
- paintLevels(g, getPilot2().getShip(), top2, left2);
- }
-
- static void paintLevels(Graphics g, Ship ship, int top, int left) {
- if (ship == null)
- return;
- else if (ship.isAlive()) {
- g.setColor(statusMeterBorderColor);
- g.drawRect(left, top + 6, 101, 10);
- g.drawRect(left, top + 21, 101, 10);
- g.setColor(energyStatusMeterColor);
- g.fillRect(left + 1, top + 7, (int)(ship.getEnergyLevel()*100), 9);
- g.setColor(damageStatusMeterColor);
- g.fillRect(left + 1, top + 22, (int)(ship.getDamageLevel()*100), 9);
- }
- else {
- g.setColor(damageStatusMeterColor);
- g.drawString("Ship is destroyed", left+1, top+15);
- }
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-
-Display2.java
-Part of the Spacewar system.
-*/
-
-package spacewar;
-
-
-import java.awt.Graphics;
-import java.awt.Color;
-
-
-/**
- * This is the cheap Display aspect.
- */
-class Display2 extends Display {
-
- Display2(Game game) {
- super(game);
- frame.setLocation(540, 20);
- }
-
- void noticeSizeChange() {
- super.noticeSizeChange();
- setBackground(Color.darkGray);
- }
-
- void paintObjects(Graphics g) {
- SpaceObject[] objects = game.getRegistry().getObjects();
- final int len = objects.length;
- for (int i = 0; i < len; i++) {
- objects[i].paint(g);
- }
- }
-
- static aspect SpaceObjectPainting {
-
- abstract private void SpaceObject.paint(Graphics g);
-
- /*
- * Ships are by far and away the most complex of the space Objects
- * to paint.
- */
- private Color Ship.color;
-
- after(Pilot pilot) returning (Ship ship): call(Ship Game.newShip(Pilot)) && args(pilot) {
- if (pilot.getNumber() == 1)
- ship.color = Color.white;
- else if (pilot.getNumber() == 2)
- ship.color = Color.gray;
- else
- ship.color = new Color(0xa00000);
- }
-
- private void Ship.paint(Graphics g) {
- if (this.getDamage() < this.MAX_DAMAGE) {
- double x = this.getXPos();
- double y = this.getYPos();
- double sinTheta = Math.sin(this.getOrientation());
- double cosTheta = Math.cos(this.getOrientation());
-
- g.setColor(color);
- g.drawLine((int)(x + 8*cosTheta), (int)(y + 8*sinTheta),
- (int)(x - 8*cosTheta), (int)(y - 8*sinTheta));
-
- // if the ship is accelerating, draw thruster
- if (this.getRAcc() != 0) {
- g.setColor(Color.red);
- g.fillOval((int)(x - 8*cosTheta), (int)(y - 8*sinTheta), 6, 6);
- }
- }
- }
-
- private void Bullet.paint(Graphics g) {
- g.setColor(Color.green);
- g.fillOval((int)this.getXPos() - 1,
- (int)this.getYPos() - 1,
- 3,
- 3);
- }
-
- private void EnergyPacket.paint(Graphics g) {
- g.setColor(Color.white);
- g.fillOval((int)this.getXPos() - 5,
- (int)this.getYPos() - 5,
- 10,
- 10);
- }
- }
-
- void paintStatus(Graphics g) {
- int left1 = 60;
- int top1 = 0;
-
- int left2 = 200;
- int top2 = 0;
-
- g.setColor(Color.white);
- g.drawString("energy:", 5, top1 + 15);
- g.drawString("damage:", 5, top1 + 30);
-
- if (getPilot1() != null)
- paintLevels(g, getPilot1().getShip(), top1, left1);
- if (getPilot2() != null)
- paintLevels(g, getPilot2().getShip(), top2, left2);
- }
-
- void paintLevels(Graphics g, Ship ship, int top, int left) {
- if (ship == null)
- return;
- else if (ship.isAlive()) {
- g.drawString(Float.toString(ship.getEnergyLevel()*100), left+1, top+15);
- g.drawString(Float.toString(ship.getDamageLevel()*100), left+1, top+30);
- }
- else {
- g.setColor(Color.red);
- g.drawString("Ship is destroyed", left+1, top+15);
- }
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-
-EnergyPacket.java
-Part of the Spacewar system.
-
-*/
-
-package spacewar;
-
-
-class EnergyPacket extends SpaceObject {
-
- static private final int SIZE = 5; //Can't be changed for now!!!
- int getSize() { return SIZE; }
-
- private double energy;
-
- double getEnergy() { return energy; }
-
- EnergyPacket(Game theGame,
- double xP, double yP, double xV, double yV, double e) {
- super(theGame, xP, yP, xV, yV);
- energy = e;
- }
-
- void handleCollision(SpaceObject obj) {
- die();
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-
-EnergyPacketProducer.java
-Part of the Spacewar system.
-
- This implementation creates booby-trapped packets 20% of the time.
-
-*/
-
-package spacewar;
-
-
-class EnergyPacketProducer extends Thread {
- private final static int MIN = -20;
- private final static int MAX = 80;
- private final static int EXPECTEDINTERVAL = 15;
-
- private Game game;
-
- Game getGame() { return game; }
-
- EnergyPacketProducer(Game theGame) {
- super("EnergyPacketProducer");
- game = theGame;
- }
-
- public void run() {
- while(true) {
- produceAPacket();
- waitForABit();
- }
- }
-
- void waitForABit() {
- try { Thread.sleep((int)(Math.random() * EXPECTEDINTERVAL * 2000)); }
- catch (InterruptedException e) {}
- }
-
- void produceAPacket() {
- EnergyPacket pkt =
- new EnergyPacket(game,
- Math.random() * getGame().getWidth(),
- Math.random() * getGame().getHeight(),
- Math.random() * 2 - 1,
- Math.random() * 2 - 1,
- Math.random() * (MAX - MIN) + MIN);
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-Ship.java
-Part of the Spacewar system.
-
-*/
-
-package spacewar;
-
-/**
- * This aspect makes sure that the ship is alive before performing any console
- * commands.
- *
- */
-aspect EnsureShipIsAlive {
- void around (Ship ship): Ship.helmCommandsCut(ship) {
- if ( ship.isAlive() ) {
- proceed(ship);
- }
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-
-Game.java
-Part of the Spacewar system.
-
-*/
-
-package spacewar;
-
-import java.awt.Dimension;
-
-/**
- * The Game class is the root of the spacewar game. To start a spacewar
- * game, you can either call the main method, or instantiate this class
- * directly.
- *
- * Synchronization is done by the GameSynchronization aspect.
- */
-public class Game extends Thread {
-
- /**
- * To run the game from top level, simply say Java Game, as usual. Passing
- * an argument makes the game run in demo mode. Without an argument it runs
- * in the normal player mode.
- */
- public static void main(String[] args) {
- if ( args.length == 0 )
- new Game("1").run();
- new Game(args[0]).run();
- }
-
-
- private Timer timer;
- private EnergyPacketProducer ePP;
-
- private Registry registry;
- private Pilot pilot1, pilot2;
-
- private Dimension screenSize = new Dimension(500, 500);
-
- Registry getRegistry() { return registry; }
- Pilot getPilot1() { return pilot1; }
- Pilot getPilot2() { return pilot2; }
-
- /** returns the width of the screen, delegating to screenSize */
- int getWidth() { return screenSize.width; }
-
- /** returns the height of the screen, delegating to screenSize */
- int getHeight() { return screenSize.height; }
-
- /**
- * To run the game, simply instantiate this class. It runs in its own
- * thread. You can instantiate multiple games at once. For the time being
- * the only way to end the game is to exit from the Java VM.
- *
- * @param mode Controls whether the game runs in demo mode or not. True
- * means it is a demo, false means it runs in normal 2 player mode.
- */
- public Game(String mode) {
- timer = new Timer(this);
- ePP = new EnergyPacketProducer(this);
- registry = new Registry(this);
- }
-
- public void run() {
- timer.start();
- ePP.start();
-
- while(true) {
- try {
- newRobot(3);
- Thread.sleep(15000);
- }
- catch (InterruptedException e) {}
- }
- }
-
-
- /**
- * add a robot to the game. This is a menu command.
- */
- void addRobot() {
- newRobot(3);
- }
-
- /**
- * resurrect the ships in the game. This is a menu command.
- */
- void resetShips() {
- Ship[] ships = registry.getShips();
-
- for (int i = 0; i < ships.length; i++) {
- Ship ship = ships[i];
- Pilot pilot = ship.getPilot();
- newShip(pilot);
- }
- }
-
- /**
- * leave the game. This is a menu command.
- */
- void quit() {
- System.exit(0);
- }
-
- void error(Object o) {
- System.err.println(o);
- }
-
-
- /**
- * returns a new player. With {@link #newRobot} and {@link
- * #newShip}, the only ways to make a Player, a Robot, or a Ship.
- * The structural invariant is that there should be no calls to
- * new of one of these three classes outside these three methods.
- */
- Player newPlayer(int number) {
- Player player = new Player(this, number);
- newShip(player);
- return player;
- }
-
- /**
- * returns a new robot. With {@link #newPlayer} and {@link
- * #newShip}, the only ways to make a Player, a Robot, or a Ship.
- * The structural invariant is that there should be no calls to
- * new of one of these three classes outside these three methods.
- */
- Robot newRobot(int number) {
- Robot robot = new Robot(this, number);
- newShip(robot);
- robot.start();
- return robot;
- }
-
- /**
- * returns a new ship. With {@link #newRobot} and {@link
- * #newPlayer}, the only ways to make a Player, a Robot, or a
- * Ship. The structural invariant is that there should be no
- * calls to new of one of these three classes outside these three
- * methods.
- */
- Ship newShip(Pilot pilot) {
- //
- // If there is an old ship (we're doing a reset), then remove it from
- // the registry.
- //
- Ship oldShip = pilot.getShip();
- if (! (oldShip == null))
- oldShip.die();
-
- Ship newShip = new Ship(this,
- Math.random() * getWidth(),
- Math.random() * getHeight(),
- Math.random() * Math.PI * 2);
- pilot.setShip(newShip);
- newShip.setPilot(pilot);
-
- return newShip;
- }
-
- void clockTick() {
- registry.clockTick();
- handleCollisions();
- }
-
- // collision detection
-
- void handleCollisions() {
- SpaceObject[] objects = registry.getObjects();
-
- SpaceObject objI, objJ;
- for (int i = 0; i < objects.length; i++) {
- objI = objects[i];
- for (int j = i + 1; j < objects.length; j++) {
- objJ = objects[j];
- if (objI instanceof Bullet && objJ instanceof Bullet)
- continue;
- if (isCollision(objI, objJ)) {
- if (objI instanceof Ship && objJ instanceof Ship)
- Ship.bounce((Ship)(objI), (Ship)(objJ));
- else {
- objI.handleCollision(objJ);
- objJ.handleCollision(objI);
- }
- }
- }
- }
- }
-
- /*
- * Is the distance between the two centers less than the sum of the two
- * radii. This is a cheap and dirty (i.e. wrong) implementation of this.
- */
- static boolean isCollision(SpaceObject a, SpaceObject b) {
- return (Math.abs(a.getXPos() - b.getXPos()) +
- Math.abs(a.getYPos() - b.getYPos())) <
- (a.getSize()/2 + b.getSize()/2);
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-
-RegistrySynchronization.java
-Part of the Spacewar system.
-
-*/
-
-package spacewar;
-
-import coordination.Coordinator;
-
-/**
- * This aspect ensures synchronized access to methods of the Game in the
- * presence of several threads.
- *
- * It uses the Coordinator class, from the AspectJ coordination library.
- * (This case is right on the borderline of being too simple to use the
- * coordination library, but we use it anyways to keep the similarity
- * with the RegistrySynchronizer.)
- *
- * It uses a per-Game coordination scheme, so there is one instance of
- * this class for each instance of the Game class. When this class is
- * constructed, it registers appropriate mutexes and selfexes using
- * the behavior inherited from Coordinator.
- *
- * The coordination constraints for the Game are simple. We just need to
- * make sure that newShip and handleCollisions are mutually exclusive. That
- * ensures that they we can't destroy a ship that has just been replaced.
- */
-aspect GameSynchronization extends Coordinator perthis(this(Game)) {
-
- protected pointcut synchronizationPoint():
- call(void Game.handleCollisions(..)) || call(Ship Game.newShip(..));
-
- public GameSynchronization() {
- addMutex(new String[] {"handleCollisions", "newShip"});
- }
-
-}
+++ /dev/null
-SHELL=bash\r
-ACJOPTS=-verbose -nosymbols\r
-AJC=ajc\r
-\r
-.PHONY: demo debug\r
-\r
-demo:\r
- $(AJC) $(ACJOPTS) @demo.lst\r
-\r
-debug:\r
- $(AJC) $(ACJOPTS) @debug.lst\r
-\r
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-
-*/
-
-package spacewar;
-
-
-/**
- * Pilot is the abstract superclass of Player and Robot.
- *
- */
-
-abstract class Pilot {
- private Game game;
- private int number;
- protected Ship ship = null;
-
- Game getGame() { return game; }
- int getNumber() { return number; }
- Ship getShip() { return ship; }
-
- void setShip(Ship s) { ship = s; }
-
- Pilot (Game g, int n) {
- super();
- game = g;
- number = n;
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-
-*/
-
-package spacewar;
-
-import java.awt.event.KeyListener;
-import java.awt.event.KeyEvent;
-
-class Player extends Pilot implements KeyListener {
-
- private KeyMapping keyMapping;
-
- /** current rotation key */
- private int rotation_direction = Ship.STOP; // current rotation key
-
- /** current thrust */
- private boolean thrust_on = false;
-
- Player(Game theGame, int number) {
- super(theGame,number);
-
- if (getNumber() == 1)
- keyMapping = KeyMapping.keyMapping1;
- else if (getNumber() == 2)
- keyMapping = KeyMapping.keyMapping2;
-
- }
-
- public void keyPressed(KeyEvent e) {
- int keyCode = e.getKeyCode();
- boolean consumed = true;
-
- if (keyCode == keyMapping.fire) {
- ship.fire();
- }
- else if (keyCode == keyMapping.thrust && !thrust_on) {
- ship.thrust(true);
- thrust_on = true;
- }
- else if (keyCode == keyMapping.right &&
- rotation_direction != Ship.COUNTERCLOCKWISE) {
- //start rotating clockwise unless already rotating in the
- //opposite direction
- rotation_direction = Ship.CLOCKWISE;
- ship.rotate(Ship.CLOCKWISE);
- }
- else if (keyCode == keyMapping.left &&
- rotation_direction != Ship.CLOCKWISE) {
- //start rotating counterclockwise unless already rotating in the
- //opposite direction
- rotation_direction = Ship.COUNTERCLOCKWISE;
- ship.rotate(Ship.COUNTERCLOCKWISE);
- }
- else {
- consumed = false;
- }
-
- if (consumed) e.consume();
- }
-
- public void keyReleased(KeyEvent e) {
- int keyCode = e.getKeyCode();
-
- if (keyCode == keyMapping.thrust) {
- ship.thrust(false); //engine off
- thrust_on = false;
- }
- else if (keyCode == keyMapping.right &&
- rotation_direction == Ship.CLOCKWISE
- ||
- keyCode == keyMapping.left &&
- rotation_direction == Ship.COUNTERCLOCKWISE) {
- ship.rotate(Ship.STOP); //stop rotation
- rotation_direction = Ship.STOP;
- }
- }
-
- public void keyTyped(KeyEvent e) {
- // have to implement this because it's in KeyListener
- }
-}
-
-class KeyMapping {
-
- static final KeyMapping keyMapping1 =
- new KeyMapping(KeyEvent.VK_LEFT,
- KeyEvent.VK_RIGHT,
- KeyEvent.VK_UP,
- KeyEvent.VK_SPACE);
-
- static final KeyMapping keyMapping2 =
- new KeyMapping(KeyEvent.VK_X,
- KeyEvent.VK_V,
- KeyEvent.VK_D,
- KeyEvent.VK_ALT);
-
- int left, right, thrust, fire;
-
- KeyMapping(int k_left, int k_right, int k_thrust, int k_fire) {
- left = k_left;
- right = k_right;
- thrust = k_thrust;
- fire = k_fire;
- }
-}
+++ /dev/null
-[[_5]]
-== Exploring the Spacewar Example
-
-_© Copyright 1997-2001 Xerox Corporation. All rights reserved._
-
-_Last updated: January 10, 2001_
-
-The code in this directory is an implementation of the classic video
-game Spacewar.
-
-The Spacewar game is intended to provide a modest-sized example of a
-program that uses aspects. The code for this example is evolving, as we
-add new features to AspectJ and come up with a better understanding of
-how to use the features.
-
-In order to compile and run this example, make sure to have the latest
-version of AspectJ correctly installed. If you're not sure you do, try
-the helloworld example first by following the instructions in
-xref:../doc/primer/default.html[Primer] section Getting Started.
-
-[[_5_1]]
-=== Compiling Spacewar
-
-* Change to the `examples` directory.
-* Type `ajc -argfile spacewar/demo.lst` to compile the system.
-
-[[_5_2]]
-=== Running Spacewar
-
-* In the examples directory, type `java spacewar.Game`
-
-When the game starts up you will see two different displays. These are
-the two built-in display aspects of the game. In each you will see a
-single white ship and two red ships. The white ship is yours to control;
-the red ships are an enemy robots. Your ship is controlled with the four
-arrow keys to turn, thrust and stop; the spacebar fires. As you play,
-the game will be displayed in both windows.
-
-When running on a 1.4 or later VM, click in the main panel to give it
-focus so that your keystrokes are recognized.
-
-You can quit the game with ctl-Q.
-
-[[_5_3]]
-=== Exploring the Code
-
-There is one other built-in configurations for the Spacewar game. Try it
-by typing `ajc @spacewar\debug.lst`. This compiles in an elaborate
-debugging aspect for the game.
-
-We recommend you explore the Spacewar source code and look at the
-aspects that it uses. You will find several of them, of different scales
-and different degrees of cross-cutting. Remember that these represent
-our evolving understanding of how to use AspectJ to implement Spacewar.
-If you believe we should be doing something differently, then please let
-us know.
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-
-Registry.java
-Part of the Spacewar system.
-
-*/
-
-package spacewar;
-
-import java.util.Vector;
-import java.util.Hashtable;
-import java.util.Enumeration;
-
-/**
- * The Registry keeps track of all the space objects that are floating around.
- * It basically supports register, unregister and contents type operations.
- *
- * The synchronization is done by the RegistrySynchronization aspect.
- */
-
-class Registry {
-
- private Hashtable table;
- private Game game;
-
- Game getGame() { return game; }
-
- Registry (Game theGame) {
- game = theGame;
- table = new Hashtable();
- }
-
-
- void register(SpaceObject object) {
- table.put(object, object);
- }
-
- void unregister(SpaceObject object) {
- table.remove(object);
- }
-
- /*
- * It is an invariant of the design that only two points in SpaceObject
- * should call register and unregister. This aspect enforces that.
- *
- * Unfortunately, in the current compiler, we get a static warning when
- * there are no illegal calls that this advice has no targets. That will
- * be fixed in a future release. For the time being the dummy method
- * just below this fixes that.
- */
- static aspect RegistrationProtection {
- after() returning():
- (call(void Registry.register(SpaceObject)) ||
- call(void Registry.unregister(SpaceObject))) &&
- !(within(SpaceObject) && (withincode(new(..)) ||
- withincode(void die()))) {
- throw new IllegalAccessError(
- "This is an illegal call to " + thisJoinPoint + "\n" +
- "Only the constructor and the die() on SpaceObject\n" +
- "should call the primitive registry operations.");
- }
- }
-
- void dummy() { // see comment above
- register(getObjects()[0]);
- unregister(getObjects()[0]);
- }
-
-
- SpaceObject[] getObjects() {
- SpaceObject[] allObjects = new SpaceObject[table.size()];
- Enumeration elements = table.elements();
- for(int i = 0; elements.hasMoreElements(); i++) {
- allObjects[i] = (SpaceObject)(elements.nextElement());
- }
- return allObjects;
- }
-
- Ship[] getShips() {
- //
- // First we have to put just the Ships into a vector, then we can put
- // them into an array of exactly the right length.
- //
- Ship[] arrayOfShips;
- Vector vectorOfShips = new Vector();
- Enumeration elements = table.elements();
- while (elements.hasMoreElements()) {
- Object object = elements.nextElement();
- if (object instanceof Ship) {
- vectorOfShips.addElement(object);
- }
- }
-
- arrayOfShips = new Ship[(vectorOfShips.size())];
- vectorOfShips.copyInto(arrayOfShips);
- return arrayOfShips;
- }
-
- Hashtable getTable() { return table; }
-
- //
- // The protocol for clockTick is that it automatically cascades.
- //
- void clockTick() {
- Enumeration elements = table.elements();
- while (elements.hasMoreElements()) {
- ((SpaceObject)elements.nextElement()).clockTick();
- }
- }
-}
-
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-
-RegistrySynchronization.java
-Part of the Spacewar system.
-
-*/
-
-package spacewar;
-
-import coordination.Coordinator;
-
-
-/**
- * This aspect ensures synchronized access to methods of the Registry in
- * the presence of several threads.
- *
- * It uses the Coordinator class, from the AspectJ coordination library.
- *
- * It uses a per-Registry coordination scheme, so there is one instance of
- * this class for each instance of the Registry class. When this class is
- * constructed, it registers appropriate mutexes and selfexes using the
- * behavior inherited from Coordinator.
- *
- * The mutating methods (register and unregister) should be self-exclusive.
- * Each reader method should be mutually exclusive with the mutating
- * methods. But the readers can run concurrently. */
-aspect RegistrySynchronization extends Coordinator perthis(this(Registry)) {
-
- protected pointcut synchronizationPoint():
- call(void Registry.register(..)) ||
- call(void Registry.unregister(..)) ||
- call(SpaceObject[] Registry.getObjects(..)) ||
- call(Ship[] Registry.getShips(..));
-
- public RegistrySynchronization() {
- addSelfex("register");
- addSelfex("unregister");
-
- addMutex(new String[] {"register", "unregister", "getObjects"});
- addMutex(new String[] {"register", "unregister", "getShips"});
- }
-
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-
-Robot.java
-Part of the Spacewar system.
-
-*/
-
-package spacewar;
-
-import java.util.Random;
-
-/**
- * Robot is an automatic pilot that now has quite a bit of intelligence.
- * So, beware !
- */
-class Robot extends Pilot implements Runnable {
-
- private static final int FIRE_INTERVAL = 60;
- private static final int REBIRTH_DELAY = 900;
-
- private final Random random = new Random();
-
- private Thread runner;
- private boolean runnable = true;
-
- Robot(Game theGame, int number) {
- super(theGame, number);
- }
-
- void start() {
- if (runner == null) {
- runner = new Thread(this);
- runner.start();
- }
- }
-
- void destroy() {
- if (runner != null) {
- runnable = false;
- runner = null;
- }
- }
-
-
- // A Robot tracks User-controlled ships and fires at them
- public void run() {
- Ship target = null;
-
- while(runnable) {
- // find target ship
- do {
- Ship[] potentials = getGame().getRegistry().getShips();
- if(potentials.length != 0)
- target = potentials[Math.abs(random.nextInt() % potentials.length)];
- sleepForABit(25);
- } while (target == ship);
- // main loop
- int currentRotation = Ship.STOP;
- int time;
- boolean currentlyAccelerating = false;
- double dx, dy, angleA, angleB, theta, dtheta, d,
- targetVel, a, b, c, targetXVel, targetYVel;
-
- while(true) {
- sleepForABit(FIRE_INTERVAL);
-
- // if my ship is destroyed, give me a new one
- if (!ship.isAlive()) {
- sleepForABit(REBIRTH_DELAY);
- getGame().newShip(this);
- }
-
- // find direction and distance from target to me
- dx = ship.getXPos() - target.getXPos();
- if (dx < - getGame().getWidth() / 2)
- dx += getGame().getWidth();
- if (dx > getGame().getWidth() / 2)
- dx -= getGame().getWidth();
- dy = ship.getYPos() - target.getYPos();
- if (dy < - getGame().getHeight() / 2)
- dy += getGame().getHeight();
- if (dy > getGame().getHeight() / 2)
- dy -= getGame().getHeight();
- d = Math.sqrt(dx * dx + dy * dy);
- angleA = Math.atan(dy / dx);
- if (dx < 0)
- angleA += Math.PI;
-
- // find relative velocity and trajectory of target
- targetXVel = target.getXVel() - ship.getXVel();
- targetYVel = target.getYVel() - ship.getYVel();
- targetVel = Math.sqrt(targetXVel * targetXVel +
- targetYVel * targetYVel);
- angleB = Math.atan(targetYVel / targetXVel);
- if (targetXVel < 0)
- angleB+=Math.PI;
-
- // find angle between line to target and taget's direction of travel
- theta = (angleA - angleB) % (2 * Math.PI);
- if (theta < -Math.PI)
- theta += 2 * Math.PI;
- if (theta > Math.PI)
- theta -= 2 * Math.PI;
-
- // calculate time to bullet impact using law of cosines
- a = targetVel * targetVel + Ship.BULLET_SPEED * Ship.BULLET_SPEED;
- b = d * targetVel * Math.cos(theta);
- c = - d * d;
- time = (int)((-b + Math.sqrt(b * b - 4 * a * c)) / 2 / a);
-
- // calculate angle and distance to bullet impact location
- dx = targetXVel * time - dx;
- dy = targetYVel * time - dy;
- theta = Math.atan(dy / dx);
- if(dx < 0)
- theta += Math.PI;
-
- // find desired change in rotation
- dtheta = (theta - ship.getOrientation()) % (2 * Math.PI);
- // find the shortest path to the desired orientation;
- if(dtheta < - Math.PI)
- dtheta += 2 * Math.PI;
- if(dtheta > Math.PI)
- dtheta -= 2 * Math.PI;
-
- // turn if nessecary
- if (dtheta > Ship.DEFAULT_ANGULAR_VELOCITY / 2) {
- if (currentRotation != Ship.CLOCKWISE)
- ship.rotate(currentRotation = Ship.CLOCKWISE);
- }
- else if (dtheta < -Ship.DEFAULT_ANGULAR_VELOCITY / 2) {
- if (currentRotation != Ship.COUNTERCLOCKWISE)
- ship.rotate(currentRotation = Ship.COUNTERCLOCKWISE);
- } // otherwise, fire, maybe even a burst
- else {
- if(currentRotation != Ship.STOP)
- ship.rotate(currentRotation = Ship.STOP);
- if (random.nextInt() % 40 == 0) {
- ship.fire();
- }
- }
-
- // randomly accelerate
- if (currentlyAccelerating && random.nextInt() % 2 == 0)
- ship.thrust(currentlyAccelerating = false);
- else {
- if (ship.getXVel() == 0)
- angleA = 0;
- else
- angleA = Math.atan(ship.getYVel() / ship.getXVel());
-
- if (ship.getXVel() < 0)
- angleA+=Math.PI;
- angleB = (angleA - ship.getOrientation()) % (2 * Math.PI);
- if (angleB < -Math.PI)
- angleB += 2 * Math.PI;
- if (angleB > Math.PI)
- angleB -= 2 * Math.PI;
- angleB = Math.abs(angleB);
-
- // angleB now represents the angle between the ship's
- // orientation and velocity vector. This will be used to
- // determine the probably that the ship will thrust to
- // prevent ships from accelerating too much in one direction
- if (random.nextInt() % (int)(12 * (Math.PI - angleB) + 1) == 0)
- ship.thrust(currentlyAccelerating = true);
- }
-
- // switch targets if current one has been destroyed
- if (target.getDamage() == 100)
- break;
-
- // randomly switch targets
- if (random.nextInt() % 4000 == 0)
- break;
- }
- }
- }
-
- void sleepForABit (int time) {
- try {
- runner.sleep(time);
- }
- catch (InterruptedException e) {}
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-
-SWFrame.java
-Part of the Spacewar system.
-
-*/
-
-package spacewar;
-
-import java.awt.Frame;
-import java.awt.Menu;
-import java.awt.MenuBar;
-import java.awt.MenuItem;
-import java.awt.MenuShortcut;
-import java.awt.Dimension;
-import java.awt.Insets;
-
-import java.awt.event.ActionListener;
-import java.awt.event.ActionEvent;
-
-class SWFrame extends Frame implements ActionListener {
- private Game game;
- private Display display;
- private Menu menu;
-
- Game getGame() { return game; }
- Display getDisplay() { return display; }
- Menu getMenu() { return menu; }
-
- SWFrame(Game theGame, Display d) {
- super("Space War!");
-
- game = theGame;
-
- display = d;
- add(display);
-
- // create menu
- menu = new Menu("Game");
- MenuItem item1 = new MenuItem("Add Robot", new MenuShortcut('a'));
- MenuItem item2 = new MenuItem("Reset Ships", new MenuShortcut('r'));
- MenuItem item3 = new MenuItem("Quit", new MenuShortcut('q'));
- item1.setActionCommand("Add Robot");
- item2.setActionCommand("Reset Ships");
- item3.setActionCommand("Quit");
- menu.add(item1);
- menu.add(item2);
- menu.add(item3);
- menu.addActionListener(this);
-
- setMenuBar(new MenuBar());
- getMenuBar().add(menu);
-
- Dimension screenSize = new Dimension(500, 500);
- setSize(screenSize);
- setVisible(true);
- toFront();
-
- Insets inset = getInsets();
- int displayWidth = screenSize.width - inset.left - inset.right;
- int displayHeight = screenSize.height - inset.top - inset.bottom;
- display.setSize(displayWidth, displayHeight);
- }
-
- public void actionPerformed(ActionEvent e) {
- String s = e.getActionCommand();
- if (s.equals("Add Robot")) {
- getGame().addRobot();
- }
- else if (s.equals("Reset Ships")) {
- getGame().resetShips();
- }
- else if (s.equals("Quit")) {
- getGame().quit();
- }
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-Ship.java
-Part of the Spacewar system.
-
-*/
-
-package spacewar;
-
-class Ship extends SpaceObject {
-
- pointcut helmCommandsCut(Ship ship):
- target(ship) && ( call(void rotate(int)) ||
- call(void thrust(boolean)) ||
- call(void fire()) );
-
-
- /**
- * Energy and Damage are key values in the state of a ship. Energy is
- * basically about fuel, and damage is about how bad a shape we are in.
- *
- * The energy related values are:
- * <ul>
- * <li>MAX_ENERGY</li>
- * <li>BULLET_ENERGY</li>
- * <li>ACCELERATION_ENERGY_FACTOR</li>
- * <li>energy</li>
- * </ul>
- * The damage related values are:
- * <ul>
- * <li>MAX_DAMAGE</li>
- * <li>BULLET_DAMAGE</li>
- * <li>COLLISION_DAMAGE_FACTOR</li>
- * <li>damage</li>
- * </ul>
- * Finally, REPAIR_RATE is the rate at which energy is consumed to fix
- * damage.
- *
- */
- private static final int MAX_ENERGY = 100;
- private static final int BULLET_ENERGY= 2;
- private static final double ACCELERATION_COST_FACTOR = 0.05;
-
- //XXX was private
- static final int MAX_DAMAGE = 100;
- private static final int BULLET_DAMAGE = 15;
- private static final double COLLISION_DAMAGE_FACTOR = 0.1;
-
- private static final double REPAIR_RATE = 0.08;
-
-
- private static final int EXPLOSION_LENGTH = 10;
-
- static final int BULLET_SPEED = 10;
-
- static final int CLOCKWISE = 1;
- static final int STOP = 0;
- static final int COUNTERCLOCKWISE = (-1);
-
- static final double DEFAULT_ANGULAR_VELOCITY = 0.2;
- static final double DEFAULT_ACCELERATION = .4;
-
- static private final int SIZE = 30; //Can't be changed for now!!!
-
- private double energy; // range: 0 to MAX_ENERGY
- private double damage; // range: 0 to MAX_DAMAGE
- private double orientation; // in degrees
- private double angularVel; // in ???
- private double xAcc, yAcc, rAcc; //
- private int countdown; // remaining explosion time
-
- private Pilot pilot;
-
- Ship(Game theGame, double xPos, double yPos, double orientation) {
- super(theGame, xPos, yPos, 0, 0);
- xAcc = 0;
- yAcc = 0;
- this.orientation = orientation;
- angularVel = 0;
-
- energy = MAX_ENERGY;
- damage = 0;
- countdown = EXPLOSION_LENGTH;
- }
-
-
- int getSize() { return SIZE; }
-
- double getEnergy() { return energy; }
- double getDamage() { return damage; }
- double getOrientation() { return orientation; }
- double getRAcc() { return rAcc; }
-
- Pilot getPilot() { return pilot; }
- void setPilot (Pilot p) { pilot = p; }
-
- float getEnergyLevel() {
- return (float)energy / (float)MAX_ENERGY;
- }
- float getDamageLevel() {
- return (float)damage / (float)MAX_DAMAGE;
- }
-
- /** returns false if energy is out, otherwise decrements energy by amount
- * and returns true
- */
- boolean expendEnergy(double amount) {
- if (amount <= energy) {
- energy -= amount;
- return true;
- }
- else
- return false;
- }
-
- /** increments damage by amount and handles the destruction of a ship if
- * damage reaches MAX_DAMAGE.
- */
- void inflictDamage(double amount) {
- if (amount < 0) // shouldn't happen
- return;
- damage = Math.min(MAX_DAMAGE, damage + amount);
- if (damage == MAX_DAMAGE)
- setIsAlive(false);
- }
-
- /** repairs some damage
- */
- void repairDamage(double amount) {
- if (amount < 0) // shouldn't happen
- return;
- if (damage == 0)
- return;
- damage = Math.max(0, damage - amount);
- }
-
- public void clockTick() {
- if (! isAlive()) {
- //
- // If we aren't alive, but we are still in the registry, it means
- // we are exploding. countdown counts the length of the explosion.
- //
- if (--countdown == 0)
- die();
- }
- else {
- if (angularVel != 0) {
- orientation += angularVel;
- xAcc = rAcc * Math.cos(orientation);
- yAcc = rAcc * Math.sin(orientation);
- }
- setXVel(getXVel() + xAcc);
- setYVel(getYVel() + yAcc);
-
- //expend energy
- if (!expendEnergy(rAcc * ACCELERATION_COST_FACTOR))
- rAcc = xAcc = yAcc = 0;
-
- // fix damage
- if (energy > 10 && damage > REPAIR_RATE) {
- expendEnergy(REPAIR_RATE);
- repairDamage(REPAIR_RATE);
- }
- }
- super.clockTick();
- }
-
- /**
- * First check to make sure we have enough energy to accelerate. If
- * we do, then go ahead and do so. Acceleration is in the direction
- * we are already facing (i.e. orientation).
- */
- void setAcceleration(double acc) {
- if (acc * ACCELERATION_COST_FACTOR <= energy) {
- rAcc = acc;
- xAcc = rAcc * Math.cos(orientation);
- yAcc = rAcc * Math.sin(orientation);
- }
- }
-
- /**
- * First check to make sure we have enough energy to rotate. If
- * we do, then go ahead and do so.
- */
- void setAngularVelocity(double omega) {
- // changing direction of rotation takes energy
- if (!expendEnergy(Math.abs(omega - angularVel) / 2))
- return;
- //sets amount of degree rotation per clock tick, in radians;
- //clockwise is positive
- angularVel = omega;
- }
-
- /** affect rotation thrusters. Direction can be one of {@link
- * #CLOCKWISE}, {@link #COUNTERCLOCKWISE}, or zero for turning off
- * the thrusters.
- */
- void rotate(int direction) {
- setAngularVelocity(
- direction == CLOCKWISE ? DEFAULT_ANGULAR_VELOCITY :
- direction == COUNTERCLOCKWISE ? -DEFAULT_ANGULAR_VELOCITY :
- 0);
- }
-
- /** turn on acceleration */
- void thrust(boolean onOff) {
- setAcceleration(onOff ? DEFAULT_ACCELERATION : 0);
- }
-
- /** create a bullet and fire it */
- void fire() {
- // firing a shot takes energy
- if (!expendEnergy(BULLET_ENERGY))
- return;
-
- //create a bullet object so it doesn't hit the ship that's firing it
- double xV = getXVel() + BULLET_SPEED * (Math.cos(orientation));
- double yV = getYVel() + BULLET_SPEED * (Math.sin(orientation));
-
- // create the actual bullet
- new Bullet(
- getGame(),
- (getXPos() + ((getSize()/2 + 2) * (Math.cos(orientation))) + xV),
- (getYPos() + ((getSize()/2 + 2) * (Math.sin(orientation))) + yV),
- xV,
- yV);
- }
-
-
- void handleCollision(SpaceObject obj) {
- if (obj instanceof Ship) {
- // should never be called. ship - ship collisions are handled in
- // Ship.bounce(Ship shipA, Ship shipB)
- }
- else if (obj instanceof Bullet) {
- inflictDamage(BULLET_DAMAGE);
- }
- else if (obj instanceof EnergyPacket) {
- double packetEnergy = ((EnergyPacket)obj).getEnergy();
- energy = Math.max(0, Math.min(energy + packetEnergy, MAX_ENERGY));
- }
- else {
- System.err.println("collision with UFO!");
- }
- }
-
- static void bounce(Ship shipA, Ship shipB) {
- double dx, dy, denominator,
- xAccA, yAccA, xAccB, yAccB, damage,
- xComp, yComp, dvx, dvy;
-
- dx = Math.abs(shipA.getXPos() - shipB.getXPos());
- dy = Math.abs(shipA.getYPos() - shipB.getYPos());
- denominator = Math.sqrt(dx * dx + dy * dy);
- xComp = dx / denominator;
- yComp = dy / denominator;
- xAccA = shipB.getXVel() * xComp + shipA.getXVel() * (1 - xComp) -
- shipA.getXVel();
- yAccA = shipB.getYVel() * yComp + shipA.getYVel() * (1 - yComp) -
- shipA.getYVel();
- xAccB = shipA.getXVel() * xComp + shipB.getXVel() * (1 - xComp) -
- shipB.getXVel();
- yAccB = shipA.getYVel() * yComp + shipB.getYVel() * (1 - yComp) -
- shipB.getYVel();
- shipA.accelerate(xAccA, yAccA);
- shipB.accelerate(xAccB, yAccB);
- dvx = shipA.getXVel() - shipB.getXVel();
- dvy = shipA.getYVel() - shipA.getYVel();
- damage = COLLISION_DAMAGE_FACTOR * (dvx * dvx + dvy * dvy);
- shipA.inflictDamage(damage);
- shipB.inflictDamage(damage);
-
- // !!!
- // !!! poopers! this does a local time warp. this has to be a
- // !!! violation of the clockTick protocol
- // !!!
- while (Game.isCollision(shipA, shipB)) {
- shipA.clockTick();
- shipB.clockTick();
- }
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-
-SpaceObject.java
-Part of the Spacewar system.
-
-*/
-
-package spacewar;
-
-
-/**
- * SpaceObjects are objects that float around in space. They support the
- * minimal SpaceObject protocol, having to do with position, velocity,
- * size and liveness. They are constructed with game, position, velocity
- * and size. When constructed, a spaceobject adds itself to the registry.
- *
- * When it dies, a spaceobject removes itself from the registry. But note
- * that it doesn't decide when to die, subclasses do that.
- *
- * The display aspects actually draw the space object on the screen and say
- * how much space it takes up there.
- */
-abstract class SpaceObject {
-
- private Game game;
- private double xPos, yPos, oldXPos, oldYPos, xVel, yVel;
- private boolean alive;
-
- SpaceObject (Game theGame, double xP, double yP, double xV, double yV) {
- game = theGame;
- xPos = xP;
- yPos = yP;
- oldXPos = xP;
- oldYPos = yP;
- xVel = xV;
- yVel = yV;
-
- alive = true;
- getGame().getRegistry().register(this);
- }
-
- Game getGame() { return game; }
-
- double getXPos() { return xPos; }
- double getYPos() { return yPos; }
-
- double getOldXPos() { return oldXPos; }
- double getOldYPos() { return oldYPos; }
-
- double getXVel() { return xVel; }
- double getYVel() { return yVel; }
-
- void setXVel (double n) { xVel = n; }
- void setYVel (double n) { yVel = n; }
-
- boolean isAlive() { return alive; }
- void setIsAlive(boolean n) { alive = n; }
-
-
- /**
- * Move 1 unit of time's worth of distance. I.e. increment xPos by xVel
- * and yPos by yVel. If we move off an edge of the screen move us back
- * in the opposite edge.
- */
- void clockTick() {
- oldXPos = xPos;
- oldYPos = yPos;
- xPos = (xPos + xVel) % getGame().getWidth();
- if(xPos < 0)
- xPos += getGame().getWidth();
- yPos = (yPos + yVel) % getGame().getHeight();
- if(yPos < 0)
- yPos += getGame().getHeight();
- }
-
- void accelerate(double dXVel, double dYVel) {
- xVel += dXVel;
- yVel += dYVel;
- }
-
- void die() {
- getGame().getRegistry().unregister(this);
- }
-
- abstract int getSize();
-
- /** resolve the effects of colliding with a space object.
- * @param obj the space object that this object is colliding with.
- */
- abstract void handleCollision(SpaceObject obj);
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-
-Timer.java
-Part of the Spacewar system.
-
-*/
-
-package spacewar;
-
-
-class Timer extends Thread {
-
- private final static int TICK_PERIOD = 40; // time between ticks in millis
-
- private Game game;
-
- Game getGame() { return game; }
-
- Timer (Game theGame) {
- super("Timer");
- game = theGame;
- }
-
- public void run() {
- long t1, tdiff;
- while (true) {
- t1 = System.currentTimeMillis();
- getGame().clockTick();
- tdiff = System.currentTimeMillis() - t1;
- if (tdiff < TICK_PERIOD) {
- try {
- sleep (Math.max(0 , TICK_PERIOD - tdiff));
- }
- catch (InterruptedException e) { }
- }
- }
- }
-}
+++ /dev/null
-@demo.lst
-Debug.java
+++ /dev/null
-@../coordination/lib.lst
-Bullet.java
-EnergyPacket.java
-EnergyPacketProducer.java
-Game.java
-GameSynchronization.java
-Pilot.java
-Registry.java
-RegistrySynchronization.java
-Robot.java
-Ship.java
-EnsureShipIsAlive.java
-SpaceObject.java
-Timer.java
-SWFrame.java
-Display.java
-Display1.java
-Display2.java
-Player.java
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-package telecom;
-
-public abstract class AbstractSimulation {
-
- public static AbstractSimulation simulation;
-
- /**
- * Creates objects and puts them to work.
- */
- public void run() {
- Customer jim = new Customer("Jim", 650);
- Customer mik = new Customer("Mik", 650);
- Customer crista = new Customer("Crista", 415);
-
- say("jim calls mik...");
- Call c1 = jim.call(mik);
- wait(1.0);
- say("mik accepts...");
- mik.pickup(c1);
- wait(2.0);
- say("jim hangs up...");
- jim.hangup(c1);
- report(jim);
- report(mik);
- report(crista);
-
- say("mik calls crista...");
- Call c2 = mik.call(crista);
- say("crista accepts...");
- crista.pickup(c2);
- wait(1.5);
- say("crista hangs up...");
- crista.hangup(c2);
- report(jim);
- report(mik);
- report(crista);
- }
-
- /**
- * Print a report of the connection time for customer
- */
- abstract protected void report(Customer c);
-
- /**
- * Wait 0.1 seconds per "second" for simulation
- */
- protected static void wait(double seconds) {
- Object dummy = new Object();
- synchronized (dummy) {
- //XXX cheat and only wait 0.1 seconds per second
- try {dummy.wait((long)(seconds*100)); }
- catch (Exception e) {}
- }
- }
-
- /**
- * Put a message on standard output
- */
- protected static void say(String s){
- System.out.println(s);
- }
-
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-package telecom;
-
-/**
- * This simulation subclass implements AbstractSimulation.run(..)
- * with a test script for the telecom system with only the
- * basic objects.
- */
-public class BasicSimulation extends AbstractSimulation {
-
- public static void main(String[] args){
- simulation = new BasicSimulation();
- simulation.run();
- }
-
- protected void report(Customer c) { }
-
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package telecom;
-/**
- * The Billing aspect deals with... billing.
- * How much money did each connection cost?
- * How much money did each call cost?
- * How much money is being debited to a customer?
- * This aspect can be used by other parts of the system. (not in this example)
- *
- * Billing can depend many things, such as timing, the type of the connection,
- * some special discounts the customer has, special features, etc. In here,
- * it depends only on timing and on the type of the connection.
- */
-public aspect Billing {
- // precedence required to get advice on endtiming in the right order
- declare precedence: Billing, Timing;
-
- public static final long LOCAL_RATE = 3;
- public static final long LONG_DISTANCE_RATE = 10;
-
- public Customer Connection.payer;
- public Customer getPayer(Connection conn) { return conn.payer; }
- /**
- * Caller pays for the call
- */
- after(Customer cust) returning (Connection conn):
- args(cust, ..) && call(Connection+.new(..)) {
- conn.payer = cust;
- }
-
- /**
- * Connections give the appropriate call rate
- */
- public abstract long Connection.callRate();
-
-
- public long LongDistance.callRate() { return LONG_DISTANCE_RATE; }
- public long Local.callRate() { return LOCAL_RATE; }
-
-
- /**
- * When timing stops, calculate and add the charge from the
- * connection time
- */
- after(Connection conn): Timing.endTiming(conn) {
- long time = Timing.aspectOf().getTimer(conn).getTime();
- long rate = conn.callRate();
- long cost = rate * time;
- getPayer(conn).addCharge(cost);
- }
-
-
- /**
- * Customers have a bill paying aspect with state
- */
- public long Customer.totalCharge = 0;
- public long getTotalCharge(Customer cust) { return cust.totalCharge; }
-
- public void Customer.addCharge(long charge){
- totalCharge += charge;
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-package telecom;
-
-/**
- * This simulation subclass implements AbstractSimulation.report(..)
- *
- */
-public class BillingSimulation extends AbstractSimulation {
-
- public static void main(String[] args){
- System.out.println("\n... Billing simulation 2 ...\n");
- simulation = new BillingSimulation();
- simulation.run();
- }
-
- /**
- * Print a report of the connection time and the bill for customer
- */
- protected void report(Customer c){
- Timing t = Timing.aspectOf();
- Billing b = Billing.aspectOf();
- System.out.println(c + " has been connected for "
- + t.getTotalConnectTime(c)
- + " seconds and has a bill of "
- + b.getTotalCharge(c));
- }
-}
-
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-package telecom;
-import java.util.Vector;
-import java.util.Enumeration;
-
-/**
- * A call supports the process of a customer trying to
- * connect to others.
- */
-public class Call {
-
- private Customer caller, receiver;
- private Vector connections = new Vector();
-
- /**
- * Create a new call connecting caller to receiver
- * with a new connection. This should really only be
- * called by Customer.call(..)
- */
- public Call(Customer caller, Customer receiver) {
- this.caller = caller;
- this.receiver = receiver;
- Connection c;
- if (receiver.localTo(caller)) {
- c = new Local(caller, receiver);
- } else {
- c = new LongDistance(caller, receiver);
- }
- connections.addElement(c);
- }
-
- /**
- * picking up a call completes the current connection
- * (this means that you shouldnt merge calls until
- * they are completed)
- */
- public void pickup() {
- Connection connection = (Connection)connections.lastElement();
- connection.complete();
- }
-
-
- /**
- * Is the call in a connected state?
- */
- public boolean isConnected(){
- return ((Connection)connections.lastElement()).getState()
- == Connection.COMPLETE;
- }
-
- /**
- * hanging up a call drops the connection
- */
- public void hangup(Customer c) {
- for(Enumeration e = connections.elements(); e.hasMoreElements();) {
- ((Connection)e.nextElement()).drop();
- }
- }
-
- /**
- * is Customer c one of the customers in this call?
- */
- public boolean includes(Customer c){
- boolean result = false;
- for(Enumeration e = connections.elements(); e.hasMoreElements();) {
- result = result || ((Connection)e.nextElement()).connects(c);
- }
- return result;
- }
-
- /**
- * Merge all connections from call 'other' into 'this'
- */
- public void merge(Call other){
- for(Enumeration e = other.connections.elements(); e.hasMoreElements();){
- Connection conn = (Connection)e.nextElement();
- other.connections.removeElement(conn);
- connections.addElement(conn);
- }
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-package telecom;
-
-/**
- * Connections are circuits between customers
- * There are two kinds: local and long distance
- * see subclasses at the end of this file.
- */
-public abstract class Connection {
-
- public static final int PENDING = 0;
- public static final int COMPLETE = 1;
- public static final int DROPPED = 2;
-
- Customer caller, receiver;
- private int state = PENDING;
-
- /**
- * Creatte a new Connection between a and b
- */
- Connection(Customer a, Customer b) {
- this.caller = a;
- this.receiver = b;
- }
-
- /**
- * what is the state of the connection?
- */
- public int getState(){
- return state;
- }
-
- /**
- * get the customer who initiated this connection
- */
- public Customer getCaller() { return caller; }
-
- /**
- * get the customer who received this connection
- */
- public Customer getReceiver() { return receiver; }
-
- /**
- * Called when a call is picked up. This means the b side has picked up
- * and the connection should now complete itself and start passing data.
- */
- void complete() {
- state = COMPLETE;
- System.out.println("connection completed");
- }
-
- /**
- * Called when the connection is dropped from a call. Is intended to
- * free up any resources the connection was consuming.
- */
- void drop() {
- state = DROPPED;
- System.out.println("connection dropped");
- }
-
- /**
- * Is customer c connected by this connection?
- */
- public boolean connects(Customer c){
- return (caller == c || receiver == c);
- }
-
-}
-
-
-
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-package telecom;
-import java.util.Vector;
-
-/**
- * Customers have a unique id (name in this case for didactic purposes
- * but it could be telephone number) and area code.
- * They also have protocol for managing calls: call, pickup, etc.
- */
-public class Customer {
-
- private String name;
- private int areacode;
- private Vector calls = new Vector();
-
- /**
- * unregister a call
- */
- protected void removeCall(Call c){
- calls.removeElement(c);
- }
-
- /**
- * register a call
- */
- protected void addCall(Call c){
- calls.addElement(c);
- }
-
- /**
- * Make a new customer with given name
- */
- public Customer(String name, int areacode) {
- this.name = name;
- this.areacode = areacode;
- }
-
- /**
- * String rendition of customer
- */
- public String toString() {
- return name + "(" + areacode + ")";
- }
-
- /**
- * what area is the customer in?
- */
- public int getAreacode(){
- return areacode;
- }
-
- /**
- * Is the other customer in the same area?
- */
- public boolean localTo(Customer other){
- return areacode == other.areacode;
- }
-
- /**
- * Make a new call to receiver
- */
- public Call call(Customer receiver) {
- Call call = new Call(this, receiver);
- addCall(call);
- return call;
- }
-
- /**
- * pick up a call
- */
- public void pickup(Call call) {
- call.pickup();
- addCall(call);
- }
-
- /**
- * hang up a call
- */
- public void hangup(Call call) {
- call.hangup(this);
- removeCall(call);
- }
-
- /**
- * Merge a pair of calls -- conference them
- * PRE: call1.includes(this)
- * call2.includes(this)
- * call1.connected()
- * call2.connected()
- * POST: call1 includes all customers connected by call1@pre and call2@pre
- */
- public void merge(Call call1, Call call2){
- call1.merge(call2);
- removeCall(call2);
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-package telecom;
-
-public class Local extends Connection {
- Local(Customer a, Customer b) {
- super(a, b);
- System.out.println("[new local connection from " +
- a + " to " + b + "]");
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-package telecom;
-
-public class LongDistance extends Connection {
- LongDistance(Customer a, Customer b) {
- super(a, b);
- System.out.println("[new long distance connection from " +
- a + " to " + b + "]");
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-package telecom;
-
-
-/**
- * Simple timer machine used to record elapsed time
- */
-public class Timer {
- public long startTime, stopTime;
-
- /**
- * set the start time
- */
- public void start() {
- startTime = System.currentTimeMillis();
- stopTime = startTime;
- }
-
- /**
- * set the end time
- */
- public void stop() {
- stopTime = System.currentTimeMillis();
- }
-
- /**
- * set how much time passed between last start and stop?
- */
- public long getTime() {
- return stopTime - startTime;
- }
-}
-
-
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-package telecom;
-
-public aspect TimerLog {
-
- after(Timer t): target(t) && call(* Timer.start()) {
- System.err.println("Timer started: " + t.startTime);
- }
-
- after(Timer t): target(t) && call(* Timer.stop()) {
- System.err.println("Timer stopped: " + t.stopTime);
- }
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package telecom;
-
-/**
- * The Timing aspect is concerned with the duration
- * of connections and with customer's cumulative
- * connection time.
- */
-public aspect Timing {
-
- /**
- * Every Customer has a total connection time
- */
- public long Customer.totalConnectTime = 0;
-
- public long getTotalConnectTime(Customer cust) {
- return cust.totalConnectTime;
- }
- /**
- * Every connection has a timer
- */
- private Timer Connection.timer = new Timer();
- public Timer getTimer(Connection conn) { return conn.timer; }
-
- /**
- * Start the timer when call completed
- */
- after (Connection c): target(c) && call(void Connection.complete()) {
- getTimer(c).start();
- }
-
- /**
- * When to stop the timer
- */
- pointcut endTiming(Connection c): target(c) &&
- call(void Connection.drop());
-
- /**
- * Stop the timer when call dropped and update the involved parties
- */
- after(Connection c): endTiming(c) {
- getTimer(c).stop();
- c.getCaller().totalConnectTime += getTimer(c).getTime();
- c.getReceiver().totalConnectTime += getTimer(c).getTime();
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-package telecom;
-
-/**
- * This simulation subclass implements AbstractSimulation.report(..)
- *
- */
-public class TimingSimulation extends AbstractSimulation {
-
- public static void main(String[] args){
- System.out.println("\n... Timing simulation 2 ...\n");
- simulation = new TimingSimulation();
- simulation.run();
- }
-
- /**
- * Print a report of the connection time for customer
- */
- protected void report(Customer c){
- Timing t = Timing.aspectOf();
- System.out.println(c + " spent " + t.getTotalConnectTime(c));
- }
-
-}
+++ /dev/null
-AbstractSimulation.java
-BasicSimulation.java
-Call.java
-Connection.java
-Local.java
-LongDistance.java
-Customer.java
+++ /dev/null
-AbstractSimulation.java
-BillingSimulation.java
-Call.java
-Connection.java
-Local.java
-LongDistance.java
-Customer.java
-Timer.java
-Billing.java
-Timing.java
+++ /dev/null
-AbstractSimulation.java
-TimingSimulation.java
-Call.java
-Connection.java
-Local.java
-LongDistance.java
-Customer.java
-Timer.java
-TimerLog.java
-Timing.java
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-*/
-package tjp;
-
-public class Demo {
- static Demo d;
-
- public static void main(String[] args){
- new Demo().go();
- }
-
- void go(){
- d = new Demo();
- d.foo(1,d);
- System.out.println(d.bar(new Integer(3)));
- }
-
- void foo(int i, Object o){
- System.out.println("Demo.foo(" + i + ", " + o + ")\n");
- }
-
- String bar (Integer j){
- System.out.println("Demo.bar(" + j + ")\n");
- return "Demo.bar(" + j + ")";
- }
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package tjp;
-
-import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.reflect.CodeSignature;
-
-aspect GetInfo {
-
- static final void println(String s){ System.out.println(s); }
-
- pointcut goCut(): cflow(this(Demo) && execution(void go()));
-
- pointcut demoExecs(): within(Demo) && execution(* *(..));
-
- Object around(): demoExecs() && !execution(* go()) && goCut() {
- println("Intercepted message: " +
- thisJoinPointStaticPart.getSignature().getName());
- println("in class: " +
- thisJoinPointStaticPart.getSignature().getDeclaringType().getName());
- printParameters(thisJoinPoint);
- println("Running original method: \n" );
- Object result = proceed();
- println(" result: " + result );
- return result;
- }
-
- static private void printParameters(JoinPoint jp) {
- println("Arguments: " );
- Object[] args = jp.getArgs();
- String[] names = ((CodeSignature)jp.getSignature()).getParameterNames();
- Class[] types = ((CodeSignature)jp.getSignature()).getParameterTypes();
- for (int i = 0; i < args.length; i++) {
- println(" " + i + ". " + names[i] +
- " : " + types[i].getName() +
- " = " + args[i]);
- }
- }
-}
+++ /dev/null
-Demo.java
-GetInfo.java
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-
-package tracing;
-
-/**
- *
- * Circle is a 2D shape. It extends the TwoDShape class with the radius
- * variable, and it implements TwoDShape's abstract methods for
- * correctly computing a circle's area and distance.
- *
- */
-public class Circle extends TwoDShape {
- protected double r; // radius
-
- /*
- * All sorts of constructors
- */
- public Circle(double x, double y, double r) {
- super(x, y); this.r = r;
- }
-
- public Circle(double x, double y) {
- this(x, y, 1.0);
- }
-
- public Circle(double r) {
- this(0.0, 0.0, r);
- }
-
- public Circle() {
- this(0.0, 0.0, 1.0);
- }
-
- /**
- * Returns the perimeter of this circle
- */
- public double perimeter() {
- return 2 * Math.PI * r;
- }
-
- /**
- * Returns the area of this circle
- */
- public double area() {
- return Math.PI * r*r;
- }
-
- /**
- * This method overrides the one in the superclass. It adds some
- * circle-specific information.
- */
- public String toString() {
- return ("Circle radius = " + String.valueOf(r) + super.toString());
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-
-package tracing;
-
-/**
- *
- * A main function for testing 2D shapes.
- *
- */
-public class ExampleMain {
- public static void main(String[] args) {
- Circle c1 = new Circle(3.0, 3.0, 2.0);
- Circle c2 = new Circle(4.0);
-
- Square s1 = new Square(1.0, 2.0);
-
- System.out.println("c1.perimeter() = " + c1.perimeter());
- System.out.println("c1.area() = " + c1.area());
-
- System.out.println("s1.perimeter() = " + s1.perimeter());
- System.out.println("s1.area() = " + s1.area());
-
- System.out.println("c2.distance(c1) = " + c2.distance(c1));
- System.out.println("s1.distance(c1) = " + s1.distance(c1));
-
- System.out.println("s1.toString(): " + s1.toString());
- }
-}
+++ /dev/null
-\r
-This directory contains several examples of tracing aspects,\r
-including a reusable tracing library and examples of \r
-using that library.\r
-\r
-A lesson in the AspectJ Primer explains all of this code.\r
-\r
-To work with these (or any other examples), first be sure .../examples\r
-is on your classpath, where ... is where you have installed AspectJ.\r
-\r
-\r
---To compile and run the example without tracing--\r
-\r
- ajc @.../examples/tracing/notrace.lst\r
-\r
- java tracing.ExampleMain\r
-\r
-\r
---To compile and run the example with tracing version<N>--\r
-\r
- ajc @.../examples/tracing/tracev<N>.lst\r
-\r
- java tracing.version<N>.TraceMyClasses\r
-\r
-where <N> is 1, 2, 3 or 4\r
-\r
---To use the tracing.lib.AbstractTrace aspect--\r
-\r
- Make sure .../examples is in your classpath.\r
-\r
- In order to use this aspect, please read the documentation under\r
- tracing/doc\r
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-
-package tracing;
-
-/**
- *
- * Square is a 2D shape. It extends the TwoDShape class with the side
- * variable, and it implements TwoDShape's abstract methods for
- * correctly computing a square's area and distance.
- *
- */
-public class Square extends TwoDShape {
- protected double s; // side
-
- /*
- * All sorts of constructors
- */
- public Square(double x, double y, double s) {
- super(x, y); this.s = s;
- }
-
- public Square(double x, double y) {
- this(x, y, 1.0);
- }
-
- public Square(double s) {
- this(0.0, 0.0, s);
- }
-
- public Square() {
- this(0.0, 0.0, 1.0);
- }
-
- /**
- * Returns the perimeter of this square
- */
- public double perimeter() {
- return 4 * s;
- }
-
- /**
- * Returns the area of this square
- */
- public double area() {
- return s*s;
- }
-
- /**
- * This method overrides the one in the superclass. It adds some
- * circle-specific information.
- */
- public String toString() {
- return ("Square side = " + String.valueOf(s) + super.toString());
- }
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package tracing;
-
-/**
- * TwoDShape is an abstract class that defines generic functionality
- * for 2D shapes.
- */
-public abstract class TwoDShape {
- /**
- * Coordinates of the center of the shape.
- */
- protected double x, y;
-
- protected TwoDShape(double x, double y) {
- this.x = x; this.y = y;
- }
-
- /**
- * Returns the x coordinate of the shape.
- */
- public double getX() { return x; }
-
- /**
- * Returns the y coordinate of the shape.
- */
- public double getY() { return y; }
-
- /**
- * Returns the distance between this shape and the shape given as
- * parameter.
- */
- public double distance(TwoDShape s) {
- double dx = Math.abs(s.getX() - x);
- double dy = Math.abs(s.getY() - y);
- return Math.sqrt(dx*dx + dy*dy);
- }
-
- /**
- * Returns the perimeter of this shape. Must be defined in
- * subclasses.
- */
- public abstract double perimeter();
-
- /**
- * Returns the area of this shape. Must be defined in
- * subclasses.
- */
- public abstract double area();
-
- /**
- * Returns a string representation of 2D shapes -- simply its
- * coordinates.
- */
- public String toString() {
- return (" @ (" + String.valueOf(x) + ", " + String.valueOf(y) + ") ");
- }
-}
-
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-
-package tracing.lib;
-
-import java.io.PrintStream;
-import org.aspectj.lang.JoinPoint;
-
-
-/**
- * This class provides support for printing trace messages into a stream.
- * The trace messages consist of the class name, method name (if method)
- * and the list of parameter types.<P>
- * The class is thread-safe. Different threads may use different output streams
- * by simply calling the method initStream(myStream).<P>
- * This class should be extended.
- * It defines 3 abstract crosscuts for injecting the tracing functionality
- * into any constructors and methods of any application classes.<P>
- *
- * One example of using this class might be
- * <PRE>
- * import tracing.lib.AbstractTrace;
- * aspect TraceMyClasses extends AbstractTrace of eachJVM() {
- * pointcut classes(): within(TwoDShape) | within(Circle) | within(Square);
- * pointcut constructors(): executions(new(..));
- * pointcut methods(): executions(!abstract * *(..))
- * }
- * </PRE>
- * (Make sure .../aspectj/examples is in your classpath)
- */
-public abstract aspect AbstractTrace {
-
- /**
- * Application classes - left unspecified.
- * Subclasses should concretize this crosscut with class names.
- */
- abstract pointcut classes();
- /**
- * Constructors - left unspecified.
- * Subclasses should concretize this crosscut with constructors.
- */
- abstract pointcut constructors();
- /**
- * Methods - left unspecified.
- * Subclasses should concretize this crosscut with method names.
- */
- abstract pointcut methods();
-
- before(): classes() && constructors() {
- doTraceEntry(thisJoinPoint, true);
- }
- after(): classes() && constructors() {
- doTraceExit(thisJoinPoint, true);
- }
-
- before(): classes() && methods() {
- doTraceEntry(thisJoinPoint, false);
- }
- after(): classes() && methods() {
- doTraceExit(thisJoinPoint, false);
- }
-
- /*
- * From here on, it's an ordinary class implementation.
- * The static state is thread-safe by using ThreadLocal variables.
- */
-
- /**
- * This method initializes this thread's trace output stream.
- * By default, the output stream is System.err, and it is the same for
- * all threads. In multithreaded applications, you may want to define
- * different output streams for the different threads. For doing it,
- * simply call this method in the beginning of each thread's main loop,
- * giving it different output streams.
- */
- public void initStream(PrintStream _stream) {
- setStream(_stream);
- }
-
-
- private ThreadLocal stream = new ThreadLocal() {
- protected Object initialValue() {
- return System.err;
- }
- };
- private ThreadLocal callDepth = new ThreadLocal() {
- protected Object initialValue() {
- return new Integer(0);
- }
- };
-
- private PrintStream getStream() {
- return (PrintStream)stream.get();
- }
- private void setStream(PrintStream s) {
- stream.set(s);
- }
- private int getCallDepth() {
- return ((Integer)(callDepth.get())).intValue();
- }
- private void setCallDepth(int n) {
- callDepth.set(new Integer(n));
- }
-
- private void doTraceEntry (JoinPoint jp, boolean isConstructor) {
- setCallDepth(getCallDepth() + 1);
- printEntering(jp, isConstructor);
- }
-
- private void doTraceExit (JoinPoint jp, boolean isConstructor) {
- printExiting(jp, isConstructor);
- setCallDepth(getCallDepth() - 1);
- }
-
- private void printEntering (JoinPoint jp, boolean isConstructor) {
- printIndent();
- getStream().print("--> ");
- getStream().print(jp);
- // printParameterTypes(jp);
- getStream().println();
- }
-
- private void printExiting (JoinPoint jp, boolean isConstructor) {
- printIndent();
- getStream().print("<-- ");
- getStream().print(jp);
- // printParameterTypes(jp);
- getStream().println();
- }
-
-// private void printParameterTypes(JoinPoint jp) {
-// Class[] ptypes = jp.parameterTypes;
-
-// getStream().print("(");
-// for (int i = 0; i < ptypes.length; i++) {
-// getStream().print(ptypes[i].getName());
-// if (i < ptypes.length - 1) getStream().print(", ");
-// }
-// getStream().print(")");
-// }
-
- private void printIndent() {
- for (int i = 0; i < getCallDepth(); i++)
- getStream().print(" ");
- }
-
- /**
- * This method is not being used.
- * It's being included solely for illustrating how to access and use
- * the information in JoinPoint.
- * If you want, you can replace the calls to printParameterTypes (above)
- * by calls to this method.
- */
-// private void printParameters(JoinPoint jp) {
-// Class[] ptypes = jp.parameterTypes;
-// String[] pnames = jp.parameterNames;
-// Object[] params = jp.parameters;
-
-// getStream().print("(");
-// for (int i = 0; i < ptypes.length; i++) {
-// getStream().print(ptypes[i].getName() + " " +
-// pnames[i] + "=" +
-// params[i]);
-// if (i < ptypes.length - 1) getStream().print(", ");
-// }
-// getStream().print(")");
-// }
-
-}
-
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-
-package tracing.lib;
-
-import tracing.TwoDShape;
-import tracing.Circle;
-import tracing.Square;
-import tracing.ExampleMain;
-
-import java.io.FileOutputStream;
-import java.io.PrintStream;
-import java.io.FileNotFoundException;
-
-aspect TraceMyClasses extends AbstractTrace {
- /**
- * The application classes
- */
- pointcut classes(): within(TwoDShape) || within(Circle) || within(Square);
- /**
- * The constructors in those classes - but only the ones with 3
- * arguments.
- */
- pointcut constructors(): execution(new(double, double, double));
- /**
- * This specifies all the message executions.
- */
- pointcut methods(): execution(* *(..));
-
- /**
- * A main function for testing the trace aspect.
- */
- public static void main(String[] _args) {
- final String[] args = _args;
- new Thread() {
- public void run() {
- TraceMyClasses.aspectOf().initStream(System.err);
- ExampleMain.main(args);
- }
- }.start();
-
- new Thread() {
- public void run() {
- try {
- TraceMyClasses.aspectOf().initStream(new PrintStream(new FileOutputStream("AJTRACETEST")));
- }
- catch (FileNotFoundException e) {}
- ExampleMain.main(args);
- }
- }.start();
- }
-}
+++ /dev/null
-TwoDShape.java
-Circle.java
-Square.java
-ExampleMain.java
+++ /dev/null
-TwoDShape.java
-Circle.java
-Square.java
-ExampleMain.java
-lib/AbstractTrace.java
-lib/TraceMyClasses.java
+++ /dev/null
-TwoDShape.java
-Circle.java
-Square.java
-ExampleMain.java
-version1/Trace.java
-version1/TraceMyClasses.java
+++ /dev/null
-TwoDShape.java
-Circle.java
-Square.java
-ExampleMain.java
-version2/Trace.java
-version2/TraceMyClasses.java
+++ /dev/null
-TwoDShape.java
-Circle.java
-Square.java
-ExampleMain.java
-version3/Trace.java
-version3/TraceMyClasses.java
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package tracing.version1;
-
-import java.io.PrintStream;
-
-/**
- *
- * This class provides some basic functionality for printing trace messages
- * into a stream.
- *
- */
-public class Trace {
- /**
- * There are 3 trace levels (values of TRACELEVEL):
- * 0 - No messages are printed
- * 1 - Trace messages are printed, but there is no indentation
- * according to the call stack
- * 2 - Trace messages are printed, and they are indented
- * according to the call stack
- */
- public static int TRACELEVEL = 0;
- protected static PrintStream stream = null;
- protected static int callDepth = 0;
-
- /**
- * Initialization.
- */
- public static void initStream(PrintStream s) {
- stream = s;
- }
-
- /**
- * Prints an "entering" message. It is intended to be called in the
- * beginning of the blocks to be traced.
- */
- public static void traceEntry(String str) {
- if (TRACELEVEL == 0) return;
- if (TRACELEVEL == 2) callDepth++;
- printEntering(str);
- }
-
- /**
- * Prints an "exiting" message. It is intended to be called in the
- * end of the blocks to be traced.
- */
- public static void traceExit(String str) {
- if (TRACELEVEL == 0) return;
- printExiting(str);
- if (TRACELEVEL == 2) callDepth--;
- }
-
- private static void printEntering(String str) {
- printIndent();
- stream.println("--> " + str);
- }
-
- private static void printExiting(String str) {
- printIndent();
- stream.println("<-- " + str);
- }
-
- private static void printIndent() {
- for (int i = 0; i < callDepth; i++)
- stream.print(" ");
- }
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package tracing.version1;
-
-/**
- *
- * This class connects the tracing functions in the Trace class with
- * the constructors and methods in the application classes.
- *
- */
-import tracing.TwoDShape;
-import tracing.Circle;
-import tracing.Square;
-import tracing.ExampleMain;
-
-aspect TraceMyClasses {
- /**
- * Application classes.
- */
- pointcut myClass(): within(TwoDShape) || within(Circle) || within(Square);
- /**
- * The constructors in those classes.
- */
- pointcut myConstructor(): myClass() && execution(new(..));
- /**
- * The methods of those classes.
- */
- pointcut myMethod(): myClass() && execution(* *(..));
-
- /**
- * Prints trace messages before and after executing constructors.
- */
- before (): myConstructor() {
- Trace.traceEntry("" + thisJoinPointStaticPart.getSignature());
- }
- after(): myConstructor() {
- Trace.traceExit("" + thisJoinPointStaticPart.getSignature());
- }
-
- /**
- * Prints trace messages before and after executing methods.
- */
- before (): myMethod() {
- Trace.traceEntry("" + thisJoinPointStaticPart.getSignature());
- }
- after(): myMethod() {
- Trace.traceExit("" + thisJoinPointStaticPart.getSignature());
- }
-
- /**
- * A main function for testing the trace aspect.
- */
- public static void main(String[] args) {
- Trace.TRACELEVEL = 2;
- Trace.initStream(System.err);
- ExampleMain.main(args);
- }
-}
-
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package tracing.version2;
-
-import java.io.PrintStream;
-
-/**
- *
- * This class provides support for printing trace messages into a stream.
- * Trace messages are printed before and after constructors and methods
- * are executed.
- * It defines one abstract crosscut for injecting that tracing functionality
- * into any application classes.
- * To use it, provide a subclass that concretizes the abstract crosscut.
- */
-abstract aspect Trace {
-
- /*
- * Functional part
- */
-
- /**
- * There are 3 trace levels (values of TRACELEVEL):
- * 0 - No messages are printed
- * 1 - Trace messages are printed, but there is no indentation
- * according to the call stack
- * 2 - Trace messages are printed, and they are indented
- * according to the call stack
- */
- public static int TRACELEVEL = 2;
- protected static PrintStream stream = System.err;
- protected static int callDepth = 0;
-
- /**
- * Initialization.
- */
- public static void initStream(PrintStream s) {
- stream = s;
- }
-
- protected static void traceEntry(String str) {
- if (TRACELEVEL == 0) return;
- if (TRACELEVEL == 2) callDepth++;
- printEntering(str);
- }
-
- protected static void traceExit(String str) {
- if (TRACELEVEL == 0) return;
- printExiting(str);
- if (TRACELEVEL == 2) callDepth--;
- }
-
- private static void printEntering(String str) {
- printIndent();
- stream.println("--> " + str);
- }
-
- private static void printExiting(String str) {
- printIndent();
- stream.println("<-- " + str);
- }
-
-
- private static void printIndent() {
- for (int i = 0; i < callDepth; i++)
- stream.print(" ");
- }
-
-
- /*
- * Crosscut part
- */
-
- /**
- * Application classes - left unspecified.
- * Subclasses should concretize this pointcut with class names.
- */
- abstract pointcut myClass();
- /**
- * The constructors in those classes.
- */
- pointcut myConstructor(): myClass() && execution(new(..));
- /**
- * The methods of those classes.
- */
- pointcut myMethod(): myClass() && execution(* *(..));
-
- /**
- * Prints trace messages before and after executing constructors.
- */
- before(): myConstructor() {
- traceEntry("" + thisJoinPointStaticPart.getSignature());
- }
- after(): myConstructor() {
- traceExit("" + thisJoinPointStaticPart.getSignature());
- }
-
- /**
- * Prints trace messages before and after executing methods.
- */
- before(): myMethod() {
- traceEntry("" + thisJoinPointStaticPart.getSignature());
- }
- after(): myMethod() {
- traceExit("" + thisJoinPointStaticPart.getSignature());
- }
-}
+++ /dev/null
-/*
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-*/
-
-package tracing.version2;
-
-import tracing.TwoDShape;
-import tracing.Circle;
-import tracing.Square;
-import tracing.ExampleMain;
-
-/**
- *
- * This class concretizes the abstract crosscut in Trace,
- * applying the trace facility to these application classes.
- *
- */
-public aspect TraceMyClasses extends Trace {
- pointcut myClass(): within(TwoDShape) || within(Circle) || within(Square);
-
- /**
- * A main function for testing the trace aspect.
- */
- public static void main(String[] args) {
- Trace.TRACELEVEL = 2;
- Trace.initStream(System.err);
- ExampleMain.main(args);
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-
-package tracing.version3;
-
-import java.io.PrintStream;
-
-/**
- *
- * This class provides support for printing trace messages into a stream.
- * Trace messages are printed before and after constructors and methods
- * are executed.
- * The messages are appended with the string representation of the objects
- * whose constructors and methods are being traced.
- * It defines one abstract pointcut for injecting that tracing functionality
- * into any application classes.
- *
- */
-abstract aspect Trace {
-
- /*
- * Functional part
- */
-
- /**
- * There are 3 trace levels (values of TRACELEVEL):
- * 0 - No messages are printed
- * 1 - Trace messages are printed, but there is no indentation
- * according to the call stack
- * 2 - Trace messages are printed, and they are indented
- * according to the call stack
- */
- public static int TRACELEVEL = 0;
- protected static PrintStream stream = null;
- protected static int callDepth = 0;
-
- /**
- * Initialization.
- */
- public static void initStream(PrintStream s) {
- stream = s;
- }
-
- protected static void traceEntry(String str, Object o) {
- if (TRACELEVEL == 0) return;
- if (TRACELEVEL == 2) callDepth++;
- printEntering(str + ": " + o.toString());
- }
-
- protected static void traceExit(String str, Object o) {
- if (TRACELEVEL == 0) return;
- printExiting(str + ": " + o.toString());
- if (TRACELEVEL == 2) callDepth--;
- }
-
- private static void printEntering(String str) {
- printIndent();
- stream.println("--> " + str);
- }
-
- private static void printExiting(String str) {
- printIndent();
- stream.println("<-- " + str);
- }
-
-
- private static void printIndent() {
- for (int i = 0; i < callDepth; i++)
- stream.print(" ");
- }
-
-
- /*
- * Crosscut part
- */
-
- /**
- * Application classes - left unspecified.
- */
- abstract pointcut myClass(Object obj);
- /**
- * The constructors in those classes.
- */
- pointcut myConstructor(Object obj): myClass(obj) && execution(new(..));
- /**
- * The methods of those classes.
- */
- // toString is called from within our advice, so we shouldn't
- // advise its executions. But if toString is overridden, even
- // this might not be enough, so we might want
- // && !cflow(execution(String toString()))
- pointcut myMethod(Object obj): myClass(obj) &&
- execution(* *(..)) && !execution(String toString());
-
- before(Object obj): myConstructor(obj) {
- traceEntry("" + thisJoinPointStaticPart.getSignature(), obj);
- }
- after(Object obj): myConstructor(obj) {
- traceExit("" + thisJoinPointStaticPart.getSignature(), obj);
- }
-
- before(Object obj): myMethod(obj) {
- traceEntry("" + thisJoinPointStaticPart.getSignature(), obj);
- }
- after(Object obj): myMethod(obj) {
- traceExit("" + thisJoinPointStaticPart.getSignature(), obj);
- }
-}
+++ /dev/null
-/*
-
-Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
-
-Use and copying of this software and preparation of derivative works based
-upon this software are permitted. Any distribution of this software or
-derivative works must comply with all applicable United States export control
-laws.
-
-This software is made available AS IS, and Xerox Corporation makes no warranty
-about the software, its performance or its conformity to any specification.
-
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-|<--- this code is formatted to fit into 80 columns --->|
-
-*/
-
-package tracing.version3;
-
-import tracing.TwoDShape;
-import tracing.Circle;
-import tracing.Square;
-import tracing.ExampleMain;
-
-/**
- *
- * This class concretizes the abstract crosscut in Trace,
- * applying the trace facility to these application classes.
- *
- */
-public aspect TraceMyClasses extends Trace {
- pointcut myClass(Object obj):
- this(obj) &&
- (within(TwoDShape) || within(Circle) || within(Square));
-
- /**
- * A main function for testing the trace aspect.
- */
- public static void main(String[] args) {
- Trace.TRACELEVEL = 2;
- Trace.initStream(System.err);
- ExampleMain.main(args);
- }
-}
-
--- /dev/null
+/*
+ * Copyright (c) 1998-2002 Xerox Corporation,
+ * 2004 Contributors. All rights reserved.
+ *
+ * Use and copying of this software and preparation of derivative works based
+ * upon this software are permitted. Any distribution of this software or
+ * derivative works must comply with all applicable United States export
+ * control laws.
+ *
+ * This software is made available AS IS, and Xerox Corporation makes no
+ * warranty about the software, its performance or its conformity to any
+ * specification.
+ */
+
+package bean;
+
+import java.beans.*;
+import java.io.Serializable;
+
+/**
+ * Add bound properties and serialization to Point objects
+ */
+aspect BoundPoint {
+ /*
+ * privately declare a field on Point to hold the property
+ * change support object. `this' is a reference to a Point object.
+ */
+ private PropertyChangeSupport Point.support = new PropertyChangeSupport(this);
+
+ /*
+ * Declare property change registration methods on Point,
+ * and introduce implementation of the Serializable interface.
+ */
+
+ public void Point.addPropertyChangeListener(PropertyChangeListener listener){
+ support.addPropertyChangeListener(listener);
+ }
+
+ public void Point.addPropertyChangeListener(String propertyName,
+ PropertyChangeListener listener){
+ support.addPropertyChangeListener(propertyName, listener);
+ }
+
+ public void Point.removePropertyChangeListener(String propertyName,
+ PropertyChangeListener listener) {
+ support.removePropertyChangeListener(propertyName, listener);
+ }
+
+ public void Point.removePropertyChangeListener(PropertyChangeListener listener) {
+ support.removePropertyChangeListener(listener);
+ }
+
+ public void Point.hasListeners(String propertyName) {
+ support.hasListeners(propertyName);
+ }
+
+ declare parents: Point implements Serializable;
+
+ /**
+ * Send property change event after X setter completes normally.
+ * Use around advice to keep the old value on the stack.
+ */
+ void around(Point p): execution(void Point.setX(int)) && target(p) {
+ int oldValue = p.getX();
+ proceed(p);
+ firePropertyChange(p, "x", oldValue, p.getX());
+ }
+
+ /**
+ * Send property change event after Y setter completes normally.
+ * Use around advice to keep the old value on the stack.
+ */
+ void around(Point p): execution(void Point.setY(int)) && target(p) {
+ int oldValue = p.getY();
+ proceed(p);
+ firePropertyChange(p, "y", oldValue, p.getY());
+ }
+
+ /*
+ * Utility to fire the property change event.
+ */
+ void firePropertyChange(Point p,
+ String property,
+ double oldval,
+ double newval) {
+ p.support.firePropertyChange(property,
+ new Double(oldval),
+ new Double(newval));
+ }
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+*/
+
+package bean;
+
+import java.beans.*;
+import java.io.*;
+
+public class Demo implements PropertyChangeListener {
+
+ static final String fileName = "test.tmp";
+
+ /**
+ * when Demo is playing the listener role,
+ * this method reports that a propery has changed
+ */
+ public void propertyChange(PropertyChangeEvent e){
+ System.out.println("Property " + e.getPropertyName() + " changed from " +
+ e.getOldValue() + " to " + e.getNewValue() );
+ }
+
+ /**
+ * main: test the program
+ */
+ public static void main(String[] args){
+ Point p1 = new Point();
+ p1.addPropertyChangeListener(new Demo());
+ System.out.println("p1 =" + p1);
+ p1.setRectangular(5,2);
+ System.out.println("p1 =" + p1);
+ p1.setX( 6 );
+ p1.setY( 3 );
+ System.out.println("p1 =" + p1);
+ p1.offset(6,4);
+ System.out.println("p1 =" + p1);
+ save(p1, fileName);
+ Point p2 = (Point) restore(fileName);
+ System.out.println("Had: " + p1);
+ System.out.println("Got: " + p2);
+ }
+
+ /**
+ * Save a serializable object to a file
+ */
+ static void save(Serializable p, String fn){
+ try {
+ System.out.println("Writing to file: " + p);
+ FileOutputStream fo = new FileOutputStream(fn);
+ ObjectOutputStream so = new ObjectOutputStream(fo);
+ so.writeObject(p);
+ so.flush();
+ } catch (Exception e) {
+ System.out.println(e);
+ System.exit(1);
+ }
+ }
+
+ /**
+ * Restore a serializable object from the file
+ */
+ static Object restore(String fn){
+ try {
+ Object result;
+ System.out.println("Reading from file: " + fn);
+ FileInputStream fi = new FileInputStream(fn);
+ ObjectInputStream si = new ObjectInputStream(fi);
+ return si.readObject();
+ } catch (Exception e) {
+ System.out.println(e);
+ System.exit(1);
+ }
+ return null;
+ }
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package bean;
+
+class Point {
+
+ protected int x = 0;
+ protected int y = 0;
+
+ /**
+ * Return the X coordinate
+ */
+ public int getX(){
+ return x;
+ }
+
+ /**
+ * Return the y coordinate
+ */
+ public int getY(){
+ return y;
+ }
+
+ /**
+ * Set the x and y coordinates
+ */
+ public void setRectangular(int newX, int newY){
+ setX(newX);
+ setY(newY);
+ }
+
+ /**
+ * Set the X coordinate
+ */
+ public void setX(int newX) {
+ x = newX;
+ }
+
+ /**
+ * set the y coordinate
+ */
+ public void setY(int newY) {
+ y = newY;
+ }
+
+ /**
+ * Move the point by the specified x and y offset
+ */
+ public void offset(int deltaX, int deltaY){
+ setRectangular(x + deltaX, y + deltaY);
+ }
+
+ /**
+ * Make a string of this
+ */
+ public String toString(){
+ return "(" + getX() + ", " + getY() + ")" ;
+ }
+}
--- /dev/null
+BoundPoint.java
+Point.java
+Demo.java
--- /dev/null
+
+<!-- ========================================================================= -->
+<!-- Copyright (c) 1999-2001 Xerox Corporation, -->
+<!-- 2002 Palo Alto Research Center, Incorporated (PARC). -->
+<!-- All rights reserved. -->
+<!-- This program and the accompanying materials are made available -->
+<!-- under the terms of the Eclipse Public License v 2.0 -->
+<!-- which accompanies this distribution and is available at -->
+<!-- https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt -->
+<!-- -->
+<!-- Contributors: -->
+<!-- Xerox/PARC initial implementation -->
+<!-- ========================================================================= -->
+
+<project name="aspectj-examples" default="spacewar" basedir=".">
+
+ <target name="info" >
+ <echo>
+ This script builds the AspectJ examples.
+
+ Relevant targets:
+ spacewar build and run spacewar with debugging (default)
+ all build and run each example
+ {example} build and run any {example}
+ (use -projecthelp to list {example} names)
+ tracing-bc use AspectJ 1.1 bytecode weaving to build tracing example
+
+ Setup:
+ - Run from the doc/examples directory in your AspectJ distribution.
+ The tasks in ../../lib/aspectjtools.jar are used automatically.
+
+ Variants:
+ - To avoid running (i.e., compile only), define variable "norun"
+ - To define a variable, use the Ant -D option - e.g., on Windows:
+
+ ant -f build.xml -DJAVA_HOME=c:\jdk1.3.1 -Dnorun=skip
+
+ </echo>
+ </target>
+
+ <!-- ============================================================= -->
+ <!-- setup and cleanup targets -->
+ <!-- ============================================================= -->
+
+ <target name="clean" depends="init"
+ description="clean and create classes/jar dir, .ajesym files">
+ <delete quiet="on" dir="${classes.dir}"/>
+ <delete quiet="on" dir="${jar.dir}"/>
+ <delete quiet="on">
+ <fileset dir="${example.dir}" includes="**/*.ajesym"/>
+ </delete>
+ <mkdir dir="${classes.dir}"/>
+ <mkdir dir="${jar.dir}"/>
+ </target>
+
+ <target name="init" depends="init.variables,init.taskdefs"/>
+
+ <target name="init.variables"
+ description="init variables">
+
+ <!-- build.compiler value to pick up our CompilerAdapter for javac -->
+ <property name="ajc.adapter"
+ value="org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter"/>
+
+ <!-- required directories - run from examples or predefine -->
+ <property name="example.dir"
+ location="${basedir}"/>
+ <property name="aspectj.lib.dir"
+ location="${basedir}/../../lib"/>
+
+ <!-- required libraries - install or predefine -->
+ <property name="aspectjrt.jar"
+ location="${aspectj.lib.dir}/aspectjrt.jar"/>
+ <property name="aspectjtools.jar"
+ location="${aspectj.lib.dir}/aspectjtools.jar"/>
+ <property name="aspectjweaver.jar"
+ location="${aspectj.lib.dir}/aspectjweaver.jar"/>
+
+ <!-- created directories -->
+ <property name="classes.dir"
+ location="${example.dir}/classes"/>
+ <property name="jar.dir"
+ location="${example.dir}/jars"/>
+
+ <!-- checking required libraries -->
+ <available file="${aspectjtools.jar}"
+ property="aspectjtools.jar.available"/>
+ <available file="${aspectjrt.jar}"
+ property="aspectjrt.jar.available"/>
+
+ <property name="example.packages"
+ value="bean, coordination, evolution, figures, figures.gui,
+ helloworld, icount, icount.lib, introduction,
+ observer, shadow, shadow.version1, shadow.version2,
+ spacewar, telecom, telecom.version1, timeserver, tjp,
+ tracing, tracing.lib tracing.version1, tracing.version2,
+ tracing.version3"/>
+ </target>
+
+ <target name="init.taskdefs" depends="init.variables,
+ aspectjtools.jar.available,
+ aspectjrt.jar.available"
+ unless="taskdefs.init">
+ <!-- sets name of new task to iajc, old task to ajc -->
+ <taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties">
+ <classpath>
+ <pathelement path="${aspectjtools.jar}"/>
+ </classpath>
+ </taskdef>
+ <property name="taskdefs.init" value="true"/>
+ </target>
+
+ <!-- targets to fail unless required libraries available -->
+
+ <target name="aspectjrt.jar.available" depends="init.variables"
+ unless="aspectjrt.jar.available" >
+ <fail message="expecting aspectjrt.jar at ${aspectjrt.jar}"/>
+ </target>
+
+ <target name="aspectjtools.jar.available" depends="init.variables"
+ unless="aspectjtools.jar.available" >
+ <fail message="expecting aspectjtools.jar at ${aspectjtools.jar}"/>
+ </target>
+
+ <!-- ============================================================= -->
+ <!-- these targets compile and run any example -->
+ <!-- ============================================================= -->
+ <target name="Ajx" depends="init"
+ description="compile {list} and run {class} of example">
+ <echo message="##### Ajx list=${list} class=${class}" />
+ <antcall target="clean" />
+ <!-- can use ajc or iajc here -->
+ <iajc destdir="${classes.dir}" argfiles="${list}"
+ fork="true"
+ forkclasspath="${aspectjtools.jar}"
+ classpath="${aspectjrt.jar}"/>
+
+ <antcall target="Ajx-run" >
+ <param name="class" value="${class}"/>
+ </antcall>
+
+ </target>
+
+ <target name="Ajx-run"
+ description="run {class} unless {norun} is set"
+ unless="norun" >
+ <echo message="##### Ajx-run list=${list} class=${class}" />
+ <java classname="${class}" fork="yes">
+ <classpath>
+ <pathelement path="${classes.dir}"/>
+ <pathelement path="${aspectjrt.jar}"/>
+ </classpath>
+ </java>
+ </target>
+
+ <!-- ============================================================= -->
+ <!-- example targets -->
+ <!-- ============================================================= -->
+ <target name="all"
+ description="build and run all examples"
+ depends="bean,intro,intro-clone,intro-compare,intro-hash,
+ observer,spacewar,spacewar-demo,telecom,
+ telecom-timing,tracing-none,tracing-1,
+ tracing-2,tracing-3,tracing-lt,tjp"/>
+
+ <target name="nonGui"
+ description="build and run non-GUI examples"
+ depends="bean,intro,intro-clone,intro-compare,intro-hash,
+ telecom,telecom-timing,tracing-none,tracing-1,
+ tracing-2,tracing-3,tracing-lt,tjp"/>
+
+ <target name="bean"
+ description="build bean example">
+ <antcall target="Ajx">
+ <param name="list" value="bean/files.lst"/>
+ <param name="class" value="bean.Demo"/>
+ </antcall>
+ </target>
+
+ <target name="intro"
+ description="build inter-type declaration example">
+ <antcall target="Ajx">
+ <param name="list" value="introduction/files.lst"/>
+ <param name="class" value="introduction.Point"/>
+ </antcall>
+ </target>
+
+ <target name="intro-clone"
+ description="build inter-type declaration (clone) example">
+ <antcall target="Ajx">
+ <param name="list" value="introduction/files.lst"/>
+ <param name="class" value="introduction.CloneablePoint"/>
+ </antcall>
+ </target>
+
+ <target name="intro-compare"
+ description="build inter-type declaration (Comparable) example">
+ <antcall target="Ajx">
+ <param name="list" value="introduction/files.lst"/>
+ <param name="class" value="introduction.ComparablePoint"/>
+ </antcall>
+ </target>
+
+ <target name="intro-hash"
+ description="build inter-type declaration (hashcode) example">
+ <antcall target="Ajx">
+ <param name="list" value="introduction/files.lst"/>
+ <param name="class" value="introduction.HashablePoint"/>
+ </antcall>
+ </target>
+
+ <target name="observer"
+ description="build observer example">
+ <antcall target="Ajx">
+ <param name="list" value="observer/files.lst"/>
+ <param name="class" value="observer.Demo"/>
+ </antcall>
+ </target>
+
+ <target name="spacewar"
+ description="build spacewar debug example">
+ <antcall target="Ajx">
+ <param name="list" value="spacewar/debug.lst"/>
+ <param name="class" value="spacewar.Game"/>
+ </antcall>
+ </target>
+
+ <target name="spacewar-demo"
+ description="build spacewar demo (no debug) example">
+ <antcall target="Ajx">
+ <param name="list" value="spacewar/demo.lst"/>
+ <param name="class" value="spacewar.Game"/>
+ </antcall>
+ </target>
+
+ <target name="telecom"
+ description="build telecom basic example">
+ <antcall target="Ajx">
+ <param name="list" value="telecom/basic.lst"/>
+ <param name="class" value="telecom.BasicSimulation"/>
+ </antcall>
+ </target>
+
+ <target name="telecom-billing"
+ description="build telecom billing example">
+ <antcall target="Ajx">
+ <param name="list" value="telecom/billing.lst"/>
+ <param name="class" value="telecom.BillingSimulation"/>
+ </antcall>
+ </target>
+
+ <target name="telecom-timing"
+ description="build telecome timing example">
+ <antcall target="Ajx">
+ <param name="list" value="telecom/timing.lst"/>
+ <param name="class" value="telecom.TimingSimulation"/>
+ </antcall>
+ </target>
+
+ <target name="tjp"
+ description="build thisJoinPoint example">
+ <antcall target="Ajx">
+ <param name="list" value="tjp/files.lst"/>
+ <param name="class" value="tjp.Demo"/>
+ </antcall>
+ </target>
+
+ <target name="tracing-none"
+ description="build tracing (base) example">
+ <antcall target="Ajx">
+ <param name="list" value="tracing/notrace.lst"/>
+ <param name="class" value="tracing.ExampleMain"/>
+ </antcall>
+ </target>
+
+ <target name="tracing-1"
+ description="build tracing (version 1) example">
+ <antcall target="Ajx">
+ <param name="list" value="tracing/tracev1.lst"/>
+ <param name="class" value="tracing.version1.TraceMyClasses"/>
+ </antcall>
+ </target>
+
+ <target name="tracing-2"
+ description="build tracing (version 2) example">
+ <antcall target="Ajx">
+ <param name="list" value="tracing/tracev2.lst"/>
+ <param name="class" value="tracing.version2.TraceMyClasses"/>
+ </antcall>
+ </target>
+
+ <target name="tracing-3"
+ description="build tracing (version 3) example">
+ <antcall target="Ajx">
+ <param name="list" value="tracing/tracev3.lst"/>
+ <param name="class" value="tracing.version3.TraceMyClasses"/>
+ </antcall>
+ </target>
+
+ <!-- ============================================================= -->
+ <!-- do tracing example using compiler adapter -->
+ <!-- ============================================================= -->
+ <target name="tracing-adapter" depends="init"
+ description="tracing example compiled via javac task">
+ <antcall target="clean" />
+ <!-- to fork, set adapter.fork=true
+ and put aspectjtools.jar on ant classpath -->
+ <javac destdir="${classes.dir}"
+ fork="${adapter.fork}">
+ <src path="${example.dir}"/>
+ <include name="tracing/*.java"/>
+
+ <!-- compilerarg's ignored unless using our compiler adapter -->
+ <compilerarg compiler="${ajc.adapter}"
+ line="-verbose -Xlint -proceedOnError"/>
+ <!-- use separate values if a path might have spaces -->
+ <compilerarg compiler="${ajc.adapter}"
+ value="-classpath"/>
+ <compilerarg compiler="${ajc.adapter}"
+ value="${aspectjrt.jar}"/>
+ <compilerarg compiler="${ajc.adapter}"
+ path="${example.dir}/tracing/version3/Trace.java"/>
+ <compilerarg compiler="${ajc.adapter}"
+ path="${example.dir}/tracing/version3/TraceMyClasses.java"/>
+ </javac>
+ </target>
+
+ <target name="tracing-adapter-ajc" depends="init"
+ description="tracing example compiled using ajc via compiler adapter">
+ <!-- aspectjtools.jar must be on system/ant classpath -->
+ <antcall target="tracing-adapter">
+ <param name="build.compiler" value="${ajc.adapter}"/>
+ </antcall>
+ </target>
+
+ <!-- ============================================================= -->
+ <!-- do tracing example with 1.1 bytecode weaving (binary aspects) -->
+ <!-- (and use fork/forkclasspath to avoid Eclipse 2.x bug) -->
+ <!-- ============================================================= -->
+ <target name="tracing-bc" depends="init"
+ description="tracing example with bytecode weaving (binary aspects)">
+ <antcall target="clean" />
+
+ <!-- build application classes -->
+ <iajc outjar="${jar.dir}/tracingApp.jar"
+ classpath="${aspectjrt.jar}"
+ fork="true"
+ forkclasspath="${aspectjtools.jar}"
+ verbose="off">
+ <src path="${example.dir}"/>
+ <include name="tracing/*.java" />
+ </iajc>
+
+ <!-- test standalone application by running without tracing -->
+ <echo message="---------- running without tracing - START"/>
+ <java classname="tracing.ExampleMain">
+ <classpath>
+ <pathelement path="${aspectjrt.jar}"/>
+ <pathelement path="${jar.dir}/tracingApp.jar"/>
+ </classpath>
+ </java>
+ <echo message="---------- running without tracing - FINISH "/>
+
+ <!-- Build a read-only tracing library -->
+ <iajc outjar="${jar.dir}/tracingLib.jar"
+ classpath="${aspectjrt.jar}"
+ fork="true"
+ forkclasspath="${aspectjtools.jar}"
+ verbose="off">
+ <src path="${example.dir}"/>
+ <include name="tracing/version3/Trace.java" />
+ </iajc>
+
+ <!-- weave them -->
+ <!-- This example uses a concrete aspect in source form, -->
+ <!-- but the aspects could be written to be binary only. -->
+ <iajc outjar="${jar.dir}/tracedApp.jar"
+ inpath="${jar.dir}/tracingApp.jar"
+ aspectpath="${jar.dir}/tracingLib.jar"
+ classpath="${aspectjrt.jar}"
+ fork="true"
+ forkclasspath="${aspectjtools.jar}"
+ verbose="off">
+ <src path="${example.dir}"/>
+ <include name="tracing/version3/TraceMyClasses.java" />
+ </iajc>
+
+ <!-- run with tracing -->
+ <echo message="---------- running with tracing - START"/>
+ <java classname="tracing.version3.TraceMyClasses">
+ <classpath>
+ <pathelement path="${aspectjrt.jar}"/>
+ <pathelement path="${jar.dir}/tracingLib.jar"/>
+ <pathelement path="${jar.dir}/tracedApp.jar"/>
+ </classpath>
+ </java>
+ <echo message="---------- running with tracing - FINISH"/>
+
+ </target>
+
+ <!-- ============================================================= -->
+ <!-- do tracing example with 1.2 load-time weaving -->
+ <!-- (and use fork/forkclasspath to avoid Eclipse 2.x bug) -->
+ <!-- ============================================================= -->
+ <target name="tracing-lt" depends="init"
+ description="tracing example with load-time aspect weaving">
+ <antcall target="clean" />
+
+ <!-- build application classes -->
+ <iajc outjar="${jar.dir}/tracingApp.jar"
+ classpath="${aspectjrt.jar}"
+ fork="true"
+ forkclasspath="${aspectjtools.jar}"
+ verbose="off">
+ <src path="${example.dir}"/>
+ <include name="tracing/*.java" />
+ </iajc>
+
+ <!-- Build a read-only tracing library -->
+ <iajc outjar="${jar.dir}/tracingLib.jar"
+ classpath="${aspectjrt.jar}:${jar.dir}/tracingApp.jar"
+ fork="true"
+ forkclasspath="${aspectjtools.jar}"
+ verbose="off">
+ <src path="${example.dir}"/>
+ <include name="tracing/version2/Trace.java" />
+ <include name="tracing/version2/TraceMyClasses.java" />
+ </iajc>
+
+ <!-- test standalone application by running without tracing -->
+ <echo message="---------- running without tracing - START"/>
+ <java classname="tracing.ExampleMain">
+ <classpath>
+ <pathelement path="${aspectjrt.jar}"/>
+ <pathelement path="${jar.dir}/tracingApp.jar"/>
+ </classpath>
+ </java>
+ <echo message="---------- running without tracing - FINISH "/>
+
+ <!-- run application with LTW to add tracing -->
+ <echo message="---------- running with tracing - START"/>
+ <java classname="tracing.ExampleMain"
+ fork="true">
+ <classpath>
+ <pathelement path="${aspectjweaver.jar}"/>
+ </classpath>
+ <jvmarg line="-showversion"/>
+ <sysproperty key="java.system.class.loader" value="org.aspectj.weaver.loadtime.WeavingURLClassLoader"/>
+ <sysproperty key="aj.weaving.verbose" value="True"/>
+ <sysproperty key="org.aspectj.weaver.showWeaveInfo" value="True"/>
+ <sysproperty key="aj.class.path" path="${jar.dir}/tracingLib.jar:${jar.dir}/tracingApp.jar"/>
+ <sysproperty key="aj.aspect.path" path="${jar.dir}/tracingLib.jar"/>
+ </java>
+ <echo message="---------- running with tracing - FINISH"/>
+
+ </target>
+
+</project>
--- /dev/null
+/* -*- Mode: Java; -*-
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package coordination;
+
+
+/**
+ * Interface for pre-conditions that are passed to guardedEntry methods of
+ * Coordinator.
+ * Conditions should be passed as anonymous classes that simply implement
+ * the checkit method.
+ *
+ */
+public interface Condition {
+
+ /**
+ * This method is called automatically by Coordinator.guardedEntry(...)
+ * and it's called everytime the coordination state changes.
+ */
+
+ public boolean checkit();
+}
--- /dev/null
+/* -*- Mode: Java; -*-
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package coordination;
+
+
+/**
+ * Interface for coordination actions that are passed to guardedEntry methods of
+ * Coordinator.
+ * Coordination actions should be passed as anonymous classes that simply
+ * implement the doit method.
+ *
+ */
+public interface CoordinationAction {
+ /**
+ * This method is called by Coordinator.guardedEntry(...) and
+ * Coordinator.guardedExit(...). Use it for changing coordination state
+ * upon entering and exiting methods.
+ */
+
+ public void doit();
+}
--- /dev/null
+/* -*- Mode: Java; -*-
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package coordination;
+
+import java.util.*; //!!!
+
+/**
+ * The Coordinator class provides the basic functionality for synchronizing
+ * and coordinating different threads upon entering and exiting methods.
+ * It can be used in two different ways:
+ * 1) by instantiating regular coordinator objects that are used by aspects; or
+ * 2) by extending it (sub-classing) with coordinator aspects.
+ * <P>
+ * Method invocations are the smallest units for defining critical sections
+ * and pre-conditions. The use of coordinators, either regular objects or aspect
+ * instances, should always end up by invoking guardedEntry(...) in a
+ * before weave and guardedExit(...) in an after weave for all methods that
+ * need coordination. guardedEntry and guardedExit are the methods that
+ * actually manage the synchronization and coordination constraints given
+ * by their parameters and by pre-existent exclusion markers.
+ * <P>
+ * The synchronization of threads for the execution of critical section
+ * methods in an object is done by marking those methods as self- and/or
+ * mutually-exclusive (addSelfex, addMutex).
+ * Just by itself, addSelfex("M") does not enforce the self-exclusion
+ * of method M - enforcement is done by invoking guardedEntry before
+ * M is executed. Similarly, addMutex(new String[] {"M1", "M2"}) does
+ * not enforce the mutual exclusion between methods M1 and M2.
+ * <P>
+ * A guardedEntry on a method that has been marked as self-exclusive
+ * ensures that the method is executed in the invoked object by only one thread
+ * at a time. A guardedEntry on a method that has been marked has mutually-
+ * exclusive with other methods ensures that the execution of that method
+ * by a thread in the invoked object temporarily blocks the execution by
+ * other threads of the methods that are in the same mutex set.
+ * <P>
+ * The coordination of threads, i.e. their explicit suspension and
+ * resumption, is done through the use of pre-conditions and coordination
+ * actions that are passed as parameters to guardedEntry and guardedExit
+ * with the form of anonymous classes.
+ */
+public abstract aspect Coordinator {
+ private Hashtable methods = null;
+ private Vector exclusions = null;
+
+ abstract protected pointcut synchronizationPoint();
+
+ public Coordinator() {
+ methods = new Hashtable();
+ exclusions = new Vector(5);
+ }
+
+ before (): synchronizationPoint() {
+ this.guardedEntry(thisJoinPointStaticPart.getSignature().getName());
+ }
+
+ after (): synchronizationPoint() {
+ this.guardedExit(thisJoinPointStaticPart.getSignature().getName());
+ }
+
+ /**
+ * Takes a multi-part method name (eg "BoundedBuffer.put")
+ * and marks that method as self-exclusive.
+ * No checks are made with respect to the existence of the method
+ * whose name is given.
+ */
+ public synchronized void addSelfex(String methName) {
+ Selfex sex = new Selfex (methName);
+
+ // update db of all exclusions in this coordinator
+ exclusions.addElement(sex);
+
+ // update local info in method
+ Method aMeth = getOrSetMethod(methName);
+ aMeth.addExclusion(sex);
+ }
+
+ /**
+ * Takes a multi-part method name (e.g. "BoundedBuffer.put")
+ * and removes that method from the list of self-exclusive methods.
+ */
+ public synchronized void removeSelfex(String methName) {
+ for (int i = 0; i < exclusions.size(); i++) {
+ Exclusion sex = (Exclusion)exclusions.elementAt(i);
+ if ((sex instanceof Selfex) &&
+ (((Selfex)sex).methodName.equals(methName))) {
+
+ // update db of all exclusions in this coordinator
+ exclusions.removeElementAt(i);
+
+ // update local info in method
+ Method aMeth = getOrSetMethod(methName);
+ aMeth.removeExclusion(sex);
+ }
+ }
+ }
+
+ /**
+ * Takes an array of multi-part method names and marks those
+ * methods as mutually exclusive.
+ * No checks are made with respect to the existence of the methods
+ * whose names are given.
+ */
+ public synchronized void addMutex(String[] methNames) {
+ Mutex mux = new Mutex(methNames);
+
+ // update db of all exclusions in this coordinator
+ exclusions.addElement(mux);
+
+ // update local info in each method
+ for (int i = 0; i < methNames.length; i++) {
+ Method aMeth = getOrSetMethod(methNames[i]);
+ aMeth.addExclusion(mux);
+ }
+ }
+
+ /**
+ * Takes an array of multi-part method names that correspond
+ * to an existing mutex set and remove the mutual exclusion constraint.
+ * If the given mutex set does not exist, removeMutex does nothing.
+ */
+ public synchronized void removeMutex(String[] methNames) {
+ for (int i = 0; i < exclusions.size(); i++) {
+ Exclusion mux = (Exclusion)exclusions.elementAt(i);
+ if (mux instanceof Mutex) {
+ boolean same = true;
+ for (int j = 0; j < methNames.length; j++)
+ if (!methNames[j].equals(((Mutex)mux).methodNames[j]))
+ same = false;
+ if (same) {
+ // update db of all exclusions in this coordinator
+ exclusions.removeElementAt(i);
+
+ // update local info in each method involved
+ for (int j = 0; j < methNames.length; j++) {
+ Method aMeth = getOrSetMethod(methNames[j]);
+ aMeth.removeExclusion(mux);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * This method is the guard for enforcing all synchronization and
+ * coordination constraints of a given method, and it should be called
+ * just before the method is executed.
+ * In this form, only the method name is given. The only constraints
+ * checked are the exclusion constraints.
+ * If the method was previousely marked as selfex (through addSelfex),
+ * guardedEntry ensures that the method is executed only when no other
+ * thread is executing it.
+ * If the method was previousely marked as being in one or more mutex
+ * sets, guardedEntry ensures that the method is executed only when no other
+ * thread is executing any of the methods with which the give method is
+ * mutexed.
+ */
+ public synchronized void guardedEntry(String methName) {
+ guardedEntry(methName, new Condition() {
+ public boolean checkit() {
+ return true;
+ }
+ }, null);
+ }
+
+ /**
+ * Just like guardedEntry(String methName), but the given method is executed
+ * only when the given condition is true.
+ * guardedEntry is the guard for enforcing all synchronization and
+ * coordination constraints of a given method, and it should be called
+ * just before the method is executed.
+ * In this form, the method name is given along with a condition.
+ * The constraints checked are the exclusion constraints and whether
+ * the given condition is true.
+ * If the method was previousely marked as selfex (through addSelfex),
+ * guardedEntry ensures that the method is executed only when no other
+ * thread is executing it.
+ * If the method was previousely marked as being in one or more mutex
+ * sets, guardedEntry ensures that the method is executed only when no other
+ * thread is executing any of the methods with which the give method is
+ * mutexed.
+ * If the condition is false, guardedEntry suspends the current thread.
+ * That thread remains suspended until the condition becomes true, in
+ * which case all constraints are rechecked before the method is executed.
+ * When all exclusion constraints are checked and the given condition is
+ * true, the given method is executed.
+ */
+ public synchronized void guardedEntry(String methName, Condition condition) {
+ guardedEntry(methName, condition, null);
+ }
+
+ /**
+ * Just like guardedEntry(String methName), but with an additional
+ * coordination action that is executed before the given method is
+ * executed.
+ * guardedEntry is the guard for enforcing all synchronization and
+ * coordination constraints of a given method, and it should be called
+ * just before the method is executed.
+ * In this form, the method name is given along with a coordination action.
+ * The only constraints checked are the exclusion constraints.
+ * If the method was previousely marked as selfex (through addSelfex),
+ * guardedEntry ensures that the method is executed only when no other
+ * thread is executing it.
+ * If the method was previousely marked as being in one or more mutex
+ * sets, guardedEntry ensures that the method is executed only when no other
+ * thread is executing any of the methods with which the give method is
+ * mutexed.
+ * The given coordination action is executed just before the given method
+ * is executed.
+ */
+ public synchronized void guardedEntry(String methName,
+ CoordinationAction action) {
+ guardedEntry(methName, new Condition() {
+ public boolean checkit() {
+ return true;
+ }
+ },
+ action);
+ }
+
+ /**
+ * Just like guardedEntry(String methName), but the given method is executed
+ * only when the given condition is true; the additional
+ * coordination action that is executed before the given method is
+ * executed.
+ * guardedEntry is the guard for enforcing all synchronization and
+ * coordination constraints of a given method, and it should be called
+ * just before the method is executed.
+ * In this form, the method name is given along with a condition and
+ * a coordination action.
+ * The constraints checked are the exclusion constraints and whether the
+ * given condition is true.
+ * If the method was previousely marked as selfex (through addSelfex),
+ * guardedEntry ensures that the method is executed only when no other
+ * thread is executing it.
+ * If the method was previousely marked as being in one or more mutex
+ * sets, guardedEntry ensures that the method is executed only when no other
+ * thread is executing any of the methods with which the give method is
+ * mutexed.
+ * If the condition is false, guardedEntry suspends the current thread.
+ * That thread remains suspended until the condition becomes true, in
+ * which case all constraints are rechecked before the method is executed.
+ * When all exclusion constraints are checked and the given condition is
+ * true, the given method is executed.
+ * The given coordination action is executed just before the given method
+ * is executed.
+ */
+ public synchronized void guardedEntry(String methName,
+ Condition condition,
+ CoordinationAction action) {
+ Method aMeth = getOrSetMethod(methName);
+ boolean canGo = false;
+
+ // test pre-conditions for entering the method
+ while (!canGo) {
+ canGo = true;
+ for (int i = 0; i < aMeth.exes.size() && canGo; i++)
+ if (!((Exclusion)aMeth.exes.elementAt(i)).testExclusion(aMeth.name)) {
+ canGo = false;
+ }
+ if (canGo && !condition.checkit()) {
+ canGo = false;
+ }
+ if (!canGo)
+ try {
+ wait();
+ } catch (InterruptedException e) { }
+ }
+
+ // OK.
+ enterMethod(aMeth, action);
+ }
+
+ /**
+ * This method is similar to guardedEntry, but it takes
+ * an additional parameter - the milliseconds after which any suspension
+ * will abort with a timeout.
+ */
+ public synchronized void guardedEntryWithTimeout(String methName,
+ long millis)
+ throws TimeoutException {
+ guardedEntryWithTimeout(methName, new Condition() {
+ public boolean checkit() {
+ return true;
+ }
+ }, null, millis);
+ }
+
+ /**
+ * This method is similar to guardedEntry, but it takes
+ * an additional parameter - the milliseconds after which any suspension
+ * will abort with a timeout.
+ */
+ public synchronized void guardedEntryWithTimeout(String methName,
+ Condition condition,
+ long millis)
+ throws TimeoutException {
+ guardedEntryWithTimeout(methName, condition, null, millis);
+ }
+
+ /**
+ * This method is similar to guardedEntry, but it takes
+ * an additional parameter - the milliseconds after which any suspension
+ * will abort with a timeout.
+ */
+ public synchronized void guardedEntryWithTimeout(String methName,
+ CoordinationAction action,
+ long millis)
+ throws TimeoutException {
+ guardedEntryWithTimeout(methName, new Condition() {
+ public boolean checkit() {
+ return true;
+ }
+ }, action, millis);
+ }
+
+ /**
+ * This method is similar to guardedEntry, but it takes
+ * an additional parameter - the milliseconds after which any suspension
+ * will abort with a timeout.
+ */
+ public synchronized void guardedEntryWithTimeout(String methName,
+ Condition condition,
+ CoordinationAction action,
+ long millis)
+ throws TimeoutException {
+
+ Method aMeth = getOrSetMethod(methName);
+ boolean canGo = false;
+ long waitTime = millis;
+ long startTime = System.currentTimeMillis();
+
+ // test pre-conditions for entering the method
+ while (!canGo) {
+ canGo = true;
+ for (int i = 0; i < aMeth.exes.size() && canGo; i++)
+ if ((!((Exclusion)aMeth.exes.elementAt(i)).testExclusion(aMeth.name)) ||
+ (!condition.checkit())) {
+ canGo = false;
+ }
+ if (!canGo) {
+ try {
+ wait(waitTime);
+ } catch (InterruptedException e) {}
+
+ long now = System.currentTimeMillis();
+ long timeSoFar = now - startTime;
+ if (timeSoFar >= millis) // timeout!
+ throw new TimeoutException(timeSoFar);
+ else // adjust time
+ waitTime = millis - timeSoFar;
+ }
+ }
+
+ // OK.
+ enterMethod(aMeth, action);
+ }
+
+ /**
+ * This method provides the means for updating all synchronization and
+ * coordination state after the execution of a given method, and it should be
+ * called after the method is executed.
+ * In this form, only the method name is given.
+ * The synchronization state for self- and mutual-exclusion is
+ * automatically upadted.
+ */
+ public synchronized void guardedExit(String methName) {
+ guardedExit(methName, null);
+ }
+
+ /**
+ * Just like guardedExit(String methName) but with an additional
+ * coordination action that is executed.
+ * guardedExit provides the means for updating all synchronization and
+ * coordination state after the execution of a given method, and it should be
+ * called after the method is executed.
+ * In this form, the method name is given along with a coordination action.
+ * The synchronization state for self- and mutual-exclusion is
+ * automatically upadted.
+ * The given coordination action is executed.
+ */
+ public synchronized void guardedExit(String methName,
+ CoordinationAction action) {
+ Method aMeth = getOrSetMethod(methName);
+
+ for (int i = 0; i < aMeth.exes.size(); i++)
+ ((Exclusion)aMeth.exes.elementAt(i)).exitExclusion(methName);
+ if (action != null) action.doit();
+ notifyAll();
+ }
+
+ private Method getOrSetMethod(String methName) {
+ Method aMeth = null;
+ if (!methods.containsKey(methName)) {
+ methods.put(methName, (aMeth = new Method(methName)));
+ }
+ else {
+ aMeth = (Method) methods.get(methName);
+ }
+ return aMeth;
+ }
+
+ private void enterMethod(Method aMeth, CoordinationAction action) {
+ for (int i = 0; i < aMeth.exes.size(); i++)
+ ((Exclusion)aMeth.exes.elementAt(i)).enterExclusion(aMeth.name);
+
+ if (action != null) action.doit();
+ }
+
+
+
+}
+
+class Method {
+ String name;
+ Vector exes = new Vector(3);
+
+ Method(String n) {
+ name = n;
+ }
+
+ void addExclusion(Exclusion ex) {
+ exes.addElement(ex);
+ }
+
+ void removeExclusion(Exclusion ex) {
+ for (int i = 0; i < exes.size(); i++) {
+ if (exes.elementAt(i) == ex)
+ exes.removeElementAt(i);
+ }
+ }
+}
+
--- /dev/null
+/* -*- Mode: Java; -*-
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package coordination;
+
+
+interface Exclusion {
+
+ boolean testExclusion(String methodName);
+
+ void enterExclusion(String methodName);
+
+ void exitExclusion(String methodName);
+
+ // for debug !!!
+ void printNames();
+}
+
--- /dev/null
+/* -*- Mode: Java; -*-
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package coordination;
+
+import java.util.Vector;
+import java.util.Enumeration;
+
+
+class MethodState {
+
+ Vector threads=new Vector();
+
+ void enterInThread (Thread t) {
+ threads.addElement(t);
+ }
+
+ void exitInThread(Thread t) {
+ threads.removeElement(t);
+ }
+
+ boolean hasOtherThreadThan(Thread t) {
+ Enumeration e = threads.elements();
+ while (e.hasMoreElements())
+ if (e.nextElement() != t)
+ return(true);
+ return (false);
+ }
+
+}
--- /dev/null
+/* -*- Mode: Java; -*-
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package coordination;
+
+import java.lang.String;
+
+
+class Mutex implements Exclusion {
+ String[] methodNames;
+ MethodState[] methodStates;
+
+ String prettyName;
+
+ Mutex (String[] _methodNames) {
+ methodNames = _methodNames;
+ methodStates = new MethodState[methodNames.length];
+ for (int i = 0; i < methodNames.length; i++) {
+ methodStates[i] = new MethodState();
+ }
+ }
+
+ private boolean isMethodIn (String _methodName) {
+ for (int i = 0; i < methodNames.length; i++) {
+ if (_methodName.equals(methodNames[i]))
+ return(true);
+ }
+ return(false);
+ }
+
+ private MethodState getMethodState (String _methodName) {
+ for (int i = 0; i < methodNames.length; i++) {
+ if (_methodName.equals(methodNames[i]))
+ return(methodStates[i]);
+ }
+ return(null);
+ }
+
+ public boolean testExclusion (String _methodName) {
+ Thread ct = Thread.currentThread();
+ //
+ // Loop through each of the other methods in this exclusion set, to be sure
+ // that no other thread is running them. Note that we have to be careful
+ // about selfex.
+ //
+ for (int i = 0; i < methodNames.length; i++) {
+ if (!_methodName.equals(methodNames[i])) {
+ if (methodStates[i].hasOtherThreadThan(ct))
+ return(false);
+ }
+ }
+ return (true);
+ }
+
+ public void enterExclusion (String _methodName) {
+ MethodState methodState = getMethodState(_methodName);
+ methodState.enterInThread(Thread.currentThread());
+ }
+
+ public void exitExclusion (String _methodName) {
+ MethodState methodState = getMethodState(_methodName);
+ methodState.exitInThread(Thread.currentThread());
+ }
+
+ public void printNames() {
+ System.out.print("Mutex names: ");
+ for (int i = 0; i < methodNames.length; i++)
+ System.out.print(methodNames[i] + " ");
+ System.out.println();
+ }
+}
--- /dev/null
+/* -*- Mode: Java; -*-
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package coordination;
+
+
+import java.lang.String;
+
+class Selfex implements Exclusion {
+ String methodName;
+ Thread thread;
+ int count = 0;
+
+ Selfex (String _methodName) {
+ methodName = _methodName;
+ }
+
+ public boolean testExclusion (String _methodName) {
+ if (count == 0)
+ return(true);
+ return (thread == Thread.currentThread());
+ }
+
+ public void enterExclusion (String _methodName) {
+ count++;
+ thread = Thread.currentThread(); // note that if count wasn't 0
+ // we aren't changing thread
+ }
+
+ public void exitExclusion (String _methodName) {
+ count--;
+ if (count == 0) // not stricly necessary, but...
+ thread = null;
+ }
+
+ public void printNames() {
+ System.out.println("Selfex name: " + methodName);
+ }
+
+}
--- /dev/null
+/* -*- Mode: Java; -*-
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package coordination;
+
+
+public class TimeoutException extends Exception {
+ long time;
+ TimeoutException(long _time) {
+ time = _time;
+ }
+}
--- /dev/null
+Condition.java
+CoordinationAction.java
+Coordinator.java
+Exclusion.java
+MethodState.java
+Mutex.java
+Selfex.java
+TimeoutException.java
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+*/
+package introduction;
+
+public aspect CloneablePoint {
+
+ declare parents: Point implements Cloneable;
+
+ public Object Point.clone() throws CloneNotSupportedException {
+ // we choose to bring all fields up to date before cloning.
+ makeRectangular();
+ makePolar();
+ return super.clone();
+ }
+
+ public static void main(String[] args){
+ Point p1 = new Point();
+ Point p2 = null;
+
+ p1.setPolar(Math.PI, 1.0);
+ try {
+ p2 = (Point)p1.clone();
+ } catch (CloneNotSupportedException e) {}
+ System.out.println("p1 =" + p1 );
+ System.out.println("p2 =" + p2 );
+
+ p1.rotate(Math.PI / -2);
+ System.out.println("p1 =" + p1 );
+ System.out.println("p2 =" + p2 );
+ }
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package introduction;
+
+public aspect ComparablePoint {
+
+ declare parents: Point implements Comparable;
+
+ public int Point.compareTo(Object o) {
+ return (int) (this.getRho() - ((Point)o).getRho());
+ }
+
+ public static void main(String[] args){
+ Point p1 = new Point();
+ Point p2 = new Point();
+
+ System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
+
+ p1.setRectangular(2,5);
+ p2.setRectangular(2,5);
+ System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
+
+ p2.setRectangular(3,6);
+ System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
+
+ p1.setPolar(Math.PI, 4);
+ p2.setPolar(Math.PI, 4);
+ System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
+
+ p1.rotate(Math.PI / 4.0);
+ System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
+
+ p1.offset(1,1);
+ System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
+ }
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package introduction;
+
+import java.util.Hashtable;
+
+public aspect HashablePoint {
+
+ public int Point.hashCode() {
+ return (int) (getX() + getY() % Integer.MAX_VALUE);
+ }
+
+ public boolean Point.equals(Object o) {
+ if (o == this) { return true; }
+ if (!(o instanceof Point)) { return false; }
+ Point other = (Point)o;
+ return (getX() == other.getX()) && (getY() == other.getY());
+ }
+
+ public static void main(String[] args) {
+ Hashtable h = new Hashtable();
+ Point p1 = new Point();
+
+ p1.setRectangular(10, 10);
+ Point p2 = new Point();
+
+ p2.setRectangular(10, 10);
+
+ System.out.println("p1 = " + p1);
+ System.out.println("p2 = " + p2);
+ System.out.println("p1.hashCode() = " + p1.hashCode());
+ System.out.println("p2.hashCode() = " + p2.hashCode());
+
+ h.put(p1, "P1");
+ System.out.println("Got: " + h.get(p2));
+ }
+}
--- /dev/null
+/*
+ Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+ Use and copying of this software and preparation of derivative works based
+ upon this software are permitted. Any distribution of this software or
+ derivative works must comply with all applicable United States export control
+ laws.
+
+ This software is made available AS IS, and Xerox Corporation makes no warranty
+ about the software, its performance or its conformity to any specification.
+*/
+
+package introduction;
+
+public class Point {
+
+ protected double x = 0;
+ protected double y = 0;
+ protected double theta = 0;
+ protected double rho = 0;
+
+ protected boolean polar = true;
+ protected boolean rectangular = true;
+
+ public double getX(){
+ makeRectangular();
+ return x;
+ }
+
+ public double getY(){
+ makeRectangular();
+ return y;
+ }
+
+ public double getTheta(){
+ makePolar();
+ return theta;
+ }
+
+ public double getRho(){
+ makePolar();
+ return rho;
+ }
+
+ public void setRectangular(double newX, double newY){
+ x = newX;
+ y = newY;
+ rectangular = true;
+ polar = false;
+ }
+
+ public void setPolar(double newTheta, double newRho){
+ theta = newTheta;
+ rho = newRho;
+ rectangular = false;
+ polar = true;
+ }
+
+ public void rotate(double angle){
+ setPolar(theta + angle, rho);
+ }
+
+ public void offset(double deltaX, double deltaY){
+ setRectangular(x + deltaX, y + deltaY);
+ }
+
+ protected void makePolar(){
+ if (!polar){
+ theta = Math.atan2(y,x);
+ rho = y / Math.sin(theta);
+ polar = true;
+ }
+ }
+
+ protected void makeRectangular(){
+ if (!rectangular) {
+ y = rho * Math.sin(theta);
+ x = rho * Math.cos(theta);
+ rectangular = true;
+ }
+ }
+
+ public String toString(){
+ return "(" + getX() + ", " + getY() + ")["
+ + getTheta() + " : " + getRho() + "]";
+ }
+
+ public static void main(String[] args){
+ Point p1 = new Point();
+ System.out.println("p1 =" + p1);
+ p1.setRectangular(5,2);
+ System.out.println("p1 =" + p1);
+ p1.setPolar( Math.PI / 4.0 , 1.0);
+ System.out.println("p1 =" + p1);
+ p1.setPolar( 0.3805 , 5.385);
+ System.out.println("p1 =" + p1);
+ }
+}
--- /dev/null
+Point.java
+CloneablePoint.java
+ComparablePoint.java
+HashablePoint.java
--- /dev/null
+/*
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
+ *
+ * Contributors:
+ * Matthew Webster initial implementation
+ */
+public class HelloWorld {
+
+ public static void main (String[] args) {
+ System.out.println("Hello World!");
+ }
+}
--- /dev/null
+
+For users of JDK 1.4 the bin directory of your AspectJ distribution
+contains a script "aj" to perform load-time weaving. Java classes on
+the CLASSPATH are loaded and woven with aspects also on the CLASSPATH
+which are declared in an aop.xml file. This file is either created by
+the user or generated by the compiler. Alternatively aspects can be
+loaded from an explicitly defined ASPECTPATH.
+
+For users of JDK 1.5 the bin directory of your AspectJ distribution
+contains a script "aj5" to perform load-time weaving using an agent.
+This uses an aop.xml as described above.
+
+--To compile the HelloWorld program--
+
+ ajc -outjar hello.jar HelloWorld.java
+
+--To compile the Tracing aspect--
+
+ ajc -outjar tracing.jar -outxml Tracing.aj
+
+--To run the example--
+
+ set CLASSPATH to include hello.jar
+
+ aj HelloWorld
+
+--To run the example with tracing--
+
+ set CLASSPATH to include "tracing.jar"
+
+ aj HelloWorld
+
+--To run the example with tracing using ASPECTPATH--
+
+ set ASPECTPATH=tracing.jar
+
+ aj HelloWorld
+
+--To run the example with tracing using an agent--
+
+ aj5 HelloWorld
+
--- /dev/null
+/*
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
+ *
+ * Contributors:
+ * Matthew Webster initial implementation
+ */
+public aspect Tracing {
+
+ private pointcut mainMethod () :
+ execution(public static void main(String[]));
+
+ before () : mainMethod() {
+ System.out.println("> " + thisJoinPoint);
+ }
+
+ after () : mainMethod() {
+ System.out.println("< " + thisJoinPoint);
+ }
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+
+package observer;
+
+import java.awt.Color;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+class Button extends java.awt.Button {
+
+ static final Color defaultBackgroundColor = Color.gray;
+ static final Color defaultForegroundColor = Color.black;
+ static final String defaultText = "cycle color";
+
+ Button(Display display) {
+ super();
+ setLabel(defaultText);
+ setBackground(defaultBackgroundColor);
+ setForeground(defaultForegroundColor);
+ addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ Button.this.click();
+ }
+ });
+ display.addToFrame(this);
+ }
+
+ public void click() {}
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package observer;
+import java.awt.Color;
+import java.awt.Label;
+
+class ColorLabel extends Label {
+
+ ColorLabel(Display display) {
+ super();
+ display.addToFrame(this);
+ }
+
+ final static Color[] colors = {Color.red, Color.blue,
+ Color.green, Color.magenta};
+ private int colorIndex = 0;
+ private int cycleCount = 0;
+ void colorCycle() {
+ cycleCount++;
+ colorIndex = (colorIndex + 1) % colors.length;
+ setBackground(colors[colorIndex]);
+ setText("" + cycleCount);
+ }
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package observer;
+
+public class Demo {
+ public static void main(String[] args) {
+
+ Display display = new Display();
+ Button b1 = new Button(display);
+ Button b2 = new Button(display);
+ ColorLabel c1 = new ColorLabel(display);
+ ColorLabel c2 = new ColorLabel(display);
+ ColorLabel c3 = new ColorLabel(display);
+
+ b1.addObserver(c1);
+ b1.addObserver(c2);
+ b2.addObserver(c3);
+ }
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package observer;
+import java.awt.Frame;
+import java.awt.Panel;
+import java.awt.Container;
+import java.awt.Component;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.BorderLayout;
+
+/*
+ * Display is the container class that holds all the views of the
+ * colored number.
+ * In this demo, it holds buttons.
+ */
+
+class Display extends Panel {
+
+ protected Frame frame = new Frame("Subject/Observer Demo");
+
+ Display() {
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {System.exit(0);}
+ });
+
+ frame.add(this, BorderLayout.CENTER);
+ frame.pack();
+ frame.setVisible(true);
+ }
+
+ void addToFrame(Component c) {
+ add(c);
+ frame.pack();
+ }
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+package observer;
+
+interface Observer {
+ void setSubject(Subject s);
+ Subject getSubject();
+ void update();
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package observer;
+import java.util.Vector;
+
+interface Subject {
+ void addObserver(Observer obs);
+ void removeObserver(Observer obs);
+ Vector getObservers();
+ Object getData();
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package observer;
+
+import java.util.Vector;
+
+abstract aspect SubjectObserverProtocol {
+
+ abstract pointcut stateChanges(Subject s);
+
+ after(Subject s): stateChanges(s) {
+ for (int i = 0; i < s.getObservers().size(); i++) {
+ ((Observer)s.getObservers().elementAt(i)).update();
+ }
+ }
+
+ private Vector Subject.observers = new Vector();
+ public void Subject.addObserver(Observer obs) {
+ observers.addElement(obs);
+ obs.setSubject(this);
+ }
+ public void Subject.removeObserver(Observer obs) {
+ observers.removeElement(obs);
+ obs.setSubject(null);
+ }
+ public Vector Subject.getObservers() { return observers; }
+
+ private Subject Observer.subject = null;
+ public void Observer.setSubject(Subject s) { subject = s; }
+ public Subject Observer.getSubject() { return subject; }
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package observer;
+
+import java.util.Vector;
+
+aspect SubjectObserverProtocolImpl extends SubjectObserverProtocol {
+
+ declare parents: Button implements Subject;
+ public Object Button.getData() { return this; }
+
+ declare parents: ColorLabel implements Observer;
+ public void ColorLabel.update() {
+ colorCycle();
+ }
+
+ pointcut stateChanges(Subject s):
+ target(s) &&
+ call(void Button.click());
+
+}
--- /dev/null
+ColorLabel.java
+Button.java
+Display.java
+Subject.java
+Observer.java
+SubjectObserverProtocol.java
+SubjectObserverProtocolImpl.java
+Demo.java
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+Bullet.java
+Part of the Spacewar game.
+
+*/
+
+package spacewar;
+
+class Bullet extends SpaceObject {
+
+ static private final int SIZE = 3; //Can't be changed for now!!!
+ static private int LIFETIME = 50;
+
+ private int lifeLeft;
+
+ Bullet (Game theGame, double xP, double yP, double xV, double yV) {
+ super(theGame, xP, yP, xV, yV);
+ lifeLeft = LIFETIME;
+ }
+
+ int getSize() { return SIZE; }
+
+ void handleCollision(SpaceObject obj) {
+ die();
+ }
+
+ void clockTick() {
+ if (--lifeLeft == 0)
+ die();
+ super.clockTick();
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+Debug.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+import java.awt.Menu;
+import java.awt.CheckboxMenuItem;
+import java.awt.Frame;
+import java.awt.TextArea;
+import java.awt.Dimension;
+
+/**
+ * This aspect specifies debugging information to be output to the
+ * information window.
+ *
+ * When the debug aspect is compiled in the Frame menu has several checkbox
+ * items that can be used to control the amount of tracing information
+ * displayed. (By default the first three are off, because they generate
+ * so much information.)
+ *
+ * There are two reasons to gather all this debugging code into an aspect
+ * like this:
+ *
+ * (1) It makes it easier to understand when it is all in one place.
+ *
+ * (2) It means that we can "plug and debug". We can enable/disable
+ * the debugging code simply by weaving or not weaving this
+ * aspect in.
+ *
+ * All in all, this is a lot better than the usual practice of writing
+ * complex debugging code and then deleting it when the bug is found,
+ * only to regret it a month later when a related bug surfaces. (Or even
+ * the same bug!)
+ *
+ * This file also defines a class InfoWin, which it uses to display all the
+ * debugging information.
+ */
+aspect Debug {
+
+ private static InfoWin infoWin = new InfoWin();
+
+ private static Menu menu = new Menu("Debug");
+
+ private static CheckboxMenuItem traceConstructors =
+ new CheckboxMenuItem("trace constructors", false);
+ private static CheckboxMenuItem traceInitializations =
+ new CheckboxMenuItem("trace initializations", false);
+ private static CheckboxMenuItem traceMethods =
+ new CheckboxMenuItem("trace methods", false);
+ private static CheckboxMenuItem traceClockTick =
+ new CheckboxMenuItem("trace clock tick", false);
+ private static CheckboxMenuItem traceRegistry =
+ new CheckboxMenuItem("trace registry", true);
+ private static CheckboxMenuItem traceFireCollideDamage =
+ new CheckboxMenuItem("trace fire, collide, damage", true);
+
+ after() returning (SWFrame frame): call(SWFrame+.new(..)) {
+ menu.add(traceConstructors);
+ menu.add(traceInitializations);
+ menu.add(traceMethods);
+ menu.add(traceClockTick);
+ menu.add(traceRegistry);
+ menu.add(traceFireCollideDamage);
+ frame.getMenuBar().add(menu);
+ }
+
+ /*
+ * all constructors
+ */
+ pointcut allConstructorsCut():
+ call((spacewar.* && !(Debug+ || InfoWin+)).new(..));
+
+ before(): allConstructorsCut() {
+ if (traceConstructors.getState()) {
+ infoWin.println("begin constructing " + thisJoinPoint.getSignature());
+ }
+ }
+
+ after() returning: allConstructorsCut() {
+ if (traceConstructors.getState()) {
+ infoWin.println("done constructing " + thisJoinPoint.getSignature());
+ }
+ }
+
+ /*
+ * All dynamic initializations
+ */
+ pointcut allInitializationsCut():
+ initialization((spacewar.* && !(Debug+ || InfoWin+)).new(..));
+
+ before(): allInitializationsCut() {
+ if (traceConstructors.getState()) {
+ infoWin.println("begin initializing " + thisJoinPoint.getSignature());
+ }
+ }
+ after() returning : allInitializationsCut() {
+ if (traceConstructors.getState()) {
+ infoWin.println("done initializing " + thisJoinPoint.getSignature());
+ }
+ }
+
+ /*
+ * all methods
+ */
+ pointcut allMethodsCut():
+ execution(* (spacewar.* && !(Debug+ || InfoWin+)).*(..));
+
+ before(): allMethodsCut() {
+ if (traceMethods.getState()) {
+ infoWin.println("entering " + thisJoinPoint.getSignature());
+ }
+ }
+ after() returning : allMethodsCut() {
+ if (traceMethods.getState()) {
+ infoWin.println("exiting " + thisJoinPoint.getSignature());
+ }
+ }
+
+ /*
+ * clock ticks
+ */
+ after(Object obj) returning :
+ (target(obj) && (target(Game) ||
+ target(Registry) ||
+ target(SpaceObject)))
+ && call(void clockTick()) {
+ if (traceClockTick.getState())
+ infoWin.println("ticking " + obj);
+ }
+
+ /*
+ * registry contents
+ */
+ after(Registry registry) returning :
+ target(registry) && (call(void register(..)) ||
+ call(void unregister(..))) {
+ if (traceRegistry.getState())
+ infoWin.println(registry.getTable().size() +
+ " space objects in the registry.");
+ }
+
+ /*
+ * fire, collide, damage
+ */
+ after() returning : call(void Ship.fire()) {
+ if (traceFireCollideDamage.getState())
+ infoWin.println("firing");
+ }
+
+ after(Ship ship, SpaceObject obj) returning :
+ call(void handleCollision(SpaceObject)) && target(ship) && args(obj) {
+ if (traceFireCollideDamage.getState())
+ infoWin.println(ship + " collides with " + obj);
+ }
+
+ after(Ship shipA, Ship shipB) returning :
+ execution(void Ship.bounce(Ship, Ship)) && args(shipA, shipB) {
+ if (traceFireCollideDamage.getState())
+ infoWin.println(shipA + " bounces with " + shipB);
+ }
+
+ before(Ship ship, double amount):
+ call(void Ship.inflictDamage(double)) && target(ship) && args(amount) {
+ if (traceFireCollideDamage.getState())
+ if (amount > 0)
+ infoWin.println(ship + "gets " +
+ amount + " damage (" +
+ ship.getDamage() + ")");
+ }
+
+}
+
+class InfoWin {
+ private Frame frame;
+ private TextArea info;
+
+ InfoWin() {
+ frame = new Frame("debugging info for spacewar game");
+ info = new TextArea();
+ info.setEditable(false);
+
+ Dimension screenSize = frame.getToolkit().getScreenSize();
+ frame.setSize(250, 600);
+ frame.setLocation(screenSize.width - 250, 0);
+ frame.add(info);
+ frame.show();
+ frame.toFront();
+ }
+
+ void clear() {
+ info.setText("");
+ }
+
+ void println(String line) {
+ info.append(line + "\n");
+ }
+
+ void print(String line) {
+ info.append(line);
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+Display.java
+Part of the Spacewar system.
+*/
+
+package spacewar;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.awt.Graphics;
+import java.awt.Canvas;
+import java.awt.Image;
+
+/**
+ * The display aspects capture the look and feel of the Game in modular
+ * pluggable units.
+ *
+ * The model is that constructing a concrete subclass of Display attaches that
+ * kind of display to the game. It will Display the game as it goes along.
+ * A game can have any number of displays. Any of the displays will accept
+ * keyboard input.
+ *
+ */
+
+class Display extends Canvas {
+
+ private static Vector DISPLAYS = new Vector(2);
+ private static Vector PLAYERS = new Vector(2);
+ private static Pilot pilot1, pilot2;
+
+ Game game;
+ SWFrame frame;
+ Image offImage;
+ Graphics offGraphics;
+
+ Game getGame() { return game; }
+ static Pilot getPilot1() { return pilot1; }
+ static Pilot getPilot2() { return pilot2; }
+
+ Display(Game g) {
+ super();
+ game = g;
+
+ frame = new SWFrame(game, this);
+ DISPLAYS.addElement(this);
+ }
+
+
+ void noticeSizeChange() {
+ initializeOffImage();
+ }
+
+ private void initializeOffImage () {
+ int w = getSize().width;
+ int h = getSize().height;
+ if ( w > 0 & h > 0) {
+ offImage = createImage(w, h);
+ offGraphics = offImage.getGraphics();
+ }
+ }
+
+ /*
+ * In our double buffering scheme, painting just means copying the buffer
+ * to the screen. The Display aspect draws into the buffer.
+ */
+ public void paint(Graphics g) {
+ if (offImage != null)
+ g.drawImage(offImage, 0, 0, null);
+ }
+
+ public void update(Graphics g) {
+ /*
+ * There are 4 steps to this:
+ * - clear the double buffer
+ * - paint the objects into the double buffer
+ * - paint the status into the double buffer
+ * - paint the doublebuffer into the buffer
+ */
+ offGraphics.setColor(getBackground());
+ offGraphics.fillRect(0, 0, getBounds().width, getBounds().height);
+ paintObjects(offGraphics);
+ paintStatus(offGraphics);
+ g.drawImage(offImage, 0, 0, null);
+ }
+
+ void paintObjects(Graphics g) { }
+ void paintStatus(Graphics g) {}
+
+ static aspect DisplayAspect {
+
+ after (String mode) returning (Game game): call(Game+.new(String)) && args(mode) {
+ new Display1(game);
+ new Display2(game);
+
+ if ( mode.equals("1") ) {
+ pilot1 = game.newPlayer(1);
+ }
+ else if ( mode.equals("2") ) {
+ pilot1 = game.newPlayer(1);
+ pilot2 = game.newPlayer(2);
+ }
+ else if (mode. equals("demo")) {
+ pilot1 = game.newRobot(1);
+ pilot2 = game.newRobot(2);
+ } else {
+ game.error("Invalid mode: " + mode);
+ game.quit();
+ }
+ }
+
+
+ /*
+ * I'm not really sure this belongs here.
+ *
+ * Being here what it does is makes the Display aspect
+ * responsible for having the Players couple up to it. That's
+ * kind of nice, but its a bit incomplete, since Player is
+ * really part of the GUI, not part of the core Game.
+ *
+ * In a future re-factoring this will get worked out better.
+ * What will happen is that GUI will be an aspect that has the
+ * core GUI. Each of the different kinds of displays will be
+ * aspects that tie themselves in.
+ */
+ after () returning (Player player): call(Player+.new(..)) {
+ Enumeration elements = DISPLAYS.elements();
+ while ( elements.hasMoreElements() ) {
+ Display display = (Display)elements.nextElement();
+ display.addKeyListener(player);
+ }
+ }
+
+ after() returning (Display display): call(Display+.new(..)) {
+ display.noticeSizeChange();
+ }
+
+ after(Display display) returning (): call(void setSize(..)) && target(display) {
+ display.noticeSizeChange();
+ }
+
+ after() returning : call(void Game.clockTick()) {
+ Enumeration elements = DISPLAYS.elements();
+ while ( elements.hasMoreElements() ) {
+ Display display = (Display)elements.nextElement();
+ display.repaint();
+ }
+ }
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+Display1.java
+Part of the Spacewar system.
+*/
+
+package spacewar;
+
+
+import java.awt.Graphics;
+import java.awt.Color;
+import java.util.Random;
+
+/**
+ * This is the standard display aspect.
+ */
+class Display1 extends Display {
+ /*
+ * Here's the color scheme for the game. No other places in this file
+ * should say Color.xxx. Instead, that color should be given a symbolic
+ * name here.
+ */
+ private static Color backgroundColor = Color.black;
+ private static Color player1ShipColor = Color.white;
+ private static Color player2ShipColor = Color.gray;
+ private static Color robotShipColor = new Color(0xa00000);
+ private static Color flameColor = Color.red;
+ private static Color shipExplosionColor = Color.red;
+ private static Color bulletColor = Color.green;
+ private static Color energyPacketOuterColor = Color.blue;
+ private static Color energyPacketInnerColor = new Color(0x7070FF);
+ private static Color statusLabelsColor = Color.white;
+ private static Color statusMeterBorderColor = Color.white;
+ private static Color energyStatusMeterColor = Color.blue;
+ private static Color damageStatusMeterColor = Color.red;
+
+
+ Display1(Game game) {
+ super(game);
+ frame.setLocation(20, 20);
+ }
+
+ void noticeSizeChange() {
+ super.noticeSizeChange();
+ setBackground(backgroundColor);
+ }
+
+ void paintObjects(Graphics g) {
+ SpaceObject[] objects = game.getRegistry().getObjects();
+ final int len = objects.length;
+ for (int i = 0; i < len; i++) {
+ objects[i].paint(g);
+ }
+ }
+
+ static aspect SpaceObjectPainting {
+
+ abstract private void SpaceObject.paint(Graphics g);
+
+ /*
+ * Ships are by far and away the most complex of the space Objects
+ * to paint. First off, we need to set the color when the ship
+ * is made.
+ */
+ private Color Ship.color;
+
+ after(Pilot pilot) returning (Ship ship): call(Ship Game.newShip(Pilot)) && args(pilot) {
+ if (pilot.getNumber() == 1)
+ ship.color = player1ShipColor;
+ else if (pilot.getNumber() == 2)
+ ship.color = player2ShipColor;
+ else
+ ship.color = robotShipColor;
+ }
+
+ private void Ship.paint(Graphics g) {
+ final double PI = Math.PI;
+ int[] radius = {15, 12, -4, 12, -9, -15, -9};
+ double[] angle = {0, PI * 3/4, 0, -PI * 3/4, PI/8, 0, -PI/8};
+ int[] x;
+ int[] y;
+
+ Random random = new Random();
+
+ if (this.getDamage() >= this.MAX_DAMAGE) {
+ int lines = 20;
+ x = new int[lines];
+ y = new int[lines];
+ g.setColor(shipExplosionColor);
+ for (int i = 0; i < lines; i++) {
+ x[i] = (int)(this.getXPos()) + random.nextInt() % 20;
+ y[i] = (int)(this.getYPos()) + random.nextInt() % 20;
+ }
+ for (int i = 0; i < lines; i++)
+ g.drawLine(x[i], y[i], x[(i + 1) % lines], y[(i + 1) % lines]);
+ } else {
+ x = new int[7];
+ y = new int[7];
+
+ g.setColor(this.color);
+
+ radius[5] += random.nextInt() % 3;
+ // convert coordinates from polar to cartesian
+ for (int i = 0; i < 7; i++) {
+ x[i] = (int)
+ (this.getXPos() +
+ Math.cos(this.getOrientation() + angle[i]) * radius[i]);
+ y[i] = (int)
+ (this.getYPos() +
+ Math.sin(this.getOrientation() + angle[i]) * radius[i]);
+ }
+
+ // draw the body as a polygon
+ g.drawPolygon(x, y, 4);
+
+ // if the ship is accelerating, draw in a flame
+ if (this.getRAcc() != 0) {
+ g.setColor(flameColor);
+ g.drawLine(x[4], y[4], x[5], y[5]);
+ g.drawLine(x[5], y[5], x[6], y[6]);
+ }
+ }
+ }
+
+ /*
+ * Bullets
+ */
+ private void Bullet.paint(Graphics g) {
+ g.setColor(bulletColor);
+ g.fillOval((int)this.getXPos() - 1,
+ (int)this.getYPos() - 1,
+ 3,
+ 3);
+ }
+
+ /*
+ * energy packets
+ */
+ private void EnergyPacket.paint(Graphics g) {
+ g.setColor(energyPacketOuterColor);
+ g.fillOval((int)this.getXPos() - 5,
+ (int)this.getYPos() - 5,
+ 10, 10);
+ g.setColor(energyPacketInnerColor);
+ g.fillOval((int)this.getXPos() - 2,
+ (int)this.getYPos() - 2,
+ 3, 3);
+ }
+ }
+
+
+ void paintStatus(Graphics g) {
+ int left1 = 60;
+ int top1 = 0;
+
+ int left2 = 200;
+ int top2 = 0;
+
+ g.setColor(statusLabelsColor);
+ g.drawString("energy:", 5, top1 + 15);
+ g.drawString("damage:", 5, top1 + 30);
+
+ if (getPilot1() != null)
+ paintLevels(g, getPilot1().getShip(), top1, left1);
+ if (getPilot2() != null)
+ paintLevels(g, getPilot2().getShip(), top2, left2);
+ }
+
+ static void paintLevels(Graphics g, Ship ship, int top, int left) {
+ if (ship == null)
+ return;
+ else if (ship.isAlive()) {
+ g.setColor(statusMeterBorderColor);
+ g.drawRect(left, top + 6, 101, 10);
+ g.drawRect(left, top + 21, 101, 10);
+ g.setColor(energyStatusMeterColor);
+ g.fillRect(left + 1, top + 7, (int)(ship.getEnergyLevel()*100), 9);
+ g.setColor(damageStatusMeterColor);
+ g.fillRect(left + 1, top + 22, (int)(ship.getDamageLevel()*100), 9);
+ }
+ else {
+ g.setColor(damageStatusMeterColor);
+ g.drawString("Ship is destroyed", left+1, top+15);
+ }
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+Display2.java
+Part of the Spacewar system.
+*/
+
+package spacewar;
+
+
+import java.awt.Graphics;
+import java.awt.Color;
+
+
+/**
+ * This is the cheap Display aspect.
+ */
+class Display2 extends Display {
+
+ Display2(Game game) {
+ super(game);
+ frame.setLocation(540, 20);
+ }
+
+ void noticeSizeChange() {
+ super.noticeSizeChange();
+ setBackground(Color.darkGray);
+ }
+
+ void paintObjects(Graphics g) {
+ SpaceObject[] objects = game.getRegistry().getObjects();
+ final int len = objects.length;
+ for (int i = 0; i < len; i++) {
+ objects[i].paint(g);
+ }
+ }
+
+ static aspect SpaceObjectPainting {
+
+ abstract private void SpaceObject.paint(Graphics g);
+
+ /*
+ * Ships are by far and away the most complex of the space Objects
+ * to paint.
+ */
+ private Color Ship.color;
+
+ after(Pilot pilot) returning (Ship ship): call(Ship Game.newShip(Pilot)) && args(pilot) {
+ if (pilot.getNumber() == 1)
+ ship.color = Color.white;
+ else if (pilot.getNumber() == 2)
+ ship.color = Color.gray;
+ else
+ ship.color = new Color(0xa00000);
+ }
+
+ private void Ship.paint(Graphics g) {
+ if (this.getDamage() < this.MAX_DAMAGE) {
+ double x = this.getXPos();
+ double y = this.getYPos();
+ double sinTheta = Math.sin(this.getOrientation());
+ double cosTheta = Math.cos(this.getOrientation());
+
+ g.setColor(color);
+ g.drawLine((int)(x + 8*cosTheta), (int)(y + 8*sinTheta),
+ (int)(x - 8*cosTheta), (int)(y - 8*sinTheta));
+
+ // if the ship is accelerating, draw thruster
+ if (this.getRAcc() != 0) {
+ g.setColor(Color.red);
+ g.fillOval((int)(x - 8*cosTheta), (int)(y - 8*sinTheta), 6, 6);
+ }
+ }
+ }
+
+ private void Bullet.paint(Graphics g) {
+ g.setColor(Color.green);
+ g.fillOval((int)this.getXPos() - 1,
+ (int)this.getYPos() - 1,
+ 3,
+ 3);
+ }
+
+ private void EnergyPacket.paint(Graphics g) {
+ g.setColor(Color.white);
+ g.fillOval((int)this.getXPos() - 5,
+ (int)this.getYPos() - 5,
+ 10,
+ 10);
+ }
+ }
+
+ void paintStatus(Graphics g) {
+ int left1 = 60;
+ int top1 = 0;
+
+ int left2 = 200;
+ int top2 = 0;
+
+ g.setColor(Color.white);
+ g.drawString("energy:", 5, top1 + 15);
+ g.drawString("damage:", 5, top1 + 30);
+
+ if (getPilot1() != null)
+ paintLevels(g, getPilot1().getShip(), top1, left1);
+ if (getPilot2() != null)
+ paintLevels(g, getPilot2().getShip(), top2, left2);
+ }
+
+ void paintLevels(Graphics g, Ship ship, int top, int left) {
+ if (ship == null)
+ return;
+ else if (ship.isAlive()) {
+ g.drawString(Float.toString(ship.getEnergyLevel()*100), left+1, top+15);
+ g.drawString(Float.toString(ship.getDamageLevel()*100), left+1, top+30);
+ }
+ else {
+ g.setColor(Color.red);
+ g.drawString("Ship is destroyed", left+1, top+15);
+ }
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+EnergyPacket.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+
+class EnergyPacket extends SpaceObject {
+
+ static private final int SIZE = 5; //Can't be changed for now!!!
+ int getSize() { return SIZE; }
+
+ private double energy;
+
+ double getEnergy() { return energy; }
+
+ EnergyPacket(Game theGame,
+ double xP, double yP, double xV, double yV, double e) {
+ super(theGame, xP, yP, xV, yV);
+ energy = e;
+ }
+
+ void handleCollision(SpaceObject obj) {
+ die();
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+EnergyPacketProducer.java
+Part of the Spacewar system.
+
+ This implementation creates booby-trapped packets 20% of the time.
+
+*/
+
+package spacewar;
+
+
+class EnergyPacketProducer extends Thread {
+ private final static int MIN = -20;
+ private final static int MAX = 80;
+ private final static int EXPECTEDINTERVAL = 15;
+
+ private Game game;
+
+ Game getGame() { return game; }
+
+ EnergyPacketProducer(Game theGame) {
+ super("EnergyPacketProducer");
+ game = theGame;
+ }
+
+ public void run() {
+ while(true) {
+ produceAPacket();
+ waitForABit();
+ }
+ }
+
+ void waitForABit() {
+ try { Thread.sleep((int)(Math.random() * EXPECTEDINTERVAL * 2000)); }
+ catch (InterruptedException e) {}
+ }
+
+ void produceAPacket() {
+ EnergyPacket pkt =
+ new EnergyPacket(game,
+ Math.random() * getGame().getWidth(),
+ Math.random() * getGame().getHeight(),
+ Math.random() * 2 - 1,
+ Math.random() * 2 - 1,
+ Math.random() * (MAX - MIN) + MIN);
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+Ship.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+/**
+ * This aspect makes sure that the ship is alive before performing any console
+ * commands.
+ *
+ */
+aspect EnsureShipIsAlive {
+ void around (Ship ship): Ship.helmCommandsCut(ship) {
+ if ( ship.isAlive() ) {
+ proceed(ship);
+ }
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+Game.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+import java.awt.Dimension;
+
+/**
+ * The Game class is the root of the spacewar game. To start a spacewar
+ * game, you can either call the main method, or instantiate this class
+ * directly.
+ *
+ * Synchronization is done by the GameSynchronization aspect.
+ */
+public class Game extends Thread {
+
+ /**
+ * To run the game from top level, simply say Java Game, as usual. Passing
+ * an argument makes the game run in demo mode. Without an argument it runs
+ * in the normal player mode.
+ */
+ public static void main(String[] args) {
+ if ( args.length == 0 )
+ new Game("1").run();
+ new Game(args[0]).run();
+ }
+
+
+ private Timer timer;
+ private EnergyPacketProducer ePP;
+
+ private Registry registry;
+ private Pilot pilot1, pilot2;
+
+ private Dimension screenSize = new Dimension(500, 500);
+
+ Registry getRegistry() { return registry; }
+ Pilot getPilot1() { return pilot1; }
+ Pilot getPilot2() { return pilot2; }
+
+ /** returns the width of the screen, delegating to screenSize */
+ int getWidth() { return screenSize.width; }
+
+ /** returns the height of the screen, delegating to screenSize */
+ int getHeight() { return screenSize.height; }
+
+ /**
+ * To run the game, simply instantiate this class. It runs in its own
+ * thread. You can instantiate multiple games at once. For the time being
+ * the only way to end the game is to exit from the Java VM.
+ *
+ * @param mode Controls whether the game runs in demo mode or not. True
+ * means it is a demo, false means it runs in normal 2 player mode.
+ */
+ public Game(String mode) {
+ timer = new Timer(this);
+ ePP = new EnergyPacketProducer(this);
+ registry = new Registry(this);
+ }
+
+ public void run() {
+ timer.start();
+ ePP.start();
+
+ while(true) {
+ try {
+ newRobot(3);
+ Thread.sleep(15000);
+ }
+ catch (InterruptedException e) {}
+ }
+ }
+
+
+ /**
+ * add a robot to the game. This is a menu command.
+ */
+ void addRobot() {
+ newRobot(3);
+ }
+
+ /**
+ * resurrect the ships in the game. This is a menu command.
+ */
+ void resetShips() {
+ Ship[] ships = registry.getShips();
+
+ for (int i = 0; i < ships.length; i++) {
+ Ship ship = ships[i];
+ Pilot pilot = ship.getPilot();
+ newShip(pilot);
+ }
+ }
+
+ /**
+ * leave the game. This is a menu command.
+ */
+ void quit() {
+ System.exit(0);
+ }
+
+ void error(Object o) {
+ System.err.println(o);
+ }
+
+
+ /**
+ * returns a new player. With {@link #newRobot} and {@link
+ * #newShip}, the only ways to make a Player, a Robot, or a Ship.
+ * The structural invariant is that there should be no calls to
+ * new of one of these three classes outside these three methods.
+ */
+ Player newPlayer(int number) {
+ Player player = new Player(this, number);
+ newShip(player);
+ return player;
+ }
+
+ /**
+ * returns a new robot. With {@link #newPlayer} and {@link
+ * #newShip}, the only ways to make a Player, a Robot, or a Ship.
+ * The structural invariant is that there should be no calls to
+ * new of one of these three classes outside these three methods.
+ */
+ Robot newRobot(int number) {
+ Robot robot = new Robot(this, number);
+ newShip(robot);
+ robot.start();
+ return robot;
+ }
+
+ /**
+ * returns a new ship. With {@link #newRobot} and {@link
+ * #newPlayer}, the only ways to make a Player, a Robot, or a
+ * Ship. The structural invariant is that there should be no
+ * calls to new of one of these three classes outside these three
+ * methods.
+ */
+ Ship newShip(Pilot pilot) {
+ //
+ // If there is an old ship (we're doing a reset), then remove it from
+ // the registry.
+ //
+ Ship oldShip = pilot.getShip();
+ if (! (oldShip == null))
+ oldShip.die();
+
+ Ship newShip = new Ship(this,
+ Math.random() * getWidth(),
+ Math.random() * getHeight(),
+ Math.random() * Math.PI * 2);
+ pilot.setShip(newShip);
+ newShip.setPilot(pilot);
+
+ return newShip;
+ }
+
+ void clockTick() {
+ registry.clockTick();
+ handleCollisions();
+ }
+
+ // collision detection
+
+ void handleCollisions() {
+ SpaceObject[] objects = registry.getObjects();
+
+ SpaceObject objI, objJ;
+ for (int i = 0; i < objects.length; i++) {
+ objI = objects[i];
+ for (int j = i + 1; j < objects.length; j++) {
+ objJ = objects[j];
+ if (objI instanceof Bullet && objJ instanceof Bullet)
+ continue;
+ if (isCollision(objI, objJ)) {
+ if (objI instanceof Ship && objJ instanceof Ship)
+ Ship.bounce((Ship)(objI), (Ship)(objJ));
+ else {
+ objI.handleCollision(objJ);
+ objJ.handleCollision(objI);
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * Is the distance between the two centers less than the sum of the two
+ * radii. This is a cheap and dirty (i.e. wrong) implementation of this.
+ */
+ static boolean isCollision(SpaceObject a, SpaceObject b) {
+ return (Math.abs(a.getXPos() - b.getXPos()) +
+ Math.abs(a.getYPos() - b.getYPos())) <
+ (a.getSize()/2 + b.getSize()/2);
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+RegistrySynchronization.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+import coordination.Coordinator;
+
+/**
+ * This aspect ensures synchronized access to methods of the Game in the
+ * presence of several threads.
+ *
+ * It uses the Coordinator class, from the AspectJ coordination library.
+ * (This case is right on the borderline of being too simple to use the
+ * coordination library, but we use it anyways to keep the similarity
+ * with the RegistrySynchronizer.)
+ *
+ * It uses a per-Game coordination scheme, so there is one instance of
+ * this class for each instance of the Game class. When this class is
+ * constructed, it registers appropriate mutexes and selfexes using
+ * the behavior inherited from Coordinator.
+ *
+ * The coordination constraints for the Game are simple. We just need to
+ * make sure that newShip and handleCollisions are mutually exclusive. That
+ * ensures that they we can't destroy a ship that has just been replaced.
+ */
+aspect GameSynchronization extends Coordinator perthis(this(Game)) {
+
+ protected pointcut synchronizationPoint():
+ call(void Game.handleCollisions(..)) || call(Ship Game.newShip(..));
+
+ public GameSynchronization() {
+ addMutex(new String[] {"handleCollisions", "newShip"});
+ }
+
+}
--- /dev/null
+SHELL=bash
+ACJOPTS=-verbose -nosymbols
+AJC=ajc
+
+.PHONY: demo debug
+
+demo:
+ $(AJC) $(ACJOPTS) @demo.lst
+
+debug:
+ $(AJC) $(ACJOPTS) @debug.lst
+
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+*/
+
+package spacewar;
+
+
+/**
+ * Pilot is the abstract superclass of Player and Robot.
+ *
+ */
+
+abstract class Pilot {
+ private Game game;
+ private int number;
+ protected Ship ship = null;
+
+ Game getGame() { return game; }
+ int getNumber() { return number; }
+ Ship getShip() { return ship; }
+
+ void setShip(Ship s) { ship = s; }
+
+ Pilot (Game g, int n) {
+ super();
+ game = g;
+ number = n;
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+*/
+
+package spacewar;
+
+import java.awt.event.KeyListener;
+import java.awt.event.KeyEvent;
+
+class Player extends Pilot implements KeyListener {
+
+ private KeyMapping keyMapping;
+
+ /** current rotation key */
+ private int rotation_direction = Ship.STOP; // current rotation key
+
+ /** current thrust */
+ private boolean thrust_on = false;
+
+ Player(Game theGame, int number) {
+ super(theGame,number);
+
+ if (getNumber() == 1)
+ keyMapping = KeyMapping.keyMapping1;
+ else if (getNumber() == 2)
+ keyMapping = KeyMapping.keyMapping2;
+
+ }
+
+ public void keyPressed(KeyEvent e) {
+ int keyCode = e.getKeyCode();
+ boolean consumed = true;
+
+ if (keyCode == keyMapping.fire) {
+ ship.fire();
+ }
+ else if (keyCode == keyMapping.thrust && !thrust_on) {
+ ship.thrust(true);
+ thrust_on = true;
+ }
+ else if (keyCode == keyMapping.right &&
+ rotation_direction != Ship.COUNTERCLOCKWISE) {
+ //start rotating clockwise unless already rotating in the
+ //opposite direction
+ rotation_direction = Ship.CLOCKWISE;
+ ship.rotate(Ship.CLOCKWISE);
+ }
+ else if (keyCode == keyMapping.left &&
+ rotation_direction != Ship.CLOCKWISE) {
+ //start rotating counterclockwise unless already rotating in the
+ //opposite direction
+ rotation_direction = Ship.COUNTERCLOCKWISE;
+ ship.rotate(Ship.COUNTERCLOCKWISE);
+ }
+ else {
+ consumed = false;
+ }
+
+ if (consumed) e.consume();
+ }
+
+ public void keyReleased(KeyEvent e) {
+ int keyCode = e.getKeyCode();
+
+ if (keyCode == keyMapping.thrust) {
+ ship.thrust(false); //engine off
+ thrust_on = false;
+ }
+ else if (keyCode == keyMapping.right &&
+ rotation_direction == Ship.CLOCKWISE
+ ||
+ keyCode == keyMapping.left &&
+ rotation_direction == Ship.COUNTERCLOCKWISE) {
+ ship.rotate(Ship.STOP); //stop rotation
+ rotation_direction = Ship.STOP;
+ }
+ }
+
+ public void keyTyped(KeyEvent e) {
+ // have to implement this because it's in KeyListener
+ }
+}
+
+class KeyMapping {
+
+ static final KeyMapping keyMapping1 =
+ new KeyMapping(KeyEvent.VK_LEFT,
+ KeyEvent.VK_RIGHT,
+ KeyEvent.VK_UP,
+ KeyEvent.VK_SPACE);
+
+ static final KeyMapping keyMapping2 =
+ new KeyMapping(KeyEvent.VK_X,
+ KeyEvent.VK_V,
+ KeyEvent.VK_D,
+ KeyEvent.VK_ALT);
+
+ int left, right, thrust, fire;
+
+ KeyMapping(int k_left, int k_right, int k_thrust, int k_fire) {
+ left = k_left;
+ right = k_right;
+ thrust = k_thrust;
+ fire = k_fire;
+ }
+}
--- /dev/null
+[[_5]]
+== Exploring the Spacewar Example
+
+_© Copyright 1997-2001 Xerox Corporation. All rights reserved._
+
+_Last updated: January 10, 2001_
+
+The code in this directory is an implementation of the classic video
+game Spacewar.
+
+The Spacewar game is intended to provide a modest-sized example of a
+program that uses aspects. The code for this example is evolving, as we
+add new features to AspectJ and come up with a better understanding of
+how to use the features.
+
+In order to compile and run this example, make sure to have the latest
+version of AspectJ correctly installed. If you're not sure you do, try
+the helloworld example first by following the instructions in
+xref:../doc/primer/default.html[Primer] section Getting Started.
+
+[[_5_1]]
+=== Compiling Spacewar
+
+* Change to the `examples` directory.
+* Type `ajc -argfile spacewar/demo.lst` to compile the system.
+
+[[_5_2]]
+=== Running Spacewar
+
+* In the examples directory, type `java spacewar.Game`
+
+When the game starts up you will see two different displays. These are
+the two built-in display aspects of the game. In each you will see a
+single white ship and two red ships. The white ship is yours to control;
+the red ships are an enemy robots. Your ship is controlled with the four
+arrow keys to turn, thrust and stop; the spacebar fires. As you play,
+the game will be displayed in both windows.
+
+When running on a 1.4 or later VM, click in the main panel to give it
+focus so that your keystrokes are recognized.
+
+You can quit the game with ctl-Q.
+
+[[_5_3]]
+=== Exploring the Code
+
+There is one other built-in configurations for the Spacewar game. Try it
+by typing `ajc @spacewar\debug.lst`. This compiles in an elaborate
+debugging aspect for the game.
+
+We recommend you explore the Spacewar source code and look at the
+aspects that it uses. You will find several of them, of different scales
+and different degrees of cross-cutting. Remember that these represent
+our evolving understanding of how to use AspectJ to implement Spacewar.
+If you believe we should be doing something differently, then please let
+us know.
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+Registry.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+import java.util.Vector;
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/**
+ * The Registry keeps track of all the space objects that are floating around.
+ * It basically supports register, unregister and contents type operations.
+ *
+ * The synchronization is done by the RegistrySynchronization aspect.
+ */
+
+class Registry {
+
+ private Hashtable table;
+ private Game game;
+
+ Game getGame() { return game; }
+
+ Registry (Game theGame) {
+ game = theGame;
+ table = new Hashtable();
+ }
+
+
+ void register(SpaceObject object) {
+ table.put(object, object);
+ }
+
+ void unregister(SpaceObject object) {
+ table.remove(object);
+ }
+
+ /*
+ * It is an invariant of the design that only two points in SpaceObject
+ * should call register and unregister. This aspect enforces that.
+ *
+ * Unfortunately, in the current compiler, we get a static warning when
+ * there are no illegal calls that this advice has no targets. That will
+ * be fixed in a future release. For the time being the dummy method
+ * just below this fixes that.
+ */
+ static aspect RegistrationProtection {
+ after() returning():
+ (call(void Registry.register(SpaceObject)) ||
+ call(void Registry.unregister(SpaceObject))) &&
+ !(within(SpaceObject) && (withincode(new(..)) ||
+ withincode(void die()))) {
+ throw new IllegalAccessError(
+ "This is an illegal call to " + thisJoinPoint + "\n" +
+ "Only the constructor and the die() on SpaceObject\n" +
+ "should call the primitive registry operations.");
+ }
+ }
+
+ void dummy() { // see comment above
+ register(getObjects()[0]);
+ unregister(getObjects()[0]);
+ }
+
+
+ SpaceObject[] getObjects() {
+ SpaceObject[] allObjects = new SpaceObject[table.size()];
+ Enumeration elements = table.elements();
+ for(int i = 0; elements.hasMoreElements(); i++) {
+ allObjects[i] = (SpaceObject)(elements.nextElement());
+ }
+ return allObjects;
+ }
+
+ Ship[] getShips() {
+ //
+ // First we have to put just the Ships into a vector, then we can put
+ // them into an array of exactly the right length.
+ //
+ Ship[] arrayOfShips;
+ Vector vectorOfShips = new Vector();
+ Enumeration elements = table.elements();
+ while (elements.hasMoreElements()) {
+ Object object = elements.nextElement();
+ if (object instanceof Ship) {
+ vectorOfShips.addElement(object);
+ }
+ }
+
+ arrayOfShips = new Ship[(vectorOfShips.size())];
+ vectorOfShips.copyInto(arrayOfShips);
+ return arrayOfShips;
+ }
+
+ Hashtable getTable() { return table; }
+
+ //
+ // The protocol for clockTick is that it automatically cascades.
+ //
+ void clockTick() {
+ Enumeration elements = table.elements();
+ while (elements.hasMoreElements()) {
+ ((SpaceObject)elements.nextElement()).clockTick();
+ }
+ }
+}
+
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+RegistrySynchronization.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+import coordination.Coordinator;
+
+
+/**
+ * This aspect ensures synchronized access to methods of the Registry in
+ * the presence of several threads.
+ *
+ * It uses the Coordinator class, from the AspectJ coordination library.
+ *
+ * It uses a per-Registry coordination scheme, so there is one instance of
+ * this class for each instance of the Registry class. When this class is
+ * constructed, it registers appropriate mutexes and selfexes using the
+ * behavior inherited from Coordinator.
+ *
+ * The mutating methods (register and unregister) should be self-exclusive.
+ * Each reader method should be mutually exclusive with the mutating
+ * methods. But the readers can run concurrently. */
+aspect RegistrySynchronization extends Coordinator perthis(this(Registry)) {
+
+ protected pointcut synchronizationPoint():
+ call(void Registry.register(..)) ||
+ call(void Registry.unregister(..)) ||
+ call(SpaceObject[] Registry.getObjects(..)) ||
+ call(Ship[] Registry.getShips(..));
+
+ public RegistrySynchronization() {
+ addSelfex("register");
+ addSelfex("unregister");
+
+ addMutex(new String[] {"register", "unregister", "getObjects"});
+ addMutex(new String[] {"register", "unregister", "getShips"});
+ }
+
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+Robot.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+import java.util.Random;
+
+/**
+ * Robot is an automatic pilot that now has quite a bit of intelligence.
+ * So, beware !
+ */
+class Robot extends Pilot implements Runnable {
+
+ private static final int FIRE_INTERVAL = 60;
+ private static final int REBIRTH_DELAY = 900;
+
+ private final Random random = new Random();
+
+ private Thread runner;
+ private boolean runnable = true;
+
+ Robot(Game theGame, int number) {
+ super(theGame, number);
+ }
+
+ void start() {
+ if (runner == null) {
+ runner = new Thread(this);
+ runner.start();
+ }
+ }
+
+ void destroy() {
+ if (runner != null) {
+ runnable = false;
+ runner = null;
+ }
+ }
+
+
+ // A Robot tracks User-controlled ships and fires at them
+ public void run() {
+ Ship target = null;
+
+ while(runnable) {
+ // find target ship
+ do {
+ Ship[] potentials = getGame().getRegistry().getShips();
+ if(potentials.length != 0)
+ target = potentials[Math.abs(random.nextInt() % potentials.length)];
+ sleepForABit(25);
+ } while (target == ship);
+ // main loop
+ int currentRotation = Ship.STOP;
+ int time;
+ boolean currentlyAccelerating = false;
+ double dx, dy, angleA, angleB, theta, dtheta, d,
+ targetVel, a, b, c, targetXVel, targetYVel;
+
+ while(true) {
+ sleepForABit(FIRE_INTERVAL);
+
+ // if my ship is destroyed, give me a new one
+ if (!ship.isAlive()) {
+ sleepForABit(REBIRTH_DELAY);
+ getGame().newShip(this);
+ }
+
+ // find direction and distance from target to me
+ dx = ship.getXPos() - target.getXPos();
+ if (dx < - getGame().getWidth() / 2)
+ dx += getGame().getWidth();
+ if (dx > getGame().getWidth() / 2)
+ dx -= getGame().getWidth();
+ dy = ship.getYPos() - target.getYPos();
+ if (dy < - getGame().getHeight() / 2)
+ dy += getGame().getHeight();
+ if (dy > getGame().getHeight() / 2)
+ dy -= getGame().getHeight();
+ d = Math.sqrt(dx * dx + dy * dy);
+ angleA = Math.atan(dy / dx);
+ if (dx < 0)
+ angleA += Math.PI;
+
+ // find relative velocity and trajectory of target
+ targetXVel = target.getXVel() - ship.getXVel();
+ targetYVel = target.getYVel() - ship.getYVel();
+ targetVel = Math.sqrt(targetXVel * targetXVel +
+ targetYVel * targetYVel);
+ angleB = Math.atan(targetYVel / targetXVel);
+ if (targetXVel < 0)
+ angleB+=Math.PI;
+
+ // find angle between line to target and taget's direction of travel
+ theta = (angleA - angleB) % (2 * Math.PI);
+ if (theta < -Math.PI)
+ theta += 2 * Math.PI;
+ if (theta > Math.PI)
+ theta -= 2 * Math.PI;
+
+ // calculate time to bullet impact using law of cosines
+ a = targetVel * targetVel + Ship.BULLET_SPEED * Ship.BULLET_SPEED;
+ b = d * targetVel * Math.cos(theta);
+ c = - d * d;
+ time = (int)((-b + Math.sqrt(b * b - 4 * a * c)) / 2 / a);
+
+ // calculate angle and distance to bullet impact location
+ dx = targetXVel * time - dx;
+ dy = targetYVel * time - dy;
+ theta = Math.atan(dy / dx);
+ if(dx < 0)
+ theta += Math.PI;
+
+ // find desired change in rotation
+ dtheta = (theta - ship.getOrientation()) % (2 * Math.PI);
+ // find the shortest path to the desired orientation;
+ if(dtheta < - Math.PI)
+ dtheta += 2 * Math.PI;
+ if(dtheta > Math.PI)
+ dtheta -= 2 * Math.PI;
+
+ // turn if nessecary
+ if (dtheta > Ship.DEFAULT_ANGULAR_VELOCITY / 2) {
+ if (currentRotation != Ship.CLOCKWISE)
+ ship.rotate(currentRotation = Ship.CLOCKWISE);
+ }
+ else if (dtheta < -Ship.DEFAULT_ANGULAR_VELOCITY / 2) {
+ if (currentRotation != Ship.COUNTERCLOCKWISE)
+ ship.rotate(currentRotation = Ship.COUNTERCLOCKWISE);
+ } // otherwise, fire, maybe even a burst
+ else {
+ if(currentRotation != Ship.STOP)
+ ship.rotate(currentRotation = Ship.STOP);
+ if (random.nextInt() % 40 == 0) {
+ ship.fire();
+ }
+ }
+
+ // randomly accelerate
+ if (currentlyAccelerating && random.nextInt() % 2 == 0)
+ ship.thrust(currentlyAccelerating = false);
+ else {
+ if (ship.getXVel() == 0)
+ angleA = 0;
+ else
+ angleA = Math.atan(ship.getYVel() / ship.getXVel());
+
+ if (ship.getXVel() < 0)
+ angleA+=Math.PI;
+ angleB = (angleA - ship.getOrientation()) % (2 * Math.PI);
+ if (angleB < -Math.PI)
+ angleB += 2 * Math.PI;
+ if (angleB > Math.PI)
+ angleB -= 2 * Math.PI;
+ angleB = Math.abs(angleB);
+
+ // angleB now represents the angle between the ship's
+ // orientation and velocity vector. This will be used to
+ // determine the probably that the ship will thrust to
+ // prevent ships from accelerating too much in one direction
+ if (random.nextInt() % (int)(12 * (Math.PI - angleB) + 1) == 0)
+ ship.thrust(currentlyAccelerating = true);
+ }
+
+ // switch targets if current one has been destroyed
+ if (target.getDamage() == 100)
+ break;
+
+ // randomly switch targets
+ if (random.nextInt() % 4000 == 0)
+ break;
+ }
+ }
+ }
+
+ void sleepForABit (int time) {
+ try {
+ runner.sleep(time);
+ }
+ catch (InterruptedException e) {}
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+SWFrame.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+import java.awt.Frame;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuItem;
+import java.awt.MenuShortcut;
+import java.awt.Dimension;
+import java.awt.Insets;
+
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+class SWFrame extends Frame implements ActionListener {
+ private Game game;
+ private Display display;
+ private Menu menu;
+
+ Game getGame() { return game; }
+ Display getDisplay() { return display; }
+ Menu getMenu() { return menu; }
+
+ SWFrame(Game theGame, Display d) {
+ super("Space War!");
+
+ game = theGame;
+
+ display = d;
+ add(display);
+
+ // create menu
+ menu = new Menu("Game");
+ MenuItem item1 = new MenuItem("Add Robot", new MenuShortcut('a'));
+ MenuItem item2 = new MenuItem("Reset Ships", new MenuShortcut('r'));
+ MenuItem item3 = new MenuItem("Quit", new MenuShortcut('q'));
+ item1.setActionCommand("Add Robot");
+ item2.setActionCommand("Reset Ships");
+ item3.setActionCommand("Quit");
+ menu.add(item1);
+ menu.add(item2);
+ menu.add(item3);
+ menu.addActionListener(this);
+
+ setMenuBar(new MenuBar());
+ getMenuBar().add(menu);
+
+ Dimension screenSize = new Dimension(500, 500);
+ setSize(screenSize);
+ setVisible(true);
+ toFront();
+
+ Insets inset = getInsets();
+ int displayWidth = screenSize.width - inset.left - inset.right;
+ int displayHeight = screenSize.height - inset.top - inset.bottom;
+ display.setSize(displayWidth, displayHeight);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ String s = e.getActionCommand();
+ if (s.equals("Add Robot")) {
+ getGame().addRobot();
+ }
+ else if (s.equals("Reset Ships")) {
+ getGame().resetShips();
+ }
+ else if (s.equals("Quit")) {
+ getGame().quit();
+ }
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+Ship.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+class Ship extends SpaceObject {
+
+ pointcut helmCommandsCut(Ship ship):
+ target(ship) && ( call(void rotate(int)) ||
+ call(void thrust(boolean)) ||
+ call(void fire()) );
+
+
+ /**
+ * Energy and Damage are key values in the state of a ship. Energy is
+ * basically about fuel, and damage is about how bad a shape we are in.
+ *
+ * The energy related values are:
+ * <ul>
+ * <li>MAX_ENERGY</li>
+ * <li>BULLET_ENERGY</li>
+ * <li>ACCELERATION_ENERGY_FACTOR</li>
+ * <li>energy</li>
+ * </ul>
+ * The damage related values are:
+ * <ul>
+ * <li>MAX_DAMAGE</li>
+ * <li>BULLET_DAMAGE</li>
+ * <li>COLLISION_DAMAGE_FACTOR</li>
+ * <li>damage</li>
+ * </ul>
+ * Finally, REPAIR_RATE is the rate at which energy is consumed to fix
+ * damage.
+ *
+ */
+ private static final int MAX_ENERGY = 100;
+ private static final int BULLET_ENERGY= 2;
+ private static final double ACCELERATION_COST_FACTOR = 0.05;
+
+ //XXX was private
+ static final int MAX_DAMAGE = 100;
+ private static final int BULLET_DAMAGE = 15;
+ private static final double COLLISION_DAMAGE_FACTOR = 0.1;
+
+ private static final double REPAIR_RATE = 0.08;
+
+
+ private static final int EXPLOSION_LENGTH = 10;
+
+ static final int BULLET_SPEED = 10;
+
+ static final int CLOCKWISE = 1;
+ static final int STOP = 0;
+ static final int COUNTERCLOCKWISE = (-1);
+
+ static final double DEFAULT_ANGULAR_VELOCITY = 0.2;
+ static final double DEFAULT_ACCELERATION = .4;
+
+ static private final int SIZE = 30; //Can't be changed for now!!!
+
+ private double energy; // range: 0 to MAX_ENERGY
+ private double damage; // range: 0 to MAX_DAMAGE
+ private double orientation; // in degrees
+ private double angularVel; // in ???
+ private double xAcc, yAcc, rAcc; //
+ private int countdown; // remaining explosion time
+
+ private Pilot pilot;
+
+ Ship(Game theGame, double xPos, double yPos, double orientation) {
+ super(theGame, xPos, yPos, 0, 0);
+ xAcc = 0;
+ yAcc = 0;
+ this.orientation = orientation;
+ angularVel = 0;
+
+ energy = MAX_ENERGY;
+ damage = 0;
+ countdown = EXPLOSION_LENGTH;
+ }
+
+
+ int getSize() { return SIZE; }
+
+ double getEnergy() { return energy; }
+ double getDamage() { return damage; }
+ double getOrientation() { return orientation; }
+ double getRAcc() { return rAcc; }
+
+ Pilot getPilot() { return pilot; }
+ void setPilot (Pilot p) { pilot = p; }
+
+ float getEnergyLevel() {
+ return (float)energy / (float)MAX_ENERGY;
+ }
+ float getDamageLevel() {
+ return (float)damage / (float)MAX_DAMAGE;
+ }
+
+ /** returns false if energy is out, otherwise decrements energy by amount
+ * and returns true
+ */
+ boolean expendEnergy(double amount) {
+ if (amount <= energy) {
+ energy -= amount;
+ return true;
+ }
+ else
+ return false;
+ }
+
+ /** increments damage by amount and handles the destruction of a ship if
+ * damage reaches MAX_DAMAGE.
+ */
+ void inflictDamage(double amount) {
+ if (amount < 0) // shouldn't happen
+ return;
+ damage = Math.min(MAX_DAMAGE, damage + amount);
+ if (damage == MAX_DAMAGE)
+ setIsAlive(false);
+ }
+
+ /** repairs some damage
+ */
+ void repairDamage(double amount) {
+ if (amount < 0) // shouldn't happen
+ return;
+ if (damage == 0)
+ return;
+ damage = Math.max(0, damage - amount);
+ }
+
+ public void clockTick() {
+ if (! isAlive()) {
+ //
+ // If we aren't alive, but we are still in the registry, it means
+ // we are exploding. countdown counts the length of the explosion.
+ //
+ if (--countdown == 0)
+ die();
+ }
+ else {
+ if (angularVel != 0) {
+ orientation += angularVel;
+ xAcc = rAcc * Math.cos(orientation);
+ yAcc = rAcc * Math.sin(orientation);
+ }
+ setXVel(getXVel() + xAcc);
+ setYVel(getYVel() + yAcc);
+
+ //expend energy
+ if (!expendEnergy(rAcc * ACCELERATION_COST_FACTOR))
+ rAcc = xAcc = yAcc = 0;
+
+ // fix damage
+ if (energy > 10 && damage > REPAIR_RATE) {
+ expendEnergy(REPAIR_RATE);
+ repairDamage(REPAIR_RATE);
+ }
+ }
+ super.clockTick();
+ }
+
+ /**
+ * First check to make sure we have enough energy to accelerate. If
+ * we do, then go ahead and do so. Acceleration is in the direction
+ * we are already facing (i.e. orientation).
+ */
+ void setAcceleration(double acc) {
+ if (acc * ACCELERATION_COST_FACTOR <= energy) {
+ rAcc = acc;
+ xAcc = rAcc * Math.cos(orientation);
+ yAcc = rAcc * Math.sin(orientation);
+ }
+ }
+
+ /**
+ * First check to make sure we have enough energy to rotate. If
+ * we do, then go ahead and do so.
+ */
+ void setAngularVelocity(double omega) {
+ // changing direction of rotation takes energy
+ if (!expendEnergy(Math.abs(omega - angularVel) / 2))
+ return;
+ //sets amount of degree rotation per clock tick, in radians;
+ //clockwise is positive
+ angularVel = omega;
+ }
+
+ /** affect rotation thrusters. Direction can be one of {@link
+ * #CLOCKWISE}, {@link #COUNTERCLOCKWISE}, or zero for turning off
+ * the thrusters.
+ */
+ void rotate(int direction) {
+ setAngularVelocity(
+ direction == CLOCKWISE ? DEFAULT_ANGULAR_VELOCITY :
+ direction == COUNTERCLOCKWISE ? -DEFAULT_ANGULAR_VELOCITY :
+ 0);
+ }
+
+ /** turn on acceleration */
+ void thrust(boolean onOff) {
+ setAcceleration(onOff ? DEFAULT_ACCELERATION : 0);
+ }
+
+ /** create a bullet and fire it */
+ void fire() {
+ // firing a shot takes energy
+ if (!expendEnergy(BULLET_ENERGY))
+ return;
+
+ //create a bullet object so it doesn't hit the ship that's firing it
+ double xV = getXVel() + BULLET_SPEED * (Math.cos(orientation));
+ double yV = getYVel() + BULLET_SPEED * (Math.sin(orientation));
+
+ // create the actual bullet
+ new Bullet(
+ getGame(),
+ (getXPos() + ((getSize()/2 + 2) * (Math.cos(orientation))) + xV),
+ (getYPos() + ((getSize()/2 + 2) * (Math.sin(orientation))) + yV),
+ xV,
+ yV);
+ }
+
+
+ void handleCollision(SpaceObject obj) {
+ if (obj instanceof Ship) {
+ // should never be called. ship - ship collisions are handled in
+ // Ship.bounce(Ship shipA, Ship shipB)
+ }
+ else if (obj instanceof Bullet) {
+ inflictDamage(BULLET_DAMAGE);
+ }
+ else if (obj instanceof EnergyPacket) {
+ double packetEnergy = ((EnergyPacket)obj).getEnergy();
+ energy = Math.max(0, Math.min(energy + packetEnergy, MAX_ENERGY));
+ }
+ else {
+ System.err.println("collision with UFO!");
+ }
+ }
+
+ static void bounce(Ship shipA, Ship shipB) {
+ double dx, dy, denominator,
+ xAccA, yAccA, xAccB, yAccB, damage,
+ xComp, yComp, dvx, dvy;
+
+ dx = Math.abs(shipA.getXPos() - shipB.getXPos());
+ dy = Math.abs(shipA.getYPos() - shipB.getYPos());
+ denominator = Math.sqrt(dx * dx + dy * dy);
+ xComp = dx / denominator;
+ yComp = dy / denominator;
+ xAccA = shipB.getXVel() * xComp + shipA.getXVel() * (1 - xComp) -
+ shipA.getXVel();
+ yAccA = shipB.getYVel() * yComp + shipA.getYVel() * (1 - yComp) -
+ shipA.getYVel();
+ xAccB = shipA.getXVel() * xComp + shipB.getXVel() * (1 - xComp) -
+ shipB.getXVel();
+ yAccB = shipA.getYVel() * yComp + shipB.getYVel() * (1 - yComp) -
+ shipB.getYVel();
+ shipA.accelerate(xAccA, yAccA);
+ shipB.accelerate(xAccB, yAccB);
+ dvx = shipA.getXVel() - shipB.getXVel();
+ dvy = shipA.getYVel() - shipA.getYVel();
+ damage = COLLISION_DAMAGE_FACTOR * (dvx * dvx + dvy * dvy);
+ shipA.inflictDamage(damage);
+ shipB.inflictDamage(damage);
+
+ // !!!
+ // !!! poopers! this does a local time warp. this has to be a
+ // !!! violation of the clockTick protocol
+ // !!!
+ while (Game.isCollision(shipA, shipB)) {
+ shipA.clockTick();
+ shipB.clockTick();
+ }
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+SpaceObject.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+
+/**
+ * SpaceObjects are objects that float around in space. They support the
+ * minimal SpaceObject protocol, having to do with position, velocity,
+ * size and liveness. They are constructed with game, position, velocity
+ * and size. When constructed, a spaceobject adds itself to the registry.
+ *
+ * When it dies, a spaceobject removes itself from the registry. But note
+ * that it doesn't decide when to die, subclasses do that.
+ *
+ * The display aspects actually draw the space object on the screen and say
+ * how much space it takes up there.
+ */
+abstract class SpaceObject {
+
+ private Game game;
+ private double xPos, yPos, oldXPos, oldYPos, xVel, yVel;
+ private boolean alive;
+
+ SpaceObject (Game theGame, double xP, double yP, double xV, double yV) {
+ game = theGame;
+ xPos = xP;
+ yPos = yP;
+ oldXPos = xP;
+ oldYPos = yP;
+ xVel = xV;
+ yVel = yV;
+
+ alive = true;
+ getGame().getRegistry().register(this);
+ }
+
+ Game getGame() { return game; }
+
+ double getXPos() { return xPos; }
+ double getYPos() { return yPos; }
+
+ double getOldXPos() { return oldXPos; }
+ double getOldYPos() { return oldYPos; }
+
+ double getXVel() { return xVel; }
+ double getYVel() { return yVel; }
+
+ void setXVel (double n) { xVel = n; }
+ void setYVel (double n) { yVel = n; }
+
+ boolean isAlive() { return alive; }
+ void setIsAlive(boolean n) { alive = n; }
+
+
+ /**
+ * Move 1 unit of time's worth of distance. I.e. increment xPos by xVel
+ * and yPos by yVel. If we move off an edge of the screen move us back
+ * in the opposite edge.
+ */
+ void clockTick() {
+ oldXPos = xPos;
+ oldYPos = yPos;
+ xPos = (xPos + xVel) % getGame().getWidth();
+ if(xPos < 0)
+ xPos += getGame().getWidth();
+ yPos = (yPos + yVel) % getGame().getHeight();
+ if(yPos < 0)
+ yPos += getGame().getHeight();
+ }
+
+ void accelerate(double dXVel, double dYVel) {
+ xVel += dXVel;
+ yVel += dYVel;
+ }
+
+ void die() {
+ getGame().getRegistry().unregister(this);
+ }
+
+ abstract int getSize();
+
+ /** resolve the effects of colliding with a space object.
+ * @param obj the space object that this object is colliding with.
+ */
+ abstract void handleCollision(SpaceObject obj);
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+Timer.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+
+class Timer extends Thread {
+
+ private final static int TICK_PERIOD = 40; // time between ticks in millis
+
+ private Game game;
+
+ Game getGame() { return game; }
+
+ Timer (Game theGame) {
+ super("Timer");
+ game = theGame;
+ }
+
+ public void run() {
+ long t1, tdiff;
+ while (true) {
+ t1 = System.currentTimeMillis();
+ getGame().clockTick();
+ tdiff = System.currentTimeMillis() - t1;
+ if (tdiff < TICK_PERIOD) {
+ try {
+ sleep (Math.max(0 , TICK_PERIOD - tdiff));
+ }
+ catch (InterruptedException e) { }
+ }
+ }
+ }
+}
--- /dev/null
+@demo.lst
+Debug.java
--- /dev/null
+@../coordination/lib.lst
+Bullet.java
+EnergyPacket.java
+EnergyPacketProducer.java
+Game.java
+GameSynchronization.java
+Pilot.java
+Registry.java
+RegistrySynchronization.java
+Robot.java
+Ship.java
+EnsureShipIsAlive.java
+SpaceObject.java
+Timer.java
+SWFrame.java
+Display.java
+Display1.java
+Display2.java
+Player.java
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+public abstract class AbstractSimulation {
+
+ public static AbstractSimulation simulation;
+
+ /**
+ * Creates objects and puts them to work.
+ */
+ public void run() {
+ Customer jim = new Customer("Jim", 650);
+ Customer mik = new Customer("Mik", 650);
+ Customer crista = new Customer("Crista", 415);
+
+ say("jim calls mik...");
+ Call c1 = jim.call(mik);
+ wait(1.0);
+ say("mik accepts...");
+ mik.pickup(c1);
+ wait(2.0);
+ say("jim hangs up...");
+ jim.hangup(c1);
+ report(jim);
+ report(mik);
+ report(crista);
+
+ say("mik calls crista...");
+ Call c2 = mik.call(crista);
+ say("crista accepts...");
+ crista.pickup(c2);
+ wait(1.5);
+ say("crista hangs up...");
+ crista.hangup(c2);
+ report(jim);
+ report(mik);
+ report(crista);
+ }
+
+ /**
+ * Print a report of the connection time for customer
+ */
+ abstract protected void report(Customer c);
+
+ /**
+ * Wait 0.1 seconds per "second" for simulation
+ */
+ protected static void wait(double seconds) {
+ Object dummy = new Object();
+ synchronized (dummy) {
+ //XXX cheat and only wait 0.1 seconds per second
+ try {dummy.wait((long)(seconds*100)); }
+ catch (Exception e) {}
+ }
+ }
+
+ /**
+ * Put a message on standard output
+ */
+ protected static void say(String s){
+ System.out.println(s);
+ }
+
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+/**
+ * This simulation subclass implements AbstractSimulation.run(..)
+ * with a test script for the telecom system with only the
+ * basic objects.
+ */
+public class BasicSimulation extends AbstractSimulation {
+
+ public static void main(String[] args){
+ simulation = new BasicSimulation();
+ simulation.run();
+ }
+
+ protected void report(Customer c) { }
+
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package telecom;
+/**
+ * The Billing aspect deals with... billing.
+ * How much money did each connection cost?
+ * How much money did each call cost?
+ * How much money is being debited to a customer?
+ * This aspect can be used by other parts of the system. (not in this example)
+ *
+ * Billing can depend many things, such as timing, the type of the connection,
+ * some special discounts the customer has, special features, etc. In here,
+ * it depends only on timing and on the type of the connection.
+ */
+public aspect Billing {
+ // precedence required to get advice on endtiming in the right order
+ declare precedence: Billing, Timing;
+
+ public static final long LOCAL_RATE = 3;
+ public static final long LONG_DISTANCE_RATE = 10;
+
+ public Customer Connection.payer;
+ public Customer getPayer(Connection conn) { return conn.payer; }
+ /**
+ * Caller pays for the call
+ */
+ after(Customer cust) returning (Connection conn):
+ args(cust, ..) && call(Connection+.new(..)) {
+ conn.payer = cust;
+ }
+
+ /**
+ * Connections give the appropriate call rate
+ */
+ public abstract long Connection.callRate();
+
+
+ public long LongDistance.callRate() { return LONG_DISTANCE_RATE; }
+ public long Local.callRate() { return LOCAL_RATE; }
+
+
+ /**
+ * When timing stops, calculate and add the charge from the
+ * connection time
+ */
+ after(Connection conn): Timing.endTiming(conn) {
+ long time = Timing.aspectOf().getTimer(conn).getTime();
+ long rate = conn.callRate();
+ long cost = rate * time;
+ getPayer(conn).addCharge(cost);
+ }
+
+
+ /**
+ * Customers have a bill paying aspect with state
+ */
+ public long Customer.totalCharge = 0;
+ public long getTotalCharge(Customer cust) { return cust.totalCharge; }
+
+ public void Customer.addCharge(long charge){
+ totalCharge += charge;
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+/**
+ * This simulation subclass implements AbstractSimulation.report(..)
+ *
+ */
+public class BillingSimulation extends AbstractSimulation {
+
+ public static void main(String[] args){
+ System.out.println("\n... Billing simulation 2 ...\n");
+ simulation = new BillingSimulation();
+ simulation.run();
+ }
+
+ /**
+ * Print a report of the connection time and the bill for customer
+ */
+ protected void report(Customer c){
+ Timing t = Timing.aspectOf();
+ Billing b = Billing.aspectOf();
+ System.out.println(c + " has been connected for "
+ + t.getTotalConnectTime(c)
+ + " seconds and has a bill of "
+ + b.getTotalCharge(c));
+ }
+}
+
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+import java.util.Vector;
+import java.util.Enumeration;
+
+/**
+ * A call supports the process of a customer trying to
+ * connect to others.
+ */
+public class Call {
+
+ private Customer caller, receiver;
+ private Vector connections = new Vector();
+
+ /**
+ * Create a new call connecting caller to receiver
+ * with a new connection. This should really only be
+ * called by Customer.call(..)
+ */
+ public Call(Customer caller, Customer receiver) {
+ this.caller = caller;
+ this.receiver = receiver;
+ Connection c;
+ if (receiver.localTo(caller)) {
+ c = new Local(caller, receiver);
+ } else {
+ c = new LongDistance(caller, receiver);
+ }
+ connections.addElement(c);
+ }
+
+ /**
+ * picking up a call completes the current connection
+ * (this means that you shouldnt merge calls until
+ * they are completed)
+ */
+ public void pickup() {
+ Connection connection = (Connection)connections.lastElement();
+ connection.complete();
+ }
+
+
+ /**
+ * Is the call in a connected state?
+ */
+ public boolean isConnected(){
+ return ((Connection)connections.lastElement()).getState()
+ == Connection.COMPLETE;
+ }
+
+ /**
+ * hanging up a call drops the connection
+ */
+ public void hangup(Customer c) {
+ for(Enumeration e = connections.elements(); e.hasMoreElements();) {
+ ((Connection)e.nextElement()).drop();
+ }
+ }
+
+ /**
+ * is Customer c one of the customers in this call?
+ */
+ public boolean includes(Customer c){
+ boolean result = false;
+ for(Enumeration e = connections.elements(); e.hasMoreElements();) {
+ result = result || ((Connection)e.nextElement()).connects(c);
+ }
+ return result;
+ }
+
+ /**
+ * Merge all connections from call 'other' into 'this'
+ */
+ public void merge(Call other){
+ for(Enumeration e = other.connections.elements(); e.hasMoreElements();){
+ Connection conn = (Connection)e.nextElement();
+ other.connections.removeElement(conn);
+ connections.addElement(conn);
+ }
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+/**
+ * Connections are circuits between customers
+ * There are two kinds: local and long distance
+ * see subclasses at the end of this file.
+ */
+public abstract class Connection {
+
+ public static final int PENDING = 0;
+ public static final int COMPLETE = 1;
+ public static final int DROPPED = 2;
+
+ Customer caller, receiver;
+ private int state = PENDING;
+
+ /**
+ * Creatte a new Connection between a and b
+ */
+ Connection(Customer a, Customer b) {
+ this.caller = a;
+ this.receiver = b;
+ }
+
+ /**
+ * what is the state of the connection?
+ */
+ public int getState(){
+ return state;
+ }
+
+ /**
+ * get the customer who initiated this connection
+ */
+ public Customer getCaller() { return caller; }
+
+ /**
+ * get the customer who received this connection
+ */
+ public Customer getReceiver() { return receiver; }
+
+ /**
+ * Called when a call is picked up. This means the b side has picked up
+ * and the connection should now complete itself and start passing data.
+ */
+ void complete() {
+ state = COMPLETE;
+ System.out.println("connection completed");
+ }
+
+ /**
+ * Called when the connection is dropped from a call. Is intended to
+ * free up any resources the connection was consuming.
+ */
+ void drop() {
+ state = DROPPED;
+ System.out.println("connection dropped");
+ }
+
+ /**
+ * Is customer c connected by this connection?
+ */
+ public boolean connects(Customer c){
+ return (caller == c || receiver == c);
+ }
+
+}
+
+
+
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+import java.util.Vector;
+
+/**
+ * Customers have a unique id (name in this case for didactic purposes
+ * but it could be telephone number) and area code.
+ * They also have protocol for managing calls: call, pickup, etc.
+ */
+public class Customer {
+
+ private String name;
+ private int areacode;
+ private Vector calls = new Vector();
+
+ /**
+ * unregister a call
+ */
+ protected void removeCall(Call c){
+ calls.removeElement(c);
+ }
+
+ /**
+ * register a call
+ */
+ protected void addCall(Call c){
+ calls.addElement(c);
+ }
+
+ /**
+ * Make a new customer with given name
+ */
+ public Customer(String name, int areacode) {
+ this.name = name;
+ this.areacode = areacode;
+ }
+
+ /**
+ * String rendition of customer
+ */
+ public String toString() {
+ return name + "(" + areacode + ")";
+ }
+
+ /**
+ * what area is the customer in?
+ */
+ public int getAreacode(){
+ return areacode;
+ }
+
+ /**
+ * Is the other customer in the same area?
+ */
+ public boolean localTo(Customer other){
+ return areacode == other.areacode;
+ }
+
+ /**
+ * Make a new call to receiver
+ */
+ public Call call(Customer receiver) {
+ Call call = new Call(this, receiver);
+ addCall(call);
+ return call;
+ }
+
+ /**
+ * pick up a call
+ */
+ public void pickup(Call call) {
+ call.pickup();
+ addCall(call);
+ }
+
+ /**
+ * hang up a call
+ */
+ public void hangup(Call call) {
+ call.hangup(this);
+ removeCall(call);
+ }
+
+ /**
+ * Merge a pair of calls -- conference them
+ * PRE: call1.includes(this)
+ * call2.includes(this)
+ * call1.connected()
+ * call2.connected()
+ * POST: call1 includes all customers connected by call1@pre and call2@pre
+ */
+ public void merge(Call call1, Call call2){
+ call1.merge(call2);
+ removeCall(call2);
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+public class Local extends Connection {
+ Local(Customer a, Customer b) {
+ super(a, b);
+ System.out.println("[new local connection from " +
+ a + " to " + b + "]");
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+public class LongDistance extends Connection {
+ LongDistance(Customer a, Customer b) {
+ super(a, b);
+ System.out.println("[new long distance connection from " +
+ a + " to " + b + "]");
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+
+/**
+ * Simple timer machine used to record elapsed time
+ */
+public class Timer {
+ public long startTime, stopTime;
+
+ /**
+ * set the start time
+ */
+ public void start() {
+ startTime = System.currentTimeMillis();
+ stopTime = startTime;
+ }
+
+ /**
+ * set the end time
+ */
+ public void stop() {
+ stopTime = System.currentTimeMillis();
+ }
+
+ /**
+ * set how much time passed between last start and stop?
+ */
+ public long getTime() {
+ return stopTime - startTime;
+ }
+}
+
+
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+package telecom;
+
+public aspect TimerLog {
+
+ after(Timer t): target(t) && call(* Timer.start()) {
+ System.err.println("Timer started: " + t.startTime);
+ }
+
+ after(Timer t): target(t) && call(* Timer.stop()) {
+ System.err.println("Timer stopped: " + t.stopTime);
+ }
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package telecom;
+
+/**
+ * The Timing aspect is concerned with the duration
+ * of connections and with customer's cumulative
+ * connection time.
+ */
+public aspect Timing {
+
+ /**
+ * Every Customer has a total connection time
+ */
+ public long Customer.totalConnectTime = 0;
+
+ public long getTotalConnectTime(Customer cust) {
+ return cust.totalConnectTime;
+ }
+ /**
+ * Every connection has a timer
+ */
+ private Timer Connection.timer = new Timer();
+ public Timer getTimer(Connection conn) { return conn.timer; }
+
+ /**
+ * Start the timer when call completed
+ */
+ after (Connection c): target(c) && call(void Connection.complete()) {
+ getTimer(c).start();
+ }
+
+ /**
+ * When to stop the timer
+ */
+ pointcut endTiming(Connection c): target(c) &&
+ call(void Connection.drop());
+
+ /**
+ * Stop the timer when call dropped and update the involved parties
+ */
+ after(Connection c): endTiming(c) {
+ getTimer(c).stop();
+ c.getCaller().totalConnectTime += getTimer(c).getTime();
+ c.getReceiver().totalConnectTime += getTimer(c).getTime();
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+/**
+ * This simulation subclass implements AbstractSimulation.report(..)
+ *
+ */
+public class TimingSimulation extends AbstractSimulation {
+
+ public static void main(String[] args){
+ System.out.println("\n... Timing simulation 2 ...\n");
+ simulation = new TimingSimulation();
+ simulation.run();
+ }
+
+ /**
+ * Print a report of the connection time for customer
+ */
+ protected void report(Customer c){
+ Timing t = Timing.aspectOf();
+ System.out.println(c + " spent " + t.getTotalConnectTime(c));
+ }
+
+}
--- /dev/null
+AbstractSimulation.java
+BasicSimulation.java
+Call.java
+Connection.java
+Local.java
+LongDistance.java
+Customer.java
--- /dev/null
+AbstractSimulation.java
+BillingSimulation.java
+Call.java
+Connection.java
+Local.java
+LongDistance.java
+Customer.java
+Timer.java
+Billing.java
+Timing.java
--- /dev/null
+AbstractSimulation.java
+TimingSimulation.java
+Call.java
+Connection.java
+Local.java
+LongDistance.java
+Customer.java
+Timer.java
+TimerLog.java
+Timing.java
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+*/
+package tjp;
+
+public class Demo {
+ static Demo d;
+
+ public static void main(String[] args){
+ new Demo().go();
+ }
+
+ void go(){
+ d = new Demo();
+ d.foo(1,d);
+ System.out.println(d.bar(new Integer(3)));
+ }
+
+ void foo(int i, Object o){
+ System.out.println("Demo.foo(" + i + ", " + o + ")\n");
+ }
+
+ String bar (Integer j){
+ System.out.println("Demo.bar(" + j + ")\n");
+ return "Demo.bar(" + j + ")";
+ }
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package tjp;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.reflect.CodeSignature;
+
+aspect GetInfo {
+
+ static final void println(String s){ System.out.println(s); }
+
+ pointcut goCut(): cflow(this(Demo) && execution(void go()));
+
+ pointcut demoExecs(): within(Demo) && execution(* *(..));
+
+ Object around(): demoExecs() && !execution(* go()) && goCut() {
+ println("Intercepted message: " +
+ thisJoinPointStaticPart.getSignature().getName());
+ println("in class: " +
+ thisJoinPointStaticPart.getSignature().getDeclaringType().getName());
+ printParameters(thisJoinPoint);
+ println("Running original method: \n" );
+ Object result = proceed();
+ println(" result: " + result );
+ return result;
+ }
+
+ static private void printParameters(JoinPoint jp) {
+ println("Arguments: " );
+ Object[] args = jp.getArgs();
+ String[] names = ((CodeSignature)jp.getSignature()).getParameterNames();
+ Class[] types = ((CodeSignature)jp.getSignature()).getParameterTypes();
+ for (int i = 0; i < args.length; i++) {
+ println(" " + i + ". " + names[i] +
+ " : " + types[i].getName() +
+ " = " + args[i]);
+ }
+ }
+}
--- /dev/null
+Demo.java
+GetInfo.java
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing;
+
+/**
+ *
+ * Circle is a 2D shape. It extends the TwoDShape class with the radius
+ * variable, and it implements TwoDShape's abstract methods for
+ * correctly computing a circle's area and distance.
+ *
+ */
+public class Circle extends TwoDShape {
+ protected double r; // radius
+
+ /*
+ * All sorts of constructors
+ */
+ public Circle(double x, double y, double r) {
+ super(x, y); this.r = r;
+ }
+
+ public Circle(double x, double y) {
+ this(x, y, 1.0);
+ }
+
+ public Circle(double r) {
+ this(0.0, 0.0, r);
+ }
+
+ public Circle() {
+ this(0.0, 0.0, 1.0);
+ }
+
+ /**
+ * Returns the perimeter of this circle
+ */
+ public double perimeter() {
+ return 2 * Math.PI * r;
+ }
+
+ /**
+ * Returns the area of this circle
+ */
+ public double area() {
+ return Math.PI * r*r;
+ }
+
+ /**
+ * This method overrides the one in the superclass. It adds some
+ * circle-specific information.
+ */
+ public String toString() {
+ return ("Circle radius = " + String.valueOf(r) + super.toString());
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing;
+
+/**
+ *
+ * A main function for testing 2D shapes.
+ *
+ */
+public class ExampleMain {
+ public static void main(String[] args) {
+ Circle c1 = new Circle(3.0, 3.0, 2.0);
+ Circle c2 = new Circle(4.0);
+
+ Square s1 = new Square(1.0, 2.0);
+
+ System.out.println("c1.perimeter() = " + c1.perimeter());
+ System.out.println("c1.area() = " + c1.area());
+
+ System.out.println("s1.perimeter() = " + s1.perimeter());
+ System.out.println("s1.area() = " + s1.area());
+
+ System.out.println("c2.distance(c1) = " + c2.distance(c1));
+ System.out.println("s1.distance(c1) = " + s1.distance(c1));
+
+ System.out.println("s1.toString(): " + s1.toString());
+ }
+}
--- /dev/null
+
+This directory contains several examples of tracing aspects,
+including a reusable tracing library and examples of
+using that library.
+
+A lesson in the AspectJ Primer explains all of this code.
+
+To work with these (or any other examples), first be sure .../examples
+is on your classpath, where ... is where you have installed AspectJ.
+
+
+--To compile and run the example without tracing--
+
+ ajc @.../examples/tracing/notrace.lst
+
+ java tracing.ExampleMain
+
+
+--To compile and run the example with tracing version<N>--
+
+ ajc @.../examples/tracing/tracev<N>.lst
+
+ java tracing.version<N>.TraceMyClasses
+
+where <N> is 1, 2, 3 or 4
+
+--To use the tracing.lib.AbstractTrace aspect--
+
+ Make sure .../examples is in your classpath.
+
+ In order to use this aspect, please read the documentation under
+ tracing/doc
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing;
+
+/**
+ *
+ * Square is a 2D shape. It extends the TwoDShape class with the side
+ * variable, and it implements TwoDShape's abstract methods for
+ * correctly computing a square's area and distance.
+ *
+ */
+public class Square extends TwoDShape {
+ protected double s; // side
+
+ /*
+ * All sorts of constructors
+ */
+ public Square(double x, double y, double s) {
+ super(x, y); this.s = s;
+ }
+
+ public Square(double x, double y) {
+ this(x, y, 1.0);
+ }
+
+ public Square(double s) {
+ this(0.0, 0.0, s);
+ }
+
+ public Square() {
+ this(0.0, 0.0, 1.0);
+ }
+
+ /**
+ * Returns the perimeter of this square
+ */
+ public double perimeter() {
+ return 4 * s;
+ }
+
+ /**
+ * Returns the area of this square
+ */
+ public double area() {
+ return s*s;
+ }
+
+ /**
+ * This method overrides the one in the superclass. It adds some
+ * circle-specific information.
+ */
+ public String toString() {
+ return ("Square side = " + String.valueOf(s) + super.toString());
+ }
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package tracing;
+
+/**
+ * TwoDShape is an abstract class that defines generic functionality
+ * for 2D shapes.
+ */
+public abstract class TwoDShape {
+ /**
+ * Coordinates of the center of the shape.
+ */
+ protected double x, y;
+
+ protected TwoDShape(double x, double y) {
+ this.x = x; this.y = y;
+ }
+
+ /**
+ * Returns the x coordinate of the shape.
+ */
+ public double getX() { return x; }
+
+ /**
+ * Returns the y coordinate of the shape.
+ */
+ public double getY() { return y; }
+
+ /**
+ * Returns the distance between this shape and the shape given as
+ * parameter.
+ */
+ public double distance(TwoDShape s) {
+ double dx = Math.abs(s.getX() - x);
+ double dy = Math.abs(s.getY() - y);
+ return Math.sqrt(dx*dx + dy*dy);
+ }
+
+ /**
+ * Returns the perimeter of this shape. Must be defined in
+ * subclasses.
+ */
+ public abstract double perimeter();
+
+ /**
+ * Returns the area of this shape. Must be defined in
+ * subclasses.
+ */
+ public abstract double area();
+
+ /**
+ * Returns a string representation of 2D shapes -- simply its
+ * coordinates.
+ */
+ public String toString() {
+ return (" @ (" + String.valueOf(x) + ", " + String.valueOf(y) + ") ");
+ }
+}
+
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing.lib;
+
+import java.io.PrintStream;
+import org.aspectj.lang.JoinPoint;
+
+
+/**
+ * This class provides support for printing trace messages into a stream.
+ * The trace messages consist of the class name, method name (if method)
+ * and the list of parameter types.<P>
+ * The class is thread-safe. Different threads may use different output streams
+ * by simply calling the method initStream(myStream).<P>
+ * This class should be extended.
+ * It defines 3 abstract crosscuts for injecting the tracing functionality
+ * into any constructors and methods of any application classes.<P>
+ *
+ * One example of using this class might be
+ * <PRE>
+ * import tracing.lib.AbstractTrace;
+ * aspect TraceMyClasses extends AbstractTrace of eachJVM() {
+ * pointcut classes(): within(TwoDShape) | within(Circle) | within(Square);
+ * pointcut constructors(): executions(new(..));
+ * pointcut methods(): executions(!abstract * *(..))
+ * }
+ * </PRE>
+ * (Make sure .../aspectj/examples is in your classpath)
+ */
+public abstract aspect AbstractTrace {
+
+ /**
+ * Application classes - left unspecified.
+ * Subclasses should concretize this crosscut with class names.
+ */
+ abstract pointcut classes();
+ /**
+ * Constructors - left unspecified.
+ * Subclasses should concretize this crosscut with constructors.
+ */
+ abstract pointcut constructors();
+ /**
+ * Methods - left unspecified.
+ * Subclasses should concretize this crosscut with method names.
+ */
+ abstract pointcut methods();
+
+ before(): classes() && constructors() {
+ doTraceEntry(thisJoinPoint, true);
+ }
+ after(): classes() && constructors() {
+ doTraceExit(thisJoinPoint, true);
+ }
+
+ before(): classes() && methods() {
+ doTraceEntry(thisJoinPoint, false);
+ }
+ after(): classes() && methods() {
+ doTraceExit(thisJoinPoint, false);
+ }
+
+ /*
+ * From here on, it's an ordinary class implementation.
+ * The static state is thread-safe by using ThreadLocal variables.
+ */
+
+ /**
+ * This method initializes this thread's trace output stream.
+ * By default, the output stream is System.err, and it is the same for
+ * all threads. In multithreaded applications, you may want to define
+ * different output streams for the different threads. For doing it,
+ * simply call this method in the beginning of each thread's main loop,
+ * giving it different output streams.
+ */
+ public void initStream(PrintStream _stream) {
+ setStream(_stream);
+ }
+
+
+ private ThreadLocal stream = new ThreadLocal() {
+ protected Object initialValue() {
+ return System.err;
+ }
+ };
+ private ThreadLocal callDepth = new ThreadLocal() {
+ protected Object initialValue() {
+ return new Integer(0);
+ }
+ };
+
+ private PrintStream getStream() {
+ return (PrintStream)stream.get();
+ }
+ private void setStream(PrintStream s) {
+ stream.set(s);
+ }
+ private int getCallDepth() {
+ return ((Integer)(callDepth.get())).intValue();
+ }
+ private void setCallDepth(int n) {
+ callDepth.set(new Integer(n));
+ }
+
+ private void doTraceEntry (JoinPoint jp, boolean isConstructor) {
+ setCallDepth(getCallDepth() + 1);
+ printEntering(jp, isConstructor);
+ }
+
+ private void doTraceExit (JoinPoint jp, boolean isConstructor) {
+ printExiting(jp, isConstructor);
+ setCallDepth(getCallDepth() - 1);
+ }
+
+ private void printEntering (JoinPoint jp, boolean isConstructor) {
+ printIndent();
+ getStream().print("--> ");
+ getStream().print(jp);
+ // printParameterTypes(jp);
+ getStream().println();
+ }
+
+ private void printExiting (JoinPoint jp, boolean isConstructor) {
+ printIndent();
+ getStream().print("<-- ");
+ getStream().print(jp);
+ // printParameterTypes(jp);
+ getStream().println();
+ }
+
+// private void printParameterTypes(JoinPoint jp) {
+// Class[] ptypes = jp.parameterTypes;
+
+// getStream().print("(");
+// for (int i = 0; i < ptypes.length; i++) {
+// getStream().print(ptypes[i].getName());
+// if (i < ptypes.length - 1) getStream().print(", ");
+// }
+// getStream().print(")");
+// }
+
+ private void printIndent() {
+ for (int i = 0; i < getCallDepth(); i++)
+ getStream().print(" ");
+ }
+
+ /**
+ * This method is not being used.
+ * It's being included solely for illustrating how to access and use
+ * the information in JoinPoint.
+ * If you want, you can replace the calls to printParameterTypes (above)
+ * by calls to this method.
+ */
+// private void printParameters(JoinPoint jp) {
+// Class[] ptypes = jp.parameterTypes;
+// String[] pnames = jp.parameterNames;
+// Object[] params = jp.parameters;
+
+// getStream().print("(");
+// for (int i = 0; i < ptypes.length; i++) {
+// getStream().print(ptypes[i].getName() + " " +
+// pnames[i] + "=" +
+// params[i]);
+// if (i < ptypes.length - 1) getStream().print(", ");
+// }
+// getStream().print(")");
+// }
+
+}
+
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing.lib;
+
+import tracing.TwoDShape;
+import tracing.Circle;
+import tracing.Square;
+import tracing.ExampleMain;
+
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.io.FileNotFoundException;
+
+aspect TraceMyClasses extends AbstractTrace {
+ /**
+ * The application classes
+ */
+ pointcut classes(): within(TwoDShape) || within(Circle) || within(Square);
+ /**
+ * The constructors in those classes - but only the ones with 3
+ * arguments.
+ */
+ pointcut constructors(): execution(new(double, double, double));
+ /**
+ * This specifies all the message executions.
+ */
+ pointcut methods(): execution(* *(..));
+
+ /**
+ * A main function for testing the trace aspect.
+ */
+ public static void main(String[] _args) {
+ final String[] args = _args;
+ new Thread() {
+ public void run() {
+ TraceMyClasses.aspectOf().initStream(System.err);
+ ExampleMain.main(args);
+ }
+ }.start();
+
+ new Thread() {
+ public void run() {
+ try {
+ TraceMyClasses.aspectOf().initStream(new PrintStream(new FileOutputStream("AJTRACETEST")));
+ }
+ catch (FileNotFoundException e) {}
+ ExampleMain.main(args);
+ }
+ }.start();
+ }
+}
--- /dev/null
+TwoDShape.java
+Circle.java
+Square.java
+ExampleMain.java
--- /dev/null
+TwoDShape.java
+Circle.java
+Square.java
+ExampleMain.java
+lib/AbstractTrace.java
+lib/TraceMyClasses.java
--- /dev/null
+TwoDShape.java
+Circle.java
+Square.java
+ExampleMain.java
+version1/Trace.java
+version1/TraceMyClasses.java
--- /dev/null
+TwoDShape.java
+Circle.java
+Square.java
+ExampleMain.java
+version2/Trace.java
+version2/TraceMyClasses.java
--- /dev/null
+TwoDShape.java
+Circle.java
+Square.java
+ExampleMain.java
+version3/Trace.java
+version3/TraceMyClasses.java
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package tracing.version1;
+
+import java.io.PrintStream;
+
+/**
+ *
+ * This class provides some basic functionality for printing trace messages
+ * into a stream.
+ *
+ */
+public class Trace {
+ /**
+ * There are 3 trace levels (values of TRACELEVEL):
+ * 0 - No messages are printed
+ * 1 - Trace messages are printed, but there is no indentation
+ * according to the call stack
+ * 2 - Trace messages are printed, and they are indented
+ * according to the call stack
+ */
+ public static int TRACELEVEL = 0;
+ protected static PrintStream stream = null;
+ protected static int callDepth = 0;
+
+ /**
+ * Initialization.
+ */
+ public static void initStream(PrintStream s) {
+ stream = s;
+ }
+
+ /**
+ * Prints an "entering" message. It is intended to be called in the
+ * beginning of the blocks to be traced.
+ */
+ public static void traceEntry(String str) {
+ if (TRACELEVEL == 0) return;
+ if (TRACELEVEL == 2) callDepth++;
+ printEntering(str);
+ }
+
+ /**
+ * Prints an "exiting" message. It is intended to be called in the
+ * end of the blocks to be traced.
+ */
+ public static void traceExit(String str) {
+ if (TRACELEVEL == 0) return;
+ printExiting(str);
+ if (TRACELEVEL == 2) callDepth--;
+ }
+
+ private static void printEntering(String str) {
+ printIndent();
+ stream.println("--> " + str);
+ }
+
+ private static void printExiting(String str) {
+ printIndent();
+ stream.println("<-- " + str);
+ }
+
+ private static void printIndent() {
+ for (int i = 0; i < callDepth; i++)
+ stream.print(" ");
+ }
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package tracing.version1;
+
+/**
+ *
+ * This class connects the tracing functions in the Trace class with
+ * the constructors and methods in the application classes.
+ *
+ */
+import tracing.TwoDShape;
+import tracing.Circle;
+import tracing.Square;
+import tracing.ExampleMain;
+
+aspect TraceMyClasses {
+ /**
+ * Application classes.
+ */
+ pointcut myClass(): within(TwoDShape) || within(Circle) || within(Square);
+ /**
+ * The constructors in those classes.
+ */
+ pointcut myConstructor(): myClass() && execution(new(..));
+ /**
+ * The methods of those classes.
+ */
+ pointcut myMethod(): myClass() && execution(* *(..));
+
+ /**
+ * Prints trace messages before and after executing constructors.
+ */
+ before (): myConstructor() {
+ Trace.traceEntry("" + thisJoinPointStaticPart.getSignature());
+ }
+ after(): myConstructor() {
+ Trace.traceExit("" + thisJoinPointStaticPart.getSignature());
+ }
+
+ /**
+ * Prints trace messages before and after executing methods.
+ */
+ before (): myMethod() {
+ Trace.traceEntry("" + thisJoinPointStaticPart.getSignature());
+ }
+ after(): myMethod() {
+ Trace.traceExit("" + thisJoinPointStaticPart.getSignature());
+ }
+
+ /**
+ * A main function for testing the trace aspect.
+ */
+ public static void main(String[] args) {
+ Trace.TRACELEVEL = 2;
+ Trace.initStream(System.err);
+ ExampleMain.main(args);
+ }
+}
+
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package tracing.version2;
+
+import java.io.PrintStream;
+
+/**
+ *
+ * This class provides support for printing trace messages into a stream.
+ * Trace messages are printed before and after constructors and methods
+ * are executed.
+ * It defines one abstract crosscut for injecting that tracing functionality
+ * into any application classes.
+ * To use it, provide a subclass that concretizes the abstract crosscut.
+ */
+abstract aspect Trace {
+
+ /*
+ * Functional part
+ */
+
+ /**
+ * There are 3 trace levels (values of TRACELEVEL):
+ * 0 - No messages are printed
+ * 1 - Trace messages are printed, but there is no indentation
+ * according to the call stack
+ * 2 - Trace messages are printed, and they are indented
+ * according to the call stack
+ */
+ public static int TRACELEVEL = 2;
+ protected static PrintStream stream = System.err;
+ protected static int callDepth = 0;
+
+ /**
+ * Initialization.
+ */
+ public static void initStream(PrintStream s) {
+ stream = s;
+ }
+
+ protected static void traceEntry(String str) {
+ if (TRACELEVEL == 0) return;
+ if (TRACELEVEL == 2) callDepth++;
+ printEntering(str);
+ }
+
+ protected static void traceExit(String str) {
+ if (TRACELEVEL == 0) return;
+ printExiting(str);
+ if (TRACELEVEL == 2) callDepth--;
+ }
+
+ private static void printEntering(String str) {
+ printIndent();
+ stream.println("--> " + str);
+ }
+
+ private static void printExiting(String str) {
+ printIndent();
+ stream.println("<-- " + str);
+ }
+
+
+ private static void printIndent() {
+ for (int i = 0; i < callDepth; i++)
+ stream.print(" ");
+ }
+
+
+ /*
+ * Crosscut part
+ */
+
+ /**
+ * Application classes - left unspecified.
+ * Subclasses should concretize this pointcut with class names.
+ */
+ abstract pointcut myClass();
+ /**
+ * The constructors in those classes.
+ */
+ pointcut myConstructor(): myClass() && execution(new(..));
+ /**
+ * The methods of those classes.
+ */
+ pointcut myMethod(): myClass() && execution(* *(..));
+
+ /**
+ * Prints trace messages before and after executing constructors.
+ */
+ before(): myConstructor() {
+ traceEntry("" + thisJoinPointStaticPart.getSignature());
+ }
+ after(): myConstructor() {
+ traceExit("" + thisJoinPointStaticPart.getSignature());
+ }
+
+ /**
+ * Prints trace messages before and after executing methods.
+ */
+ before(): myMethod() {
+ traceEntry("" + thisJoinPointStaticPart.getSignature());
+ }
+ after(): myMethod() {
+ traceExit("" + thisJoinPointStaticPart.getSignature());
+ }
+}
--- /dev/null
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package tracing.version2;
+
+import tracing.TwoDShape;
+import tracing.Circle;
+import tracing.Square;
+import tracing.ExampleMain;
+
+/**
+ *
+ * This class concretizes the abstract crosscut in Trace,
+ * applying the trace facility to these application classes.
+ *
+ */
+public aspect TraceMyClasses extends Trace {
+ pointcut myClass(): within(TwoDShape) || within(Circle) || within(Square);
+
+ /**
+ * A main function for testing the trace aspect.
+ */
+ public static void main(String[] args) {
+ Trace.TRACELEVEL = 2;
+ Trace.initStream(System.err);
+ ExampleMain.main(args);
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing.version3;
+
+import java.io.PrintStream;
+
+/**
+ *
+ * This class provides support for printing trace messages into a stream.
+ * Trace messages are printed before and after constructors and methods
+ * are executed.
+ * The messages are appended with the string representation of the objects
+ * whose constructors and methods are being traced.
+ * It defines one abstract pointcut for injecting that tracing functionality
+ * into any application classes.
+ *
+ */
+abstract aspect Trace {
+
+ /*
+ * Functional part
+ */
+
+ /**
+ * There are 3 trace levels (values of TRACELEVEL):
+ * 0 - No messages are printed
+ * 1 - Trace messages are printed, but there is no indentation
+ * according to the call stack
+ * 2 - Trace messages are printed, and they are indented
+ * according to the call stack
+ */
+ public static int TRACELEVEL = 0;
+ protected static PrintStream stream = null;
+ protected static int callDepth = 0;
+
+ /**
+ * Initialization.
+ */
+ public static void initStream(PrintStream s) {
+ stream = s;
+ }
+
+ protected static void traceEntry(String str, Object o) {
+ if (TRACELEVEL == 0) return;
+ if (TRACELEVEL == 2) callDepth++;
+ printEntering(str + ": " + o.toString());
+ }
+
+ protected static void traceExit(String str, Object o) {
+ if (TRACELEVEL == 0) return;
+ printExiting(str + ": " + o.toString());
+ if (TRACELEVEL == 2) callDepth--;
+ }
+
+ private static void printEntering(String str) {
+ printIndent();
+ stream.println("--> " + str);
+ }
+
+ private static void printExiting(String str) {
+ printIndent();
+ stream.println("<-- " + str);
+ }
+
+
+ private static void printIndent() {
+ for (int i = 0; i < callDepth; i++)
+ stream.print(" ");
+ }
+
+
+ /*
+ * Crosscut part
+ */
+
+ /**
+ * Application classes - left unspecified.
+ */
+ abstract pointcut myClass(Object obj);
+ /**
+ * The constructors in those classes.
+ */
+ pointcut myConstructor(Object obj): myClass(obj) && execution(new(..));
+ /**
+ * The methods of those classes.
+ */
+ // toString is called from within our advice, so we shouldn't
+ // advise its executions. But if toString is overridden, even
+ // this might not be enough, so we might want
+ // && !cflow(execution(String toString()))
+ pointcut myMethod(Object obj): myClass(obj) &&
+ execution(* *(..)) && !execution(String toString());
+
+ before(Object obj): myConstructor(obj) {
+ traceEntry("" + thisJoinPointStaticPart.getSignature(), obj);
+ }
+ after(Object obj): myConstructor(obj) {
+ traceExit("" + thisJoinPointStaticPart.getSignature(), obj);
+ }
+
+ before(Object obj): myMethod(obj) {
+ traceEntry("" + thisJoinPointStaticPart.getSignature(), obj);
+ }
+ after(Object obj): myMethod(obj) {
+ traceExit("" + thisJoinPointStaticPart.getSignature(), obj);
+ }
+}
--- /dev/null
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing.version3;
+
+import tracing.TwoDShape;
+import tracing.Circle;
+import tracing.Square;
+import tracing.ExampleMain;
+
+/**
+ *
+ * This class concretizes the abstract crosscut in Trace,
+ * applying the trace facility to these application classes.
+ *
+ */
+public aspect TraceMyClasses extends Trace {
+ pointcut myClass(Object obj):
+ this(obj) &&
+ (within(TwoDShape) || within(Circle) || within(Square));
+
+ /**
+ * A main function for testing the trace aspect.
+ */
+ public static void main(String[] args) {
+ Trace.TRACELEVEL = 2;
+ Trace.initStream(System.err);
+ ExampleMain.main(args);
+ }
+}
+
xref:progguide/index.adoc[programming],
xref:devguide/index.adoc[development] and
xref:pdguide/index.adoc[problem diagnosis] guides,
-link:runtime-api/index.html[API] and link:https://github.com/eclipse-aspectj/aspectj/tree/master/docs/dist/doc/examples[example code].
+link:runtime-api/index.html[API] and link:https://github.com/eclipse-aspectj/aspectj/tree/master/docs/examples[example code].
|xref:#distributions[Distributions]
|https://eclipse.org/aspectj[AspectJ]; development environment support
|xref:dist/doc/changes.adoc[Changes] |Changes between historical releases up to 1.6.0.
-|link:https://github.com/eclipse-aspectj/aspectj/tree/master/docs/dist/doc/examples[Examples] |AspectJ code to demonstrate some language
+|link:https://github.com/eclipse-aspectj/aspectj/tree/master/docs/examples[Examples] |AspectJ code to demonstrate some language
features and implement JavaBean properties, the Observer pattern, a
tracing library, and a game application where aspects handle display
updating.
xref:progguide/semantics.adoc[Semantics appendix] nearby as the best
reference for AspectJ usage. Focus initially on the join point model and
pointcuts, concepts AOP adds to OOP. To read about how the
-link:https://github.com/eclipse-aspectj/aspectj/tree/master/docs/dist/doc/examples[examples] work, see the
+link:https://github.com/eclipse-aspectj/aspectj/tree/master/docs/examples[examples] work, see the
xref:progguide/examples.adoc[Examples] section in the
xref:progguide/index.adoc[Programming Guide]. View and navigate the
crosscutting structure using https://eclipse.org/ajdt[AJDT].
TestUtil.runMain("out;../lib/test/testing-client.jar", "org.schmidmeier.unittests.cache.AllTimeCacheTests");
}
- private static String examplesDir = "../docs/dist/doc/examples/";
+ private static String examplesDir = "../docs/examples/";
private static void example(String[] argfiles, String[] classes) {
List args = new ArrayList();
args.add("-verbose");
}
void setupTracingJava(Javac javac) { // XXX assumes module dir, doc loc
- String exDir = "../docs/dist/doc/examples";
+ String exDir = "../docs/examples";
javac.setSrcdir(new Path(javac.getProject(), exDir));
javac.setIncludes("tracing/*.java"); // XXX assumes tracing example
}
<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd">
-<!--
+<!--
Test documentation examples.
- Results unverified except for compiler messages,
+ Results unverified except for compiler messages,
runtime exceptions, System.exit codes, and System.err
messages (the latter not for all tests).
To run the example classes using a forked 1.1 vm:
-
+
java -Djavarun.fork=true \
-Djavarun.java.home=d:\\jdk11 \
-Djavarun.java=d:\\jdk11\\bin\\javaw \
-jar ../aj-build/jars/testing-drivers-all.jar \
ajcTestsExamples.xml \
-ajctestSkipKeywords=knownLimitation-run11 \
- -logFail
+ -logFail
-->
<suite>
- <ajc-test dir="../docs/dist/doc/examples"
+ <ajc-test dir="../docs/examples"
keywords="doc-examples"
title="bean example">
<compile argfiles="bean/files.lst"/>
<run class="bean.Demo"
errStreamIsError="false"/>
<!-- ??: error security properties not found. using defaults. -->
- </ajc-test>
+ </ajc-test>
- <ajc-test dir="../docs/dist/doc/examples"
+ <ajc-test dir="../docs/examples"
keywords="doc-examples,knownLimitation-run11"
title="introduction">
<compile argfiles="introduction/files.lst"/>
<run vm="1.2" class="introduction.CloneablePoint"/>
<run vm="1.2" class="introduction.ComparablePoint"/>
<run vm="1.2" class="introduction.HashablePoint"/>
- </ajc-test>
+ </ajc-test>
- <ajc-test dir="../docs/dist/doc/examples"
+ <ajc-test dir="../docs/examples"
keywords="doc-examples"
title="observer example">
<compile argfiles="observer/files.lst"/>
<!-- GUI run class="observer.Demo"/ -->
- </ajc-test>
+ </ajc-test>
- <ajc-test dir="../docs/dist/doc/examples"
+ <ajc-test dir="../docs/examples"
keywords="doc-examples"
title="spacewar example">
<compile argfiles="spacewar/debug.lst"/>
<compile argfiles="spacewar/demo.lst"/>
<!-- GUI run class="spacewar.Game"/ -->
- </ajc-test>
+ </ajc-test>
<!--
TODO: change 1.2 API's in telecom to 1.1:
(Vector.[add|remove](..) to [add|remove]Element(..))
then remove the knownLimitation-run11 keywords
- -->
- <ajc-test dir="../docs/dist/doc/examples"
+ -->
+ <ajc-test dir="../docs/examples"
keywords="doc-examples,knownLimitation-run11"
title="telecom basic example">
<compile argfiles="telecom/basic.lst"/>
<run class="telecom.BasicSimulation"/>
- </ajc-test>
+ </ajc-test>
- <ajc-test dir="../docs/dist/doc/examples"
+ <ajc-test dir="../docs/examples"
keywords="doc-examples,knownLimitation-run11"
title="telecom billing example">
<compile argfiles="telecom/billing.lst"/>
<run class="telecom.BillingSimulation"/>
- </ajc-test>
+ </ajc-test>
- <ajc-test dir="../docs/dist/doc/examples"
+ <ajc-test dir="../docs/examples"
keywords="doc-examples,knownLimitation-run11"
title="telecom timing example">
<compile argfiles="telecom/timing.lst"/>
<run class="telecom.TimingSimulation"/>
- </ajc-test>
+ </ajc-test>
- <ajc-test dir="../docs/dist/doc/examples"
+ <ajc-test dir="../docs/examples"
keywords="doc-examples"
title="thisJoinPoint example">
<compile argfiles="tjp/files.lst"/>
<run class="tjp.Demo"/>
- </ajc-test>
+ </ajc-test>
- <ajc-test dir="../docs/dist/doc/examples"
+ <ajc-test dir="../docs/examples"
keywords="doc-examples"
title="tracing example - none">
<compile argfiles="tracing/notrace.lst"/>
<run class="tracing.ExampleMain"/>
- </ajc-test>
+ </ajc-test>
- <ajc-test dir="../docs/dist/doc/examples"
+ <ajc-test dir="../docs/examples"
keywords="doc-examples"
title="tracing example - version 1">
<compile argfiles="tracing/tracev1.lst"/>
<run class="tracing.version1.TraceMyClasses"
errStreamIsError="false"/>
- </ajc-test>
+ </ajc-test>
- <ajc-test dir="../docs/dist/doc/examples"
+ <ajc-test dir="../docs/examples"
keywords="doc-examples"
title="tracing example - version 2">
<compile argfiles="tracing/tracev2.lst"/>
<run class="tracing.version2.TraceMyClasses"
errStreamIsError="false"/>
- </ajc-test>
+ </ajc-test>
- <ajc-test dir="../docs/dist/doc/examples"
+ <ajc-test dir="../docs/examples"
keywords="doc-examples"
title="tracing example - version 3">
<compile argfiles="tracing/tracev3.lst"/>
<run class="tracing.version3.TraceMyClasses"
errStreamIsError="false"/>
- </ajc-test>
+ </ajc-test>
</suite>
<!-- end of atOverride tests with ITDs -->
- <ajc-test dir="../docs/dist/doc/examples/introduction" title="introduction sample" vm="1.5">
+ <ajc-test dir="../docs/examples/introduction" title="introduction sample" vm="1.5">
<compile files="CloneablePoint.java,ComparablePoint.java,HashablePoint.java,Point.java" options="-1.5 -Xlint:ignore"/>
</ajc-test>
<!-- end of atOverride tests with ITDs -->
- <ajc-test dir="../docs/dist/doc/examples/introduction" title="introduction sample" vm="1.5">
+ <ajc-test dir="../docs/examples/introduction" title="introduction sample" vm="1.5">
<compile files="CloneablePoint.java,ComparablePoint.java,HashablePoint.java,Point.java" options="-1.9 -Xlint:ignore"/>
</ajc-test>
location="${aj.otherSystems.dir}/examples"/>
<mkdir dir="${aj.tempExamples.dir}"/>
<copy todir="${aj.tempExamples.dir}">
- <fileset dir="../docs/dist/doc/examples"/>
+ <fileset dir="../docs/examples"/>
</copy>
<!-- copy to temp.examples.dir -->
<ajctest testId="examples"