diff options
author | jhugunin <jhugunin> | 2003-08-01 18:53:07 +0000 |
---|---|---|
committer | jhugunin <jhugunin> | 2003-08-01 18:53:07 +0000 |
commit | 57445dd3ec8a67d06f16fe02e7c0eaefb8ea4051 (patch) | |
tree | 4797aad7b10f19d1d71c71699d3e95de0a4d9262 | |
parent | a92e9c5c8c8646ec08759b7a940a6d32f2c541c6 (diff) | |
download | aspectj-57445dd3ec8a67d06f16fe02e7c0eaefb8ea4051.tar.gz aspectj-57445dd3ec8a67d06f16fe02e7c0eaefb8ea4051.zip |
Addendum to the original contribution from PARC. Three presentations:
oneHour talk
three hour tutorial
six hour tutorial including exercises
58 files changed, 3192 insertions, 0 deletions
diff --git a/docs/teaching/exercises/answers/Answer1a.java b/docs/teaching/exercises/answers/Answer1a.java new file mode 100644 index 000000000..94d4522c4 --- /dev/null +++ b/docs/teaching/exercises/answers/Answer1a.java @@ -0,0 +1,22 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.*; + +aspect Answer1a { + declare error + : get(java.io.PrintStream System.out) + && within(figures..*) + : "illegal access to System.out"; +} diff --git a/docs/teaching/exercises/answers/Answer1b.java b/docs/teaching/exercises/answers/Answer1b.java new file mode 100644 index 000000000..ef634a974 --- /dev/null +++ b/docs/teaching/exercises/answers/Answer1b.java @@ -0,0 +1,21 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +aspect Answer1b { + declare warning + : set(private * *) + && !withincode(* set*(..)) + && within(figures.*) + : "bad field set"; +} diff --git a/docs/teaching/exercises/answers/Answer1c.java b/docs/teaching/exercises/answers/Answer1c.java new file mode 100644 index 000000000..ff31b6378 --- /dev/null +++ b/docs/teaching/exercises/answers/Answer1c.java @@ -0,0 +1,21 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +aspect Answer1c { + declare error + : set(private * *) + && !(withincode(* set*(..)) || withincode(new(..))) + && within(figures.*) + : "bad field set"; +} diff --git a/docs/teaching/exercises/answers/Answer1d.java b/docs/teaching/exercises/answers/Answer1d.java new file mode 100644 index 000000000..9fb32390b --- /dev/null +++ b/docs/teaching/exercises/answers/Answer1d.java @@ -0,0 +1,23 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +aspect Answer1c { + declare error + : set(private * *) + && !(withincode(* set*(..)) + || withincode(new(..)) + || withincode(void figures.Point.move(int, int))) + && within(figures.*) + : "bad field set"; +} diff --git a/docs/teaching/exercises/answers/Answer2a.java b/docs/teaching/exercises/answers/Answer2a.java new file mode 100644 index 000000000..b874f06eb --- /dev/null +++ b/docs/teaching/exercises/answers/Answer2a.java @@ -0,0 +1,26 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.Point; +import figures.FigureElement; + +public aspect Answer2a { + before(int newValue): set(int Point.*) && args(newValue) { + if (newValue < FigureElement.MIN_VALUE) { + throw new IllegalArgumentException("too small"); + } else if (newValue > FigureElement.MAX_VALUE) { + throw new IllegalArgumentException("too large"); + } + } +} diff --git a/docs/teaching/exercises/answers/Answer2b.java b/docs/teaching/exercises/answers/Answer2b.java new file mode 100644 index 000000000..fc45ad265 --- /dev/null +++ b/docs/teaching/exercises/answers/Answer2b.java @@ -0,0 +1,26 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.Group; +import figures.FigureElement; + +public aspect Answer2b { + before(FigureElement newValue): + call(void Group.add(FigureElement)) + && args(newValue) { + if (newValue == null) { + throw new IllegalArgumentException("null not allowed"); + } + } +} diff --git a/docs/teaching/exercises/answers/Answer2c.java b/docs/teaching/exercises/answers/Answer2c.java new file mode 100644 index 000000000..6dbd7fa90 --- /dev/null +++ b/docs/teaching/exercises/answers/Answer2c.java @@ -0,0 +1,31 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.Group; +import figures.FigureElement; + +public aspect Answer2c { + before(FigureElement newValue, Group g): + call(void Group.add(FigureElement)) + && args(newValue) + && target(g) { + if (newValue == null) { + throw new IllegalArgumentException("null not allowed"); + } + if (newValue == g) { + throw new IllegalArgumentException("self not allowed"); + } + + } +} diff --git a/docs/teaching/exercises/answers/Answer2d.java b/docs/teaching/exercises/answers/Answer2d.java new file mode 100644 index 000000000..75937ca86 --- /dev/null +++ b/docs/teaching/exercises/answers/Answer2d.java @@ -0,0 +1,24 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.SlothfulPoint; + +aspect Answer2d { + after(int newValue, SlothfulPoint p) returning: + call(void setX(int)) && args(newValue) && target(p) { + if (newValue != p.getX()) { + throw new RuntimeException("setter didn't set"); + } + } +} diff --git a/docs/teaching/exercises/answers/Answer2e.java b/docs/teaching/exercises/answers/Answer2e.java new file mode 100644 index 000000000..a0500bc6b --- /dev/null +++ b/docs/teaching/exercises/answers/Answer2e.java @@ -0,0 +1,24 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.*; + +public aspect Answer2e { + pointcut checkpoint(Box box): + call(void move(int, int)) && target(box); + + after(Box box) returning: checkpoint(box) { + box.checkBoxness(); + } +} diff --git a/docs/teaching/exercises/answers/Answer2f.java b/docs/teaching/exercises/answers/Answer2f.java new file mode 100644 index 000000000..aad64f4e2 --- /dev/null +++ b/docs/teaching/exercises/answers/Answer2f.java @@ -0,0 +1,24 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.*; + +public aspect Answer2f { + pointcut checkpoint(Box box): + target(box) && call(public * *(..)) && !within(Answer*); + + after(Box box) returning: checkpoint(box) { + box.checkBoxness(); + } +} diff --git a/docs/teaching/exercises/answers/Answer2g.java b/docs/teaching/exercises/answers/Answer2g.java new file mode 100644 index 000000000..9bc9a521c --- /dev/null +++ b/docs/teaching/exercises/answers/Answer2g.java @@ -0,0 +1,27 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.*; + +aspect Answer2g { + int around(int val): (set(int Point._x) || set(int Point._y)) + && args(val) { + return proceed(trim(val)); + } + + private int trim(int val) { + return Math.max(Math.min(val, FigureElement.MAX_VALUE), + FigureElement.MIN_VALUE); + } +} diff --git a/docs/teaching/exercises/answers/Answer2h.java b/docs/teaching/exercises/answers/Answer2h.java new file mode 100644 index 000000000..3dcc47bef --- /dev/null +++ b/docs/teaching/exercises/answers/Answer2h.java @@ -0,0 +1,31 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.*; + +import java.awt.Rectangle; + +aspect Answer2h { + void around(FigureElement fe, int dx, int dy): + target(fe) && call(void move(int, int)) && args(dx, dy) { + Rectangle preBounds = new Rectangle(fe.getBounds()); + proceed(fe, dx, dy); + + preBounds.translate(dx, dy); + + if (!preBounds.equals(fe.getBounds())) { + throw new IllegalStateException("bounds don't match move"); + } + } +} diff --git a/docs/teaching/exercises/answers/Answer3a.java b/docs/teaching/exercises/answers/Answer3a.java new file mode 100644 index 000000000..7d9c91f0e --- /dev/null +++ b/docs/teaching/exercises/answers/Answer3a.java @@ -0,0 +1,23 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import support.Log; + +import figures.Point; + +aspect Answer3a { + before(): execution(void Point.move(int, int)) { + Log.log("moving"); + } +} diff --git a/docs/teaching/exercises/answers/Answer3b.java b/docs/teaching/exercises/answers/Answer3b.java new file mode 100644 index 000000000..b978f1a5e --- /dev/null +++ b/docs/teaching/exercises/answers/Answer3b.java @@ -0,0 +1,26 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import support.Log; + +import figures.Point; +import figures.Group; +import figures.FigureElement; + +aspect Answer3b { + before(): + execution(void Group.add(FigureElement)) && args(Point) { + Log.log("adding Point"); + } +} diff --git a/docs/teaching/exercises/answers/Answer3c.java b/docs/teaching/exercises/answers/Answer3c.java new file mode 100644 index 000000000..68797b9e0 --- /dev/null +++ b/docs/teaching/exercises/answers/Answer3c.java @@ -0,0 +1,34 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import support.Log; + +import figures.Point; +import figures.Group; +import figures.FigureElement; + +aspect Answer3c { + private Group Point.enclosingGroup = null; + + before(Point p, Group g): + execution(void add(FigureElement)) && args(p) && target(g) { + p.enclosingGroup = g; + } + + before(Point p): + call(void move(int, int)) && target(p) { + Log.log("moving as a part of " + p.enclosingGroup); + } + +} diff --git a/docs/teaching/exercises/answers/Answer4a.java b/docs/teaching/exercises/answers/Answer4a.java new file mode 100644 index 000000000..2f3956aea --- /dev/null +++ b/docs/teaching/exercises/answers/Answer4a.java @@ -0,0 +1,28 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.FigureElement; +import figures.Group; +import java.awt.Rectangle; + +aspect Answer4a { + private Rectangle wholeCanvas = + new Rectangle(FigureElement.MIN_VALUE, FigureElement.MIN_VALUE, + FigureElement.MAX_VALUE - FigureElement.MIN_VALUE, + FigureElement.MAX_VALUE - FigureElement.MIN_VALUE); + + Rectangle around(): execution(Rectangle Group.getBounds()) { + return wholeCanvas; + } +} diff --git a/docs/teaching/exercises/answers/Answer4b.java b/docs/teaching/exercises/answers/Answer4b.java new file mode 100644 index 000000000..d0292b14f --- /dev/null +++ b/docs/teaching/exercises/answers/Answer4b.java @@ -0,0 +1,29 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.FigureElement; +import figures.Group; +import java.awt.Rectangle; + +aspect Answer4b { + private Rectangle Group.cache = null; + + Rectangle around(Group g): + execution(Rectangle Group.getBounds()) && this(g) { + if (g.cache == null) { + g.cache = proceed(g); + } + return g.cache; + } +} diff --git a/docs/teaching/exercises/answers/Answer4c.java b/docs/teaching/exercises/answers/Answer4c.java new file mode 100644 index 000000000..54107cf8f --- /dev/null +++ b/docs/teaching/exercises/answers/Answer4c.java @@ -0,0 +1,33 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.FigureElement; +import figures.Group; +import java.awt.Rectangle; + +aspect Answer4c { + private Rectangle Group.cache = null; + + Rectangle around(Group g): + execution(Rectangle Group.getBounds()) && this(g) { + if (g.cache == null) { + g.cache = proceed(g); + } + return g.cache; + } + + before(Group g): call(void move(int, int)) && target(g) { + g.cache = null; + } +} diff --git a/docs/teaching/exercises/answers/Answer4d.java b/docs/teaching/exercises/answers/Answer4d.java new file mode 100644 index 000000000..10d90f6dd --- /dev/null +++ b/docs/teaching/exercises/answers/Answer4d.java @@ -0,0 +1,42 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.FigureElement; +import figures.Group; +import figures.Point; +import java.awt.Rectangle; + +aspect Answer4d { + private Rectangle Group.cache = null; + private Group Point.enclosingGroup = null; + + before(Point p, Group g): + execution(void add(FigureElement)) && args(p) && target(g) { + p.enclosingGroup = g; + } + + Rectangle around(Group g): + execution(Rectangle Group.getBounds()) && this(g) { + if (g.cache == null) { + g.cache = proceed(g); + } + return g.cache; + } + + before(Point p): set(* Point.*) && target(p) { + if (p.enclosingGroup != null) { + p.enclosingGroup.cache = null; + } + } +} diff --git a/docs/teaching/exercises/answers/Answer4e.java b/docs/teaching/exercises/answers/Answer4e.java new file mode 100644 index 000000000..20f98909a --- /dev/null +++ b/docs/teaching/exercises/answers/Answer4e.java @@ -0,0 +1,44 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.FigureElement; +import figures.Group; +import figures.Point; +import java.awt.Rectangle; + +aspect Answer4e { + private Rectangle Group.cache = null; + private Group FigureElement.enclosingGroup = null; + + before(FigureElement p, Group g): + execution(void add(FigureElement)) && args(p) && target(g) { + p.enclosingGroup = g; + } + + Rectangle around(Group g): + execution(Rectangle Group.getBounds()) && this(g) { + if (g.cache == null) { + g.cache = proceed(g); + } + return g.cache; + } + + before(Point p): set(* Point.*) && target(p) { + FigureElement fe = p; + while (fe.enclosingGroup != null) { + fe.enclosingGroup.cache = null; + fe = fe.enclosingGroup; + } + } +} diff --git a/docs/teaching/exercises/base.lst b/docs/teaching/exercises/base.lst new file mode 100644 index 000000000..ae9c8c65e --- /dev/null +++ b/docs/teaching/exercises/base.lst @@ -0,0 +1,29 @@ +figures/Box.java +figures/FigureElement.java +figures/Group.java +figures/Line.java +figures/Point.java +figures/ShapeFigureElement.java +figures/SlothfulPoint.java + +support/Log.java + +answers/Answer.java + +tests/Test.java +tests/Test2a.java +tests/Test2b.java +tests/Test2c.java +tests/Test2d.java +tests/Test2e.java +tests/Test2f.java +tests/Test2g.java +tests/Test2h.java +tests/Test3a.java +tests/Test3b.java +tests/Test3c.java +tests/Test4a.java +tests/Test4b.java +tests/Test4c.java +tests/Test4d.java +tests/Test4e.java diff --git a/docs/teaching/exercises/figures/Box.java b/docs/teaching/exercises/figures/Box.java new file mode 100644 index 000000000..b10faa612 --- /dev/null +++ b/docs/teaching/exercises/figures/Box.java @@ -0,0 +1,64 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public class Box extends ShapeFigureElement { + private Point _p0; + private Point _p1; + private Point _p2; + private Point _p3; + + public Box(int x0, int y0, int width, int height) { + _p0 = new Point(x0, y0); + _p1 = new Point(x0+width, y0); + _p2 = new Point(x0+width, y0+height); + _p3 = new Point(x0, y0+height); + } + + public Point getP0() { return _p0; } + public Point getP1() { return _p1; } + public Point getP2() { return _p2; } + public Point getP3() { return _p3; } + + public void move(int dx, int dy) { + _p0.move(dx, dy); + _p1.move(dx, dy); + _p2.move(dx, dy); + _p3.move(dx, dy); + } + + public void checkBoxness() { + if ((_p0.getX() == _p3.getX()) && + (_p1.getX() == _p2.getX()) && + (_p0.getY() == _p1.getY()) && + (_p2.getY() == _p3.getY())) + return; + throw new IllegalStateException("This is not a square."); + } + + public String toString() { + return "Box(" + _p0 + ", " + _p1 + ", " + _p2 + ", " + _p3 + ")"; + } + + public Shape getShape() { + return new Rectangle(getP1().getX(), + getP1().getY(), + getP3().getX() - getP1().getX(), + getP3().getY() - getP1().getY()); + } +} + diff --git a/docs/teaching/exercises/figures/FigureElement.java b/docs/teaching/exercises/figures/FigureElement.java new file mode 100644 index 000000000..d6d5c261c --- /dev/null +++ b/docs/teaching/exercises/figures/FigureElement.java @@ -0,0 +1,30 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public interface FigureElement { + public static final int MIN_VALUE = 0; + public static final int MAX_VALUE = 500; + + public abstract void move(int dx, int dy); + + public abstract Rectangle getBounds(); + + public abstract boolean contains(Point2D p); + + public abstract void paint(Graphics2D g2); +} diff --git a/docs/teaching/exercises/figures/Group.java b/docs/teaching/exercises/figures/Group.java new file mode 100644 index 000000000..ad2f224c6 --- /dev/null +++ b/docs/teaching/exercises/figures/Group.java @@ -0,0 +1,97 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures; + +import java.util.*; +import java.awt.*; +import java.awt.geom.*; + +public class Group implements FigureElement { + private Collection _members; + private String _identifier; + + public Group(FigureElement first) { + this._members = new ArrayList(); + add(first); + } + + public void add(FigureElement fe) { + _members.add(fe); + } + + public Iterator members() { + return _members.iterator(); + } + + public void move(int dx, int dy) { + for (Iterator i = _members.iterator(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + fe.move(dx, dy); + } + } + + public void setIdentifier(String identifier) { + _identifier = identifier; + } + + public String toString() { + if (_identifier != null) { + return _identifier; + } + + StringBuffer buf = new StringBuffer("Group("); + for (Iterator i = _members.iterator(); i.hasNext(); ) { + buf.append(i.next().toString()); + if (i.hasNext()) { + buf.append(", "); + } + } + buf.append(")"); + return buf.toString(); + } + + public Rectangle getBounds() { + Rectangle previous = null; + for (Iterator i = _members.iterator(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + Rectangle rect = fe.getBounds(); + if (previous != null) { + previous = previous.union(rect); + } else { + previous = rect; + } + } + return previous; + } + + public boolean contains(Point2D p) { + for (Iterator i = _members.iterator(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + if (fe.contains(p)) return true; + } + return false; + } + + public void paint(Graphics2D g2) { + for (Iterator i = _members.iterator(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + fe.paint(g2); + } + } + + public int size() { + return _members.size(); + } +} + diff --git a/docs/teaching/exercises/figures/Line.java b/docs/teaching/exercises/figures/Line.java new file mode 100644 index 000000000..f21c1eff1 --- /dev/null +++ b/docs/teaching/exercises/figures/Line.java @@ -0,0 +1,64 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public class Line extends ShapeFigureElement { + private Point _p1; + private Point _p2; + + public Line(Point p1, Point p2) { + _p1 = p1; + _p2 = p2; + } + + public Point getP1() { return _p1; } + public Point getP2() { return _p2; } + + public void move(int dx, int dy) { + _p1.move(dx, dy); + _p2.move(dx, dy); + } + + public String toString() { + return "Line(" + _p1 + ", " + _p2 + ")"; + } + + /** + * Used to determine if this line {@link contains(Point2D)} a point. + */ + final static int THRESHHOLD = 5; + + /** + * Returns <code>true</code> if the point segment distance is less than + * {@link THRESHHOLD}. + */ + public boolean contains(Point2D p) { + return getLine2D().ptLineDist(p) < THRESHHOLD; + } + + private Line2D getLine2D() { + return new Line2D.Float((float)getP1().getX(), + (float)getP1().getY(), + (float)getP2().getX(), + (float)getP2().getY()); + } + + public Shape getShape() { + return getLine2D(); + } +} + diff --git a/docs/teaching/exercises/figures/Point.java b/docs/teaching/exercises/figures/Point.java new file mode 100644 index 000000000..63126d96f --- /dev/null +++ b/docs/teaching/exercises/figures/Point.java @@ -0,0 +1,58 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public class Point extends ShapeFigureElement { + private int _x; + private int _y; + + public Point(int x, int y) { + _x = x; + _y = y; + } + + public int getX() { return _x; } + + public int getY() { return _y; } + + public void setX(int x) { _x = x; } + + public void setY(int y) { _y = y; } + + public void move(int dx, int dy) { + _x += dx; + _y += dy; + } + + public String toString() { + return "Point(" + _x + ", " + _y + ")"; + } + + /** The height of displayed {@link Point}s. */ + private final static int HEIGHT = 10; + + /** The width of displayed {@link Point}s. -- same as {@link HEIGHT}. */ + private final static int WIDTH = Point.HEIGHT; + + public Shape getShape() { + return new Ellipse2D.Float((float)getX()-Point.WIDTH/2, + (float)getY()-Point.HEIGHT/2, + (float)Point.HEIGHT, + (float)Point.WIDTH); + } +} + diff --git a/docs/teaching/exercises/figures/ShapeFigureElement.java b/docs/teaching/exercises/figures/ShapeFigureElement.java new file mode 100644 index 000000000..b09bad10e --- /dev/null +++ b/docs/teaching/exercises/figures/ShapeFigureElement.java @@ -0,0 +1,47 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public abstract class ShapeFigureElement implements FigureElement { + public abstract void move(int dx, int dy); + + public abstract Shape getShape(); + + public Rectangle getBounds() { + return getShape().getBounds(); + } + + public boolean contains(Point2D p) { + return getShape().contains(p); + } + + public Color getLineColor() { + return Color.black; + } + + public Color getFillColor() { + return Color.red; + } + + public final void paint(Graphics2D g2) { + Shape shape = getShape(); + g2.setPaint(getFillColor()); + g2.fill(shape); + g2.setPaint(getLineColor()); + g2.draw(shape); + } +} diff --git a/docs/teaching/exercises/figures/SlothfulPoint.java b/docs/teaching/exercises/figures/SlothfulPoint.java new file mode 100644 index 000000000..ede073b24 --- /dev/null +++ b/docs/teaching/exercises/figures/SlothfulPoint.java @@ -0,0 +1,50 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +/** + * This class makes mistakes to be caught by invariant checkers. + */ +public class SlothfulPoint extends ShapeFigureElement { + private int _x; + private int _y; + + public SlothfulPoint(int x, int y) { + } + + public int getX() { return _x; } + + public int getY() { return _y; } + + public void setX(int x) { } + + public void setY(int y) { } + + public void move(int dx, int dy) { + System.out.println("Slothful moving"); + } + + public String toString() { + return "SlothfulPoint"; + } + + public Shape getShape() { + return new Ellipse2D.Float((float)_x, + (float)_y, 1.0f, 1.0f); + } +} + diff --git a/docs/teaching/exercises/figures/gui/FigurePanel.java b/docs/teaching/exercises/figures/gui/FigurePanel.java new file mode 100644 index 000000000..4746bc057 --- /dev/null +++ b/docs/teaching/exercises/figures/gui/FigurePanel.java @@ -0,0 +1,181 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures.gui; + +import figures.Point; +import figures.Line; +import figures.FigureElement; +import figures.Group; + + +import java.awt.*; +import java.awt.geom.*; +import java.awt.event.*; +import java.io.*; +import java.util.*; +import javax.swing.*; +import javax.swing.text.*; +import javax.swing.border.*; + +public class FigurePanel extends JComponent { + + ButtonsPanel bp = new ButtonsPanel(); + FigureSurface fs = new FigureSurface(); + ConsolePanel cp = new ConsolePanel(); + + + public FigurePanel() { + setLayout(new BorderLayout()); + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + panel.add(fs); + panel.add(bp); + JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, panel, cp); + sp.setPreferredSize(new Dimension(500, 400)); + sp.setDividerLocation(250); + add(BorderLayout.CENTER, sp); + } + + class ButtonsPanel extends JPanel { + JLabel msgs = new JLabel("click to add a point or line"); + public ButtonsPanel() { + setLayout(new FlowLayout(FlowLayout.LEFT)); + add(new JButton(new AbstractAction("Main") { + public void actionPerformed(ActionEvent e) { + Main.main(new String[]{}); + fs.repaint(); + } + })); + add(msgs); + } + + public void log(String msg) { + msgs.setText(msg); + } + } + + static class ConsolePanel extends JPanel { + + JTextArea text = new JTextArea(); + + public ConsolePanel() { + super(new BorderLayout()); + text.setFont(StyleContext.getDefaultStyleContext().getFont("SansSerif", Font.PLAIN, 10)); + JScrollPane scroller = new JScrollPane(text); + scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + add(BorderLayout.CENTER, scroller); + } + + public void println(String msg) { + text.append(msg + '\n'); + } + } + + final static Color BACKGROUND = Color.white; + + static class FigureSurface extends JPanel implements MouseListener, MouseMotionListener { + Group canvas; + + public FigureSurface() { + canvas = new Group(new Point(250, 250)); + addMouseMotionListener(this); + addMouseListener(this); + setPreferredSize(new Dimension(500,500)); + } + + private Point addPoint(int x, int y) { + Point p = new Point(x, y); + canvas.add(p); + repaint(); + return p; + } + + private Line addLine(Point p1, Point p2) { + if (Math.abs(p1.getX()-p2.getX()) < 5 || + Math.abs(p1.getY()-p2.getY()) < 5) { + return null; + } + + Line line = null; + if (p1 != null && p2 != null) { + line = new Line(p1, p2); + canvas.add(line); + } + repaint(); + return line; + } + + public void paint(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + g2.setPaint(BACKGROUND); + g2.fill(new Rectangle2D.Float(0f, 0f, (float)g2.getClipBounds().width, (float)g2.getClipBounds().height)); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + canvas.paint(g2); + } + + + int lastX, lastY; + int pressX, pressY; + + FigureElement first = null; + Point point1 = null; + + public void mousePressed(MouseEvent e){ + int x = e.getX(), y = e.getY(); + pressX = lastX = x; pressY = lastY = y; + first = findFigureElement(x, y); + if (first == null) { + point1 = addPoint(x, y); + } + } + + public void mouseDragged(MouseEvent e) { + int x = e.getX(), y = e.getY(), dx = lastX-x, dy = lastY-y; + lastX = x; + lastY = y; + if (first == null) { + Line line = addLine(point1, new Point(x, y)); + if (line != null) { + canvas.add(line.getP2()); + first = line.getP2(); + canvas.add(line); + } + } else { + first.move(-dx, -dy); + } + repaint(); + } + + public void mouseReleased(MouseEvent e){ + mouseDragged(e); + first = null; + point1 = null; + } + + + public void mouseMoved(MouseEvent e){} + public void mouseClicked(MouseEvent e){} + public void mouseExited(MouseEvent e){} + public void mouseEntered(MouseEvent e){} + + private FigureElement findFigureElement(int x, int y) { + Point2D p = new Point2D.Float((float)x, (float)y); + for (Iterator i = canvas.members(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + if (fe.contains(p)) return fe; + } + return null; + } + } +} diff --git a/docs/teaching/exercises/figures/gui/LogAdapter.java b/docs/teaching/exercises/figures/gui/LogAdapter.java new file mode 100644 index 000000000..9d7d7d94d --- /dev/null +++ b/docs/teaching/exercises/figures/gui/LogAdapter.java @@ -0,0 +1,25 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures.gui; + +import support.Log; + +aspect LogAdapter { + + before(String s): call(void Log.log(String)) && args(s) { + if (Main.panel != null) { + Main.panel.cp.println(s); + } + } +} diff --git a/docs/teaching/exercises/figures/gui/Main.java b/docs/teaching/exercises/figures/gui/Main.java new file mode 100644 index 000000000..c2d41c3b0 --- /dev/null +++ b/docs/teaching/exercises/figures/gui/Main.java @@ -0,0 +1,31 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures.gui; + +import javax.swing.*; +import support.Log; + +public class Main { + static FigurePanel panel; + + public static void main(String[] args) { + JFrame figureFrame = new JFrame("Figure Editor"); + panel = new FigurePanel(); + figureFrame.setContentPane(panel); + figureFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + figureFrame.pack(); + figureFrame.setVisible(true); + } + +} diff --git a/docs/teaching/exercises/guibase.lst b/docs/teaching/exercises/guibase.lst new file mode 100644 index 000000000..0a9371462 --- /dev/null +++ b/docs/teaching/exercises/guibase.lst @@ -0,0 +1,5 @@ +-argfile +base.lst +figures/gui/FigurePanel.java +figures/gui/Main.java +figures/gui/LogAdapter.java
\ No newline at end of file diff --git a/docs/teaching/exercises/index.html b/docs/teaching/exercises/index.html new file mode 100644 index 000000000..4dff3dae0 --- /dev/null +++ b/docs/teaching/exercises/index.html @@ -0,0 +1,769 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> <head> +<title>AspectJ Tutorial Exercises</title> +</head> + +<body bgcolor="white"> +<h1>AspectJ Tutorial Exercises</h1> + +<h3>Organization</h3> + +<p> The exercises work with a figure editor together with JUnit test +cases. They progress, as most users do in their adoption of AspectJ, +from non-functional, development-only aspects to aspects which augment +a deployed program with crosscutting features. </p> + +<p> We have made available a package that includes the tests, the base +code, JUnit, and a distribution of AspectJ. All it needs is +information about where Java lives (so set your JAVA_HOME environment +variable). It assumes that you unzip it in c:\ (on Windows) or in +your home directory (on Linux): If you put it somewhere else, edit +setpaths or setpaths.bat, as appropriate. Once all this is done, run +<code>setpaths.bat</code> or <code>source setpaths</code> to export +some other needed environment variables. </p> + +<p> All the files in the program are listed in base.lst, including +test cases and an empty answer aspect, +<code>answers/Answer.java</code>. Therefore, if you write your +answers there, all you need to do is compile base.lst, either in an +IDE or with </p> + +<blockquote><PRE> +$ ajc -Xlint -argfile base.lst +</PRE></blockquote> + +<p> Before you move onto another exercise, though, make sure to copy +your answer into a different file so we can discuss the answers +together: +</p> + +<blockquote><PRE> +> copy answers/Answer.java answers/2a.java (Windows) +$ cp answers/Answer.java answers/2a.java (Linux) +</PRE></blockquote> + +<p> If you want to put your answer in a different file, say, +<code>answers/Answer2a.java</code>, you can compile with </p> + +<blockquote><PRE> +$ ajc -Xlint -argfile base.lst answers/Answer2a.java +</PRE> </blockquote> + +<p> In any case, after building the system, you should invoke Java on +the compiled test class. On the command-line, this this would be </p> + +<blockquote><PRE> +$ java tests.Test2a +</PRE> </blockquote> + +<p> (For these exercises, when we give examples of execution we will +show the command-line use, but of course if you are using JBuilder, +Forte/NetBeans, Emacs, or Eclipse, use the appropriate compile and +execute tools.) </p> + +<p> The default test, <code>tests.Test</code>, performs some +rudimentary tests on figure elements, and so is a useful test to run +periodically. Looking at the JUnit tests for each exercise may also +be helpful. </p> + +<p> Again, ae will be looking at some solutions and having discussion, +which is much more difficult without incremental solutions. So when +you go from one exercise to the next, make sure to save your work in a +file and go on to work in a different file, even if you plan to +duplicate some code. </p> + +<hr> +<!-- page break --> +<h2>1. Static Invariants</h2> + +<h3>a. Catch old tracing</h3> + +<p> The way that we are all taught to print "hello world" from Java is +to use <code>System.out.println()</code>, so that is what we typically +use for one-off debugging traces. It's a common mistake to leave +these in your system longer than is necessary. Type in the aspect +below to forces an error at compile time if this mistake is made. +</p> + +<p> When you use this on the given system, you'll find one incorrect +trace in <code>SlothfulPoint</code>. +</p> + +<blockquote><PRE> +$ ajc -argfile base.lst +./figures/SlothfulPoint.java:29:9: illegal access to System.out + System.out.println("Slothful moving"); + ^ +1 errors +</PRE></blockquote> + +<p> Remove the illegal tracing call. +</p> + +<p> Make sure your program still passes the JUnit test +<code>tests.Test</code> (which it should also pass at the beginning of +all exercises) before continuing. </p> + +<blockquote><PRE> +$ java tests.Test +.... +Time: 0.076 + +OK (4 tests) +</PRE></blockquote> + +<p> <strong>Answer:</strong> +</p> + +<blockquote><PRE> +package answers; + +import figures.*; + +aspect Answer1a { + declare error + : get(java.io.PrintStream System.out) && within(figures..*) + : "illegal access to System.out"; +} +</PRE></blockquote> + +<p> Note that this answer does not say that the <em>call</em> to the +<code>println()</code> method is incorrect, rather, that the field get +of the <code>out</code> field is illegal. This will also catch those +users who bind System.out to a static field to save typing. </p> + + +<h3>b. Mandate setters</h3> + +<p> One common coding convention is that no private field should be +set outside of setter methods. Write an aspect to warn at compile +time when such an illegal assignment expression exists. </p> + +<p> This is going to look like +</p> + +<pre> +aspect A { + declare warning: <em><pointcut here></em> : "bad field set"; +} +</pre> + +<p> where the pointcut picks out join points of private field sets +outside of setter methods. "Outside", here, means that the code for +the assignment is outside the <em>text</em> of the setter (a setter is +a method that looks like "void set*(..)"), so check out the quick +reference for <code>set</code> and <code>withincode</code> primitive +pointcuts. ) </p> + +<p> Make sure your program still passes the JUnit test +<code>tests.Test</code> before continuing, and that you see all of the +following warning messages. You'll notice a LOT of warnings here. +Wait to fix them until the next exercise... +</p> + +<pre> +.\figures\Box.java:17:9: bad field set (warning) + _p0 = new Point(x0, y0); + ^ +.\figures\Box.java:18:9: bad field set (warning) + _p1 = new Point(x0+width, y0); + ^ +.\figures\Box.java:19:9: bad field set (warning) + _p2 = new Point(x0+width, y0+height); + ^ +.\figures\Box.java:20:9: bad field set (warning) + _p3 = new Point(x0, y0+height); + ^ +.\figures\Group.java:16:23: bad field set (warning) + this._members = new ArrayList(); + ^ +.\figures\Line.java:15:9: bad field set (warning) + _p1 = p1; + ^ +.\figures\Line.java:16:9: bad field set (warning) + _p2 = p2; + ^ +.\figures\Point.java:15:9: bad field set (warning) + _x = x; + ^ +.\figures\Point.java:16:9: bad field set (warning) + _y = y; + ^ +.\figures\Point.java:28:9: bad field set (warning) + _x += dx; + ^ +.\figures\Point.java:29:9: bad field set (warning) + _y += dy; + ^ +</pre> + + +<h3>c. Refine setters mandate</h3> + +<p> Look at some of the warnings. Notice that a lot of them are from +within constructors. Actually, the common coding convention is that +no private field should be set outside of setter methods <b>or +constructors</b>. Modify your answer (in a new file) to signal an +actual error at compile time (rather than just a warning) when such an +illegal assignment expression exists. </p> + +<p>You'll want to add another <code>withincode</code> primitive +pointcut to deal with the constructors. +</p> + +<p>After you specify your pointcut correctly, you'll still find that +the convention is violated twice in the figures package. You should see +the following two errors:</p> + +<pre> +.\figures\Point.java:28:9: bad field set + _x += dx; + ^ +.\figures\Point.java:29:9: bad field set + _y += dy; + ^ +2 errors +</pre> + +<p> (If you see more, go back to 1b; you may be capturing sets to +too many fields.) +</p> + +<p>Rewrite these two occurrences so as not to violate +the convention. Make sure your program still passes the JUnit test +<code>tests.Test</code> before continuing. </p> + +<h3>d. Re-refine setters mandate</h3> + +<p> In part (c), you rewrote the code to fit the convention enforced +by the aspect. It may be that this code doesn't violate the convention +of your mythical organization. Try to instead fix the pointcut so it +doesn't signal an error for these two assignments, and then change +your code back to making the assignments. </p> + +<p> Make sure your program still passes the JUnit test +<code>tests.Test</code> before continuing. </p> + +<h3>Help Yourself by Helping Others</h3> + +<p> At this point, check the people to your left and right. If +they're stuck somewhere, see if you can help them. </p> + + +<!-- ============================== --> + +<hr /> + +<h2>2. Dynamic invariants</h2> + + +<h3>a. Check a simple precondition</h3> + +<p> Write an aspect to throw an <code>IllegalArgumentException</code> +whenever an attempt is made to set one of <code>Point</code>'s +<code>int</code> fields to a value that is either too large (greater +than <code>FigureElement.MAX_VALUE</code>) or too small (less than +<code>FigureElement.MIN_VALUE</code>). </p> + +<p> This should make the test case of <code>tests.Test2a</code> pass, +which wouldn't without your aspect. So before compiling in the +aspect, +</p> + +<blockquote><PRE> +$ ajc -Xlint -argfile base.lst + +$ java tests.Test2a +.F.F.F.... +Time: 0.099 +There were 3 failures: +1) testTooSmall(tests.Test2a)junit.framework.AssertionFailedError: should have thrown IllegalArgumentException +2) testTooBig(tests.Test2a)junit.framework.AssertionFailedError: should have thrown IllegalArgumentException +3) testMove(tests.Test2a)junit.framework.AssertionFailedError: should have thrown IllegalArgumentException + +FAILURES!!! +Tests run: 7, Failures: 3, Errors: 0 +</PRE></blockquote> + +<p> But after compiling in the aspect... +</p> + +<blockquote><PRE> +$ ajc -Xlint -argfile base.lst + +$ java tests.Test2a +....... +Time: 0.097 + +OK (7 tests) +</PRE></blockquote> + +<p> <strong>Answer:</strong> +</p> + +<blockquote><PRE> +package answers; + +import figures.*; + +aspect Answer2a { + before(int newValue): set(int Point.*) && args(newValue) { + if (newValue < FigureElement.MIN_VALUE) { + throw new IllegalArgumentException("too small"); + } else if (newValue > FigureElement.MAX_VALUE) { + throw new IllegalArgumentException("too large"); + } + } +} +</PRE></blockquote> + +<h3>b. Check another precondition</h3> + +<p> <code>Group</code> is a <code>FigureElement</code> class that +encapsulates groups of other figure elements. As such, only actual +figure element objects should be added to <code>Group</code> objects. Write +an aspect to throw an <code>IllegalArgumentException</code> whenever +<code>Group.add()</code> is called with a +<code>null</code> value. If you look at the source code for +tests/Test2b.java, you'll see an example of the desired behavior, +i.e. </p> + +<pre> + public void testNull() { + try { + g.add(null); + fail("should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException ea) { + } + } +</pre> + +<p> For each of these exercises, you'll find that the corresponding +test case provides that most concrete example of the desired behavior +for your aspect. Please avail yourself of this resource. </p> + +<p> With this aspect in place, your code should pass +<code>tests.Test2b</code>. +</p> + +<h3>c. Check yet another precondition</h3> + +<p> Another constraint on a well-formed group is that it should not +contain itself as a member (though it may contain other groups). Write +an aspect to throw an <code>IllegalArgumentException</code> whenever +an attempt is made to call <code>Group.add()</code> on a +<code>null</code> value, or on the group itself. </p> + +<p> You will want to use a <code>target</code> pointcut to expose the +<code>Group</code> object that is the target of the <code>add</code> +call. +</p> + +<p> With this aspect in place, your code should pass +<code>tests.Test2c</code>. +</p> + +<h3>d. Check a simple postcondition</h3> + +<p> One of the simplest postconditions to check is that a setter +actually sets its value. Write an aspect that throws a +<code>java.lang.RuntimeException</code> if, after calling +<code>setX()</code> on <code>SlothfulPoint</code> objects, +<code>getX()</code> doesn't return the new value. </p> + +<p> You'll want to use an <code>args</code> pointcut to expose the +argument to <code>setX()</code> and a <code>target</code> pointcut to +expose the <code>SlothfulPoint</code> object itself (so you can later +call <code>getX()</code> on it). +</p> + +<p> An interesting question to think about for discussion is whether +this postcondition should apply when getX() throws an exception, or +when it returns normally, or both? </p> + +<p> With this aspect in place, your code should pass +<code>tests.Test2d</code>. +</p> + +<h3>e. Check invariant</h3> + +<p> There is a method on the <code>Box</code> class, <code>void +checkBoxness()</code>, that checks whether the four points making up a +box are correctly positioned relative to each other (i.e., they form a +rectangle). Write an aspect that will make sure that after every time +the <code>void move(int, int)</code> method on <code>Box</code> is +called, that you also call <code>Box.checkBoxness()</code> to ensure +that the <code>move</code> didn't break this invariant. </p> + +<p> With this aspect in place, your code should pass +<code>tests.Test2e</code>. +</p> + +<h3>f. Refine your invariant</h3> + +<p> <code>move</code> is not the only interesting method on +<code>Box</code>. It may be that a box gets malformed between calls +to <code>move</code>. So instead of checking boxness only +after the <code>move</code> method of <code>Box</code>, check +after the call to every one of <code>Box</code>'s public methods. +</p> + +<p> When testing this aspect, you may find yourself facing a +<code>StackOverflowException</code>. If so, carefully look at your +pointcuts. Needless to say, there should not be an infinite loop in +your program. You might want to look at using a <code>within</code> +pointcut for a filter. </p> + +<p> (You might even find that this test case aborts with no message, +i.e., +</p> + +<blockquote><pre> +$ java tests.test2f +. +$ +</pre></blockquote> + +<p> this is a bug in Sun's JVM where a particular stack overflow +causes the VM to abort.) +</p> + +<p> Make sure to pass the JUnit test <code>tests.Test2f</code> +before continuing. </p> + + +<h3>g. Assure input</h3> + +<p> Instead of throwing an exception when one of <code>Point</code>'s +<code>int</code> fields are set to an out-of-bounds value, write an +aspect to trim the value into an in-bounds one. You'll want to use +<code>around</code> advice that exposes the new value of the field +assignment with an <code>args</code> pointcut, and +<code>proceed</code> with the trimmed value. Becuase this is tricky, +type in the below aspect... the trick for this exercise is not to come +up with an answer, but to understand the answer. </p> + +<p> Make sure to pass the JUnit test <code>tests.Test2g</code> +before continuing. </p> + +<p> <strong>Answer: </strong> +</p> + +<blockquote><PRE> +package answers; + +import figures.*; + +aspect Answer2g { + int around(int val): + (set(int Point._x) || set(int Point._y)) + && args(val) { + return proceed(trim(val)); + } + + private int trim(int val) { + return Math.max(Math.min(val, FigureElement.MAX_VALUE), + FigureElement.MIN_VALUE); + } +} +</PRE></blockquote> + + +<h3>h. Check another invariant</h3> + +<p> <code>FigureElement</code> objects have a <code>getBounds()</code> +method that returns a <code>java.awt.Rectangle</code> representing the +bounds of the object. An important postcondition of the +<code>move</code> operation is that the figure element's bounds +rectangle should move by the same amount as the figure itself. Write +an aspect to check for this postcondition -- throw an +<code>IllegalStateException</code> if it is violated. </p> + +<p> Note that because we're dealing with how the bounds changes during +move, we need some way of getting access to the bounds both before +<em>and</em> after the move, in one piece of advice. Also, note that +you can create a copy of a figure element's bounds rectangle with +<code>new Rectangle(fe.getBounds())</code>, and you can move a bounds +rectangle <code>rect</code> with <code>rect.translate(dx, +dy)</code>. </p> + +<p> Make sure to pass the JUnit test <code>tests.Test2h</code> +before continuing. </p> + + +<h3>Help Yourself by Helping Others</h3> + +<p> At this point, check the people to your left and right. If +they're stuck somewhere, see if you can help them. </p> + +<!-- ============================== --> + +<hr /> +<!-- page break --> + +<h2>3. Tracing</h2> + +<p> The crosscutting feature you will be adding in part (4) will be +support for caching the bound objects of <code>Group</code> figure +elements, which may be costly to compute. On the way to that, though, +it's useful to explore the system with some tracing aspects. </p> + +<h3>a. Simple tracing</h3> + +<p> Write an aspect to trace whenever a <code>Point</code> is moved. +To do this, use the utility class <code>Log</code> (with an import +from <code>support.Log</code>) and call </p> + +<blockquote><PRE> +Log.log("moving") +</PRE></blockquote> + +<p> This will write the string "moving", followed by a semicolon +terminator, to the Log. For example, with your aspect enabled, +</p> + +<blockquote><PRE> +Point p1 = new Point(10, 100); +p1.move(37, 8); +System.out.println(Log.getString()); +</PRE></blockquote> + +<p> should print out "moving;". +</p> + +<p> Test this with the JUnit test case <code>tests.Test3a</code>. +Without adding any aspects, this test should fail: </p> + +<blockquote><PRE> +$ ajc -Xlint -argfile base.lst +$ java tests.Test3a +..F....... +Time: 0.07 +There was 1 failure: +1) testMovePointLog(tests.Test3a)junit.framework.AssertionFailedError: expected:<set;> but was:<> + at tests.Test3a.testMovePointLog(Test1a.java:30) + at tests.Test3a.main(Test1a.java:16) + +FAILURES!!! +Tests run: 9, Failures: 1, Errors: 0 +</PRE></blockquote> + +<p> But with the proper aspect added to the compilation, (in this +case, <code>answers/Answer3a.java</code>, but you should feel free to +use more evocative names), the test should pass </p> + +<blockquote><PRE> +$ ajc -Xlint -argfile base.lst answers/Answer3a.java +$ java tests.Test3a +......... +Time: 0.089 + +OK (9 tests) +</PRE></blockquote> + +<p> <strong>Answer: </strong> +</p> + +<blockquote><PRE> +package answers; + +import support.Log; +import figures.*; + +aspect Answer3a { + before(): execution(void Point.move(int, int)) { + Log.log("moving"); + } +} +</PRE></blockquote> + +<h3>b. More complex tracing</h3> + +<p> Write an aspect to trace whenever a <code>Point</code> is added to +a group (including initially). To do this, use the utility class +<code>Log</code> (with an import from <code>support.Log</code>) and +call </p> + +<blockquote><PRE> +Log.log("adding Point") +</PRE></blockquote> + +<p> This will write the string "adding Point", followed by a semicolon +terminator, to the Log. For example, with your aspect enabled, </p> + +<blockquote><PRE> +Point p1 = new Point(10, 100); +Point p2 = new Point(10, 100); +Group g = new Group(p1); +g.add(p2); +System.out.println(Log.getString()); +</PRE></blockquote> + +<p> should print out "adding Point;adding Point;". +</p> + +<p> <em>Hint: The <code>args</code> pointcut allows you to select join points +based on the type of a parameter to a method call. </em> </p> + +<p> Test this with the JUnit test case <code>tests.Test3b</code>. + + +<h3>c. Keeping track of state</h3> + +<p> In this exercise, perform the tracing from part (a), but also log +the enclosing group, if any, of the moving point. You can use an +inter-type declaration inside your aspect to associate a +<code>Group</code> field with <code>Point</code> objects, and then +work with that field, setting it appropriately when the +<code>Point</code> is added to a <code>Group</code> (at the same join +points you were tracing in part b). So </p> + +<blockquote><PRE> +Point p1 = new Point(10, 100); +p1.move(0, 0); +System.out.println(Log.getString()); +</PRE></blockquote> + +<p> should print out "moving as a part of null;", but +</p> + +<blockquote><PRE> +Point p1 = new Point(10, 100); +Group g = new Group(p1); +p1.move(0, 0); +System.out.println(Log.getString()); +</PRE></blockquote> + +<p> should print out "moving as a part of Group(Point(10, 100));", +which you can do by using the toString() method already defined on +Group. </p> + +<p> <em> Hint: This exercise combines the tracing from parts a and b. +If you start with an aspect that includes the solutions to those +previous exercises, you'll be most of the way there. </em> </p> + +<p> Test this with the JUnit test case <code>tests.Test3c</code>. + + +<h3>Help Yourself by Helping Others</h3> + +<p> At this point, check the people to your left and right. If +they're stuck somewhere, see if you can help them. </p> + + +<!-- ============================== --> + +<hr /> + +<!-- page break --> +<h3>4. Caching</h3> + +<p> Computation of the bounding box of <code>Group</code> objects +needs to deal with all aggregate parts of the group, and this +computation can be expensive. In this section, we will explore +various ways of reducing this expense. </p> + +<p> <strong>Optional</strong>: In all of these exercises, you should +only deal with points that are added directly to Groups, rather than +those that are added "indirectly" through Lines and Boxes. You should +handle those points contained in Lines and Boxes only if time permits. +</p> + +<h3>a. Make a constant override</h3> + +<p> <code>Group</code>'s <code>getBounds()</code> method could be +understood to be a conservative approximation of the bounding box of a +group. If that is true, then it would be a legal (and much faster) +implementation of <code>getBounds()</code> to simply always return a +rectangle consisting of the entire canvas, that is +</p> + +<blockquote><PRE> +new Rectangle(FigureElement.MIN_VALUE, FigureElement.MIN_VALUE, + FigureElement.MAX_VALUE - FigureElement.MIN_VALUE, + FigureElement.MAX_VALUE - FigureElement.MIN_VALUE) +</PRE></blockquote> + +<p> Write an aspect to implement this change. You can override +<code>Group</code>'s <code>getBounds()</code> method entirely with +around advice intercepting the method. +</p> + +<p> Your code should pass the JUnit test case +<code>tests.Test4a</code> with this change. +</p> + +<p> <strong>Answer: </strong> +</p> + +<blockquote><PRE> +package answers; + +import figures.*; +import java.awt.Rectangle; + +aspect Answer4a { + private Rectangle wholeCanvas = + new Rectangle(FigureElement.MIN_VALUE, FigureElement.MIN_VALUE, + FigureElement.MAX_VALUE - FigureElement.MIN_VALUE, + FigureElement.MAX_VALUE - FigureElement.MIN_VALUE); + + Rectangle around(): execution(Rectangle Group.getBounds()) { + return wholeCanvas; + } +} +</PRE></blockquote> + +<h3>b. Make a constant cache</h3> + +<p> Instead of making the (very) conservative approximation of +<code>getBounds()</code> from part (a), write an aspect instead that +remembers the return value from the first time +<code>getBounds()</code> has been called on a <code>Group</code>, and +returns that first <code>Rectangle</code> for every subsequent +call. </p> + +<p> <em>Hint: You can use an inter-type declaration to keep some +state for every <code>Group</code> object.</em> </p> + +<p> Your code should pass the JUnit test case +<code>tests.Test4b</code> with this change. +</p> + + +<h3>c. Invalidate, part 1</h3> + +<p> While caching in this way does save computation, it will lead to +incorrect bounding boxes if a <code>Group</code> is ever moved. +Change your aspect so that it invalidates the cache whenever the +<code>move()</code> method of <code>Group</code> is called. +</p> + +<p> Your code should pass the JUnit test case +<code>tests.Test4c</code> with this change. +</p> + +<h3>d. Invalidate, part 2</h3> + +<p> Of course, part (c) didn't really solve the problem. What if a +<code>Point</code> that is part of a <code>Group</code> moves? +Whenever either of a Point's fields are set it should invalidate the +caches of all enclosing groups. Use your solution to problem 3c to +modify your invalidation criteria in this way, but note that this is +slightly different than the problem in 3c: Here you care about fields, +where there you cared about method calls. </p> + +<p> Your code should pass the JUnit test case +<code>tests.Test4d</code> with this change. +</p> + +<h3>e. Invalidate, part 3</h3> + +<p> Did you really do part (d) correctly? Run the JUnit test +<code>tests.Test4e</code> to see. If you pass, congratulations, now +go help other people. Otherwise, you have fallen prey to our cruel +trap: Remember that whenever a point moves it should invalidate the +caches of <em>all</em> enclosing groups. </p> + +<hr> +</body> </html> diff --git a/docs/teaching/exercises/pre-letter.txt b/docs/teaching/exercises/pre-letter.txt new file mode 100644 index 000000000..4833beeb5 --- /dev/null +++ b/docs/teaching/exercises/pre-letter.txt @@ -0,0 +1,130 @@ +Dear OOPSLA 2002 attendee; + +We have you listed as being registered for tutorial T40, +Aspect-oriented programming with AspectJ. We are excited about giving +this tutorial, and hope you will enjoy the presentation, exercises and +discussion we have prepared. + +As with our past tutorials of this form, in the afternoon we would +like to break the attendees into groups of two or three and work +through a number of AspectJ exercises together. + +We will be bringing media and making ourselves available during breaks +for help with setup, but in order to jump straight in and give you the +most we can from this tutorial, it would really help us if many of you +had an AspectJ environment installed early. + +This message contains basic instructions on where to get some needed +tools. These instructions will not take much time. + +If you are planning to bring a laptop to the tutorial, would you +please take the time to do the steps outlined in this message? + +If you're not planning to, you might want to install an AspectJ +environment on your desktop anyway and try the instructions below, so +you will be comfortable when we meet on Wednesday. + +[If you already have a working AspectJ environment and are familliar +with it, we still recommend that you upgrade to 1.0.6 and follow the +steps below] + +Thank you, and please don't hesitate to contact us (at +support@aspectj.org) if you have any questions. See you on +Wednesday... + +-Erik Hilsdale, + Jim Hugunin, + and the whole AspectJ Team + + +Getting Ready for T40, Aspect-oriented programming with AspectJ +-------------------------------------- + +Overview: + + 0. Install AspectJ + 1. Download JUnit and put it on your classpath + 2. Test your setup + +------------------------------ +0. AspectJ + +Download the AspectJ 1.0.6 from + + http://aspectj.org/dl + +You should definitly download and intstall the tools package and the +docs package. If you plan to use JBuilder, Forte/NetBeans, Emacs, or +Eclipse for your development, you should download the appropriate +plugin. + + +------------------------------ +1. JUnit + +We use the JUnit framework for testing our exercises. Download JUnit +from + + http://www.junit.org + +and place junit.jar on your CLASSPATH. + + +------------------------------ +2. Test your setup + +a. Create a file "Hello.java" with this class: + + class Hello { + public static void main(String[] args) { + System.err.println(getHelloString()); + } + public static String getHelloString() { + return "Hello, WORLD"; + } + } + +b. Compile the class with ajc and run it... + + > ajc Hello.java + > java Hello + Hello, WORLD + +c. Create a file "TestHello.java" with this class: + + public class TestHello extends junit.framework.TestCase { + public TestHello(String name) { + super(name); + } + public static void main(String[] args) { + junit.textui.TestRunner.run(TestHello.class); + } + public void testHello() { + assertEquals("Hello, OOPSLA", Hello.getHelloString()); + } + } + +d. Compile the class with ajc and run it... + + > ajc TestHello.java + > java TestHello + .F + Time: 0.01 + There was 1 failure: + 1) testHello(TestHello)junit.framework.ComparisonFailure: + expected:<...OOPSLA> but was:<...WORLD> + at TestHello.testHello(TestHello.java:9) + at TestHello.main(TestHello.java:6) + + FAILURES!!! + Tests run: 1, Failures: 1, Errors: 0 + +e. Oops... the test case seems to want a different string than the + tested class. Fix that, compile whichever file you changed with + ajc, run the tester again, and you're done. Thanks! + + > java TestHello + . + Time: 0 + + OK (1 test) diff --git a/docs/teaching/exercises/setpaths b/docs/teaching/exercises/setpaths new file mode 100644 index 000000000..1e9a858c4 --- /dev/null +++ b/docs/teaching/exercises/setpaths @@ -0,0 +1,14 @@ +#!/bin/sh
+
+# Change this to be the full path for this directory
+EXTRACTION=$HOME/aj-oopsla
+
+if [ "$JAVA_HOME" = "" ]
+then
+ echo Please remember to manually set $JAVA_HOME to
+ echo the location of your java installation
+fi
+
+export ASPECTJ_HOME=$EXTRACTION/aspectj
+export PATH=$ASPECTJ_HOME/bin:$PATH
+export CLASSPATH=.:$ASPECTJ_HOME/lib/aspectjrt.jar:$EXTRACTION/junit.jar
diff --git a/docs/teaching/exercises/setpaths.bat b/docs/teaching/exercises/setpaths.bat new file mode 100644 index 000000000..bfb9a8046 --- /dev/null +++ b/docs/teaching/exercises/setpaths.bat @@ -0,0 +1,15 @@ +@echo off
+
+rem Change this to be the full path for this directory
+set EXTRACTION=c:\aj-oopsla
+
+if exist "%JAVA_HOME%\bin\java.exe" goto haveJava
+if exist "%JAVA_HOME%\bin\java.bat" goto haveJava
+if exist "%JAVA_HOME%\bin\java" goto haveJava
+echo java does not exist as %JAVA_HOME%\bin\java
+echo please fix the JAVA_HOME environment variable
+
+:haveJava
+set ASPECTJ_HOME=%EXTRACTION%\aspectj
+set PATH=%ASPECTJ_HOME%\bin;%PATH%
+set CLASSPATH=.;%ASPECTJ_HOME%\lib\aspectjrt.jar;%EXTRACTION%\junit.jar
diff --git a/docs/teaching/exercises/support/Log.java b/docs/teaching/exercises/support/Log.java new file mode 100644 index 000000000..37d4d7ad2 --- /dev/null +++ b/docs/teaching/exercises/support/Log.java @@ -0,0 +1,45 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package support; + +public class Log { + static StringBuffer data = new StringBuffer(); + + public static void traceObject(Object o) { + throw new UnsupportedOperationException(); + } + + public static void log(String s) { + data.append(s); + data.append(';'); + } + + public static void logClassName(Class _class) { + String name = _class.getName(); + int dot = name.lastIndexOf('.'); + if (dot == -1) { + log(name); + } else { + log(name.substring(dot+1, name.length())); + } + } + + public static String getString() { + return data.toString(); + } + + public static void clear() { + data.setLength(0); + } +} diff --git a/docs/teaching/exercises/tests/Test.java b/docs/teaching/exercises/tests/Test.java new file mode 100644 index 000000000..e4f5b60f9 --- /dev/null +++ b/docs/teaching/exercises/tests/Test.java @@ -0,0 +1,80 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; + +import junit.framework.*; + +public class Test extends TestCase { + public Test(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test.class); + } + + Box bb; + Point p1; + Point p2; + Line l1; + SlothfulPoint sloth1; + Group g; + + public void setUp() { + p1 = new Point(10, 100); + p2 = new Point(20, 200); + l1 = new Line(p1, p2); + bb = new Box(5, 5, 10, 10); + sloth1 = new SlothfulPoint(0, 0); + g = new Group(p1); + } + + public final void testCreate() { + assertEquals(p1.getX(), 10); + assertEquals(p1.getY(), 100); + + assertEquals(l1.getP1(), p1); + assertEquals(l1.getP2(), p2); + } + + public final void testSetPoint() { + p1.setX(20); + assertEquals(p1.getX(), 20); + assertEquals(p1.getY(), 100); + + p1.setY(10); + assertEquals(p1.getX(), 20); + assertEquals(p1.getY(), 10); + } + + public final void testMoveLine1() { + l1.move(40, 40); + assertEquals(l1.getP1(), p1); + assertEquals(l1.getP2(), p2); + + assertEquals(p1.getX(), 50); + assertEquals(p1.getY(), 140); + + assertEquals(p2.getX(), 60); + assertEquals(p2.getY(), 240); + } + + public final void testMoveLine2() { + l1.move(-10, -10); + assertEquals(p1.getX(), 0); + assertEquals(p1.getY(), 90); + + assertEquals(p2.getX(), 10); + assertEquals(p2.getY(), 190); + } +} diff --git a/docs/teaching/exercises/tests/Test1a.java b/docs/teaching/exercises/tests/Test1a.java new file mode 100644 index 000000000..b8bb2e120 --- /dev/null +++ b/docs/teaching/exercises/tests/Test1a.java @@ -0,0 +1,55 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import support.Log; + +import junit.framework.*; + +public class Test1a extends Test { + public Test1a(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test1a.class); + } + + public void setUp() { + Log.clear(); + super.setUp(); + } + + public void testCreateLog() { + assertEquals("", Log.getString()); + } + + public void testSetXPointLog() { + p1.setX(20); + assertEquals("set;", Log.getString()); + } + + public void testSetYPointLog() { + p1.setY(10); + assertEquals("", Log.getString()); + } + + public void testGetYPointLog() { + p1.getY(); + assertEquals("", Log.getString()); + } + + public void testMoveLineLog() { + l1.move(40, 40); + assertEquals("", Log.getString()); + } +} diff --git a/docs/teaching/exercises/tests/Test2a.java b/docs/teaching/exercises/tests/Test2a.java new file mode 100644 index 000000000..21ce08a9f --- /dev/null +++ b/docs/teaching/exercises/tests/Test2a.java @@ -0,0 +1,55 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; + +import junit.framework.*; + +public class Test2a extends Test { + public Test2a(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test2a.class); + } + + public void setUp() { + super.setUp(); + } + + public void testTooSmall() { + try { + p1.setX(-10); + fail("should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException ea) { + } + } + + + public void testTooBig() { + try { + p1.setY(1000); + fail("should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException ea) { + } + } + + + public void testMove() { + try { + l1.move(-500, -500); + fail("should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException ea) { + } + } +} diff --git a/docs/teaching/exercises/tests/Test2b.java b/docs/teaching/exercises/tests/Test2b.java new file mode 100644 index 000000000..63a10b7b0 --- /dev/null +++ b/docs/teaching/exercises/tests/Test2b.java @@ -0,0 +1,37 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; + +import junit.framework.*; + +public class Test2b extends Test { + public Test2b(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test2b.class); + } + + public void setUp() { + super.setUp(); + } + + public void testNull() { + try { + g.add(null); + fail("should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException ea) { + } + } +} diff --git a/docs/teaching/exercises/tests/Test2c.java b/docs/teaching/exercises/tests/Test2c.java new file mode 100644 index 000000000..cfcb0d1d8 --- /dev/null +++ b/docs/teaching/exercises/tests/Test2c.java @@ -0,0 +1,45 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; + +import junit.framework.*; + +public class Test2c extends Test { + public Test2c(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test2c.class); + } + + public void setUp() { + super.setUp(); + } + + public void testNull() { + try { + g.add(null); + fail("should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException ea) { + } + } + + public void testSelf() { + try { + g.add(g); + fail("should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException ea) { + } + } +} diff --git a/docs/teaching/exercises/tests/Test2d.java b/docs/teaching/exercises/tests/Test2d.java new file mode 100644 index 000000000..89e47c088 --- /dev/null +++ b/docs/teaching/exercises/tests/Test2d.java @@ -0,0 +1,37 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; + +import junit.framework.*; + +public class Test2d extends Test { + public Test2d(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test2d.class); + } + + public void setUp() { + super.setUp(); + } + + public void testSetting() { + try { + sloth1.setX(10); + fail("should have thrown RuntimeException"); + } catch (RuntimeException ea) { + } + } +} diff --git a/docs/teaching/exercises/tests/Test2e.java b/docs/teaching/exercises/tests/Test2e.java new file mode 100644 index 000000000..57af08501 --- /dev/null +++ b/docs/teaching/exercises/tests/Test2e.java @@ -0,0 +1,42 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; + +import junit.framework.*; + +public class Test2e extends Test { + public Test2e(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test2e.class); + } + + public void setUp() { + super.setUp(); + } + + public void testEasy() { + Box sq = new Box(0, 0, 10, 10); + sq.move(5,5); + assertEquals(sq.getP0().getX(), 5); + assertEquals(sq.getP0().getY(), 5); + + try { + sq.getP0().setX(100); + sq.move(37, 1); + fail("should have thrown IllegalStateException"); + } catch (IllegalStateException e) { } + } +} diff --git a/docs/teaching/exercises/tests/Test2f.java b/docs/teaching/exercises/tests/Test2f.java new file mode 100644 index 000000000..da63b12e1 --- /dev/null +++ b/docs/teaching/exercises/tests/Test2f.java @@ -0,0 +1,42 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; + +import junit.framework.*; + +public class Test2f extends Test { + public Test2f(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test2f.class); + } + + public void setUp() { + super.setUp(); + } + + public void testEasy() { + Box sq = new Box(0, 0, 10, 10); + sq.move(5,5); + assertEquals(sq.getP0().getX(), 5); + assertEquals(sq.getP0().getY(), 5); + + try { + sq.getP0().setX(100); + sq.getP1(); + fail("should have thrown IllegalStateException"); + } catch (IllegalStateException e) { } + } +} diff --git a/docs/teaching/exercises/tests/Test2g.java b/docs/teaching/exercises/tests/Test2g.java new file mode 100644 index 000000000..7ed9ba341 --- /dev/null +++ b/docs/teaching/exercises/tests/Test2g.java @@ -0,0 +1,42 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; + +import junit.framework.*; + +public class Test2g extends Test { + public Test2g(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test2g.class); + } + + public void setUp() { + super.setUp(); + } + + public void testBounds() { + p1.setX(FigureElement.MAX_VALUE + 1); + assertEquals(FigureElement.MAX_VALUE, p1.getX()); + p1.setY(FigureElement.MIN_VALUE - 1); + assertEquals(FigureElement.MIN_VALUE, p1.getY()); + } + + public void testBox() { + Box s = new Box(50, 50, 20000, 20000); + assertEquals(FigureElement.MAX_VALUE, s.getP2().getX()); + assertEquals(FigureElement.MAX_VALUE, s.getP2().getY()); + } +} diff --git a/docs/teaching/exercises/tests/Test2h.java b/docs/teaching/exercises/tests/Test2h.java new file mode 100644 index 000000000..9ed695d9b --- /dev/null +++ b/docs/teaching/exercises/tests/Test2h.java @@ -0,0 +1,42 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; + +import junit.framework.*; + +public class Test2h extends Test { + public Test2h(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test2h.class); + } + + public void setUp() { + super.setUp(); + } + + public void testSloth() { + FigureElement fe = new SlothfulPoint(10, 10); + try { + fe.move(10, 10); + fail("should have thrown IllegalStateException"); + } catch (IllegalStateException e) { } + } + + public void movePoints() { + p1.move(30, 45); + p2.move(10, 33); + } +} diff --git a/docs/teaching/exercises/tests/Test3a.java b/docs/teaching/exercises/tests/Test3a.java new file mode 100644 index 000000000..3cb063251 --- /dev/null +++ b/docs/teaching/exercises/tests/Test3a.java @@ -0,0 +1,49 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import support.Log; + +import junit.framework.*; + +public class Test3a extends Test { + public Test3a(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test3a.class); + } + + public void setUp() { + Log.clear(); + super.setUp(); + } + + public void testCreateLog() { + assertEquals("", Log.getString()); + } + + public void testMovePointLog() { + p1.move(20, 30); + assertEquals("moving;", Log.getString()); + } + + public void testSetYPointLog() { + assertEquals("", Log.getString()); + } + + public void testGetYPointLog() { + p1.getY(); + assertEquals("", Log.getString()); + } +} diff --git a/docs/teaching/exercises/tests/Test3b.java b/docs/teaching/exercises/tests/Test3b.java new file mode 100644 index 000000000..6ec933cee --- /dev/null +++ b/docs/teaching/exercises/tests/Test3b.java @@ -0,0 +1,54 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import support.Log; + +import junit.framework.*; + +public class Test3b extends Test { + public Test3b(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test3b.class); + } + + public void setUp() { + super.setUp(); + Log.clear(); + } + + public void testCreateLog() { + assertEquals("", Log.getString()); + } + + public void testCreateWithPointLog() { + g = new Group(p1); + assertEquals("adding Point;", Log.getString()); + } + + public void testCreateWithoutPointLog() { + g = new Group(l1); + assertEquals("", Log.getString()); + } + + public void testAddPointLog() { + g.add(p1); + assertEquals("adding Point;", Log.getString()); + } + public void testAddNonPointLog() { + g.add(l1); + assertEquals("", Log.getString()); + } +} diff --git a/docs/teaching/exercises/tests/Test3c.java b/docs/teaching/exercises/tests/Test3c.java new file mode 100644 index 000000000..6c135e91c --- /dev/null +++ b/docs/teaching/exercises/tests/Test3c.java @@ -0,0 +1,47 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import support.Log; + +import junit.framework.*; + +public class Test3c extends Test { + public Test3c(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test3c.class); + } + + public void setUp() { + Log.clear(); + super.setUp(); + } + + public void testCreateLog() { + assertEquals("", Log.getString()); + } + + public void testMoveLonePoint() { + p1 = new Point(0, 0); + p1.move(37, 88); + assertEquals("moving as a part of null;", Log.getString()); + } + + public void testMoveGroupedPoint() { + g = new Group(p1); + p1.move(0, 0); + assertEquals("moving as a part of " + g + ";", Log.getString()); + } +} diff --git a/docs/teaching/exercises/tests/Test4a.java b/docs/teaching/exercises/tests/Test4a.java new file mode 100644 index 000000000..ddb18415a --- /dev/null +++ b/docs/teaching/exercises/tests/Test4a.java @@ -0,0 +1,38 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import java.awt.Rectangle; + +import junit.framework.*; + +public class Test4a extends Test { + Rectangle wholeCanvas = + new Rectangle(FigureElement.MIN_VALUE, FigureElement.MIN_VALUE, + FigureElement.MAX_VALUE, FigureElement.MAX_VALUE); + + public Test4a(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test4a.class); + } + + public void setUp() { + super.setUp(); + } + + public void testGroupBounds() { + assertEquals(g.getBounds(), wholeCanvas); + } +} diff --git a/docs/teaching/exercises/tests/Test4b.java b/docs/teaching/exercises/tests/Test4b.java new file mode 100644 index 000000000..609289508 --- /dev/null +++ b/docs/teaching/exercises/tests/Test4b.java @@ -0,0 +1,70 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import java.awt.Rectangle; + +import junit.framework.*; + +public class Test4b extends Test { + + public Test4b(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test4b.class); + } + + public void setUp() { + super.setUp(); + } + + public void testBasicEquality() { + assertTrue(g.getBounds() == g.getBounds()); + } + + public void testEqualityAfterAddition() { + Point p0 = new Point(1, 2); + Point p1 = new Point(2, 3); + + Group g0 = new Group(p0); + Group g1 = new Group(p1); + + Rectangle r0 = g0.getBounds(); + Rectangle r1 = g1.getBounds(); + assertTrue(r0 != r1); + g0.add(new Point(37, 90)); + assertTrue(g0.getBounds() == r0); + assertTrue(g1.getBounds() != r0); + assertTrue(g0.getBounds() != r1); + assertTrue(g1.getBounds() == r1); + + g1.add(new Point(4, 8)); + assertTrue(g0.getBounds() == r0); + assertTrue(g1.getBounds() != r0); + assertTrue(g0.getBounds() != r1); + assertTrue(g1.getBounds() == r1); + } + + public void testNotWholeCanvas() { + assertTrue("bounds for this group should not be the whole canvas", + g.getBounds().getWidth() < + (FigureElement.MAX_VALUE - FigureElement.MIN_VALUE)); + assertTrue("bounds for this group should not be the whole canvas", + g.getBounds().getHeight() < + (FigureElement.MAX_VALUE - FigureElement.MIN_VALUE)); + + } +} + + diff --git a/docs/teaching/exercises/tests/Test4c.java b/docs/teaching/exercises/tests/Test4c.java new file mode 100644 index 000000000..b5bf8f708 --- /dev/null +++ b/docs/teaching/exercises/tests/Test4c.java @@ -0,0 +1,84 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import java.awt.Rectangle; + +import junit.framework.*; + +public class Test4c extends Test { + + public Test4c(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test4c.class); + } + + public void setUp() { + super.setUp(); + } + + public void testBasicEquality() { + assertTrue(g.getBounds() == g.getBounds()); + } + + public void testEqualityAfterAddition() { + Point p0 = new Point(1, 2); + Point p1 = new Point(2, 3); + + Group g0 = new Group(p0); + Group g1 = new Group(p1); + + Rectangle r0 = g0.getBounds(); + Rectangle r1 = g1.getBounds(); + assertTrue(r0 != r1); + g0.add(new Point(37, 90)); + assertTrue(g0.getBounds() == r0); + assertTrue(g1.getBounds() != r0); + assertTrue(g0.getBounds() != r1); + assertTrue(g1.getBounds() == r1); + + g1.add(new Point(4, 8)); + assertTrue(g0.getBounds() == r0); + assertTrue(g1.getBounds() != r0); + assertTrue(g0.getBounds() != r1); + assertTrue(g1.getBounds() == r1); + } + + public void testEqualityAfterMove() { + Point p0 = new Point(1, 2); + Point p1 = new Point(2, 3); + + Group g0 = new Group(p0); + Group g1 = new Group(p1); + + Rectangle r0 = g0.getBounds(); + Rectangle r1 = g1.getBounds(); + assertTrue(r0 != r1); + assertTrue(g0.getBounds() == r0); + assertTrue(g1.getBounds() != r0); + assertTrue(g0.getBounds() != r1); + assertTrue(g1.getBounds() == r1); + + g0.move(3, 1); + Rectangle r00 = g0.getBounds(); + Rectangle r10 = g1.getBounds(); + + assertTrue(r10 != r00); + assertTrue(r0 != r00); + assertTrue(g0.getBounds() == r00); + } +} + + diff --git a/docs/teaching/exercises/tests/Test4d.java b/docs/teaching/exercises/tests/Test4d.java new file mode 100644 index 000000000..e4458c6a4 --- /dev/null +++ b/docs/teaching/exercises/tests/Test4d.java @@ -0,0 +1,81 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import java.awt.Rectangle; + +import junit.framework.*; + +public class Test4d extends Test { + + public Test4d(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test4d.class); + } + + public void setUp() { + super.setUp(); + } + + public void testBasicEquality() { + assertTrue(g.getBounds() == g.getBounds()); + } + + public void testNonGroupMove() { + p1.move(3, 27); + } + + public void testEqualityAfterAddition() { + Rectangle r = g.getBounds(); + g.add(new Point(37, 90)); + assertTrue(g.getBounds() == r); + } + + public void testEqualityAfterMove() { + Point p0 = new Point(1, 2); + Point p1 = new Point(2, 3); + + Group g0 = new Group(p0); + Group g1 = new Group(p1); + + Rectangle r0 = g0.getBounds(); + Rectangle r1 = g1.getBounds(); + assertTrue(r0 != r1); + assertTrue(g0.getBounds() == r0); + assertTrue(g1.getBounds() != r0); + assertTrue(g0.getBounds() != r1); + assertTrue(g1.getBounds() == r1); + + p0.move(3, 1); + Rectangle r00 = g0.getBounds(); + Rectangle r10 = g1.getBounds(); + + assertTrue(r10 != r00); + assertTrue(r0 != r00); + assertTrue(g0.getBounds() == r00); + } + + public void testEqualityAfterMove0() { + g = new Group(p1); + Rectangle r0 = g.getBounds(); + assertTrue(g.getBounds() == r0); + p1.move(3, 1); + Rectangle r1 = g.getBounds(); + assertTrue(r0 != r1); + assertTrue(r1 == g.getBounds()); + } +} + + diff --git a/docs/teaching/exercises/tests/Test4e.java b/docs/teaching/exercises/tests/Test4e.java new file mode 100644 index 000000000..f6a3635d2 --- /dev/null +++ b/docs/teaching/exercises/tests/Test4e.java @@ -0,0 +1,68 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import java.awt.Rectangle; + +import junit.framework.*; + +public class Test4e extends Test { + + public Test4e(String name) { super(name); } + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test4e.class); + } + + public void setUp() { + super.setUp(); + } + + public void testBasicEquality() { + assertTrue(g.getBounds() == g.getBounds()); + } + + public void testNonGroupMove() { + p1.move(3, 27); + } + + public void testEqualityAfterAddition() { + Rectangle r = g.getBounds(); + g.add(new Point(37, 90)); + assertTrue(g.getBounds() == r); + } + + public void testEqualityAfterMove() { + g = new Group(p1); + Rectangle r0 = g.getBounds(); + assertTrue(g.getBounds() == r0); + p1.move(3, 1); + Rectangle r1 = g.getBounds(); + assertTrue(r0 != r1); + assertTrue(r1 == g.getBounds()); + } + + public void testSecondEnclosingGroup() { + g = new Group(p1); + Group h = new Group(g); + Rectangle r0 = h.getBounds(); + assertTrue(h.getBounds() == r0); + p1.move(3, 1); + Rectangle r1 = h.getBounds(); + assertTrue(r0 != r1); + assertTrue(r1 == h.getBounds()); + } +} + + diff --git a/docs/teaching/oneHour.ppt b/docs/teaching/oneHour.ppt Binary files differnew file mode 100644 index 000000000..c6a00c4e3 --- /dev/null +++ b/docs/teaching/oneHour.ppt diff --git a/docs/teaching/readme.txt b/docs/teaching/readme.txt new file mode 100644 index 000000000..f346cd414 --- /dev/null +++ b/docs/teaching/readme.txt @@ -0,0 +1,11 @@ +These presentations (oneHour.ppt, tutorial.ppt, and the teaching materials in exercises) are +Copyright (c) 1998-2002 Palo Alto Research Center, Incorporated (PARC). +All rights reserved. + + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * PARC initial implementation
\ No newline at end of file diff --git a/docs/teaching/tutorial.ppt b/docs/teaching/tutorial.ppt Binary files differnew file mode 100644 index 000000000..0ba0c5b20 --- /dev/null +++ b/docs/teaching/tutorial.ppt |