ソースを参照

Addendum to the original contribution from PARC. Three presentations:

oneHour talk
three hour tutorial
six hour tutorial including exercises
tags/V1_1_1
jhugunin 21年前
コミット
57445dd3ec
58個のファイルの変更3192行の追加0行の削除
  1. 22
    0
      docs/teaching/exercises/answers/Answer1a.java
  2. 21
    0
      docs/teaching/exercises/answers/Answer1b.java
  3. 21
    0
      docs/teaching/exercises/answers/Answer1c.java
  4. 23
    0
      docs/teaching/exercises/answers/Answer1d.java
  5. 26
    0
      docs/teaching/exercises/answers/Answer2a.java
  6. 26
    0
      docs/teaching/exercises/answers/Answer2b.java
  7. 31
    0
      docs/teaching/exercises/answers/Answer2c.java
  8. 24
    0
      docs/teaching/exercises/answers/Answer2d.java
  9. 24
    0
      docs/teaching/exercises/answers/Answer2e.java
  10. 24
    0
      docs/teaching/exercises/answers/Answer2f.java
  11. 27
    0
      docs/teaching/exercises/answers/Answer2g.java
  12. 31
    0
      docs/teaching/exercises/answers/Answer2h.java
  13. 23
    0
      docs/teaching/exercises/answers/Answer3a.java
  14. 26
    0
      docs/teaching/exercises/answers/Answer3b.java
  15. 34
    0
      docs/teaching/exercises/answers/Answer3c.java
  16. 28
    0
      docs/teaching/exercises/answers/Answer4a.java
  17. 29
    0
      docs/teaching/exercises/answers/Answer4b.java
  18. 33
    0
      docs/teaching/exercises/answers/Answer4c.java
  19. 42
    0
      docs/teaching/exercises/answers/Answer4d.java
  20. 44
    0
      docs/teaching/exercises/answers/Answer4e.java
  21. 29
    0
      docs/teaching/exercises/base.lst
  22. 64
    0
      docs/teaching/exercises/figures/Box.java
  23. 30
    0
      docs/teaching/exercises/figures/FigureElement.java
  24. 97
    0
      docs/teaching/exercises/figures/Group.java
  25. 64
    0
      docs/teaching/exercises/figures/Line.java
  26. 58
    0
      docs/teaching/exercises/figures/Point.java
  27. 47
    0
      docs/teaching/exercises/figures/ShapeFigureElement.java
  28. 50
    0
      docs/teaching/exercises/figures/SlothfulPoint.java
  29. 181
    0
      docs/teaching/exercises/figures/gui/FigurePanel.java
  30. 25
    0
      docs/teaching/exercises/figures/gui/LogAdapter.java
  31. 31
    0
      docs/teaching/exercises/figures/gui/Main.java
  32. 5
    0
      docs/teaching/exercises/guibase.lst
  33. 769
    0
      docs/teaching/exercises/index.html
  34. 130
    0
      docs/teaching/exercises/pre-letter.txt
  35. 14
    0
      docs/teaching/exercises/setpaths
  36. 15
    0
      docs/teaching/exercises/setpaths.bat
  37. 45
    0
      docs/teaching/exercises/support/Log.java
  38. 80
    0
      docs/teaching/exercises/tests/Test.java
  39. 55
    0
      docs/teaching/exercises/tests/Test1a.java
  40. 55
    0
      docs/teaching/exercises/tests/Test2a.java
  41. 37
    0
      docs/teaching/exercises/tests/Test2b.java
  42. 45
    0
      docs/teaching/exercises/tests/Test2c.java
  43. 37
    0
      docs/teaching/exercises/tests/Test2d.java
  44. 42
    0
      docs/teaching/exercises/tests/Test2e.java
  45. 42
    0
      docs/teaching/exercises/tests/Test2f.java
  46. 42
    0
      docs/teaching/exercises/tests/Test2g.java
  47. 42
    0
      docs/teaching/exercises/tests/Test2h.java
  48. 49
    0
      docs/teaching/exercises/tests/Test3a.java
  49. 54
    0
      docs/teaching/exercises/tests/Test3b.java
  50. 47
    0
      docs/teaching/exercises/tests/Test3c.java
  51. 38
    0
      docs/teaching/exercises/tests/Test4a.java
  52. 70
    0
      docs/teaching/exercises/tests/Test4b.java
  53. 84
    0
      docs/teaching/exercises/tests/Test4c.java
  54. 81
    0
      docs/teaching/exercises/tests/Test4d.java
  55. 68
    0
      docs/teaching/exercises/tests/Test4e.java
  56. バイナリ
      docs/teaching/oneHour.ppt
  57. 11
    0
      docs/teaching/readme.txt
  58. バイナリ
      docs/teaching/tutorial.ppt

+ 22
- 0
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";
}

+ 21
- 0
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";
}

+ 21
- 0
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";
}

+ 23
- 0
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";
}

+ 26
- 0
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");
}
}
}

+ 26
- 0
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");
}
}
}

+ 31
- 0
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");
}

}
}

+ 24
- 0
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");
}
}
}

+ 24
- 0
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();
}
}

+ 24
- 0
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();
}
}

+ 27
- 0
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);
}
}

+ 31
- 0
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");
}
}
}

+ 23
- 0
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");
}
}

+ 26
- 0
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");
}
}

+ 34
- 0
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);
}

}

+ 28
- 0
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;
}
}

+ 29
- 0
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;
}
}

+ 33
- 0
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;
}
}

+ 42
- 0
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;
}
}
}

+ 44
- 0
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;
}
}
}

+ 29
- 0
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

+ 64
- 0
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());
}
}


+ 30
- 0
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);
}

+ 97
- 0
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();
}
}


+ 64
- 0
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();
}
}


+ 58
- 0
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);
}
}


+ 47
- 0
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);
}
}

+ 50
- 0
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);
}
}


+ 181
- 0
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;
}
}
}

+ 25
- 0
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);
}
}
}

+ 31
- 0
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);
}

}

+ 5
- 0
docs/teaching/exercises/guibase.lst ファイルの表示

@@ -0,0 +1,5 @@
-argfile
base.lst
figures/gui/FigurePanel.java
figures/gui/Main.java
figures/gui/LogAdapter.java

+ 769
- 0
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>
&gt; 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) &amp;&amp; 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>&lt;pointcut here&gt;</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.*) &amp;&amp; args(newValue) {
if (newValue &lt; FigureElement.MIN_VALUE) {
throw new IllegalArgumentException("too small");
} else if (newValue &gt; 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))
&amp;&amp; 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:&lt;set;&gt; but was:&lt;&gt;
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>

+ 130
- 0
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)

+ 14
- 0
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

+ 15
- 0
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

+ 45
- 0
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);
}
}

+ 80
- 0
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);
}
}

+ 55
- 0
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());
}
}

+ 55
- 0
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) {
}
}
}

+ 37
- 0
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) {
}
}
}

+ 45
- 0
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) {
}
}
}

+ 37
- 0
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) {
}
}
}

+ 42
- 0
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) { }
}
}

+ 42
- 0
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) { }
}
}

+ 42
- 0
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());
}
}

+ 42
- 0
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);
}
}

+ 49
- 0
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());
}
}

+ 54
- 0
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());
}
}

+ 47
- 0
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());
}
}

+ 38
- 0
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);
}
}

+ 70
- 0
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));

}
}



+ 84
- 0
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);
}
}



+ 81
- 0
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());
}
}



+ 68
- 0
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());
}
}



バイナリ
docs/teaching/oneHour.ppt ファイルの表示


+ 11
- 0
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

バイナリ
docs/teaching/tutorial.ppt ファイルの表示


読み込み中…
キャンセル
保存