summaryrefslogtreecommitdiffstats
path: root/docs/sandbox/inoculated/src
diff options
context:
space:
mode:
authorwisberg <wisberg>2003-08-06 02:08:40 +0000
committerwisberg <wisberg>2003-08-06 02:08:40 +0000
commita63bc04fb1cb6e8d6d0bc2a509ab9658e3d78c43 (patch)
treecd4e827c60136df7bf9850591b0c64baff549d20 /docs/sandbox/inoculated/src
parentb0d37c4b51a344bee94bb7f7cc1ecef1a233e3ab (diff)
downloadaspectj-a63bc04fb1cb6e8d6d0bc2a509ab9658e3d78c43.tar.gz
aspectj-a63bc04fb1cb6e8d6d0bc2a509ab9658e3d78c43.zip
initial checkin of the sandbox.
The basic structure and examples of each type are there, but I have more examples and the ones there are not altogether validated. I'll make a few more changes before emailing dev and users about usage, etc.
Diffstat (limited to 'docs/sandbox/inoculated/src')
-rw-r--r--docs/sandbox/inoculated/src/BufferTest.java61
-rw-r--r--docs/sandbox/inoculated/src/Injection.java123
-rw-r--r--docs/sandbox/inoculated/src/MainFailure.java74
-rw-r--r--docs/sandbox/inoculated/src/RunTime.java72
-rw-r--r--docs/sandbox/inoculated/src/RuntimeWrites.java145
-rw-r--r--docs/sandbox/inoculated/src/StubReplace.java64
-rw-r--r--docs/sandbox/inoculated/src/buildRun.sh20
-rw-r--r--docs/sandbox/inoculated/src/com/xerox/printing/CompileTime.java69
-rw-r--r--docs/sandbox/inoculated/src/com/xerox/printing/RecordingInput.java44
-rw-r--r--docs/sandbox/inoculated/src/com/xerox/printing/RoundTrip.java77
10 files changed, 749 insertions, 0 deletions
diff --git a/docs/sandbox/inoculated/src/BufferTest.java b/docs/sandbox/inoculated/src/BufferTest.java
new file mode 100644
index 000000000..f2cc479e8
--- /dev/null
+++ b/docs/sandbox/inoculated/src/BufferTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1998-2002 PARC Inc. 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 PARC Inc. makes no
+ * warranty about the software, its performance or its conformity to any
+ * specification.
+ */
+
+import java.util.*;
+import java.io.*;
+
+import org.aspectj.lang.*;
+
+/** @author Wes Isberg */
+public aspect BufferTest {
+
+ // article page 43 - input driver
+ // START-SAMPLE testing-inoculated-proceedVariants Using around for integration testing
+ /**
+ * When PrinterBuffer.capacity(int) is called,
+ * test it with repeatedly with a set of input
+ * (validating the result) and then continue with
+ * the original call.
+ *
+ * This assumes that the capacity method causes no
+ * relevant state changes in the buffer.
+ */
+ int around(int original, PrinterBuffer buffer) :
+ call(int PrinterBuffer.capacity(int)) && args(original) && target(buffer) {
+ int[] input = new int[] { 0, 1, 10, 1000, -1, 4096 };
+ for (int i = 0; i < input.length; i++) {
+ int result = proceed(input[i], buffer); // invoke test
+ validateResult(buffer, input[i], result);
+ }
+ return proceed(original, buffer); // continue with original processing
+ }
+ // END-SAMPLE testing-inoculated-proceedVariants
+
+ void validateResult(PrinterBuffer buffer, int input, int result) {
+ System.err.println("validating input=" + input + " result=" + result
+ + " buffer=" + buffer);
+ }
+
+ public static void main(String[] args) {
+ PrinterBuffer p = new PrinterBuffer();
+ int i = p.capacity(0);
+ System.err.println("main - result " + i);
+ }
+}
+
+class PrinterBuffer {
+ int capacity(int i) {
+ System.err.println("capacity " + i);
+ return i;
+ }
+}
diff --git a/docs/sandbox/inoculated/src/Injection.java b/docs/sandbox/inoculated/src/Injection.java
new file mode 100644
index 000000000..6a857ef7a
--- /dev/null
+++ b/docs/sandbox/inoculated/src/Injection.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1998-2002 PARC Inc. 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 PARC Inc. makes no
+ * warranty about the software, its performance or its conformity to any
+ * specification.
+ */
+
+import java.io.*;
+
+/**
+ * Demonstrate technique of fault-injection
+ * as coordinated by test driver.
+ * @author Wes Isberg
+ */
+aspect InjectingIOException {
+
+ // article page 43 - fault injection
+ // START-SAMPLE testing-inoculated-injectIOException Inject IOException on test driver command
+ /** the test starts when the driver starts executing */
+ pointcut testEntryPoint(TestDriver driver) :
+ target(driver) && execution(* TestDriver.startTest());
+
+ /**
+ * The fault may be injected at the execution of any
+ * (non-static) PrinterStream method that throws an IOException
+ */
+ pointcut testCheckPoint(PrinterStream stream) : target(stream)
+ && execution(public * PrinterStream+.*(..) throws IOException);
+
+ /**
+ * After the method returns normally, query the
+ * test driver to see if we should instead throw
+ * an exception ("inject" the fault).
+ */
+ after (TestDriver driver, PrinterStream stream) returning
+ throws IOException :
+ cflowbelow(testEntryPoint(driver))
+ && testCheckPoint(stream) {
+ IOException e = driver.createException(stream);
+ if (null != e) {
+ System.out.println("InjectingIOException - injecting " + e);
+ throw e;
+ }
+ }
+ /* Comment on the after advice IOException declaration:
+
+ "throws IOException" is a declaration of the advice,
+ not the pointcut.
+
+ Since the advice might throw the injected fault, it
+ must declare that it throws IOException. When advice declares
+ exceptions thrown, the compiler will emit an error if any
+ join point is not also declared to throw an IOException.
+
+ In this case, the testCheckPoint pointcut only picks out
+ methods that throw IOException, so the compile will not
+ signal any errors.
+ */
+ // END-SAMPLE testing-inoculated-injectIOException
+}
+
+/** this runs the test case */
+public class Injection {
+ /** Run three print jobs, two as a test and one normally */
+ public static void main(String[] args) throws Exception {
+ Runnable r = new Runnable() {
+ public void run() {
+ try { new TestDriver().startTest(); }
+ catch (IOException e) {
+ System.err.println("got expected injected error " + e.getMessage());
+ }
+ }
+ };
+
+ System.out.println("Injection.main() - starting separate test thread");
+ Thread t = new Thread(r);
+ t.start();
+
+ System.out.println("Injection.main() - running test in this thread");
+ r.run();
+ t.join();
+
+ System.out.println("Injection.main() - running job normally, not by TestDriver");
+ new PrintJob().runPrintJob();
+ }
+}
+
+/** handle starting of test and determining whether to inject failure */
+class TestDriver {
+
+ /** start a new test */
+ public void startTest() throws IOException {
+ new PrintJob().runPrintJob();
+ }
+
+ /** this implementation always injects a failure */
+ public IOException createException(PrinterStream p) {
+ return new IOException(""+p);
+ }
+}
+
+//--------------------------------------- target classes
+
+class PrintJob {
+ /** this job writes to the printer stream */
+ void runPrintJob() throws IOException {
+ new PrinterStream().write();
+ }
+}
+
+class PrinterStream {
+ /** this printer stream writes without exception */
+ public void write() throws IOException {
+ System.err.println("PrinterStream.write() - not throwing exception");
+ }
+}
+
diff --git a/docs/sandbox/inoculated/src/MainFailure.java b/docs/sandbox/inoculated/src/MainFailure.java
new file mode 100644
index 000000000..6d5a62a35
--- /dev/null
+++ b/docs/sandbox/inoculated/src/MainFailure.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1998-2002 PARC Inc. 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 PARC Inc. makes no
+ * warranty about the software, its performance or its conformity to any
+ * specification.
+ */
+
+import java.util.*;
+import java.io.*;
+import org.aspectj.lang.*;
+
+/** @author Wes Isberg */
+
+public aspect MainFailure {
+
+ public static void main (String[] args) { TargetClass.main(args); }
+
+ pointcut main(String[] args) :
+ args(args) && execution(public static void main(String[]));
+
+ // article page 42 - recording failures from main
+ // START-SAMPLE testing-inoculated-failureCapture Log failures
+ /** log after failure, but do not affect exception */
+ after(String[] args) throwing (Throwable t) : main(args) {
+ logFailureCase(args, t, thisJoinPoint);
+ }
+ // END-SAMPLE testing-inoculated-failureCapture
+
+ // alternate to swallow exception
+// /** log after failure and swallow exception */
+// Object around() : main(String[]) {
+// try {
+// return proceed();
+// } catch (Error e) { // ignore
+// logFailureCase(args, t, thisJoinPoint);
+// // can log here instead
+// }
+// return null;
+// }
+
+ public static void logFailureCase(String[] args, Throwable t, Object jp) {
+ System.err.println("failure case: args " + Arrays.asList(args));
+ }
+}
+
+class TargetClass {
+ static Thread thread;
+ /** will throw error if exactly one argument */
+ public static void main (String[] args) {
+ // make sure to do at least one failure
+ if (thread == null) {
+ Runnable r = new Runnable() {
+ public void run() {
+ main(new String[] {"throwError" });
+ }
+ };
+ thread = new Thread(r);
+ thread.start();
+ }
+ if (1 == args.length) {
+ throw new Error("hello");
+ }
+ try { thread.join(); }
+ catch (InterruptedException ie) { }
+ }
+}
+
+
diff --git a/docs/sandbox/inoculated/src/RunTime.java b/docs/sandbox/inoculated/src/RunTime.java
new file mode 100644
index 000000000..e3e93e9d0
--- /dev/null
+++ b/docs/sandbox/inoculated/src/RunTime.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1998-2002 PARC Inc. 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 PARC Inc. makes no
+ * warranty about the software, its performance or its conformity to any
+ * specification.
+ */
+
+import java.util.*;
+import java.awt.Point;
+
+import org.aspectj.lang.JoinPoint;
+
+public class RunTime {
+ public static void main(String[] a) {
+ AnotherPoint.create();
+ SubPoint.create();
+ }
+}
+
+/** @author Wes Isberg */
+aspect FactoryValidation {
+
+ // START-SAMPLE declares-inoculated-prohibitNonprivateConstructors Error to have accessible sub-Point constructors
+ /** We make it an error for any Point subclasses to have non-private constructors */
+ declare error : execution(!private Point+.new(..))
+ && !within(java*..*) :
+ "non-private Point subclass constructor";
+ // END-SAMPLE declares-inoculated-prohibitNonprivateConstructors
+
+ // article page 41 - runtime NPE
+ // START-SAMPLE testing-inoculated-runtimeErrorWhenNullReturnedFromFactory Throw Error when factory returns null
+ /** Throw Error if a factory method for creating a Point returns null */
+ after () returning (Point p) :
+ call(Point+ SubPoint+.create(..)) {
+ if (null == p) {
+ String err = "Null Point constructed when this ("
+ + thisJoinPoint.getThis()
+ + ") called target ("
+ + thisJoinPoint.getTarget()
+ + ") at join point ("
+ + thisJoinPoint.getSignature()
+ + ") from source location ("
+ + thisJoinPoint.getSourceLocation()
+ + ") with args ("
+ + Arrays.asList(thisJoinPoint.getArgs())
+ + ")";
+ throw new Error(err);
+ }
+ }
+ // END-SAMPLE testing-inoculated-runtimeErrorWhenNullReturnedFromFactory
+}
+
+class SubPoint extends Point {
+ public static SubPoint create() { return null; } // will cause Error
+ private SubPoint(){}
+}
+
+class AnotherPoint extends Point {
+ public static Point create() { return new Point(); }
+
+ // to see that default constructor is picked out by declare error
+ // comment out this constructor
+ private AnotherPoint(){}
+}
+
+
diff --git a/docs/sandbox/inoculated/src/RuntimeWrites.java b/docs/sandbox/inoculated/src/RuntimeWrites.java
new file mode 100644
index 000000000..0f49247cb
--- /dev/null
+++ b/docs/sandbox/inoculated/src/RuntimeWrites.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 1998-2002 PARC Inc. 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 PARC Inc. makes no
+ * warranty about the software, its performance or its conformity to any
+ * specification.
+ */
+
+import org.aspectj.lang.*;
+
+/** test cases for controlling field writes */
+public class RuntimeWrites {
+
+ public static void main(String[] args) {
+ System.err.println("---- setup: valid write");
+ final SubPrinterStream me = new SubPrinterStream();
+
+ System.err.println("---- setup: invalid write, outside initialization - nonstatic");
+ me.setOne(1);
+
+ System.err.println("---- setup: invalid write, outside initialization - static");
+ me.one = 0;
+
+ System.err.println("---- setup: invalid write, caller is not same as target");
+ PrinterStream other = new PrinterStream(me);
+ }
+}
+
+
+/**
+ * Control field writes.
+ * This implementation restricts writes to the same object during initialization.
+ * This is like having field values be final, except that
+ * they may be set set outside the constructor.
+ * @author Wes Isberg
+ */
+aspect ControlFieldWrites {
+ public static boolean throwError;
+
+ // article page 42 - field writes
+
+ // START-SAMPLE testing-inoculated-permitWritesDuringConstruction Constructor execution
+ /** execution of any constructor for PrinterStream */
+ pointcut init() : execution(PrinterStream+.new(..));
+ // END-SAMPLE testing-inoculated-permitWritesDuringConstruction
+
+ // START-SAMPLE testing-inoculated-prohibitWritesExceptWhenConstructing Prohibit field writes after construction
+ /** any write to a non-static field in PrinterStream itself */
+ pointcut fieldWrites() : set(!static * PrinterStream.*);
+
+
+ /**
+ * Handle any situation where fields are written
+ * outside of the control flow of initialization
+ */
+ before() : fieldWrites() && !cflow(init()) {
+ handle("field set outside of init", thisJoinPointStaticPart);
+ }
+ // END-SAMPLE testing-inoculated-prohibitWritesExceptWhenConstructing
+
+ // START-SAMPLE testing-inoculated-prohibitWritesByOthers Prohibit field writes by other instances
+ /**
+ * Handle any situation where fields are written
+ * by another object.
+ */
+ before(Object caller, PrinterStream targ) : this(caller)
+ && target(targ) && fieldWrites() {
+ if (caller != targ) {
+ String err = "variation 1: caller (" + caller
+ + ") setting fields in targ (" + targ + ")";
+ handle(err, thisJoinPointStaticPart);
+ }
+ }
+ // END-SAMPLE testing-inoculated-prohibitWritesByOthers
+
+ //---- variations to pick out subclasses as well
+ // START-SAMPLE testing-inoculated-prohibitWritesEvenBySubclasses Prohibit writes by subclasses
+ /** any write to a non-static field in PrinterStream or any subclasses */
+ //pointcut fieldWrites() : set(!static * PrinterStream+.*);
+
+ /** execution of any constructor for PrinterStream or any subclasses */
+ //pointcut init() : execution(PrinterStream+.new(..));
+ // END-SAMPLE testing-inoculated-prohibitWritesEvenBySubclasses
+
+ //---- variation to pick out static callers as well
+ // START-SAMPLE testing-inoculated-prohibitWritesEvenByStaticOthers Prohibit writes by other instances and static methods
+ /**
+ * Handle any situation where fields are written
+ * other than by the same object.
+ */
+ before(PrinterStream targ) : target(targ) && fieldWrites() {
+ Object caller = thisJoinPoint.getThis();
+ if (targ != caller) {
+ String err = "variation 2: caller (" + caller
+ + ") setting fields in targ (" + targ + ")";
+ handle(err, thisJoinPointStaticPart);
+ }
+ }
+ // END-SAMPLE testing-inoculated-prohibitWritesEvenByStaticOthers
+
+ //-------------- utility method
+ void handle(String error, JoinPoint.StaticPart jpsp) {
+ error += " - " + jpsp;
+ if (throwError) {
+ throw new Error(error);
+ } else {
+ System.err.println(error);
+ }
+ }
+}
+
+
+class PrinterStream {
+ int one;
+ private int another;
+
+ PrinterStream() { setOne(1); }
+
+ PrinterStream(PrinterStream other) {
+ other.another = 3;
+ }
+
+ public void setOne(int i) {
+ one = i;
+ }
+}
+
+class SubPrinterStream extends PrinterStream {
+ private int two;
+
+ SubPrinterStream() {
+ setOne(2);
+ setTwo();
+ }
+
+ public void setTwo() {
+ two = 2;
+ }
+}
+
diff --git a/docs/sandbox/inoculated/src/StubReplace.java b/docs/sandbox/inoculated/src/StubReplace.java
new file mode 100644
index 000000000..56bda0367
--- /dev/null
+++ b/docs/sandbox/inoculated/src/StubReplace.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1998-2002 PARC Inc. 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 PARC Inc. makes no
+ * warranty about the software, its performance or its conformity to any
+ * specification.
+ */
+
+public class StubReplace {
+ public static void main(String[] args) {
+ new PrintJob().run();
+ }
+}
+
+/** @author Wes Isberg */
+aspect Stubs {
+
+ // article page 76 - stubs
+
+ // START-SAMPLE testing-inoculated-replaceWithProxy Replace object with proxy on constructiono
+ /**
+ * Replace all PrintStream with our StubStream
+ * by replacing the call to any constructor of
+ * PrinterStream or any subclasses.
+ */
+ PrinterStream around () : within(PrintJob)
+ && call (PrinterStream+.new(..)) && !call (StubStream+.new(..)) {
+ return new StubStream(thisJoinPoint.getArgs());
+ }
+ // END-SAMPLE testing-inoculated-replaceWithProxy
+
+ // START-SAMPLE testing-inoculated-adviseProxyCallsOnly Advise calls to the proxy object only
+ pointcut stubWrite() : printerStreamTestCalls() && target(StubStream);
+
+ pointcut printerStreamTestCalls() : call(* PrinterStream.write());
+
+ before() : stubWrite() {
+ System.err.println("picking out stubWrite" );
+ }
+ // END-SAMPLE testing-inoculated-adviseProxyCallsOnly
+}
+
+class PrinterStream {
+ public void write() {}
+}
+
+class StubStream extends PrinterStream {
+ public StubStream(Object[] args) {}
+}
+
+class PrintJob {
+ public void run() {
+ PrinterStream p = new PrinterStream();
+ System.err.println("not PrinterStream: " + p);
+ System.err.println("now trying call...");
+ p.write();
+ }
+}
+
diff --git a/docs/sandbox/inoculated/src/buildRun.sh b/docs/sandbox/inoculated/src/buildRun.sh
new file mode 100644
index 000000000..8f3c283c3
--- /dev/null
+++ b/docs/sandbox/inoculated/src/buildRun.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+JDKDIR="${JDKDIR:-${JAVA_HOME:-`setjdk.sh`}}"
+AJ_HOME="${AJ_HOME:-`setajhome.sh`}"
+PS="${PS:-;}"
+ajrt=`pathtojava.sh "$AJ_HOME/lib/aspectjrt.jar"`
+mkdir -p ../classes
+
+for i in *.java; do
+ pack=`sed -n '/package/s|.*package *\([^ ][^ ]*\)[ ;].*|\1|p' "$i"`
+ [ -n "$pack" ] && pack="${pack}."
+ rm -rf classes/*
+ cname=$pack`basename $i .java`
+ echo ""
+ echo "########## $cname"
+ $AJ_HOME/bin/ajc -d ../classes -classpath "$ajrt" "$i"
+ && $JDKDIR/bin/java -classpath "../classes${PS}$ajrt" $cname
+done
+
+rm -rf ../classes
diff --git a/docs/sandbox/inoculated/src/com/xerox/printing/CompileTime.java b/docs/sandbox/inoculated/src/com/xerox/printing/CompileTime.java
new file mode 100644
index 000000000..f7af344e0
--- /dev/null
+++ b/docs/sandbox/inoculated/src/com/xerox/printing/CompileTime.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1998-2002 PARC Inc. 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 PARC Inc. makes no
+ * warranty about the software, its performance or its conformity to any
+ * specification.
+ */
+
+package com.xerox.printing;
+
+import java.awt.Point;
+import java.io.IOException;
+
+class ClassOne {
+ int i = 1 ; // 20 expect warning
+}
+
+class ClassError {
+ int i = 1 ; // 24 expect warning
+}
+
+class PrinterStream {}
+
+class SubPrinterStream extends PrinterStream {
+ public void delegate() {
+ try {
+ throw new IOException("");
+ } catch (IOException e) {} // 33 expect error
+ }
+}
+
+class SubPoint extends Point {
+ Point create() { return new Point(); } // no error
+ Point another() { return new Point(); } // 39 expect error
+}
+
+/** @author Wes Isberg */
+aspect CompileTime {
+
+ // article page 40 - warning
+ // START-SAMPLE declares-inoculated-nonSetterWrites Warn when setting non-public field
+ /** warn if setting non-public field outside a setter */
+ declare warning :
+ within(com.xerox.printing..*)
+ && set(!public * *) && !withincode(* set*(..))
+ : "writing field outside setter" ;
+ // END-SAMPLE declares-inoculated-nonSetterWrites
+
+ // article page 41 - error
+ // START-SAMPLE declares-inoculated-validExceptionHandlingMethod Error when subclass method handles exception
+ declare error : handler(IOException+)
+ && withincode(* PrinterStream+.delegate(..))
+ : "do not handle IOException in this method";
+ // END-SAMPLE declares-inoculated-validExceptionHandlingMethod
+
+ // START-SAMPLE declares-inoculated-validPointConstruction Error when factory not used
+ declare error : !withincode(Point+ SubPoint+.create(..))
+ && within(com.xerox..*)
+ && call(Point+.new(..))
+ : "use SubPoint.create() to create Point";
+ // END-SAMPLE declares-inoculated-validPointConstruction
+}
+
+
diff --git a/docs/sandbox/inoculated/src/com/xerox/printing/RecordingInput.java b/docs/sandbox/inoculated/src/com/xerox/printing/RecordingInput.java
new file mode 100644
index 000000000..aab1d2076
--- /dev/null
+++ b/docs/sandbox/inoculated/src/com/xerox/printing/RecordingInput.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1998-2002 PARC Inc. 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 PARC Inc. makes no
+ * warranty about the software, its performance or its conformity to any
+ * specification.
+ */
+
+package com.xerox.printing;
+
+class PrinterBuffer {
+ public int capacity(int i) { return i; }
+}
+
+public aspect RecordingInput {
+
+ // @author Wes Isberg
+ // article page 42 - recording input
+ pointcut capacityCall (int i) :
+ within(com.xerox..*) && args(i)
+ && call(public * PrinterBuffer.capacity(int)) ;
+ // XXX style error - + not needed
+ // call(public * PrinterBuffer+.capacity(int))
+
+ before (int i) : capacityCall(i) {
+ log.print("<capacityCall tjp=\"" + thisJoinPoint
+ + "\" input=\"" + i + "\"/>");
+ }
+
+ Log log = new Log();
+ class Log {
+ void print(String s) { System.out.println(s); }
+ }
+ public static void main(String[] args) {
+ PrinterBuffer p = new PrinterBuffer();
+ p.capacity(1);
+ p.capacity(2);
+ }
+}
diff --git a/docs/sandbox/inoculated/src/com/xerox/printing/RoundTrip.java b/docs/sandbox/inoculated/src/com/xerox/printing/RoundTrip.java
new file mode 100644
index 000000000..4aeb0892b
--- /dev/null
+++ b/docs/sandbox/inoculated/src/com/xerox/printing/RoundTrip.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1998-2002 PARC Inc. 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 PARC Inc. makes no
+ * warranty about the software, its performance or its conformity to any
+ * specification.
+ */
+
+package com.xerox.printing;
+
+public class RoundTrip {
+ public static void main(String[] args) {
+ PrinterStream p = testing();
+ System.err.println(" got "+ p.number);
+ }
+ static PrinterStream testing() { return new PrinterStream(1); }
+
+}
+
+/** @author Wes Isberg */
+aspect VerifyPrinterStreamIntegrity {
+ // article page 76 - round trip
+ // START-SAMPLE testing-inoculated-roundTrip Round-trip integration testing
+ /**
+ * After returning a PrinterStream from any call in our
+ * packages, verify it by doing a round-trip between
+ * PrinterStream and BufferedPrinterStream.
+ * This uses a round-trip as a way to verify the
+ * integrity of PrinterStream, but one could also use
+ * a self-test (built-in or otherwise) coded specifically
+ * for validating the object (without changing state).
+ */
+ after () returning (PrinterStream stream) :
+ call (PrinterStream+ com.xerox.printing..*(..))
+ && !call (PrinterStream PrinterStream.make(BufferedPrinterStream)) {
+ BufferedPrinterStream bufferStream = new BufferedPrinterStream(stream);
+ PrinterStream newStream = PrinterStream.make(bufferStream);
+ if (!stream.equals(newStream)) {
+ throw new Error("round-trip failed for " + stream);
+ } else {
+ System.err.println("round-trip passed for " + stream);
+ }
+ }
+ // END-SAMPLE testing-inoculated-roundTrip
+}
+
+class BufferedPrinterStream {
+ int num;
+ BufferedPrinterStream(int i) { this.num = i; }
+ BufferedPrinterStream(PrinterStream p) { this(p.number); }
+}
+
+class PrinterStream {
+ int number;
+ static PrinterStream make(BufferedPrinterStream p) {
+ return new PrinterStream(p.num);
+ }
+ PrinterStream(int i) { this.number = i; }
+ void write() {}
+ // XXX hashcode
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ } else if (null == o) {
+ return false;
+ } else if (o instanceof PrinterStream) {
+ return ((PrinterStream)o).number == number;
+ } else {
+ return o.equals(this);
+ }
+ }
+}